LibreOffice Module vcl (master)  1
salgdilayout.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 <sal/config.h>
21 
22 #include <memory>
23 #include <config_features.h>
24 #include <sal/log.hxx>
26 #include <fontsubset.hxx>
27 #include <salgdi.hxx>
28 #include <salframe.hxx>
29 #include <sft.hxx>
33 #include <rtl/math.hxx>
34 #include <comphelper/lok.hxx>
35 #include <toolbarvalue.hxx>
36 
37 // The only common SalFrame method
38 
40 {
41  // mirror frame coordinates at parent
42  SalFrame *pParent = GetParent();
43  if( pParent && AllSettings::GetLayoutRTL() )
44  {
46  int parent_x = aGeom.nX - pParent->maGeometry.nX;
47  aGeom.nX = pParent->maGeometry.nX + pParent->maGeometry.nWidth - maGeometry.nWidth - parent_x;
48  return aGeom;
49  }
50  else
51  return maGeometry;
52 }
53 
55 : m_nLayout( SalLayoutFlags::NONE ),
56  m_eLastMirrorMode(MirrorMode::NONE),
57  m_nLastMirrorTranslation(0),
58  m_bAntiAlias(false),
59  m_bTextRenderModeForResolutionIndependentLayout(false)
60 {
61  // read global RTL settings
64 }
65 
67 {
68  bool bFileDefinitionsWidgetDraw = !!getenv("VCL_DRAW_WIDGETS_FROM_FILE");
69 
70  if (bFileDefinitionsWidgetDraw || bForce)
71  {
73  auto pFileDefinitionWidgetDraw = static_cast<vcl::FileDefinitionWidgetDraw*>(m_pWidgetDraw.get());
74  if (!pFileDefinitionWidgetDraw->isActive())
75  {
76  m_pWidgetDraw.reset();
77  return false;
78  }
79  return true;
80  }
81  return false;
82 }
83 
84 SalGraphics::~SalGraphics() COVERITY_NOEXCEPT_FALSE
85 {
86  // can't call ReleaseFonts here, as the destructor just calls this classes SetFont (pure virtual)!
87 }
88 
90  const basegfx::B2DPoint& /* rNull */,
91  const basegfx::B2DPoint& /* rX */,
92  const basegfx::B2DPoint& /* rY */,
93  const SalBitmap& /* rSourceBitmap */,
94  const SalBitmap* /* pAlphaBitmap */,
95  double /* fAlpha */)
96 {
97  // here direct support for transformed bitmaps can be implemented
98  return false;
99 }
100 
102 {
103  mirror(x, rOutDev);
104  return x;
105 }
106 
108 {
109  return rOutDev.IsVirtual() ? rOutDev.GetOutputWidthPixel() : GetGraphicsWidth();
110 }
111 
112 void SalGraphics::mirror( tools::Long& x, const OutputDevice& rOutDev ) const
113 {
114  const tools::Long w = GetDeviceWidth(rOutDev);
115  if( !w )
116  return;
117 
118  if (rOutDev.ImplIsAntiparallel() )
119  {
120  // mirror this window back
122  {
123  tools::Long devX = w - rOutDev.GetOutputWidthPixel() - rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
124  x = devX + (x - rOutDev.GetOutOffXPixel());
125  }
126  else
127  {
128  tools::Long devX = rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
129  x = rOutDev.GetOutputWidthPixel() - (x - devX) + rOutDev.GetOutOffXPixel() - 1;
130  }
131  }
133  x = w-1-x;
134 }
135 
136 void SalGraphics::mirror( tools::Long& x, tools::Long nWidth, const OutputDevice& rOutDev, bool bBack ) const
137 {
138  const tools::Long w = GetDeviceWidth(rOutDev);
139  if( !w )
140  return;
141 
142  if (rOutDev.ImplIsAntiparallel() )
143  {
144  // mirror this window back
146  {
147  tools::Long devX = w - rOutDev.GetOutputWidthPixel() - rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
148  if( bBack )
149  x = x - devX + rOutDev.GetOutOffXPixel();
150  else
151  x = devX + (x - rOutDev.GetOutOffXPixel());
152  }
153  else
154  {
155  tools::Long devX = rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
156  if( bBack )
157  x = devX + (rOutDev.GetOutputWidthPixel() + devX) - (x + nWidth);
158  else
159  x = rOutDev.GetOutputWidthPixel() - (x - devX) + rOutDev.GetOutOffXPixel() - nWidth;
160  }
161  }
163  x = w-nWidth-x;
164 }
165 
166 bool SalGraphics::mirror( sal_uInt32 nPoints, const Point *pPtAry, Point *pPtAry2, const OutputDevice& rOutDev ) const
167 {
168  const tools::Long w = GetDeviceWidth(rOutDev);
169  if( w )
170  {
171  sal_uInt32 i, j;
172 
173  if (rOutDev.ImplIsAntiparallel())
174  {
175  // mirror this window back
177  {
178  tools::Long devX = w - rOutDev.GetOutputWidthPixel() - rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
179  for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
180  {
181  pPtAry2[j].setX( devX + (pPtAry[i].getX() - rOutDev.GetOutOffXPixel()) );
182  pPtAry2[j].setY( pPtAry[i].getY() );
183  }
184  }
185  else
186  {
187  tools::Long devX = rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
188  for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
189  {
190  pPtAry2[j].setX( rOutDev.GetOutputWidthPixel() - (pPtAry[i].getX() - devX) + rOutDev.GetOutOffXPixel() - 1 );
191  pPtAry2[j].setY( pPtAry[i].getY() );
192  }
193  }
194  }
196  {
197  for( i=0, j=nPoints-1; i<nPoints; i++,j-- )
198  {
199  pPtAry2[j].setX( w-1-pPtAry[i].getX() );
200  pPtAry2[j].setY( pPtAry[i].getY() );
201  }
202  }
203  return true;
204  }
205  else
206  return false;
207 }
208 
209 void SalGraphics::mirror( vcl::Region& rRgn, const OutputDevice& rOutDev ) const
210 {
211  if( rRgn.HasPolyPolygonOrB2DPolyPolygon() )
212  {
213  const basegfx::B2DPolyPolygon aPolyPoly(mirror(rRgn.GetAsB2DPolyPolygon(), rOutDev));
214 
215  rRgn = vcl::Region(aPolyPoly);
216  }
217  else
218  {
219  RectangleVector aRectangles;
220  rRgn.GetRegionRectangles(aRectangles);
221  rRgn.SetEmpty();
222 
223  for (auto & rectangle : aRectangles)
224  {
225  mirror(rectangle, rOutDev);
226  rRgn.Union(rectangle);
227  }
228 
229  //ImplRegionInfo aInfo;
230  //bool bRegionRect;
231  //Region aMirroredRegion;
232  //long nX, nY, nWidth, nHeight;
233 
234  //bRegionRect = rRgn.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
235  //while ( bRegionRect )
236  //{
237  // Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
238  // mirror( aRect, rOutDev, bBack );
239  // aMirroredRegion.Union( aRect );
240  // bRegionRect = rRgn.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
241  //}
242  //rRgn = aMirroredRegion;
243  }
244 }
245 
246 void SalGraphics::mirror( tools::Rectangle& rRect, const OutputDevice& rOutDev, bool bBack ) const
247 {
248  tools::Long nWidth = rRect.GetWidth();
249  tools::Long x = rRect.Left();
250  tools::Long x_org = x;
251 
252  mirror( x, nWidth, rOutDev, bBack );
253  rRect.Move( x - x_org, 0 );
254 }
255 
257 {
258  const basegfx::B2DHomMatrix& rMirror(getMirror(i_rOutDev));
259 
260  if(rMirror.isIdentity())
261  {
262  return i_rPoly;
263  }
264  else
265  {
266  basegfx::B2DPolyPolygon aRet(i_rPoly);
267  aRet.transform(rMirror);
268  aRet.flip();
269  return aRet;
270  }
271 }
272 
274 {
275  if (rOutDev.ImplIsAntiparallel())
276  {
279  else
281  }
283  return MirrorMode::BiDi;
284  return MirrorMode::NONE;
285 }
286 
288 {
289  // get mirroring transformation
290  MirrorMode eNewMirrorMode = GetMirrorMode(i_rOutDev);
291  tools::Long nTranslate(0);
292 
293  switch (eNewMirrorMode)
294  {
296  {
297  const tools::Long w = GetDeviceWidth(i_rOutDev);
298  SAL_WARN_IF(!w, "vcl", "missing graphics width");
299  nTranslate = w - i_rOutDev.GetOutputWidthPixel() - (2 * i_rOutDev.GetOutOffXPixel());
300  break;
301  }
303  {
304  nTranslate = i_rOutDev.GetOutputWidthPixel() + (2 * i_rOutDev.GetOutOffXPixel()) - 1;
305  break;
306  }
307  case MirrorMode::BiDi:
308  {
309  const tools::Long w = GetDeviceWidth(i_rOutDev);
310  SAL_WARN_IF(!w, "vcl", "missing graphics width");
311  nTranslate = w - 1;
312  break;
313  }
314  case MirrorMode::NONE:
315  break;
316  }
317 
318  // if the translation (due to device width), or mirror state of the device changed, then m_aLastMirror is invalid
319  bool bLastMirrorValid = eNewMirrorMode == m_eLastMirrorMode && nTranslate == m_nLastMirrorTranslation;
320  if (!bLastMirrorValid)
321  {
322  const_cast<SalGraphics*>(this)->m_nLastMirrorTranslation = nTranslate;
323  const_cast<SalGraphics*>(this)->m_eLastMirrorMode = eNewMirrorMode;
324 
325  switch (eNewMirrorMode)
326  {
327  // mirror this window back
329  {
330  /* This path gets exercised in calc's RTL UI (e.g. SAL_RTL_ENABLED=1)
331  with its LTR horizontal scrollbar */
332 
333  // Original code was:
334  // double devX = w-i_rOutDev.GetOutputWidthPixel()-i_rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
335  // aRet.setX( devX + (i_rPoint.getX() - i_rOutDev.GetOutOffXPixel()) );
337  nTranslate, 0.0);
338  break;
339  }
341  {
342  /* This path gets exercised in writers's LTR UI with a RTL horizontal
343  scrollbar, cross-reference dialog populated from contents from a
344  RTL document tdf#131725 */
345 
346  // Original code was;
347  // tools::Long devX = rOutDev.GetOutOffXPixel(); // re-mirrored mnOutOffX
348  // x = rOutDev.GetOutputWidthPixel() - (x - devX) + rOutDev.GetOutOffXPixel() - 1;
350  -1.0,
351  1.0,
352  nTranslate,
353  0.0);
354  break;
355  }
356  case MirrorMode::BiDi:
357  {
358  // Original code was:
359  // aRet.setX( w-1-i_rPoint.getX() );
360  // -mirror X -> scale(-1.0, 1.0)
361  // -translate X -> translate(w-1, 0)
362  // Checked this one, works as expected.
364  -1.0,
365  1.0,
366  nTranslate,
367  0.0);
368  break;
369  }
370  case MirrorMode::NONE:
371  const_cast<SalGraphics*>(this)->m_aLastMirror.identity();
372  break;
373  }
374  }
375 
376  return m_aLastMirror;
377 }
378 
379 bool SalGraphics::SetClipRegion( const vcl::Region& i_rClip, const OutputDevice& rOutDev )
380 {
381  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
382  {
383  vcl::Region aMirror( i_rClip );
384  mirror( aMirror, rOutDev );
385  return setClipRegion( aMirror );
386  }
387  return setClipRegion( i_rClip );
388 }
389 
391 {
392  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
393  mirror( nX, rOutDev );
394  drawPixel( nX, nY );
395 }
396 
397 void SalGraphics::DrawPixel( tools::Long nX, tools::Long nY, Color nColor, const OutputDevice& rOutDev )
398 {
399  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
400  mirror( nX, rOutDev );
401  drawPixel( nX, nY, nColor );
402 }
403 
405 {
406  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
407  {
408  mirror( nX1, rOutDev );
409  mirror( nX2, rOutDev );
410  }
411  drawLine( nX1, nY1, nX2, nY2 );
412 }
413 
414 void SalGraphics::DrawRect( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice& rOutDev )
415 {
416  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
417  mirror( nX, nWidth, rOutDev );
418  drawRect( nX, nY, nWidth, nHeight );
419 }
420 
421 void SalGraphics::DrawPolyLine( sal_uInt32 nPoints, Point const * pPtAry, const OutputDevice& rOutDev )
422 {
423  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
424  {
425  std::unique_ptr<Point[]> pPtAry2(new Point[nPoints]);
426  bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), rOutDev );
427  drawPolyLine( nPoints, bCopied ? pPtAry2.get() : pPtAry );
428  }
429  else
430  drawPolyLine( nPoints, pPtAry );
431 }
432 
433 void SalGraphics::DrawPolygon( sal_uInt32 nPoints, const Point* pPtAry, const OutputDevice& rOutDev )
434 {
435  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
436  {
437  std::unique_ptr<Point[]> pPtAry2(new Point[nPoints]);
438  bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), rOutDev );
439  drawPolygon( nPoints, bCopied ? pPtAry2.get() : pPtAry );
440  }
441  else
442  drawPolygon( nPoints, pPtAry );
443 }
444 
445 void SalGraphics::DrawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, const Point** pPtAry, const OutputDevice& rOutDev )
446 {
447  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
448  {
449  // TODO: optimize, reduce new/delete calls
450  std::unique_ptr<Point*[]> pPtAry2( new Point*[nPoly] );
451  sal_uLong i;
452  for(i=0; i<nPoly; i++)
453  {
454  sal_uLong nPoints = pPoints[i];
455  pPtAry2[i] = new Point[ nPoints ];
456  mirror( nPoints, pPtAry[i], pPtAry2[i], rOutDev );
457  }
458 
459  drawPolyPolygon( nPoly, pPoints, const_cast<const Point**>(pPtAry2.get()) );
460 
461  for(i=0; i<nPoly; i++)
462  delete [] pPtAry2[i];
463  }
464  else
465  drawPolyPolygon( nPoly, pPoints, pPtAry );
466 }
467 
468 namespace
469 {
470  basegfx::B2DHomMatrix createTranslateToMirroredBounds(const basegfx::B2DRange &rBoundingBox, const basegfx::B2DHomMatrix& rMirror)
471  {
472  basegfx::B2DRange aRTLBoundingBox(rBoundingBox);
473  aRTLBoundingBox *= rMirror;
474  return basegfx::utils::createTranslateB2DHomMatrix(aRTLBoundingBox.getMinX() - rBoundingBox.getMinX(), 0);
475  }
476 }
477 
479  const basegfx::B2DHomMatrix& rObjectToDevice,
480  const basegfx::B2DPolyPolygon& i_rPolyPolygon,
481  double i_fTransparency,
482  const OutputDevice& i_rOutDev)
483 {
484  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || i_rOutDev.IsRTLEnabled() )
485  {
486  // mirroring set
487  const basegfx::B2DHomMatrix& rMirror(getMirror(i_rOutDev));
488  if(!rMirror.isIdentity())
489  {
490  return drawPolyPolygon(
491  rMirror * rObjectToDevice,
492  i_rPolyPolygon,
493  i_fTransparency);
494  }
495  }
496 
497  return drawPolyPolygon(
498  rObjectToDevice,
499  i_rPolyPolygon,
500  i_fTransparency);
501 }
502 
503 bool SalGraphics::DrawPolyLineBezier( sal_uInt32 nPoints, const Point* pPtAry, const PolyFlags* pFlgAry, const OutputDevice& rOutDev )
504 {
505  bool bResult = false;
506  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
507  {
508  std::unique_ptr<Point[]> pPtAry2(new Point[nPoints]);
509  bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), rOutDev );
510  bResult = drawPolyLineBezier( nPoints, bCopied ? pPtAry2.get() : pPtAry, pFlgAry );
511  }
512  else
513  bResult = drawPolyLineBezier( nPoints, pPtAry, pFlgAry );
514  return bResult;
515 }
516 
517 bool SalGraphics::DrawPolygonBezier( sal_uInt32 nPoints, const Point* pPtAry, const PolyFlags* pFlgAry, const OutputDevice& rOutDev )
518 {
519  bool bResult = false;
520  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
521  {
522  std::unique_ptr<Point[]> pPtAry2(new Point[nPoints]);
523  bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), rOutDev );
524  bResult = drawPolygonBezier( nPoints, bCopied ? pPtAry2.get() : pPtAry, pFlgAry );
525  }
526  else
527  bResult = drawPolygonBezier( nPoints, pPtAry, pFlgAry );
528  return bResult;
529 }
530 
531 bool SalGraphics::DrawPolyPolygonBezier( sal_uInt32 i_nPoly, const sal_uInt32* i_pPoints,
532  const Point* const* i_pPtAry, const PolyFlags* const* i_pFlgAry, const OutputDevice& i_rOutDev )
533 {
534  bool bRet = false;
535  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || i_rOutDev.IsRTLEnabled() )
536  {
537  // TODO: optimize, reduce new/delete calls
538  std::unique_ptr<Point*[]> pPtAry2( new Point*[i_nPoly] );
539  sal_uLong i;
540  for(i=0; i<i_nPoly; i++)
541  {
542  sal_uLong nPoints = i_pPoints[i];
543  pPtAry2[i] = new Point[ nPoints ];
544  mirror( nPoints, i_pPtAry[i], pPtAry2[i], i_rOutDev );
545  }
546 
547  bRet = drawPolyPolygonBezier( i_nPoly, i_pPoints, const_cast<const Point* const *>(pPtAry2.get()), i_pFlgAry );
548 
549  for(i=0; i<i_nPoly; i++)
550  delete [] pPtAry2[i];
551  }
552  else
553  bRet = drawPolyPolygonBezier( i_nPoly, i_pPoints, i_pPtAry, i_pFlgAry );
554  return bRet;
555 }
556 
558  const basegfx::B2DHomMatrix& rObjectToDevice,
559  const basegfx::B2DPolygon& i_rPolygon,
560  double i_fTransparency,
561  double i_rLineWidth,
562  const std::vector< double >* i_pStroke, // MM01
563  basegfx::B2DLineJoin i_eLineJoin,
564  css::drawing::LineCap i_eLineCap,
565  double i_fMiterMinimumAngle,
566  bool bPixelSnapHairline,
567  const OutputDevice& i_rOutDev)
568 {
569  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || i_rOutDev.IsRTLEnabled() )
570  {
571  // mirroring set
572  const basegfx::B2DHomMatrix& rMirror(getMirror(i_rOutDev));
573  if(!rMirror.isIdentity())
574  {
575  return drawPolyLine(
576  rMirror * rObjectToDevice,
577  i_rPolygon,
578  i_fTransparency,
579  i_rLineWidth,
580  i_pStroke, // MM01
581  i_eLineJoin,
582  i_eLineCap,
583  i_fMiterMinimumAngle,
584  bPixelSnapHairline);
585  }
586  }
587 
588  // no mirroring set (or identity), use standard call
589  return drawPolyLine(
590  rObjectToDevice,
591  i_rPolygon,
592  i_fTransparency,
593  i_rLineWidth,
594  i_pStroke, // MM01
595  i_eLineJoin,
596  i_eLineCap,
597  i_fMiterMinimumAngle,
598  bPixelSnapHairline);
599 }
600 
601 bool SalGraphics::DrawGradient(const tools::PolyPolygon& rPolyPoly, const Gradient& rGradient, const OutputDevice& rOutDev)
602 {
603  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
604  {
605  tools::PolyPolygon aMirrored(mirror(rPolyPoly.getB2DPolyPolygon(), rOutDev));
606  return drawGradient(aMirrored, rGradient);
607  }
608 
609  return drawGradient( rPolyPoly, rGradient );
610 }
611 
613  tools::Long nSrcX, tools::Long nSrcY,
614  tools::Long nSrcWidth, tools::Long nSrcHeight,
615  const OutputDevice& rOutDev )
616 {
617  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
618  {
619  mirror( nDestX, nSrcWidth, rOutDev );
620  mirror( nSrcX, nSrcWidth, rOutDev );
621  }
622  copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, true/*bWindowInvalidate*/ );
623 }
624 
625 void SalGraphics::CopyBits(const SalTwoRect& rPosAry, const OutputDevice& rOutDev)
626 {
627  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
628  {
629  SalTwoRect aPosAry2 = rPosAry;
630  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
631  copyBits( aPosAry2, nullptr );
632  }
633  else
634  copyBits( rPosAry, nullptr );
635 }
636 
637 void SalGraphics::CopyBits(const SalTwoRect& rPosAry, SalGraphics& rSrcGraphics,
638  const OutputDevice& rOutDev, const OutputDevice& rSrcOutDev)
639 {
640  if( ( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() ) ||
641  ( (rSrcGraphics.GetLayout() & SalLayoutFlags::BiDiRtl) || rSrcOutDev.IsRTLEnabled()) )
642  {
643  SalTwoRect aPosAry2 = rPosAry;
644  if( (rSrcGraphics.GetLayout() & SalLayoutFlags::BiDiRtl) || rSrcOutDev.IsRTLEnabled() )
645  mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, rSrcOutDev );
646  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
647  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
648  copyBits( aPosAry2, &rSrcGraphics );
649  }
650  else
651  copyBits( rPosAry, &rSrcGraphics );
652 }
653 
654 void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry,
655  const SalBitmap& rSalBitmap, const OutputDevice& rOutDev )
656 {
657  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
658  {
659  SalTwoRect aPosAry2 = rPosAry;
660  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
661  drawBitmap( aPosAry2, rSalBitmap );
662  }
663  else
664  drawBitmap( rPosAry, rSalBitmap );
665 }
666 
667 void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry,
668  const SalBitmap& rSalBitmap,
669  const SalBitmap& rTransparentBitmap, const OutputDevice& rOutDev )
670 {
671  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
672  {
673  SalTwoRect aPosAry2 = rPosAry;
674  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
675  drawBitmap( aPosAry2, rSalBitmap, rTransparentBitmap );
676  }
677  else
678  drawBitmap( rPosAry, rSalBitmap, rTransparentBitmap );
679 }
680 
681 void SalGraphics::DrawMask( const SalTwoRect& rPosAry,
682  const SalBitmap& rSalBitmap,
683  Color nMaskColor, const OutputDevice& rOutDev )
684 {
685  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
686  {
687  SalTwoRect aPosAry2 = rPosAry;
688  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
689  drawMask( aPosAry2, rSalBitmap, nMaskColor );
690  }
691  else
692  drawMask( rPosAry, rSalBitmap, nMaskColor );
693 }
694 
695 std::shared_ptr<SalBitmap> SalGraphics::GetBitmap( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice& rOutDev )
696 {
697  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
698  mirror( nX, nWidth, rOutDev );
699  return getBitmap( nX, nY, nWidth, nHeight );
700 }
701 
703 {
704  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
705  mirror( nX, rOutDev );
706  return getPixel( nX, nY );
707 }
708 
709 void SalGraphics::Invert( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, SalInvert nFlags, const OutputDevice& rOutDev )
710 {
711  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
712  mirror( nX, nWidth, rOutDev );
713  invert( nX, nY, nWidth, nHeight, nFlags );
714 }
715 
716 void SalGraphics::Invert( sal_uInt32 nPoints, const Point* pPtAry, SalInvert nFlags, const OutputDevice& rOutDev )
717 {
718  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
719  {
720  std::unique_ptr<Point[]> pPtAry2(new Point[nPoints]);
721  bool bCopied = mirror( nPoints, pPtAry, pPtAry2.get(), rOutDev );
722  invert( nPoints, bCopied ? pPtAry2.get() : pPtAry, nFlags );
723  }
724  else
725  invert( nPoints, pPtAry, nFlags );
726 }
727 
728 bool SalGraphics::DrawEPS( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, void* pPtr, sal_uInt32 nSize, const OutputDevice& rOutDev )
729 {
730  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
731  mirror( nX, nWidth, rOutDev );
732  return drawEPS( nX, nY, nWidth, nHeight, pPtr, nSize );
733 }
734 
736  const Point& aPos, bool& rIsInside, const OutputDevice& rOutDev)
737 {
738  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
739  {
740  Point pt( aPos );
741  tools::Rectangle rgn( rControlRegion );
742  pt.setX( mirror2( pt.X(), rOutDev ) );
743  mirror( rgn, rOutDev );
744  return forWidget()->hitTestNativeControl( ControlType::Scrollbar, nPart, rgn, pt, rIsInside );
745  }
746  else
747  return forWidget()->hitTestNativeControl( ControlType::Scrollbar, nPart, rControlRegion, aPos, rIsInside );
748 }
749 
750 void SalGraphics::mirror( ImplControlValue& rVal, const OutputDevice& rOutDev ) const
751 {
752  switch( rVal.getType() )
753  {
754  case ControlType::Slider:
755  {
756  SliderValue* pSlVal = static_cast<SliderValue*>(&rVal);
757  mirror(pSlVal->maThumbRect, rOutDev);
758  }
759  break;
761  {
762  ScrollbarValue* pScVal = static_cast<ScrollbarValue*>(&rVal);
763  mirror(pScVal->maThumbRect, rOutDev);
764  mirror(pScVal->maButton1Rect, rOutDev);
765  mirror(pScVal->maButton2Rect, rOutDev);
766  }
767  break;
770  {
771  SpinbuttonValue* pSpVal = static_cast<SpinbuttonValue*>(&rVal);
772  mirror(pSpVal->maUpperRect, rOutDev);
773  mirror(pSpVal->maLowerRect, rOutDev);
774  }
775  break;
777  {
778  ToolbarValue* pTVal = static_cast<ToolbarValue*>(&rVal);
779  mirror(pTVal->maGripRect, rOutDev);
780  }
781  break;
782  default: break;
783  }
784 }
785 
786 bool SalGraphics::DrawNativeControl( ControlType nType, ControlPart nPart, const tools::Rectangle& rControlRegion,
787  ControlState nState, const ImplControlValue& aValue,
788  const OUString& aCaption, const OutputDevice& rOutDev,
789  const Color& rBackgroundColor)
790 {
791  bool bRet = false;
792  tools::Rectangle aControlRegion(rControlRegion);
793  if (aControlRegion.IsEmpty() || aControlRegion.GetWidth() <= 0 || aControlRegion.GetHeight() <= 0)
794  return bRet;
795 
796  bool bLayoutRTL = true && (m_nLayout & SalLayoutFlags::BiDiRtl);
797  bool bDevRTL = rOutDev.IsRTLEnabled();
798  bool bIsLOK = comphelper::LibreOfficeKit::isActive();
799  if( (bLayoutRTL || bDevRTL) && !bIsLOK )
800  {
801  mirror(aControlRegion, rOutDev);
802  std::unique_ptr< ImplControlValue > mirrorValue( aValue.clone());
803  mirror( *mirrorValue, rOutDev );
804  bRet = forWidget()->drawNativeControl(nType, nPart, aControlRegion, nState, *mirrorValue, aCaption, rBackgroundColor);
805  }
806  else
807  bRet = forWidget()->drawNativeControl(nType, nPart, aControlRegion, nState, aValue, aCaption, rBackgroundColor);
808 
809  if (bRet && m_pWidgetDraw)
810  handleDamage(aControlRegion);
811  return bRet;
812 }
813 
815  const ImplControlValue& aValue,
816  tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion, const OutputDevice& rOutDev )
817 {
818  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
819  {
820  tools::Rectangle rgn( rControlRegion );
821  mirror( rgn, rOutDev );
822  std::unique_ptr< ImplControlValue > mirrorValue( aValue.clone());
823  mirror( *mirrorValue, rOutDev );
824  if (forWidget()->getNativeControlRegion(nType, nPart, rgn, nState, *mirrorValue, OUString(), rNativeBoundingRegion, rNativeContentRegion))
825  {
826  mirror( rNativeBoundingRegion, rOutDev, true );
827  mirror( rNativeContentRegion, rOutDev, true );
828  return true;
829  }
830  return false;
831  }
832  else
833  return forWidget()->getNativeControlRegion(nType, nPart, rControlRegion, nState, aValue, OUString(), rNativeBoundingRegion, rNativeContentRegion);
834 }
835 
837  const SalBitmap& rBitmap,
838  const OutputDevice& rOutDev )
839 {
840  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
841  {
842  SalTwoRect aPosAry2 = rPosAry;
843  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
844  return blendBitmap( aPosAry2, rBitmap );
845  }
846  else
847  return blendBitmap( rPosAry, rBitmap );
848 }
849 
851  const SalBitmap& rSrcBitmap,
852  const SalBitmap& rMaskBitmap,
853  const SalBitmap& rAlphaBitmap,
854  const OutputDevice& rOutDev )
855 {
856  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
857  {
858  SalTwoRect aPosAry2 = rPosAry;
859  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
860  return blendAlphaBitmap( aPosAry2, rSrcBitmap, rMaskBitmap, rAlphaBitmap );
861  }
862  else
863  return blendAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap, rAlphaBitmap );
864 }
865 
867  const SalBitmap& rSourceBitmap,
868  const SalBitmap& rAlphaBitmap,
869  const OutputDevice& rOutDev )
870 {
871  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
872  {
873  SalTwoRect aPosAry2 = rPosAry;
874  mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, rOutDev );
875  return drawAlphaBitmap( aPosAry2, rSourceBitmap, rAlphaBitmap );
876  }
877  else
878  return drawAlphaBitmap( rPosAry, rSourceBitmap, rAlphaBitmap );
879 }
880 
882  const basegfx::B2DPoint& rNull,
883  const basegfx::B2DPoint& rX,
884  const basegfx::B2DPoint& rY,
885  const SalBitmap& rSourceBitmap,
886  const SalBitmap* pAlphaBitmap,
887  double fAlpha,
888  const OutputDevice& rOutDev)
889 {
890  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
891  {
892  // mirroring set
893  const basegfx::B2DHomMatrix& rMirror(getMirror(rOutDev));
894  if (!rMirror.isIdentity())
895  {
896  basegfx::B2DPolygon aPoints({rNull, rX, rY});
897  basegfx::B2DRange aBoundingBox(aPoints.getB2DRange());
898  auto aTranslateToMirroredBounds = createTranslateToMirroredBounds(aBoundingBox, rMirror);
899 
900  basegfx::B2DPoint aNull = aTranslateToMirroredBounds * rNull;
901  basegfx::B2DPoint aX = aTranslateToMirroredBounds * rX;
902  basegfx::B2DPoint aY = aTranslateToMirroredBounds * rY;
903 
904  return drawTransformedBitmap(aNull, aX, aY, rSourceBitmap, pAlphaBitmap, fAlpha);
905  }
906  }
907 
908  return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap, fAlpha);
909 }
910 
912 {
914 }
915 
917  sal_uInt8 nTransparency, const OutputDevice& rOutDev )
918 {
919  if( (m_nLayout & SalLayoutFlags::BiDiRtl) || rOutDev.IsRTLEnabled() )
920  mirror( nX, nWidth, rOutDev );
921 
922  return drawAlphaRect( nX, nY, nWidth, nHeight, nTransparency );
923 }
924 
926 {
927  if (GetImpl())
928  return GetImpl()->getRenderBackendName();
929  return OUString();
930 }
931 
933  const vcl::font::PhysicalFontFace& rFontFace, const bool bVertical,
934  std::vector<sal_Int32>& rWidths, Ucs2UIntMap& rUnicodeEnc)
935 {
936  rWidths.clear();
937  rUnicodeEnc.clear();
938 
939  const int nGlyphCount = rTTF.glyphCount();
940  if (nGlyphCount <= 0)
941  return;
942 
943  FontCharMapRef xFCMap = rFontFace.GetFontCharMap();
944  if (!xFCMap.is() || !xFCMap->GetCharCount())
945  {
946  SAL_WARN("vcl.fonts", "no charmap");
947  return;
948  }
949 
950  rWidths.resize(nGlyphCount);
951  std::vector<sal_uInt16> aGlyphIds(nGlyphCount);
952  for (int i = 0; i < nGlyphCount; i++)
953  aGlyphIds[i] = static_cast<sal_uInt16>(i);
954 
955  std::unique_ptr<sal_uInt16[]> pGlyphMetrics
956  = GetTTSimpleGlyphMetrics(&rTTF, aGlyphIds.data(), nGlyphCount, bVertical);
957  if (pGlyphMetrics)
958  {
959  for (int i = 0; i < nGlyphCount; ++i)
960  rWidths[i] = pGlyphMetrics[i];
961  pGlyphMetrics.reset();
962  }
963 
964  int nCharCount = xFCMap->GetCharCount();
965  sal_uInt32 nChar = xFCMap->GetFirstChar();
966  for (; --nCharCount >= 0; nChar = xFCMap->GetNextChar(nChar))
967  {
968  if (nChar > 0xFFFF)
969  continue;
970 
971  sal_Ucs nUcsChar = static_cast<sal_Ucs>(nChar);
972  sal_uInt32 nGlyph = xFCMap->GetGlyphIndex(nUcsChar);
973  if (nGlyph > 0)
974  rUnicodeEnc[nUcsChar] = nGlyph;
975  }
976 }
977 
979  const bool bVertical, const sal_GlyphId* pGlyphIds,
980  const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
981  const int nOrigGlyphCount)
982 {
983  // Multiple questions:
984  // - Why is there a glyph limit?
985  // MacOS used to handle 257 glyphs...
986  // Also the much more complex PrintFontManager variant has this limit.
987  // Also the very first implementation has the limit in
988  // commit 8789ed701e98031f2a1657ea0dfd6f7a0b050992
989  // - Why doesn't the PrintFontManager care about the fake glyph? It
990  // is used on all unx platforms to create the subset font.
991  // - Should the SAL_WARN actually be asserts, like on MacOS?
992  if (nOrigGlyphCount > 256)
993  {
994  SAL_WARN("vcl.fonts", "too many glyphs for subsetting");
995  return false;
996  }
997 
998  int nGlyphCount = nOrigGlyphCount;
999  sal_uInt16 aShortIDs[256];
1000  sal_uInt8 aTempEncs[256];
1001 
1002  // handle the undefined / first font glyph
1003  int nNotDef = -1, i;
1004  for (i = 0; i < nGlyphCount; ++i)
1005  {
1006  aTempEncs[i] = pEncoding[i];
1007  aShortIDs[i] = static_cast<sal_uInt16>(pGlyphIds[i]);
1008  if (!aShortIDs[i])
1009  if (nNotDef < 0)
1010  nNotDef = i;
1011  }
1012 
1013  // nNotDef glyph must be in pos 0 => swap glyphids
1014  if (nNotDef != 0)
1015  {
1016  if (nNotDef < 0)
1017  {
1018  if (nGlyphCount == 256)
1019  {
1020  SAL_WARN("vcl.fonts", "too many glyphs for subsetting");
1021  return false;
1022  }
1023  nNotDef = nGlyphCount++;
1024  }
1025 
1026  aShortIDs[nNotDef] = aShortIDs[0];
1027  aTempEncs[nNotDef] = aTempEncs[0];
1028  aShortIDs[0] = 0;
1029  aTempEncs[0] = 0;
1030  }
1031 
1032  std::unique_ptr<sal_uInt16[]> pMetrics
1033  = GetTTSimpleGlyphMetrics(&rTTF, aShortIDs, nGlyphCount, bVertical);
1034  if (!pMetrics)
1035  return false;
1036 
1037  sal_uInt16 nNotDefAdv = pMetrics[0];
1038  pMetrics[0] = pMetrics[nNotDef];
1039  pMetrics[nNotDef] = nNotDefAdv;
1040  for (i = 0; i < nOrigGlyphCount; ++i)
1041  pGlyphWidths[i] = pMetrics[i];
1042  pMetrics.reset();
1043 
1044  // write subset into destination file
1045  return (CreateTTFromTTGlyphs(&rTTF, rSysPath.getStr(), aShortIDs, aTempEncs, nGlyphCount)
1046  == vcl::SFErrCodes::Ok);
1047 }
1048 
1049 bool SalGraphics::CreateCFFfontSubset(const unsigned char* pFontBytes, int nByteLength,
1050  const OString& rSysPath, const sal_GlyphId* pGlyphIds,
1051  const sal_uInt8* pEncoding, sal_Int32* pGlyphWidths,
1052  int nGlyphCount, FontSubsetInfo& rInfo)
1053 {
1054  FILE* pOutFile = fopen(rSysPath.getStr(), "wb");
1055  if (!pOutFile)
1056  return false;
1057  rInfo.LoadFont(FontType::CFF_FONT, pFontBytes, nByteLength);
1058  bool bRet = rInfo.CreateFontSubset(FontType::TYPE1_PFB, pOutFile, nullptr, pGlyphIds, pEncoding,
1059  nGlyphCount, pGlyphWidths);
1060  fclose(pOutFile);
1061  return bRet;
1062 }
1063 
1064 void SalGraphics::FillFontSubsetInfo(const vcl::TTGlobalFontInfo& rTTInfo, const OUString& pPSName,
1065  FontSubsetInfo& rInfo)
1066 {
1067  rInfo.m_aPSName = pPSName;
1069  rInfo.m_aFontBBox
1070  = tools::Rectangle(Point(rTTInfo.xMin, rTTInfo.yMin), Point(rTTInfo.xMax, rTTInfo.yMax));
1071  rInfo.m_nCapHeight = rTTInfo.yMax; // Well ...
1072  rInfo.m_nAscent = rTTInfo.winAscent;
1073  rInfo.m_nDescent = rTTInfo.winDescent;
1074 
1075  // mac fonts usually do not have an OS2-table
1076  // => get valid ascent/descent values from other tables
1077  if (!rInfo.m_nAscent)
1078  rInfo.m_nAscent = +rTTInfo.typoAscender;
1079  if (!rInfo.m_nAscent)
1080  rInfo.m_nAscent = +rTTInfo.ascender;
1081  if (!rInfo.m_nDescent)
1082  rInfo.m_nDescent = +rTTInfo.typoDescender;
1083  if (!rInfo.m_nDescent)
1084  rInfo.m_nDescent = -rTTInfo.descender;
1085 }
1086 
1087 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual SalFrame * GetParent() const =0
FontType m_nFontType
font-type of subset result
Definition: fontsubset.hxx:71
bool is() const
int winDescent
descender metric for Windows
Definition: sft.hxx:170
virtual bool drawAlphaBitmap(const SalTwoRect &, const SalBitmap &rSourceBitmap, const SalBitmap &rAlphaBitmap)=0
Render bitmap with alpha channel.
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const OutputDevice &rOutDev, const Color &rBackgroundColor=COL_AUTO)
void DrawPixel(tools::Long nX, tools::Long nY, const OutputDevice &rOutDev)
tools::Long m_nLastMirrorTranslation
Definition: salgdi.hxx:649
bool SetClipRegion(const vcl::Region &, const OutputDevice &rOutDev)
virtual OUString getRenderBackendName() const
static void FillFontSubsetInfo(const vcl::TTGlobalFontInfo &rTTInfo, const OUString &pPSName, FontSubsetInfo &rInfo)
static bool CreateTTFfontSubset(vcl::AbstractTrueTypeFont &aTTF, const OString &rSysPath, const bool bVertical, const sal_GlyphId *pGlyphIds, const sal_uInt8 *pEncoding, sal_Int32 *pGlyphWidths, int nGlyphCount)
MirrorMode GetMirrorMode(const OutputDevice &rOutDev) const
bool BlendBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, const OutputDevice &rOutDev)
SFErrCodes CreateTTFromTTGlyphs(AbstractTrueTypeFont *ttf, const char *fname, sal_uInt16 const *glyphArray, sal_uInt8 const *encoding, int nGlyphs)
Generates a new TrueType font and dumps it to outf file.
Definition: sft.cxx:1692
virtual std::shared_ptr< SalBitmap > getBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight)=0
bool HasFastDrawTransformedBitmap() const
void DrawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2, const OutputDevice &rOutDev)
CFF-container with PSType2 glyphs.
bool CreateFontSubset(FontType nOutFontTypeMask, FILE *pOutFile, const char *pOutFontName, const sal_GlyphId *pGlyphIds, const sal_uInt8 *pEncodedIds, int nReqGlyphCount, sal_Int32 *pOutGlyphWidths=nullptr)
Definition: fontsubset.cxx:68
sal_Unicode sal_Ucs
Definition: salgdi.hxx:65
virtual bool IsVirtual() const
Definition: outdev.cxx:187
virtual bool blendAlphaBitmap(const SalTwoRect &, const SalBitmap &rSrcBitmap, const SalBitmap &rMaskBitmap, const SalBitmap &rAlphaBitmap)=0
Draw the bitmap by blending using the mask and alpha channel.
void Invert(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, SalInvert nFlags, const OutputDevice &rOutDev)
SalFrameGeometry GetGeometry() const
ControlType getType() const
std::unique_ptr< sal_uInt16[]> GetTTSimpleGlyphMetrics(AbstractTrueTypeFont const *ttf, const sal_uInt16 *glyphArray, int nGlyphs, bool vertical)
Queries glyph metrics.
Definition: sft.cxx:2075
constexpr tools::Long Left() const
tools::Long mnDestX
Definition: salgtype.hxx:44
void Union(const tools::Rectangle &rRegion)
Definition: region.cxx:506
sal_uInt32 glyphCount() const
Definition: sft.hxx:739
sal_uIntPtr sal_uLong
long Long
tools::Long GetOutOffXPixel() const
Definition: outdev.hxx:325
virtual void drawLine(tools::Long nX1, tools::Long nY1, tools::Long nX2, tools::Long nY2)=0
tools::Rectangle maButton2Rect
void CopyBits(const SalTwoRect &rPosAry, const OutputDevice &rOutDev)
void DrawPolyPolygon(sal_uInt32 nPoly, const sal_uInt32 *pPoints, const Point **pPtAry, const OutputDevice &rOutDev)
bool DrawAlphaRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, sal_uInt8 nTransparency, const OutputDevice &rOutDev)
void LoadFont(FontType eInFontType, const unsigned char *pFontBytes, int nByteLength)
Definition: fontsubset.cxx:50
tools::Long mnSrcWidth
Definition: salgtype.hxx:42
virtual bool blendBitmap(const SalTwoRect &, const SalBitmap &rBitmap)=0
Blend the bitmap with the current buffer.
float x
tools::Rectangle maLowerRect
bool DrawTransformedBitmap(const basegfx::B2DPoint &rNull, const basegfx::B2DPoint &rX, const basegfx::B2DPoint &rY, const SalBitmap &rSourceBitmap, const SalBitmap *pAlphaBitmap, double fAlpha, const OutputDevice &rOutDev)
virtual bool drawNativeControl(ControlType eType, ControlPart ePart, const tools::Rectangle &rBoundingControlRegion, ControlState eState, const ImplControlValue &aValue, const OUString &aCaptions, const Color &rBackgroundColor)
Draw the requested control.
sal_uInt16 sal_GlyphId
Definition: glyphid.hxx:24
bool DrawEPS(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, void *pPtr, sal_uInt32 nSize, const OutputDevice &rOutDev)
tools::Long mnDestWidth
Definition: salgtype.hxx:46
virtual Color getPixel(tools::Long nX, tools::Long nY)=0
bool DrawGradient(const tools::PolyPolygon &rPolyPoly, const Gradient &rGradient, const OutputDevice &rOutDev)
NONE
std::vector< tools::Rectangle > RectangleVector
Definition: region.hxx:34
int yMin
global bounding box: yMin
Definition: sft.hxx:159
virtual FontCharMapRef GetFontCharMap() const =0
tools::Rectangle maUpperRect
virtual void GetGlyphWidths(const vcl::font::PhysicalFontFace *pFont, bool bVertical, std::vector< sal_Int32 > &rWidths, Ucs2UIntMap &rUnicodeEnc)=0
virtual void drawPixel(tools::Long nX, tools::Long nY)=0
OUString m_aPSName
Definition: fontsubset.hxx:66
void DrawMask(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, Color nMaskColor, const OutputDevice &rOutDev)
virtual void drawPolygon(sal_uInt32 nPoints, const Point *pPtAry)=0
virtual bool drawTransformedBitmap(const basegfx::B2DPoint &rNull, const basegfx::B2DPoint &rX, const basegfx::B2DPoint &rY, const SalBitmap &rSourceBitmap, const SalBitmap *pAlphaBitmap, double fAlpha)=0
draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system ...
void DrawBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, const OutputDevice &rOutDev)
bool initWidgetDrawBackends(bool bForce=false)
basegfx::B2DHomMatrix m_aLastMirror
Definition: salgdi.hxx:650
constexpr tools::Long GetWidth() const
virtual void drawRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight)=0
B2DHomMatrix createScaleTranslateB2DHomMatrix(double fScaleX, double fScaleY, double fTranslateX, double fTranslateY)
int GetCharCount() const
Get the number of characters in the font character map.
int winAscent
ascender metric for Windows
Definition: sft.hxx:169
virtual bool hitTestNativeControl(ControlType eType, ControlPart ePart, const tools::Rectangle &rBoundingControlRegion, const Point &aPos, bool &rIsInside)
Query if a position is inside the native widget part.
bool BlendAlphaBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalSrcBitmap, const SalBitmap &rSalMaskBitmap, const SalBitmap &rSalAlphaBitmap, const OutputDevice &rOutDev)
constexpr bool IsEmpty() const
virtual void drawPolyPolygon(sal_uInt32 nPoly, const sal_uInt32 *pPoints, const Point **pPtAry)=0
virtual void drawBitmap(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap)=0
void DrawRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice &rOutDev)
SalLayoutFlags m_nLayout
Definition: salgdi.hxx:638
void DrawPolygon(sal_uInt32 nPoints, const Point *pPtAry, const OutputDevice &rOutDev)
sal_UCS4 GetFirstChar() const
Get the first character in the font character map.
tools::Long mirror2(tools::Long nX, const OutputDevice &rOutDev) const
virtual bool setClipRegion(const vcl::Region &)=0
bool IsRTLEnabled() const
Definition: outdev.hxx:1284
virtual ImplControlValue * clone() const
int i
int typoAscender
OS/2 portable typographic ascender.
Definition: sft.hxx:166
int ascender
typographic ascent.
Definition: sft.hxx:162
void SetEmpty()
Definition: region.cxx:1424
tools::Rectangle maButton1Rect
virtual bool drawPolyLineBezier(sal_uInt32 nPoints, const Point *pPtAry, const PolyFlags *pFlgAry)=0
int descender
typographic descent.
Definition: sft.hxx:163
static bool CreateCFFfontSubset(const unsigned char *pFontBytes, int nByteLength, const OString &rSysPath, const sal_GlyphId *pGlyphIds, const sal_uInt8 *pEncoding, sal_Int32 *pGlyphWidths, int nGlyphCount, FontSubsetInfo &rInfo)
virtual bool getNativeControlRegion(ControlType eType, ControlPart ePart, const tools::Rectangle &rBoundingControlRegion, ControlState eState, const ImplControlValue &aValue, const OUString &aCaption, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion)
Get the native control regions for the control part.
int GetGlyphIndex(sal_UCS4) const
SAL_DLLPRIVATE bool ImplIsAntiparallel() const
Definition: outdev.cxx:671
void CopyArea(tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, tools::Long nSrcY, tools::Long nSrcWidth, tools::Long nSrcHeight, const OutputDevice &rOutDev)
virtual void invert(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, SalInvert nFlags)=0
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:175
MirrorMode m_eLastMirrorMode
Definition: salgdi.hxx:648
virtual bool drawEPS(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, void *pPtr, sal_uInt32 nSize)=0
static bool GetLayoutRTL()
void transform(const basegfx::B2DHomMatrix &rMatrix)
void DrawPolyLine(sal_uInt32 nPoints, Point const *pPtAry, const OutputDevice &rOutDev)
SalFrameGeometry maGeometry
absolute, unmirrored values
Definition: salframe.hxx:129
sal_Int32 w
std::unique_ptr< vcl::WidgetDrawInterface > m_pWidgetDraw
Definition: salgdi.hxx:674
SalInvert
Definition: salgtype.hxx:74
virtual tools::Long GetGraphicsWidth() const =0
virtual bool drawPolygonBezier(sal_uInt32 nPoints, const Point *pPtAry, const PolyFlags *pFlgAry)=0
virtual OUString getRenderBackendName() const =0
bool isIdentity() const
SFNT container with TrueType glyphs.
virtual SalGraphicsImpl * GetImpl() const =0
void mirror(tools::Long &nX, const OutputDevice &rOutDev) const
virtual bool hasFastDrawTransformedBitmap() const =0
Returns true if the drawTransformedBitmap() call is fast, and so it should be used directly without t...
int yMax
global bounding box: yMax
Definition: sft.hxx:161
virtual void copyBits(const SalTwoRect &rPosAry, SalGraphics *pSrcGraphics)=0
tools::Rectangle maThumbRect
tools::Long mnSrcX
Definition: salgtype.hxx:40
tools::Long nX
Definition: salgeom.hxx:30
bool DrawPolyLineBezier(sal_uInt32 nPoints, const Point *pPtAry, const PolyFlags *pFlgAry, const OutputDevice &rOutDev)
tools::ULong nWidth
Definition: salgeom.hxx:32
abstract base class for physical font faces
vcl::WidgetDrawInterface * forWidget()
Definition: salgdi.hxx:675
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion, const OutputDevice &rOutDev)
bool DrawAlphaBitmap(const SalTwoRect &, const SalBitmap &rSourceBitmap, const SalBitmap &rAlphaBitmap, const OutputDevice &rOutDev)
int xMax
global bounding box: xMax
Definition: sft.hxx:160
ControlType
These types are all based on the supported variants vcl/salnativewidgets.hxx and must be kept in-sync...
int xMin
global bounding box: xMin
Definition: sft.hxx:158
sal_UCS4 GetNextChar(sal_UCS4 cChar) const
Get the next character in the font character map.
A SalFrame is a system window (e.g. an X11 window).
Definition: salframe.hxx:114
def rectangle(l)
bool DrawPolygonBezier(sal_uInt32 nPoints, const Point *pPtAry, const PolyFlags *pFlgAry, const OutputDevice &rOutDev)
::basegfx::B2DPolyPolygon getB2DPolyPolygon() const
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
SalLayoutFlags GetLayout() const
Definition: salgdi.hxx:222
void GetRegionRectangles(RectangleVector &rTarget) const
Definition: region.cxx:1673
Sun Font Tools.
virtual void drawMask(const SalTwoRect &rPosAry, const SalBitmap &rSalBitmap, Color nMaskColor)=0
const basegfx::B2DHomMatrix & getMirror(const OutputDevice &rOutDev) const
bool HasPolyPolygonOrB2DPolyPolygon() const
Definition: region.hxx:107
~SalGraphics() COVERITY_NOEXCEPT_FALSE override
tools::Long GetDeviceWidth(const OutputDevice &rOutDev) const
int m_nAscent
all metrics in PS font units
Definition: fontsubset.hxx:67
PSType1 Postscript Font Binary.
virtual bool drawPolyPolygonBezier(sal_uInt32 nPoly, const sal_uInt32 *pPoints, const Point *const *pPtAry, const PolyFlags *const *pFlgAry)=0
basegfx::B2DPolyPolygon GetAsB2DPolyPolygon() const
Definition: region.cxx:1296
bool HitTestNativeScrollbar(ControlPart nPart, const tools::Rectangle &rControlRegion, const Point &aPos, bool &rIsInside, const OutputDevice &rOutDev)
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
virtual void drawPolyLine(sal_uInt32 nPoints, const Point *pPtAry)=0
tools::Rectangle maGripRect
#define SAL_WARN(area, stream)
virtual bool drawAlphaRect(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, sal_uInt8 nTransparency)=0
Render solid rectangle with given transparency.
bool DrawPolyPolygonBezier(sal_uInt32 nPoly, const sal_uInt32 *pPoints, const Point *const *pPtAry, const PolyFlags *const *pFlgAry, const OutputDevice &rOutDev)
Color GetPixel(tools::Long nX, tools::Long nY, const OutputDevice &rOutDev)
virtual void copyArea(tools::Long nDestX, tools::Long nDestY, tools::Long nSrcX, tools::Long nSrcY, tools::Long nSrcWidth, tools::Long nSrcHeight, bool bWindowInvalidate)=0
B2DHomMatrix createTranslateB2DHomMatrix(double fTranslateX, double fTranslateY)
std::map< sal_Ucs, sal_uInt32 > Ucs2UIntMap
Definition: salgdi.hxx:66
tools::Rectangle m_aFontBBox
Definition: fontsubset.hxx:70
virtual bool drawGradient(const tools::PolyPolygon &rPolyPoly, const Gradient &rGradient)=0
tools::Rectangle maThumbRect
tools::Long GetOutputWidthPixel() const
Definition: outdev.hxx:323
int typoDescender
OS/2 portable typographic descender.
Definition: sft.hxx:167
virtual void handleDamage(const tools::Rectangle &rDamagedRegion)
Handle damage done by drawing with a widget draw override.
Definition: salgdi.hxx:705
Return value of GetTTGlobalFontInfo()
Definition: sft.hxx:147
PolyFlags
std::shared_ptr< SalBitmap > GetBitmap(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, const OutputDevice &rOutDev)
bool m_bDetectedRangeSegmentation false
constexpr tools::Long GetHeight() const
SalLayoutFlags