LibreOffice Module cppcanvas (master) 1
mtftools.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
22#include <com/sun/star/rendering/XCanvas.hpp>
29#include <rtl/math.hxx>
30#include <vcl/canvastools.hxx>
31#include <vcl/virdev.hxx>
32#include <vcl/metric.hxx>
33#include "mtftools.hxx"
34#include <outdevstate.hxx>
36
37
38using namespace ::com::sun::star;
39
40namespace cppcanvas::tools
41{
42 void initRenderState( rendering::RenderState& renderState,
43 const ::cppcanvas::internal::OutDevState& outdevState )
44 {
46 ::canvas::tools::setRenderStateTransform( renderState,
47 outdevState.transform );
48 renderState.Clip = outdevState.xClipPoly;
49 }
50
51 ::Size getBaselineOffset( const ::cppcanvas::internal::OutDevState& outdevState,
52 const VirtualDevice& rVDev )
53 {
54 const ::FontMetric& aMetric = rVDev.GetFontMetric();
55
56 // calc offset for text output, the XCanvas always renders
57 // baseline offset.
58 switch( outdevState.textReferencePoint )
59 {
60 case ALIGN_TOP:
61 return ::Size( 0,
62 aMetric.GetInternalLeading() + aMetric.GetAscent() );
63
64 case ALIGN_BASELINE:
65 return ::Size( 0, 0 );
66
67 case ALIGN_BOTTOM:
68 return ::Size( 0,
69 -aMetric.GetDescent() );
70
71 default:
72 throw css::uno::RuntimeException(
73 "tools::getBaselineOffset(): Unexpected TextAlign value" );
74 }
75 }
76
78 const VirtualDevice& rVDev )
79 {
80 // select size value in the middle of the available range,
81 // to have headroom both when map mode scales up, and when
82 // it scales down.
83 const ::Size aSizeLogic( 0x00010000L,
84 0x00010000L );
85
86 const ::Size aSizePixel( rVDev.LogicToPixel( aSizeLogic ) );
87
89 aSizePixel.Width() / static_cast<double>(aSizeLogic.Width()),
90 aSizePixel.Height() / static_cast<double>(aSizeLogic.Height()) );
91
92 return o_rMatrix;
93 }
94
96 const VirtualDevice& rVDev )
97 {
98 // retrieves scale
99 calcLogic2PixelLinearTransform(o_rMatrix, rVDev);
100
101 // translate according to curr map mode/pref map mode offset
102 const ::Point aEmptyPoint;
103 const ::Point& rTranslatedPoint(
104 rVDev.LogicToPixel( aEmptyPoint ));
105
106 o_rMatrix.translate(rTranslatedPoint.X(),
107 rTranslatedPoint.Y());
108
109 return o_rMatrix;
110 }
111
112 bool modifyClip( rendering::RenderState& o_rRenderState,
113 const struct ::cppcanvas::internal::OutDevState& rOutdevState,
114 const CanvasSharedPtr& rCanvas,
115 const ::basegfx::B2DPoint& rOffset,
116 const ::basegfx::B2DVector* pScaling,
117 const double* pRotation )
118 {
119 const bool bOffsetting( !rOffset.equalZero() );
120 const bool bScaling( pScaling &&
121 !rtl::math::approxEqual(pScaling->getX(), 1.0) &&
122 !rtl::math::approxEqual(pScaling->getY(), 1.0) );
123 const bool bRotation( pRotation &&
124 *pRotation != 0.0 );
125
126 if( !bOffsetting && !bScaling && !bRotation )
127 return false; // nothing to do
128
129 if( rOutdevState.clip.count() )
130 {
131 // general polygon case
132
133 ::basegfx::B2DPolyPolygon aLocalClip( rOutdevState.clip );
134 ::basegfx::B2DHomMatrix aTransform;
135
136 if( bOffsetting )
137 aTransform.translate( -rOffset.getX(),
138 -rOffset.getY() );
139 if( bScaling )
140 aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );
141
142 if( bRotation )
143 aTransform.rotate( - *pRotation );
144
145 aLocalClip.transform( aTransform );
146
147 o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
148 rCanvas->getUNOCanvas()->getDevice(),
149 aLocalClip );
150
151 return true;
152 }
153 else if( !rOutdevState.clipRect.IsEmpty() )
154 {
155 // simple rect case
156
157 const ::tools::Rectangle aLocalClipRect( rOutdevState.clipRect );
158
159 if( bRotation )
160 {
161 // rotation involved - convert to polygon first,
162 // then transform that
163 ::basegfx::B2DPolygon aLocalClip(
164 ::basegfx::utils::createPolygonFromRect(
166 ::basegfx::B2DHomMatrix aTransform;
167
168 if( bOffsetting )
169 aTransform.translate( -rOffset.getX(),
170 -rOffset.getY() );
171 if( bScaling )
172 aTransform.scale( 1.0/pScaling->getX(), 1.0/pScaling->getY() );
173
174 aTransform.rotate( - *pRotation );
175
176 aLocalClip.transform( aTransform );
177
178 o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
179 rCanvas->getUNOCanvas()->getDevice(),
180 ::basegfx::B2DPolyPolygon( aLocalClip ) );
181 }
182 else if( bScaling )
183 {
184 // scale and offset - do it on the fly, have to
185 // convert to float anyway.
186 o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
187 rCanvas->getUNOCanvas()->getDevice(),
189 ::basegfx::utils::createPolygonFromRect(
191 (aLocalClipRect.Left() - rOffset.getX())/pScaling->getX(),
192 (aLocalClipRect.Top() - rOffset.getY())/pScaling->getY(),
193 (aLocalClipRect.Right() - rOffset.getX())/pScaling->getX(),
194 (aLocalClipRect.Bottom() - rOffset.getY())/pScaling->getY() ) ) ) );
195 }
196 else
197 {
198 // offset only - do it on the fly, have to convert
199 // to float anyway.
200 o_rRenderState.Clip = ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(
201 rCanvas->getUNOCanvas()->getDevice(),
203 ::basegfx::utils::createPolygonFromRect(
204 ::basegfx::B2DRectangle( aLocalClipRect.Left() - rOffset.getX(),
205 aLocalClipRect.Top() - rOffset.getY(),
206 aLocalClipRect.Right() - rOffset.getX(),
207 aLocalClipRect.Bottom() - rOffset.getY() ) ) ) );
208 }
209
210 return true;
211 }
212
213 // empty clip, nothing to do
214 return false;
215 }
216
217 // create overline/underline/strikeout line info struct
218 TextLineInfo createTextLineInfo( const ::VirtualDevice& rVDev,
219 const ::cppcanvas::internal::OutDevState& rState )
220 {
221 const bool bOldMode( rVDev.IsMapModeEnabled() );
222
223 // #i68512# Force metric regeneration with mapmode enabled
224 // (prolly OutDev bug)
225 rVDev.GetFontMetric();
226
227 // will restore map mode below
228 const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( false );
229
230 const ::FontMetric aMetric = rVDev.GetFontMetric();
231
232 TextLineInfo aTextInfo(
233 (aMetric.GetDescent() + 2) / 4.0,
234 ((aMetric.GetInternalLeading() + 1.5) / 3.0),
235 (aMetric.GetInternalLeading() / 2.0) - aMetric.GetAscent(),
236 aMetric.GetDescent() / 2.0,
237 (aMetric.GetInternalLeading() - aMetric.GetAscent()) / 3.0,
238 rState.textOverlineStyle,
239 rState.textUnderlineStyle,
240 rState.textStrikeoutStyle );
241
242 const_cast< ::VirtualDevice& >(rVDev).EnableMapMode( bOldMode );
243
244 return aTextInfo;
245 }
246
247 namespace
248 {
249 void appendWaveline( ::basegfx::B2DPolyPolygon& o_rPoly,
250 const ::basegfx::B2DPoint& rStartPos,
251 const double nStartOffset,
252 const double nWidth,
253 const double nHeight,
254 sal_Int8 nLineStyle)
255 {
256 const double x(rStartPos.getX());
257 const double y(rStartPos.getY() + nStartOffset + nHeight);
258 double nWaveWidth = nHeight * 10.6 * 0.25;
259 // Offset for the double line.
260 double nOffset = 0.0;
261
262 if (nLineStyle == LINESTYLE_DOUBLEWAVE)
263 nOffset = -nHeight * 0.5;
264 else
265 nWaveWidth *= 2.0;
266
268 aLine.append(basegfx::B2DPoint(x, y + nOffset));
269 aLine.append(basegfx::B2DPoint(x + nWidth, y + nOffset));
270
271 o_rPoly.append(::basegfx::utils::createWaveline(aLine, nWaveWidth, nWaveWidth * 0.5));
272
273 if (nLineStyle == LINESTYLE_DOUBLEWAVE)
274 {
275 nOffset = nHeight * 1.2;
276
277 basegfx::B2DPolygon aLine2;
278 aLine2.append(basegfx::B2DPoint(x, y + nOffset));
279 aLine2.append(basegfx::B2DPoint(x + nWidth, y + nOffset));
280 o_rPoly.append(::basegfx::utils::createWaveline(aLine2, nWaveWidth, nWaveWidth * 0.5));
281 }
282 }
283
284 void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
285 const ::basegfx::B2DPoint& rStartPos,
286 const double nX1,
287 const double nY1,
288 const double nX2,
289 const double nY2 )
290 {
291 const double x( rStartPos.getX() );
292 const double y( rStartPos.getY() );
293
294 o_rPoly.append(
295 ::basegfx::utils::createPolygonFromRect(
296 ::basegfx::B2DRectangle( x + nX1, y + nY1, x + nX2, y + nY2 ) ) );
297 }
298
299 void appendRect( ::basegfx::B2DPolyPolygon& o_rPoly,
300 const double nX1,
301 const double nY1,
302 const double nX2,
303 const double nY2 )
304 {
305 o_rPoly.append(
306 ::basegfx::utils::createPolygonFromRect(
307 ::basegfx::B2DRectangle( nX1, nY1, nX2, nY2 ) ) );
308 }
309
310 bool appendDashes( ::basegfx::B2DPolyPolygon& o_rPoly,
311 const double nX,
312 double nY,
313 const double nLineWidth,
314 double nLineHeight,
315 sal_Int8 nLineStyle,
316 bool bIsOverline)
317 {
318 static const int aDottedArray[] = { 1, 1, 0}; // DOTTED LINE
319 static const int aDotDashArray[] = { 1, 1, 4, 1, 0}; // DASHDOT
320 static const int aDashDotDotArray[] = { 1, 1, 1, 1, 4, 1, 0}; // DASHDOTDOT
321 static const int aDashedArray[] = { 5, 2, 0}; // DASHED LINE
322 static const int aLongDashArray[] = { 7, 2, 0}; // LONGDASH
323 const int *pArray = nullptr;
324 bool bIsBold = false;
325
326 switch(nLineStyle)
327 {
329 bIsBold = true;
330 [[fallthrough]];
331 case LINESTYLE_DOTTED:
332 pArray = aDottedArray;
333 break;
334
336 bIsBold = true;
337 [[fallthrough]];
338 case LINESTYLE_DASH:
339 pArray = aDashedArray;
340 break;
341
343 bIsBold = true;
344 [[fallthrough]];
346 pArray = aLongDashArray;
347 break;
348
350 bIsBold = true;
351 [[fallthrough]];
353 pArray = aDotDashArray;
354 break;
356 bIsBold = true;
357 [[fallthrough]];
359 pArray = aDashDotDotArray;
360 break;
361 }
362
363 if (!pArray)
364 return false;
365
366 if (bIsBold)
367 {
368 if (bIsOverline)
369 nY -= nLineHeight;
370
371 nLineHeight *= 2;
372 }
373
374 const double nEnd = nX + nLineWidth;
375 sal_Int32 nIndex = 0;
376 bool bAppend = true;
377 double nX1 = nX;
378
379 while(nX1 < nEnd)
380 {
381 if (pArray[nIndex] == 0)
382 nIndex = 0;
383
384 const double nX2 = std::min(nEnd, nX1 + pArray[nIndex] * nLineHeight);
385
386 if (bAppend)
387 appendRect(o_rPoly, nX1, nY, nX2, nY + nLineHeight);
388
389 nX1 = nX2;
390
391 ++nIndex;
392
393 bAppend = !bAppend;
394 }
395 return true;
396 }
397
398 // create line actions for text such as underline and
399 // strikeout
400 void createOverlinePolyPolygon(::basegfx::B2DPolyPolygon& rTextLinesPolyPoly,
401 const ::basegfx::B2DPoint& rStartPos,
402 const double& rLineWidth,
403 const TextLineInfo& rTextLineInfo)
404 {
405 switch( rTextLineInfo.mnOverlineStyle )
406 {
407 case LINESTYLE_NONE: // nothing to do
409 break;
410
414 case LINESTYLE_WAVE:
415 appendWaveline(
416 rTextLinesPolyPoly,
417 rStartPos,
418 rTextLineInfo.mnOverlineOffset,
419 rLineWidth,
420 rTextLineInfo.mnOverlineHeight,
421 rTextLineInfo.mnOverlineStyle);
422
423 break;
424 case LINESTYLE_SINGLE:
425 appendRect(
426 rTextLinesPolyPoly,
427 rStartPos,
428 0,
429 rTextLineInfo.mnOverlineOffset,
430 rLineWidth,
431 rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
432 break;
433 case LINESTYLE_BOLD:
434 appendRect(
435 rTextLinesPolyPoly,
436 rStartPos,
437 0,
438 rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight,
439 rLineWidth,
440 rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight );
441 break;
442
443 case LINESTYLE_DOUBLE:
444 appendRect(
445 rTextLinesPolyPoly,
446 rStartPos,
447 0,
448 rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight * 2.0 ,
449 rLineWidth,
450 rTextLineInfo.mnOverlineOffset - rTextLineInfo.mnOverlineHeight );
451
452 appendRect(
453 rTextLinesPolyPoly,
454 rStartPos,
455 0,
456 rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight,
457 rLineWidth,
458 rTextLineInfo.mnOverlineOffset + rTextLineInfo.mnOverlineHeight * 2.0 );
459 break;
460
461 default:
462 if (!appendDashes(
463 rTextLinesPolyPoly,
464 rStartPos.getX(),
465 rStartPos.getY() + rTextLineInfo.mnOverlineOffset,
466 rLineWidth,
467 rTextLineInfo.mnOverlineHeight,
468 rTextLineInfo.mnOverlineStyle,
469 true))
470 {
471 ENSURE_OR_THROW( false,
472 "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected overline case" );
473 }
474 }
475 }
476
477 void createUnderlinePolyPolygon(::basegfx::B2DPolyPolygon& rTextLinesPolyPoly,
478 const ::basegfx::B2DPoint& rStartPos,
479 const double& rLineWidth,
480 const TextLineInfo& rTextLineInfo )
481 {
482
483 switch( rTextLineInfo.mnUnderlineStyle )
484 {
485 case LINESTYLE_NONE: // nothing to do
487 break;
488
492 case LINESTYLE_WAVE:
493 appendWaveline(
494 rTextLinesPolyPoly,
495 rStartPos,
496 rTextLineInfo.mnUnderlineOffset,
497 rLineWidth,
498 rTextLineInfo.mnLineHeight,
499 rTextLineInfo.mnUnderlineStyle);
500 break;
501 case LINESTYLE_SINGLE:
502 appendRect(
503 rTextLinesPolyPoly,
504 rStartPos,
505 0,
506 rTextLineInfo.mnUnderlineOffset,
507 rLineWidth,
508 rTextLineInfo.mnUnderlineOffset + rTextLineInfo.mnLineHeight );
509 break;
510
511 case LINESTYLE_BOLD:
512 appendRect(
513 rTextLinesPolyPoly,
514 rStartPos,
515 0,
516 rTextLineInfo.mnUnderlineOffset,
517 rLineWidth,
518 rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight );
519 break;
520
521 case LINESTYLE_DOUBLE:
522 appendRect(
523 rTextLinesPolyPoly,
524 rStartPos,
525 0,
526 rTextLineInfo.mnUnderlineOffset - rTextLineInfo.mnLineHeight,
527 rLineWidth,
528 rTextLineInfo.mnUnderlineOffset );
529
530 appendRect(
531 rTextLinesPolyPoly,
532 rStartPos,
533 0,
534 rTextLineInfo.mnUnderlineOffset + 2*rTextLineInfo.mnLineHeight,
535 rLineWidth,
536 rTextLineInfo.mnUnderlineOffset + 3*rTextLineInfo.mnLineHeight );
537 break;
538
539 default:
540 if (!appendDashes(
541 rTextLinesPolyPoly,
542 rStartPos.getX(),
543 rStartPos.getY() + rTextLineInfo.mnUnderlineOffset,
544 rLineWidth,
545 rTextLineInfo.mnLineHeight,
546 rTextLineInfo.mnUnderlineStyle,
547 false))
548 {
549 ENSURE_OR_THROW( false,
550 "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected underline case" );
551 }
552 }
553 }
554
555 void createStrikeoutPolyPolygon(::basegfx::B2DPolyPolygon& rTextLinesPolyPoly,
556 const ::basegfx::B2DPoint& rStartPos,
557 const double& rLineWidth,
558 const TextLineInfo& rTextLineInfo)
559 {
560 switch( rTextLineInfo.mnStrikeoutStyle )
561 {
562 case STRIKEOUT_NONE: // nothing to do
564 break;
565
566 case STRIKEOUT_SLASH: // TODO(Q1): we should handle this in the text layer
567 case STRIKEOUT_X:
568 break;
569
570 case STRIKEOUT_SINGLE:
571 appendRect(
572 rTextLinesPolyPoly,
573 rStartPos,
574 0,
575 rTextLineInfo.mnStrikeoutOffset,
576 rLineWidth,
577 rTextLineInfo.mnStrikeoutOffset + rTextLineInfo.mnLineHeight );
578 break;
579
580 case STRIKEOUT_BOLD:
581 appendRect(
582 rTextLinesPolyPoly,
583 rStartPos,
584 0,
585 rTextLineInfo.mnStrikeoutOffset,
586 rLineWidth,
587 rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight );
588 break;
589
590 case STRIKEOUT_DOUBLE:
591 appendRect(
592 rTextLinesPolyPoly,
593 rStartPos,
594 0,
595 rTextLineInfo.mnStrikeoutOffset - rTextLineInfo.mnLineHeight,
596 rLineWidth,
597 rTextLineInfo.mnStrikeoutOffset );
598
599 appendRect(
600 rTextLinesPolyPoly,
601 rStartPos,
602 0,
603 rTextLineInfo.mnStrikeoutOffset + 2*rTextLineInfo.mnLineHeight,
604 rLineWidth,
605 rTextLineInfo.mnStrikeoutOffset + 3*rTextLineInfo.mnLineHeight );
606 break;
607
608 default:
609 ENSURE_OR_THROW( false,
610 "::cppcanvas::internal::createTextLinesPolyPolygon(): Unexpected strikeout case" );
611 }
612 }
613 }
614
615 ::basegfx::B2DPolyPolygon createTextLinesPolyPolygon( const ::basegfx::B2DPoint& rStartPos,
616 const double& rLineWidth,
617 const TextLineInfo& rTextLineInfo )
618 {
619 // fill the polypolygon with all text lines
620 ::basegfx::B2DPolyPolygon aTextLinesPolyPoly;
621
622 createOverlinePolyPolygon(aTextLinesPolyPoly, rStartPos, rLineWidth, rTextLineInfo);
623 createUnderlinePolyPolygon(aTextLinesPolyPoly, rStartPos, rLineWidth, rTextLineInfo);
624 createStrikeoutPolyPolygon(aTextLinesPolyPoly, rStartPos, rLineWidth, rTextLineInfo);
625 return aTextLinesPolyPoly;
626 }
627
628 ::basegfx::B2DRange calcDevicePixelBounds( const ::basegfx::B2DRange& rBounds,
629 const rendering::ViewState& viewState,
630 const rendering::RenderState& renderState )
631 {
632 ::basegfx::B2DHomMatrix aTransform;
633 ::canvas::tools::mergeViewAndRenderTransform( aTransform,
634 viewState,
635 renderState );
636
637 ::basegfx::B2DRange aTransformedBounds;
638 return ::canvas::tools::calcTransformedRectBounds( aTransformedBounds,
639 rBounds,
640 aTransform );
641 }
642
643 // create line actions for text such as underline and
644 // strikeout
646 const double& rLineWidth,
647 const TextLineInfo& rTextLineInfo )
648 {
650 ::basegfx::B2DPoint( rStartOffset,
651 0.0 ),
652 rLineWidth,
653 rTextLineInfo );
654 }
655
656 void createTextLinesPolyPolygon( const double& rStartOffset,
657 const double& rLineWidth,
658 const TextLineInfo& rTextLineInfo,
659 ::basegfx::B2DPolyPolygon& rOverlinePolyPoly,
660 ::basegfx::B2DPolyPolygon& rUnderlinePolyPoly,
661 ::basegfx::B2DPolyPolygon& rStrikeoutPolyPoly )
662 {
663 ::basegfx::B2DPoint aStartPos(rStartOffset, 0.0);
664
665 createOverlinePolyPolygon(rOverlinePolyPoly, aStartPos, rLineWidth, rTextLineInfo);
666 createUnderlinePolyPolygon(rUnderlinePolyPoly, aStartPos, rLineWidth, rTextLineInfo);
667 createStrikeoutPolyPolygon(rStrikeoutPolyPoly, aStartPos, rLineWidth, rTextLineInfo);
668 }
669}
670
671/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nLineWidth
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
FontMetric GetFontMetric() const
void rotate(double fRadiant)
void translate(double fX, double fY)
void scale(double fX, double fY)
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
void transform(const basegfx::B2DHomMatrix &rMatrix)
sal_uInt32 count() const
void transform(const basegfx::B2DHomMatrix &rMatrix)
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
constexpr bool IsEmpty() const
#define ENSURE_OR_THROW(c, m)
float y
float x
LINESTYLE_BOLDDASHDOT
LINESTYLE_BOLDDASHDOTDOT
LINESTYLE_SINGLE
LINESTYLE_BOLDLONGDASH
LINESTYLE_BOLDWAVE
LINESTYLE_DASHDOTDOT
LINESTYLE_BOLDDASH
LINESTYLE_BOLDDOTTED
LINESTYLE_DOUBLEWAVE
LINESTYLE_DOUBLE
LINESTYLE_NONE
LINESTYLE_DASH
LINESTYLE_DONTKNOW
LINESTYLE_SMALLWAVE
LINESTYLE_DASHDOT
LINESTYLE_DOTTED
LINESTYLE_WAVE
LINESTYLE_LONGDASH
LINESTYLE_BOLD
STRIKEOUT_BOLD
STRIKEOUT_DOUBLE
STRIKEOUT_SINGLE
STRIKEOUT_X
STRIKEOUT_SLASH
STRIKEOUT_NONE
STRIKEOUT_DONTKNOW
ALIGN_BOTTOM
ALIGN_TOP
ALIGN_BASELINE
sal_Int32 nIndex
B2DHomMatrix createScaleB2DHomMatrix(double fScaleX, double fScaleY)
bool modifyClip(rendering::RenderState &o_rRenderState, const struct ::cppcanvas::internal::OutDevState &rOutdevState, const CanvasSharedPtr &rCanvas, const ::basegfx::B2DPoint &rOffset, const ::basegfx::B2DVector *pScaling, const double *pRotation)
Definition: mtftools.cxx:112
void initRenderState(rendering::RenderState &renderState, const ::cppcanvas::internal::OutDevState &outdevState)
Definition: mtftools.cxx:42
::basegfx::B2DHomMatrix & calcLogic2PixelAffineTransform(::basegfx::B2DHomMatrix &o_rMatrix, const VirtualDevice &rVDev)
Construct a matrix that converts from logical to pixel coordinate system.
Definition: mtftools.cxx:95
::basegfx::B2DPolyPolygon createTextLinesPolyPolygon(const ::basegfx::B2DPoint &rStartPos, const double &rLineWidth, const TextLineInfo &rTextLineInfo)
Definition: mtftools.cxx:615
TextLineInfo createTextLineInfo(const ::VirtualDevice &rVDev, const ::cppcanvas::internal::OutDevState &rState)
Generate text underline/strikeout info struct from OutDev state.
Definition: mtftools.cxx:218
::basegfx::B2DHomMatrix & calcLogic2PixelLinearTransform(::basegfx::B2DHomMatrix &o_rMatrix, const VirtualDevice &rVDev)
Construct a matrix that converts from logical to pixel coordinate system.
Definition: mtftools.cxx:77
::Size getBaselineOffset(const ::cppcanvas::internal::OutDevState &outdevState, const VirtualDevice &rVDev)
Calc output offset relative to baseline.
Definition: mtftools.cxx:51
::basegfx::B2DRange calcDevicePixelBounds(const ::basegfx::B2DRange &rBounds, const rendering::ViewState &viewState, const rendering::RenderState &renderState)
Definition: mtftools.cxx:628
std::shared_ptr< Canvas > CanvasSharedPtr
basegfx::B2DRange b2DRectangleFromRectangle(const ::tools::Rectangle &rRect)
::basegfx::B2DPolyPolygon clip
Definition: outdevstate.hxx:79
signed char sal_Int8