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