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