1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_canvas.hxx" 30 31 #include <ctype.h> // don't ask. msdev breaks otherwise... 32 #include <canvas/debug.hxx> 33 #include <canvas/verbosetrace.hxx> 34 35 #include <basegfx/matrix/b2dhommatrix.hxx> 36 #include <basegfx/numeric/ftools.hxx> 37 #include "dx_bitmap.hxx" 38 #include "dx_textlayout.hxx" 39 #include "dx_spritecanvas.hxx" 40 #include "dx_textlayout_drawhelper.hxx" 41 42 43 using namespace ::com::sun::star; 44 45 namespace dxcanvas 46 { 47 TextLayout::TextLayout( const rendering::StringContext& aText, 48 sal_Int8 nDirection, 49 sal_Int64 /*nRandomSeed*/, 50 const CanvasFont::ImplRef& rFont ) : 51 TextLayout_Base( m_aMutex ), 52 maText( aText ), 53 maLogicalAdvancements(), 54 mpFont( rFont ), 55 mnTextDirection( nDirection ) 56 { 57 } 58 59 TextLayout::~TextLayout() 60 { 61 } 62 63 void SAL_CALL TextLayout::disposing() 64 { 65 mpFont.reset(); 66 } 67 68 // XTextLayout 69 uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > > SAL_CALL TextLayout::queryTextShapes( ) throw (uno::RuntimeException) 70 { 71 ::osl::MutexGuard aGuard( m_aMutex ); 72 73 // TODO 74 return uno::Sequence< uno::Reference< rendering::XPolyPolygon2D > >(); 75 } 76 77 uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryInkMeasures( ) throw (uno::RuntimeException) 78 { 79 ::osl::MutexGuard aGuard( m_aMutex ); 80 81 // TODO 82 return uno::Sequence< geometry::RealRectangle2D >(); 83 } 84 85 uno::Sequence< geometry::RealRectangle2D > SAL_CALL TextLayout::queryMeasures( ) throw (uno::RuntimeException) 86 { 87 ::osl::MutexGuard aGuard( m_aMutex ); 88 89 // TODO 90 return uno::Sequence< geometry::RealRectangle2D >(); 91 } 92 93 uno::Sequence< double > SAL_CALL TextLayout::queryLogicalAdvancements( ) throw (uno::RuntimeException) 94 { 95 ::osl::MutexGuard aGuard( m_aMutex ); 96 97 return maLogicalAdvancements; 98 } 99 100 void SAL_CALL TextLayout::applyLogicalAdvancements( const uno::Sequence< double >& aAdvancements ) throw (lang::IllegalArgumentException, uno::RuntimeException) 101 { 102 ::osl::MutexGuard aGuard( m_aMutex ); 103 104 if( aAdvancements.getLength() != maText.Length ) 105 { 106 OSL_TRACE( "TextLayout::applyLogicalAdvancements(): mismatching number of advancements" ); 107 throw lang::IllegalArgumentException(); 108 } 109 110 maLogicalAdvancements = aAdvancements; 111 } 112 113 geometry::RealRectangle2D SAL_CALL TextLayout::queryTextBounds( ) throw (uno::RuntimeException) 114 { 115 ::osl::MutexGuard aGuard( m_aMutex ); 116 117 uno::Reference< rendering::XGraphicDevice > xGraphicDevice; 118 ::dxcanvas::TextLayoutDrawHelper aDrawHelper(xGraphicDevice); 119 120 // render text 121 const geometry::RealRectangle2D aBounds( 122 aDrawHelper.queryTextBounds( 123 maText, 124 maLogicalAdvancements, 125 mpFont.getRef(), 126 mpFont->getFontMatrix())); 127 128 return aBounds; 129 } 130 131 double SAL_CALL TextLayout::justify( double /*nSize*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException) 132 { 133 ::osl::MutexGuard aGuard( m_aMutex ); 134 135 // TODO 136 return 0.0; 137 } 138 139 double SAL_CALL TextLayout::combinedJustify( const uno::Sequence< uno::Reference< rendering::XTextLayout > >& /*aNextLayouts*/, 140 double /*nSize*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException) 141 { 142 ::osl::MutexGuard aGuard( m_aMutex ); 143 144 // TODO 145 return 0.0; 146 } 147 148 rendering::TextHit SAL_CALL TextLayout::getTextHit( const geometry::RealPoint2D& /*aHitPoint*/ ) throw (uno::RuntimeException) 149 { 150 ::osl::MutexGuard aGuard( m_aMutex ); 151 152 // TODO 153 return rendering::TextHit(); 154 } 155 156 rendering::Caret SAL_CALL TextLayout::getCaret( sal_Int32 /*nInsertionIndex*/, 157 sal_Bool /*bExcludeLigatures*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 158 { 159 ::osl::MutexGuard aGuard( m_aMutex ); 160 161 // TODO 162 return rendering::Caret(); 163 } 164 165 sal_Int32 SAL_CALL TextLayout::getNextInsertionIndex( sal_Int32 /*nStartIndex*/, 166 sal_Int32 /*nCaretAdvancement*/, 167 sal_Bool /*bExcludeLigatures*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 168 { 169 ::osl::MutexGuard aGuard( m_aMutex ); 170 171 // TODO 172 return 0; 173 } 174 175 uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryVisualHighlighting( sal_Int32 /*nStartIndex*/, 176 sal_Int32 /*nEndIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 177 { 178 ::osl::MutexGuard aGuard( m_aMutex ); 179 180 // TODO 181 return uno::Reference< rendering::XPolyPolygon2D >(); 182 } 183 184 uno::Reference< rendering::XPolyPolygon2D > SAL_CALL TextLayout::queryLogicalHighlighting( sal_Int32 /*nStartIndex*/, 185 sal_Int32 /*nEndIndex*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) 186 { 187 ::osl::MutexGuard aGuard( m_aMutex ); 188 189 // TODO 190 return uno::Reference< rendering::XPolyPolygon2D >(); 191 } 192 193 double SAL_CALL TextLayout::getBaselineOffset( ) throw (uno::RuntimeException) 194 { 195 ::osl::MutexGuard aGuard( m_aMutex ); 196 197 // TODO 198 return 0.0; 199 } 200 201 sal_Int8 SAL_CALL TextLayout::getMainTextDirection( ) throw (uno::RuntimeException) 202 { 203 ::osl::MutexGuard aGuard( m_aMutex ); 204 205 return mnTextDirection; 206 } 207 208 uno::Reference< rendering::XCanvasFont > SAL_CALL TextLayout::getFont( ) throw (uno::RuntimeException) 209 { 210 ::osl::MutexGuard aGuard( m_aMutex ); 211 212 return mpFont.getRef(); 213 } 214 215 rendering::StringContext SAL_CALL TextLayout::getText( ) throw (uno::RuntimeException) 216 { 217 ::osl::MutexGuard aGuard( m_aMutex ); 218 219 return maText; 220 } 221 222 namespace 223 { 224 // TODO(P2): Check whether this gets inlined. If not, make functor 225 // out of it 226 inline Gdiplus::PointF gdiPlusPointFromDx( const double& dx ) 227 { 228 return Gdiplus::PointF( static_cast<Gdiplus::REAL>(dx), 229 0.0f ); 230 } 231 } 232 233 bool TextLayout::draw( const GraphicsSharedPtr& rGraphics, 234 const rendering::ViewState& rViewState, 235 const rendering::RenderState& rRenderState, 236 const ::basegfx::B2ISize& rOutputOffset, 237 const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice, 238 bool bAlphaSurface ) const 239 { 240 ::osl::MutexGuard aGuard( m_aMutex ); 241 242 ::dxcanvas::TextLayoutDrawHelper aDrawHelper(xGraphicDevice); 243 244 // render text 245 aDrawHelper.drawText( 246 rGraphics, 247 rViewState, 248 rRenderState, 249 rOutputOffset, 250 maText, 251 maLogicalAdvancements, 252 mpFont.getRef(), 253 mpFont->getFontMatrix(), 254 bAlphaSurface); 255 256 return true; 257 } 258 259 260 #define SERVICE_NAME "com.sun.star.rendering.TextLayout" 261 #define IMPLEMENTATION_NAME "DXCanvas::TextLayout" 262 263 ::rtl::OUString SAL_CALL TextLayout::getImplementationName() throw( uno::RuntimeException ) 264 { 265 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) ); 266 } 267 268 sal_Bool SAL_CALL TextLayout::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException ) 269 { 270 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) ); 271 } 272 273 uno::Sequence< ::rtl::OUString > SAL_CALL TextLayout::getSupportedServiceNames() throw( uno::RuntimeException ) 274 { 275 uno::Sequence< ::rtl::OUString > aRet(1); 276 aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) ); 277 278 return aRet; 279 } 280 } 281