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