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