LibreOffice Module vcl (master)  1
textline.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 #include <cassert>
21 
22 #include <sal/types.h>
23 #include <vcl/gdimtf.hxx>
24 #include <vcl/metaact.hxx>
25 #include <vcl/outdev.hxx>
26 #include <vcl/settings.hxx>
27 #include <vcl/virdev.hxx>
28 
29 #include <tools/helpers.hxx>
30 
31 #include <salgdi.hxx>
32 #include <impglyphitem.hxx>
33 
36 
37 #define UNDERLINE_LAST LINESTYLE_BOLDWAVE
38 #define STRIKEOUT_LAST STRIKEOUT_X
39 
41 {
42  mpFontInstance->mxFontMetric->ImplInitTextLineSize( this );
43 }
44 
46 {
47  mpFontInstance->mxFontMetric->ImplInitAboveTextLineSize();
48 }
49 
51  tools::Long nCurX, tools::Long nCurY,
52  Degree10 nOrientation,
53  SalGraphics* pGraphics,
54  const OutputDevice& rOutDev,
55  bool bDrawPixAsRect,
56  tools::Long nPixWidth, tools::Long nPixHeight )
57 {
58  if ( nOrientation )
59  {
60  Point aPoint( nOriginX, nOriginY );
61  aPoint.RotateAround( nCurX, nCurY, nOrientation );
62  }
63 
64  if ( bDrawPixAsRect )
65  {
66 
67  pGraphics->DrawRect( nCurX, nCurY, nPixWidth, nPixHeight, rOutDev );
68  }
69  else
70  {
71  pGraphics->DrawPixel( nCurX, nCurY, rOutDev );
72  }
73 }
74 
76  tools::Long nDistX, tools::Long nDistY,
77  tools::Long nWidth, tools::Long nHeight,
78  tools::Long nLineWidth, Degree10 nOrientation,
79  const Color& rColor )
80 {
81  if ( !nHeight )
82  return;
83 
84  tools::Long nStartX = nBaseX + nDistX;
85  tools::Long nStartY = nBaseY + nDistY;
86 
87  // If the height is 1 pixel, it's enough output a line
88  if ( (nLineWidth == 1) && (nHeight == 1) )
89  {
90  mpGraphics->SetLineColor( rColor );
91  mbInitLineColor = true;
92 
93  tools::Long nEndX = nStartX+nWidth;
94  tools::Long nEndY = nStartY;
95  if ( nOrientation )
96  {
97  Point aOriginPt( nBaseX, nBaseY );
98  aOriginPt.RotateAround( nStartX, nStartY, nOrientation );
99  aOriginPt.RotateAround( nEndX, nEndY, nOrientation );
100  }
101  mpGraphics->DrawLine( nStartX, nStartY, nEndX, nEndY, *this );
102  }
103  else
104  {
105  tools::Long nCurX = nStartX;
106  tools::Long nCurY = nStartY;
107  tools::Long nDiffX = 2;
108  tools::Long nDiffY = nHeight-1;
109  tools::Long nCount = nWidth;
110  tools::Long nOffY = -1;
111  tools::Long nPixWidth;
112  tools::Long nPixHeight;
113  bool bDrawPixAsRect;
114  // On printers that output pixel via DrawRect()
115  if ( (GetOutDevType() == OUTDEV_PRINTER) || (nLineWidth > 1) )
116  {
117  if ( mbLineColor || mbInitLineColor )
118  {
120  mbInitLineColor = true;
121  }
122  mpGraphics->SetFillColor( rColor );
123  mbInitFillColor = true;
124  bDrawPixAsRect = true;
125  nPixWidth = nLineWidth;
126  nPixHeight = ((nLineWidth*mnDPIX)+(mnDPIY/2))/mnDPIY;
127  }
128  else
129  {
130  mpGraphics->SetLineColor( rColor );
131  mbInitLineColor = true;
132  nPixWidth = 1;
133  nPixHeight = 1;
134  bDrawPixAsRect = false;
135  }
136 
137  if ( !nDiffY )
138  {
139  while ( nWidth )
140  {
141  ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
142  mpGraphics, *this,
143  bDrawPixAsRect, nPixWidth, nPixHeight );
144  nCurX++;
145  nWidth--;
146  }
147  }
148  else
149  {
150  nCurY += nDiffY;
151  tools::Long nFreq = nCount / (nDiffX+nDiffY);
152  while ( nFreq-- )
153  {
154  for( tools::Long i = nDiffY; i; --i )
155  {
156  ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
157  mpGraphics, *this,
158  bDrawPixAsRect, nPixWidth, nPixHeight );
159  nCurX++;
160  nCurY += nOffY;
161  }
162  for( tools::Long i = nDiffX; i; --i )
163  {
164  ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
165  mpGraphics, *this,
166  bDrawPixAsRect, nPixWidth, nPixHeight );
167  nCurX++;
168  }
169  nOffY = -nOffY;
170  }
171  nFreq = nCount % (nDiffX+nDiffY);
172  if ( nFreq )
173  {
174  for( tools::Long i = nDiffY; i && nFreq; --i, --nFreq )
175  {
176  ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
177  mpGraphics, *this,
178  bDrawPixAsRect, nPixWidth, nPixHeight );
179  nCurX++;
180  nCurY += nOffY;
181 
182  }
183  for( tools::Long i = nDiffX; i && nFreq; --i, --nFreq )
184  {
185  ImplDrawWavePixel( nBaseX, nBaseY, nCurX, nCurY, nOrientation,
186  mpGraphics, *this,
187  bDrawPixAsRect, nPixWidth, nPixHeight );
188  nCurX++;
189  }
190  }
191  }
192  }
193 }
194 
196  tools::Long nDistX, tools::Long nDistY, tools::Long nWidth,
197  FontLineStyle eTextLine,
198  Color aColor,
199  bool bIsAbove )
200 {
201  LogicalFontInstance* pFontInstance = mpFontInstance.get();
202  tools::Long nLineHeight;
203  tools::Long nLinePos;
204 
205  if ( bIsAbove )
206  {
207  nLineHeight = pFontInstance->mxFontMetric->GetAboveWavelineUnderlineSize();
208  nLinePos = pFontInstance->mxFontMetric->GetAboveWavelineUnderlineOffset();
209  }
210  else
211  {
212  nLineHeight = pFontInstance->mxFontMetric->GetWavelineUnderlineSize();
213  nLinePos = pFontInstance->mxFontMetric->GetWavelineUnderlineOffset();
214  }
215  if ( (eTextLine == LINESTYLE_SMALLWAVE) && (nLineHeight > 3) )
216  nLineHeight = 3;
217 
218  tools::Long nLineWidth = mnDPIX / 300;
219  if ( !nLineWidth )
220  nLineWidth = 1;
221 
222  if ( eTextLine == LINESTYLE_BOLDWAVE )
223  nLineWidth *= 2;
224 
225  nLinePos += nDistY - (nLineHeight / 2);
226 
227  tools::Long nLineWidthHeight = ((nLineWidth * mnDPIX) + (mnDPIY / 2)) / mnDPIY;
228  if ( eTextLine == LINESTYLE_DOUBLEWAVE )
229  {
230  tools::Long nOrgLineHeight = nLineHeight;
231  nLineHeight /= 3;
232  if ( nLineHeight < 2 )
233  {
234  if ( nOrgLineHeight > 1 )
235  nLineHeight = 2;
236  else
237  nLineHeight = 1;
238  }
239 
240  tools::Long nLineDY = nOrgLineHeight-(nLineHeight*2);
241  if ( nLineDY < nLineWidthHeight )
242  nLineDY = nLineWidthHeight;
243 
244  tools::Long nLineDY2 = nLineDY/2;
245  if ( !nLineDY2 )
246  nLineDY2 = 1;
247 
248  nLinePos -= nLineWidthHeight-nLineDY2;
249  ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight,
250  nLineWidth, mpFontInstance->mnOrientation, aColor );
251  nLinePos += nLineWidthHeight+nLineDY;
252  ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight,
253  nLineWidth, mpFontInstance->mnOrientation, aColor );
254  }
255  else
256  {
257  nLinePos -= nLineWidthHeight/2;
258  ImplDrawWaveLine( nBaseX, nBaseY, nDistX, nLinePos, nWidth, nLineHeight,
259  nLineWidth, mpFontInstance->mnOrientation, aColor );
260  }
261 }
262 
264  tools::Long nDistX, tools::Long nDistY, tools::Long nWidth,
265  FontLineStyle eTextLine,
266  Color aColor,
267  bool bIsAbove )
268 {
269  LogicalFontInstance* pFontInstance = mpFontInstance.get();
270  tools::Long nLineHeight = 0;
271  tools::Long nLinePos = 0;
272  tools::Long nLinePos2 = 0;
273 
274  const tools::Long nY = nDistY;
275 
276  if ( eTextLine > UNDERLINE_LAST )
277  eTextLine = LINESTYLE_SINGLE;
278 
279  switch ( eTextLine )
280  {
281  case LINESTYLE_SINGLE:
282  case LINESTYLE_DOTTED:
283  case LINESTYLE_DASH:
284  case LINESTYLE_LONGDASH:
285  case LINESTYLE_DASHDOT:
287  if ( bIsAbove )
288  {
289  nLineHeight = pFontInstance->mxFontMetric->GetAboveUnderlineSize();
290  nLinePos = nY + pFontInstance->mxFontMetric->GetAboveUnderlineOffset();
291  }
292  else
293  {
294  nLineHeight = pFontInstance->mxFontMetric->GetUnderlineSize();
295  nLinePos = nY + pFontInstance->mxFontMetric->GetUnderlineOffset();
296  }
297  break;
298  case LINESTYLE_BOLD:
300  case LINESTYLE_BOLDDASH:
304  if ( bIsAbove )
305  {
306  nLineHeight = pFontInstance->mxFontMetric->GetAboveBoldUnderlineSize();
307  nLinePos = nY + pFontInstance->mxFontMetric->GetAboveBoldUnderlineOffset();
308  }
309  else
310  {
311  nLineHeight = pFontInstance->mxFontMetric->GetBoldUnderlineSize();
312  nLinePos = nY + pFontInstance->mxFontMetric->GetBoldUnderlineOffset();
313  }
314  break;
315  case LINESTYLE_DOUBLE:
316  if ( bIsAbove )
317  {
318  nLineHeight = pFontInstance->mxFontMetric->GetAboveDoubleUnderlineSize();
319  nLinePos = nY + pFontInstance->mxFontMetric->GetAboveDoubleUnderlineOffset1();
320  nLinePos2 = nY + pFontInstance->mxFontMetric->GetAboveDoubleUnderlineOffset2();
321  }
322  else
323  {
324  nLineHeight = pFontInstance->mxFontMetric->GetDoubleUnderlineSize();
325  nLinePos = nY + pFontInstance->mxFontMetric->GetDoubleUnderlineOffset1();
326  nLinePos2 = nY + pFontInstance->mxFontMetric->GetDoubleUnderlineOffset2();
327  }
328  break;
329  default:
330  break;
331  }
332 
333  if ( !nLineHeight )
334  return;
335 
336  if ( mbLineColor || mbInitLineColor )
337  {
339  mbInitLineColor = true;
340  }
341  mpGraphics->SetFillColor( aColor );
342  mbInitFillColor = true;
343 
344  tools::Long nLeft = nDistX;
345 
346  switch ( eTextLine )
347  {
348  case LINESTYLE_SINGLE:
349  case LINESTYLE_BOLD:
350  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
351  break;
352  case LINESTYLE_DOUBLE:
353  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
354  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos2, nWidth, nLineHeight );
355  break;
356  case LINESTYLE_DOTTED:
358  {
359  tools::Long nDotWidth = nLineHeight*mnDPIY;
360  nDotWidth += mnDPIY/2;
361  nDotWidth /= mnDPIY;
362 
363  tools::Long nTempWidth = nDotWidth;
364  tools::Long nEnd = nLeft+nWidth;
365  while ( nLeft < nEnd )
366  {
367  if ( nLeft+nTempWidth > nEnd )
368  nTempWidth = nEnd-nLeft;
369 
370  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempWidth, nLineHeight );
371  nLeft += nDotWidth*2;
372  }
373  }
374  break;
375  case LINESTYLE_DASH:
376  case LINESTYLE_LONGDASH:
377  case LINESTYLE_BOLDDASH:
379  {
380  tools::Long nDotWidth = nLineHeight*mnDPIY;
381  nDotWidth += mnDPIY/2;
382  nDotWidth /= mnDPIY;
383 
384  tools::Long nMinDashWidth;
385  tools::Long nMinSpaceWidth;
386  tools::Long nSpaceWidth;
387  tools::Long nDashWidth;
388  if ( (eTextLine == LINESTYLE_LONGDASH) ||
389  (eTextLine == LINESTYLE_BOLDLONGDASH) )
390  {
391  nMinDashWidth = nDotWidth*6;
392  nMinSpaceWidth = nDotWidth*2;
393  nDashWidth = 200;
394  nSpaceWidth = 100;
395  }
396  else
397  {
398  nMinDashWidth = nDotWidth*4;
399  nMinSpaceWidth = (nDotWidth*150)/100;
400  nDashWidth = 100;
401  nSpaceWidth = 50;
402  }
403  nDashWidth = ((nDashWidth*mnDPIX)+1270)/2540;
404  nSpaceWidth = ((nSpaceWidth*mnDPIX)+1270)/2540;
405  // DashWidth will be increased if the line is getting too thick
406  // in proportion to the line's length
407  if ( nDashWidth < nMinDashWidth )
408  nDashWidth = nMinDashWidth;
409  if ( nSpaceWidth < nMinSpaceWidth )
410  nSpaceWidth = nMinSpaceWidth;
411 
412  tools::Long nTempWidth = nDashWidth;
413  tools::Long nEnd = nLeft+nWidth;
414  while ( nLeft < nEnd )
415  {
416  if ( nLeft+nTempWidth > nEnd )
417  nTempWidth = nEnd-nLeft;
418  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempWidth, nLineHeight );
419  nLeft += nDashWidth+nSpaceWidth;
420  }
421  }
422  break;
423  case LINESTYLE_DASHDOT:
425  {
426  tools::Long nDotWidth = nLineHeight*mnDPIY;
427  nDotWidth += mnDPIY/2;
428  nDotWidth /= mnDPIY;
429 
430  tools::Long nDashWidth = ((100*mnDPIX)+1270)/2540;
431  tools::Long nMinDashWidth = nDotWidth*4;
432  // DashWidth will be increased if the line is getting too thick
433  // in proportion to the line's length
434  if ( nDashWidth < nMinDashWidth )
435  nDashWidth = nMinDashWidth;
436 
437  tools::Long nTempDotWidth = nDotWidth;
438  tools::Long nTempDashWidth = nDashWidth;
439  tools::Long nEnd = nLeft+nWidth;
440  while ( nLeft < nEnd )
441  {
442  if ( nLeft+nTempDotWidth > nEnd )
443  nTempDotWidth = nEnd-nLeft;
444 
445  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDotWidth, nLineHeight );
446  nLeft += nDotWidth*2;
447  if ( nLeft > nEnd )
448  break;
449 
450  if ( nLeft+nTempDashWidth > nEnd )
451  nTempDashWidth = nEnd-nLeft;
452 
453  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDashWidth, nLineHeight );
454  nLeft += nDashWidth+nDotWidth;
455  }
456  }
457  break;
460  {
461  tools::Long nDotWidth = nLineHeight*mnDPIY;
462  nDotWidth += mnDPIY/2;
463  nDotWidth /= mnDPIY;
464 
465  tools::Long nDashWidth = ((100*mnDPIX)+1270)/2540;
466  tools::Long nMinDashWidth = nDotWidth*4;
467  // DashWidth will be increased if the line is getting too thick
468  // in proportion to the line's length
469  if ( nDashWidth < nMinDashWidth )
470  nDashWidth = nMinDashWidth;
471 
472  tools::Long nTempDotWidth = nDotWidth;
473  tools::Long nTempDashWidth = nDashWidth;
474  tools::Long nEnd = nLeft+nWidth;
475  while ( nLeft < nEnd )
476  {
477  if ( nLeft+nTempDotWidth > nEnd )
478  nTempDotWidth = nEnd-nLeft;
479 
480  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDotWidth, nLineHeight );
481  nLeft += nDotWidth*2;
482  if ( nLeft > nEnd )
483  break;
484 
485  if ( nLeft+nTempDotWidth > nEnd )
486  nTempDotWidth = nEnd-nLeft;
487 
488  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDotWidth, nLineHeight );
489  nLeft += nDotWidth*2;
490  if ( nLeft > nEnd )
491  break;
492 
493  if ( nLeft+nTempDashWidth > nEnd )
494  nTempDashWidth = nEnd-nLeft;
495 
496  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nTempDashWidth, nLineHeight );
497  nLeft += nDashWidth+nDotWidth;
498  }
499  }
500  break;
501  default:
502  break;
503  }
504 }
505 
507  tools::Long nDistX, tools::Long nDistY, tools::Long nWidth,
508  FontStrikeout eStrikeout,
509  Color aColor )
510 {
511  LogicalFontInstance* pFontInstance = mpFontInstance.get();
512  tools::Long nLineHeight = 0;
513  tools::Long nLinePos = 0;
514  tools::Long nLinePos2 = 0;
515 
516  tools::Long nY = nDistY;
517 
518  if ( eStrikeout > STRIKEOUT_LAST )
519  eStrikeout = STRIKEOUT_SINGLE;
520 
521  switch ( eStrikeout )
522  {
523  case STRIKEOUT_SINGLE:
524  nLineHeight = pFontInstance->mxFontMetric->GetStrikeoutSize();
525  nLinePos = nY + pFontInstance->mxFontMetric->GetStrikeoutOffset();
526  break;
527  case STRIKEOUT_BOLD:
528  nLineHeight = pFontInstance->mxFontMetric->GetBoldStrikeoutSize();
529  nLinePos = nY + pFontInstance->mxFontMetric->GetBoldStrikeoutOffset();
530  break;
531  case STRIKEOUT_DOUBLE:
532  nLineHeight = pFontInstance->mxFontMetric->GetDoubleStrikeoutSize();
533  nLinePos = nY + pFontInstance->mxFontMetric->GetDoubleStrikeoutOffset1();
534  nLinePos2 = nY + pFontInstance->mxFontMetric->GetDoubleStrikeoutOffset2();
535  break;
536  default:
537  break;
538  }
539 
540  if ( !nLineHeight )
541  return;
542 
543  if ( mbLineColor || mbInitLineColor )
544  {
546  mbInitLineColor = true;
547  }
548  mpGraphics->SetFillColor( aColor );
549  mbInitFillColor = true;
550 
551  const tools::Long& nLeft = nDistX;
552 
553  switch ( eStrikeout )
554  {
555  case STRIKEOUT_SINGLE:
556  case STRIKEOUT_BOLD:
557  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
558  break;
559  case STRIKEOUT_DOUBLE:
560  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos, nWidth, nLineHeight );
561  ImplDrawTextRect( nBaseX, nBaseY, nLeft, nLinePos2, nWidth, nLineHeight );
562  break;
563  default:
564  break;
565  }
566 }
567 
569  tools::Long nDistX, tools::Long nDistY, tools::Long nWidth,
570  FontStrikeout eStrikeout,
571  Color aColor )
572 {
573  // See qadevOOo/testdocs/StrikeThrough.odt for examples if you need
574  // to tweak this
575  if (!nWidth)
576  return;
577 
578  // prepare string for strikeout measurement
579  const char cStrikeoutChar = eStrikeout == STRIKEOUT_SLASH ? '/' : 'X';
580  static const int nTestStrLen = 4;
581  static const int nMaxStrikeStrLen = 2048;
582  sal_Unicode aChars[nMaxStrikeStrLen+1]; // +1 for valgrind...
583 
584  for( int i = 0; i < nTestStrLen; ++i)
585  aChars[i] = cStrikeoutChar;
586 
587  const OUString aStrikeoutTest(aChars, nTestStrLen);
588 
589  // calculate approximation of strikeout atom size
590  tools::Long nStrikeoutWidth = 0;
591  std::unique_ptr<SalLayout> pLayout = ImplLayout( aStrikeoutTest, 0, nTestStrLen );
592  if( pLayout )
593  {
594  nStrikeoutWidth = pLayout->GetTextWidth() / (nTestStrLen * pLayout->GetUnitsPerPixel());
595  }
596  if( nStrikeoutWidth <= 0 ) // sanity check
597  return;
598 
599  int nStrikeStrLen = (nWidth+(nStrikeoutWidth-1)) / nStrikeoutWidth;
600  if( nStrikeStrLen > nMaxStrikeStrLen )
601  nStrikeStrLen = nMaxStrikeStrLen;
602 
603  // build the strikeout string
604  for( int i = nTestStrLen; i < nStrikeStrLen; ++i)
605  aChars[i] = cStrikeoutChar;
606 
607  const OUString aStrikeoutText(aChars, nStrikeStrLen);
608 
609  if( mpFontInstance->mnOrientation )
610  {
611  Point aOriginPt(0, 0);
612  aOriginPt.RotateAround( nDistX, nDistY, mpFontInstance->mnOrientation );
613  }
614 
615  nBaseX += nDistX;
616  nBaseY += nDistY;
617 
618  // strikeout text has to be left aligned
621  pLayout = ImplLayout( aStrikeoutText, 0, aStrikeoutText.getLength() );
622  mnTextLayoutMode = nOrigTLM;
623 
624  if( !pLayout )
625  return;
626 
627  // draw the strikeout text
628  const Color aOldColor = GetTextColor();
629  SetTextColor( aColor );
631 
632  pLayout->DrawBase() = Point( nBaseX+mnTextOffX, nBaseY+mnTextOffY );
633 
634  tools::Rectangle aPixelRect;
635  aPixelRect.SetLeft( nBaseX+mnTextOffX );
636  aPixelRect.SetRight( aPixelRect.Left()+nWidth );
637  aPixelRect.SetBottom( nBaseY+mpFontInstance->mxFontMetric->GetDescent() );
638  aPixelRect.SetTop( nBaseY-mpFontInstance->mxFontMetric->GetAscent() );
639 
640  if (mpFontInstance->mnOrientation)
641  {
642  tools::Polygon aPoly( aPixelRect );
643  aPoly.Rotate( Point(nBaseX+mnTextOffX, nBaseY+mnTextOffY), mpFontInstance->mnOrientation);
644  aPixelRect = aPoly.GetBoundRect();
645  }
646 
648  IntersectClipRegion( PixelToLogic(aPixelRect) );
649  if( mbInitClipRegion )
650  InitClipRegion();
651 
652  pLayout->DrawText( *mpGraphics );
653 
654  Pop();
655 
656  SetTextColor( aOldColor );
658 }
659 
661  tools::Long nDistX, DeviceCoordinate nWidth,
662  FontStrikeout eStrikeout,
663  FontLineStyle eUnderline,
664  FontLineStyle eOverline,
665  bool bUnderlineAbove )
666 {
667  if ( !nWidth )
668  return;
669 
670  Color aStrikeoutColor = GetTextColor();
671  Color aUnderlineColor = GetTextLineColor();
672  Color aOverlineColor = GetOverlineColor();
673  bool bStrikeoutDone = false;
674  bool bUnderlineDone = false;
675  bool bOverlineDone = false;
676 
677  if ( IsRTLEnabled() )
678  {
679  tools::Long nXAdd = nWidth - nDistX;
680  if( mpFontInstance->mnOrientation )
681  nXAdd = FRound( nXAdd * cos( mpFontInstance->mnOrientation.get() * F_PI1800 ) );
682 
683  nX += nXAdd - 1;
684  }
685 
686  if ( !IsTextLineColor() )
687  aUnderlineColor = GetTextColor();
688 
689  if ( !IsOverlineColor() )
690  aOverlineColor = GetTextColor();
691 
692  if ( (eUnderline == LINESTYLE_SMALLWAVE) ||
693  (eUnderline == LINESTYLE_WAVE) ||
694  (eUnderline == LINESTYLE_DOUBLEWAVE) ||
695  (eUnderline == LINESTYLE_BOLDWAVE) )
696  {
697  ImplDrawWaveTextLine( nX, nY, nDistX, 0, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove );
698  bUnderlineDone = true;
699  }
700  if ( (eOverline == LINESTYLE_SMALLWAVE) ||
701  (eOverline == LINESTYLE_WAVE) ||
702  (eOverline == LINESTYLE_DOUBLEWAVE) ||
703  (eOverline == LINESTYLE_BOLDWAVE) )
704  {
705  ImplDrawWaveTextLine( nX, nY, nDistX, 0, nWidth, eOverline, aOverlineColor, true );
706  bOverlineDone = true;
707  }
708 
709  if ( (eStrikeout == STRIKEOUT_SLASH) ||
710  (eStrikeout == STRIKEOUT_X) )
711  {
712  ImplDrawStrikeoutChar( nX, nY, nDistX, 0, nWidth, eStrikeout, aStrikeoutColor );
713  bStrikeoutDone = true;
714  }
715 
716  if ( !bUnderlineDone )
717  ImplDrawStraightTextLine( nX, nY, nDistX, 0, nWidth, eUnderline, aUnderlineColor, bUnderlineAbove );
718 
719  if ( !bOverlineDone )
720  ImplDrawStraightTextLine( nX, nY, nDistX, 0, nWidth, eOverline, aOverlineColor, true );
721 
722  if ( !bStrikeoutDone )
723  ImplDrawStrikeoutLine( nX, nY, nDistX, 0, nWidth, eStrikeout, aStrikeoutColor );
724 }
725 
727  FontLineStyle eUnderline, FontLineStyle eOverline,
728  bool bWordLine, bool bUnderlineAbove )
729 {
730  if( bWordLine )
731  {
732  // draw everything relative to the layout base point
733  const Point aStartPt = rSalLayout.DrawBase();
734 
735  // calculate distance of each word from the base point
736  Point aPos;
737  DeviceCoordinate nDist = 0;
738  DeviceCoordinate nWidth = 0;
739  const GlyphItem* pGlyph;
740  int nStart = 0;
741  while (rSalLayout.GetNextGlyph(&pGlyph, aPos, nStart))
742  {
743  // calculate the boundaries of each word
744  if (!pGlyph->IsSpacing())
745  {
746  if( !nWidth )
747  {
748  // get the distance to the base point (as projected to baseline)
749  nDist = aPos.X() - aStartPt.X();
750  if( mpFontInstance->mnOrientation )
751  {
752  const tools::Long nDY = aPos.Y() - aStartPt.Y();
753  const double fRad = mpFontInstance->mnOrientation.get() * F_PI1800;
754  nDist = FRound( nDist*cos(fRad) - nDY*sin(fRad) );
755  }
756  }
757 
758  // update the length of the textline
759  nWidth += pGlyph->m_nNewWidth;
760  }
761  else if( nWidth > 0 )
762  {
763  // draw the textline for each word
764  ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth,
765  eStrikeout, eUnderline, eOverline, bUnderlineAbove );
766  nWidth = 0;
767  }
768  }
769 
770  // draw textline for the last word
771  if( nWidth > 0 )
772  {
773  ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), nDist, nWidth,
774  eStrikeout, eUnderline, eOverline, bUnderlineAbove );
775  }
776  }
777  else
778  {
779  Point aStartPt = rSalLayout.GetDrawPosition();
780  ImplDrawTextLine( aStartPt.X(), aStartPt.Y(), 0,
781  rSalLayout.GetTextWidth() / rSalLayout.GetUnitsPerPixel(),
782  eStrikeout, eUnderline, eOverline, bUnderlineAbove );
783  }
784 }
785 
787 {
788  tools::Long nBaseX = nX;
789  if( /*HasMirroredGraphics() &&*/ IsRTLEnabled() )
790  {
791  // add some strange offset
792  nX += 2;
793  // revert the hack that will be done later in ImplDrawTextLine
794  nX = nBaseX - nWidth - (nX - nBaseX - 1);
795  }
796 
797  ImplDrawTextLine( nX, nY, 0, nWidth, STRIKEOUT_NONE, LINESTYLE_SINGLE, LINESTYLE_NONE, false );
798 }
799 
801 {
802 
803  if ( mpMetaFile )
804  mpMetaFile->AddAction( new MetaTextLineColorAction( Color(), false ) );
805 
807 
808  if( mpAlphaVDev )
810 }
811 
813 {
814 
815  Color aColor( rColor );
816 
820  {
822  {
823  aColor = COL_BLACK;
824  }
826  {
827  aColor = COL_WHITE;
828  }
829  else if ( mnDrawMode & DrawModeFlags::GrayText )
830  {
831  const sal_uInt8 cLum = aColor.GetLuminance();
832  aColor = Color( cLum, cLum, cLum );
833  }
835  {
837  }
838  }
839 
840  if ( mpMetaFile )
841  mpMetaFile->AddAction( new MetaTextLineColorAction( aColor, true ) );
842 
843  maTextLineColor = aColor;
844 
845  if( mpAlphaVDev )
847 }
848 
850 {
851 
852  if ( mpMetaFile )
853  mpMetaFile->AddAction( new MetaOverlineColorAction( Color(), false ) );
854 
856 
857  if( mpAlphaVDev )
859 }
860 
862 {
863 
864  Color aColor( rColor );
865 
869  {
871  {
872  aColor = COL_BLACK;
873  }
875  {
876  aColor = COL_WHITE;
877  }
878  else if ( mnDrawMode & DrawModeFlags::GrayText )
879  {
880  const sal_uInt8 cLum = aColor.GetLuminance();
881  aColor = Color( cLum, cLum, cLum );
882  }
884  {
886  }
887  }
888 
889  if ( mpMetaFile )
890  mpMetaFile->AddAction( new MetaOverlineColorAction( aColor, true ) );
891 
892  maOverlineColor = aColor;
893 
894  if( mpAlphaVDev )
896 }
897 
898 void OutputDevice::DrawTextLine( const Point& rPos, tools::Long nWidth,
899  FontStrikeout eStrikeout,
900  FontLineStyle eUnderline,
901  FontLineStyle eOverline,
902  bool bUnderlineAbove )
903 {
905 
906  if ( mpMetaFile )
907  mpMetaFile->AddAction( new MetaTextLineAction( rPos, nWidth, eStrikeout, eUnderline, eOverline ) );
908 
909  if ( ((eUnderline == LINESTYLE_NONE) || (eUnderline == LINESTYLE_DONTKNOW)) &&
910  ((eOverline == LINESTYLE_NONE) || (eOverline == LINESTYLE_DONTKNOW)) &&
911  ((eStrikeout == STRIKEOUT_NONE) || (eStrikeout == STRIKEOUT_DONTKNOW)) )
912  {
913  return;
914  }
916  return;
917 
918  if( mbInitClipRegion )
919  InitClipRegion();
920 
921  if( mbOutputClipped )
922  return;
923 
924  // initialize font if needed to get text offsets
925  // TODO: only needed for mnTextOff!=(0,0)
926  if (!InitFont())
927  return;
928 
929  Point aPos = ImplLogicToDevicePixel( rPos );
930  DeviceCoordinate fWidth;
931  fWidth = LogicWidthToDeviceCoordinate( nWidth );
932  aPos += Point( mnTextOffX, mnTextOffY );
933  ImplDrawTextLine( aPos.X(), aPos.X(), 0, fWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove );
934 
935  if( mpAlphaVDev )
936  mpAlphaVDev->DrawTextLine( rPos, nWidth, eStrikeout, eUnderline, eOverline, bUnderlineAbove );
937 }
938 
939 void OutputDevice::DrawWaveLine(const Point& rStartPos, const Point& rEndPos, tools::Long nLineWidth)
940 {
942 
944  return;
945 
946  // we need a graphics
947  if( !mpGraphics && !AcquireGraphics() )
948  return;
950 
951  if ( mbInitClipRegion )
952  InitClipRegion();
953 
954  if ( mbOutputClipped )
955  return;
956 
957  if (!InitFont())
958  return;
959 
960  Point aStartPt = ImplLogicToDevicePixel(rStartPos);
961  Point aEndPt = ImplLogicToDevicePixel(rEndPos);
962 
963  tools::Long nStartX = aStartPt.X();
964  tools::Long nStartY = aStartPt.Y();
965  tools::Long nEndX = aEndPt.X();
966  tools::Long nEndY = aEndPt.Y();
967  double fOrientation = 0.0;
968 
969  // handle rotation
970  if (nStartY != nEndY || nStartX > nEndX)
971  {
972  tools::Long nLengthX = nEndX - nStartX;
973  fOrientation = std::atan2(nStartY - nEndY, (nLengthX == 0 ? 0.000000001 : nLengthX));
974  fOrientation /= F_PI180;
975  // un-rotate the end point
976  aStartPt.RotateAround(nEndX, nEndY, Degree10(static_cast<sal_Int16>(-fOrientation * 10.0)));
977  }
978 
979  tools::Long nWaveHeight = 3;
980 
981  // Handle HiDPI
982  float fScaleFactor = GetDPIScaleFactor();
983  if (fScaleFactor > 1.0f)
984  {
985  nWaveHeight *= fScaleFactor;
986 
987  nStartY += fScaleFactor - 1; // Shift down additional pixel(s) to create more visual separation.
988 
989  // odd heights look better than even
990  if (nWaveHeight % 2 == 0)
991  {
992  nWaveHeight--;
993  }
994  }
995 
996  // #109280# make sure the waveline does not exceed the descent to avoid paint problems
997  LogicalFontInstance* pFontInstance = mpFontInstance.get();
998  if (nWaveHeight > pFontInstance->mxFontMetric->GetWavelineUnderlineSize())
999  {
1000  nWaveHeight = pFontInstance->mxFontMetric->GetWavelineUnderlineSize();
1001  // tdf#124848 hairline
1002  nLineWidth = 0;
1003  }
1004 
1005  const basegfx::B2DRectangle aWaveLineRectangle(nStartX, nStartY, nEndX, nEndY + nWaveHeight);
1006  const basegfx::B2DPolygon aWaveLinePolygon = basegfx::createWaveLinePolygon(aWaveLineRectangle);
1007  const basegfx::B2DHomMatrix aRotationMatrix = basegfx::utils::createRotateAroundPoint(nStartX, nStartY, basegfx::deg2rad(-fOrientation));
1008  const bool bPixelSnapHairline(mnAntialiasing & AntialiasingFlags::PixelSnapHairline);
1009 
1012  aRotationMatrix,
1013  aWaveLinePolygon,
1014  0.0,
1015  nLineWidth,
1016  nullptr, // MM01
1018  css::drawing::LineCap_BUTT,
1019  basegfx::deg2rad(15.0),
1020  bPixelSnapHairline,
1021  *this);
1022 
1023  if( mpAlphaVDev )
1024  mpAlphaVDev->DrawWaveLine( rStartPos, rEndPos, nLineWidth );
1025 }
1026 
1027 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const Color & GetTextColor() const
Definition: outdev.hxx:1136
void DrawPixel(tools::Long nX, tools::Long nY, const OutputDevice &rOutDev)
OutDevType GetOutDevType() const
Definition: outdev.hxx:528
tools::Long GetAboveBoldUnderlineSize() const
SAL_DLLPRIVATE DeviceCoordinate LogicWidthToDeviceCoordinate(tools::Long nWidth) const
Definition: map.cxx:1713
tools::Long GetUnderlineSize() const
tools::Long mnTextOffX
font specific text alignment offsets in pixel units
Definition: outdev.hxx:350
SAL_DLLPRIVATE bool ImplIsRecordLayout() const
Definition: outdev.cxx:644
int GetUnitsPerPixel() const
Definition: vcllayout.hxx:81
void DrawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2, const OutputDevice &rOutDev)
tools::Long GetBoldUnderlineOffset() const
const Color & GetTextLineColor() const
Definition: outdev.hxx:1145
tools::Long GetBoldStrikeoutSize() const
tools::Long GetAboveWavelineUnderlineSize() const
DrawModeFlags mnDrawMode
Definition: outdev.hxx:354
LINESTYLE_BOLD
tools::Long GetAboveUnderlineOffset() const
long Long
tools::Long GetWavelineUnderlineSize() const
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
const StyleSettings & GetStyleSettings() const
#define F_PI1800
sal_uInt8 GetLuminance() const
bool IsTextLineColor() const
Definition: outdev.hxx:1146
virtual DeviceCoordinate GetTextWidth() const
Definition: vcllayout.hxx:87
bool mbOutputClipped
Definition: outdev.hxx:379
LINESTYLE_BOLDWAVE
SAL_DLLPRIVATE void ImplInitTextColor()
Definition: text.cxx:71
SAL_DLLPRIVATE bool is_double_buffered_window() const
sal_Int32 mnDPIY
Definition: outdev.hxx:347
void IntersectClipRegion(const tools::Rectangle &rRect)
void DrawTextLine(const Point &rPos, tools::Long nWidth, FontStrikeout eStrikeout, FontLineStyle eUnderline, FontLineStyle eOverline, bool bUnderlineAbove=false)
Definition: textline.cxx:898
sal_Int32 mnDPIX
Definition: outdev.hxx:346
STRIKEOUT_SLASH
bool IsSpacing() const
ImplFontMetricDataRef mxFontMetric
SAL_DLLPRIVATE void ImplDrawWaveLine(tools::Long nBaseX, tools::Long nBaseY, tools::Long nStartX, tools::Long nStartY, tools::Long nWidth, tools::Long nHeight, tools::Long nLineWidth, Degree10 nOrientation, const Color &rColor)
Definition: textline.cxx:75
SAL_DLLPRIVATE void ImplDrawStrikeoutLine(tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, FontStrikeout eStrikeout, Color aColor)
Definition: textline.cxx:506
tools::Long GetStrikeoutOffset() const
void SetRight(tools::Long v)
tools::Long GetAboveDoubleUnderlineOffset1() const
LINESTYLE_DASH
const Color & GetOverlineColor() const
Definition: outdev.hxx:1150
LINESTYLE_DASHDOT
sal_uInt16 sal_Unicode
Color maOverlineColor
Definition: outdev.hxx:365
LINESTYLE_BOLDDASHDOTDOT
tools::Long Left() const
LINESTYLE_NONE
void SetLeft(tools::Long v)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
tools::Long GetUnderlineOffset() const
#define UNDERLINE_LAST
Definition: textline.cxx:37
SAL_DLLPRIVATE void ImplDrawWaveTextLine(tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove)
Definition: textline.cxx:195
int nCount
AntialiasingFlags mnAntialiasing
Definition: outdev.hxx:371
STRIKEOUT_SINGLE
void SetTextLineColor()
Definition: textline.cxx:800
SAL_DLLPRIVATE void ImplDrawMnemonicLine(tools::Long nX, tools::Long nY, tools::Long nWidth)
Definition: textline.cxx:786
void Rotate(const Point &rCenter, double fSin, double fCos)
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:315
void DrawRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice &rOutDev)
virtual void SetFillColor()=0
tools::Long GetDoubleStrikeoutOffset1() const
bool IsRTLEnabled() const
Definition: outdev.hxx:1366
int i
virtual void SetLineColor()=0
tools::Long FRound(double fVal)
ComplexTextLayoutFlags
Definition: outdevstate.hxx:66
LINESTYLE_DOUBLEWAVE
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
LINESTYLE_WAVE
SAL_DLLPRIVATE void ImplInitAboveTextLineSize()
Definition: textline.cxx:45
tools::Long GetBoldStrikeoutOffset() const
bool mbInitLineColor
Definition: outdev.hxx:382
SAL_DLLPRIVATE void ImplDrawTextRect(tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight)
Definition: text.cxx:82
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:303
const Color & GetFontColor() const
const Color & GetLineColor() const
Definition: outdev.hxx:634
LINESTYLE_SINGLE
void ImplDrawTextLine(tools::Long nBaseX, tools::Long nX, tools::Long nY, DeviceCoordinate nWidth, FontStrikeout eStrikeout, FontLineStyle eUnderline, FontLineStyle eOverline, bool bUnderlineAbove)
Definition: textline.cxx:660
tools::Long GetDoubleUnderlineSize() const
void SetTextColor(const Color &rColor)
Definition: text.cxx:662
SAL_DLLPRIVATE void ImplDrawStraightTextLine(tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, FontLineStyle eTextLine, Color aColor, bool bIsAbove)
Definition: textline.cxx:263
tools::Long DeviceCoordinate
tools::Long GetAboveDoubleUnderlineOffset2() const
void DrawPolyLine(sal_uInt32 nPoints, Point const *pPtAry, const OutputDevice &rOutDev)
LINESTYLE_BOLDLONGDASH
Point GetDrawPosition(const Point &rRelative=Point(0, 0)) const
Definition: sallayout.cxx:560
bool mbLineColor
Definition: outdev.hxx:380
constexpr double deg2rad(double v)
LINESTYLE_SMALLWAVE
void SetOverlineColor()
Definition: textline.cxx:849
void SetTop(tools::Long v)
void SetBottom(tools::Long v)
const AllSettings & GetSettings() const
Definition: outdev.hxx:418
tools::Long GetDoubleUnderlineOffset2() const
Color maTextLineColor
Definition: outdev.hxx:364
LINESTYLE_DONTKNOW
sal_Int32 nLineWidth
STRIKEOUT_X
tools::Long GetAboveWavelineUnderlineOffset() const
std::unique_ptr< SalLayout > ImplLayout(const OUString &, sal_Int32 nIndex, sal_Int32 nLen, const Point &rLogicPos=Point(0, 0), tools::Long nLogicWidth=0, const tools::Long *pLogicDXArray=nullptr, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
Definition: text.cxx:1242
tools::Long GetAboveUnderlineSize() const
Point & DrawBase()
Definition: vcllayout.hxx:70
float GetDPIScaleFactor() const
Definition: outdev.hxx:518
SAL_DLLPRIVATE void ImplDrawStrikeoutChar(tools::Long nBaseX, tools::Long nBaseY, tools::Long nX, tools::Long nY, tools::Long nWidth, FontStrikeout eStrikeout, Color aColor)
Definition: textline.cxx:568
tools::Long GetStrikeoutSize() const
LINESTYLE_LONGDASH
Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1021
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:330
tools::Long GetBoldUnderlineSize() const
BASEGFX_DLLPUBLIC B2DPolygon createWaveLinePolygon(basegfx::B2DRectangle const &rRectangle)
tools::Long GetAboveDoubleUnderlineSize() const
#define F_PI180
STRIKEOUT_DOUBLE
LINESTYLE_DASHDOTDOT
unsigned char sal_uInt8
LINESTYLE_DOTTED
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:564
bool mbInitClipRegion
Definition: outdev.hxx:386
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
B2DHomMatrix createRotateAroundPoint(double fPointX, double fPointY, double fRadiant)
virtual void InitClipRegion()
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
tools::Long GetDoubleStrikeoutSize() const
#define STRIKEOUT_LAST
Definition: textline.cxx:38
void DrawWaveLine(const Point &rStartPos, const Point &rEndPos, tools::Long nLineWidth=1)
Definition: textline.cxx:939
rtl::Reference< LogicalFontInstance > mpFontInstance
Definition: outdev.hxx:319
bool mbInitFillColor
Definition: outdev.hxx:383
LINESTYLE_BOLDDOTTED
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Definition: map.cxx:376
STRIKEOUT_DONTKNOW
virtual bool GetNextGlyph(const GlyphItem **pGlyph, Point &rPos, int &nStart, const PhysicalFontFace **pFallbackFont=nullptr) const =0
ComplexTextLayoutFlags mnTextLayoutMode
Definition: outdev.hxx:355
tools::Long GetWavelineUnderlineOffset() const
LINESTYLE_BOLDDASH
void(* f)(TrueTypeTable *)
Definition: ttcr.cxx:482
SAL_DLLPRIVATE void ImplInitTextLineSize()
Definition: textline.cxx:40
tools::Rectangle GetBoundRect() const
tools::Long GetAboveBoldUnderlineOffset() const
LINESTYLE_DOUBLE
bool IsOverlineColor() const
Definition: outdev.hxx:1151
STRIKEOUT_NONE
static SAL_DLLPRIVATE void ImplDrawWavePixel(tools::Long nOriginX, tools::Long nOriginY, tools::Long nCurX, tools::Long nCurY, Degree10 nOrientation, SalGraphics *pGraphics, const OutputDevice &rOutDev, bool bDrawPixAsRect, tools::Long nPixWidth, tools::Long nPixHeight)
Definition: textline.cxx:50
tools::Long GetDoubleStrikeoutOffset2() const
FontLineStyle
void ImplDrawTextLines(SalLayout &, FontStrikeout eStrikeout, FontLineStyle eUnderline, FontLineStyle eOverline, bool bWordLine, bool bUnderlineAbove)
Definition: textline.cxx:726
bool IsDeviceOutputNecessary() const
Definition: outdev.hxx:605
void Push(PushFlags nFlags=PushFlags::ALL)
Definition: outdevstate.cxx:59
tools::Long mnTextOffY
Definition: outdev.hxx:351
FontStrikeout
tools::Long GetDoubleUnderlineOffset1() const
LINESTYLE_BOLDDASHDOT
STRIKEOUT_BOLD
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:318
SAL_DLLPRIVATE bool InitFont() const