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