LibreOffice Module vcl (master)  1
outdev/font.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 <i18nlangtag/mslangid.hxx>
21 #include <i18nlangtag/lang.h>
22 
23 #include <unotools/configmgr.hxx>
24 #include <vcl/metric.hxx>
25 #include <vcl/virdev.hxx>
26 #include <vcl/print.hxx>
27 #include <vcl/sysdata.hxx>
28 #include <vcl/fontcharmap.hxx>
29 #include <vcl/event.hxx>
31 #include <sal/log.hxx>
32 #include <tools/debug.hxx>
33 
34 #include <sallayout.hxx>
35 #include <salgdi.hxx>
36 #include <svdata.hxx>
37 #include <impglyphitem.hxx>
38 
39 #include <outdev.h>
40 #include <window.h>
41 
43 
44 #include <strings.hrc>
45 
46 FontMetric OutputDevice::GetDevFont( int nDevFontIndex ) const
47 {
48  FontMetric aFontMetric;
49 
51 
52  int nCount = GetDevFontCount();
53  if( nDevFontIndex < nCount )
54  {
55  const PhysicalFontFace& rData = *mpDeviceFontList->Get( nDevFontIndex );
56  aFontMetric.SetFamilyName( rData.GetFamilyName() );
57  aFontMetric.SetStyleName( rData.GetStyleName() );
58  aFontMetric.SetCharSet( rData.GetCharSet() );
59  aFontMetric.SetFamily( rData.GetFamilyType() );
60  aFontMetric.SetPitch( rData.GetPitch() );
61  aFontMetric.SetWeight( rData.GetWeight() );
62  aFontMetric.SetItalic( rData.GetItalic() );
63  aFontMetric.SetAlignment( TextAlign::ALIGN_TOP );
64  aFontMetric.SetWidthType( rData.GetWidthType() );
65  aFontMetric.SetQuality( rData.GetQuality() );
66  }
67 
68  return aFontMetric;
69 }
70 
72 {
73  if( !mpDeviceFontList )
74  {
75  if (!mxFontCollection)
76  {
77  return 0;
78  }
79 
80  mpDeviceFontList = mxFontCollection->GetDeviceFontList();
81 
82  if (!mpDeviceFontList->Count())
83  {
84  mpDeviceFontList.reset();
85  return 0;
86  }
87  }
88  return mpDeviceFontList->Count();
89 }
90 
91 bool OutputDevice::IsFontAvailable( const OUString& rFontName ) const
92 {
94  PhysicalFontFamily* pFound = mxFontCollection->FindFontFamily( rFontName );
95  return (pFound != nullptr);
96 }
97 
99 {
100  mpDeviceFontSizeList.reset();
101 
103  mpDeviceFontSizeList = mxFontCollection->GetDeviceFontSizeList( rFont.GetFamilyName() );
104  return mpDeviceFontSizeList->Count();
105 }
106 
107 Size OutputDevice::GetDevFontSize( const vcl::Font& rFont, int nSizeIndex ) const
108 {
109  // check range
110  int nCount = GetDevFontSizeCount( rFont );
111  if ( nSizeIndex >= nCount )
112  return Size();
113 
114  // when mapping is enabled round to .5 points
115  Size aSize( 0, mpDeviceFontSizeList->Get( nSizeIndex ) );
116  if ( mbMap )
117  {
118  aSize.setHeight( aSize.Height() * 10 );
119  MapMode aMap( MapUnit::Map10thInch, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
120  aSize = PixelToLogic( aSize, aMap );
121  aSize.AdjustHeight(5 );
122  aSize.setHeight( aSize.Height() / 10 );
123  long nRound = aSize.Height() % 5;
124  if ( nRound >= 3 )
125  aSize.AdjustHeight(5-nRound);
126  else
127  aSize.AdjustHeight( -nRound );
128  aSize.setHeight( aSize.Height() * 10 );
129  aSize = LogicToPixel( aSize, aMap );
130  aSize = PixelToLogic( aSize );
131  aSize.AdjustHeight(5 );
132  aSize.setHeight( aSize.Height() / 10 );
133  }
134  return aSize;
135 }
136 
137 namespace
138 {
139  struct UpdateFontsGuard
140  {
141  UpdateFontsGuard()
142  {
144  }
145 
146  ~UpdateFontsGuard()
147  {
149  }
150  };
151 }
152 
153 bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFontName )
154 {
155  UpdateFontsGuard aUpdateFontsGuard;
156 
158 
159  if( !mpGraphics && !AcquireGraphics() )
160  return false;
161 
162  bool bRC = mpGraphics->AddTempDevFont( mxFontCollection.get(), rFileURL, rFontName );
163  if( !bRC )
164  return false;
165 
166  if( mpAlphaVDev )
167  mpAlphaVDev->AddTempDevFont( rFileURL, rFontName );
168 
169  return true;
170 }
171 
172 bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeatures) const
173 {
174  if (!ImplNewFont())
175  return false;
176 
177  LogicalFontInstance* pFontInstance = mpFontInstance.get();
178  if (!pFontInstance)
179  return false;
180 
181  hb_font_t* pHbFont = pFontInstance->GetHbFont();
182  if (!pHbFont)
183  return false;
184 
185  hb_face_t* pHbFace = hb_font_get_face(pHbFont);
186  if (!pHbFace)
187  return false;
188 
190 
191  vcl::font::FeatureCollector aFeatureCollector(pHbFace, rFontFeatures, eOfficeLanguage);
192  aFeatureCollector.collect();
193 
194  return true;
195 }
196 
198 {
199  FontMetric aMetric;
200  if (!ImplNewFont())
201  return aMetric;
202 
203  LogicalFontInstance* pFontInstance = mpFontInstance.get();
204  ImplFontMetricDataRef xFontMetric = pFontInstance->mxFontMetric;
205 
206  // prepare metric
207  aMetric = maFont;
208 
209  // set aMetric with info from font
210  aMetric.SetFamilyName( maFont.GetFamilyName() );
211  aMetric.SetStyleName( xFontMetric->GetStyleName() );
212  aMetric.SetFontSize( PixelToLogic( Size( xFontMetric->GetWidth(), xFontMetric->GetAscent() + xFontMetric->GetDescent() - xFontMetric->GetInternalLeading() ) ) );
213  aMetric.SetCharSet( xFontMetric->IsSymbolFont() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE );
214  aMetric.SetFamily( xFontMetric->GetFamilyType() );
215  aMetric.SetPitch( xFontMetric->GetPitch() );
216  aMetric.SetWeight( xFontMetric->GetWeight() );
217  aMetric.SetItalic( xFontMetric->GetItalic() );
218  aMetric.SetAlignment( TextAlign::ALIGN_TOP );
219  aMetric.SetWidthType( xFontMetric->GetWidthType() );
220  if ( pFontInstance->mnOwnOrientation )
221  aMetric.SetOrientation( pFontInstance->mnOwnOrientation );
222  else
223  aMetric.SetOrientation( xFontMetric->GetOrientation() );
224 
225  // set remaining metric fields
226  aMetric.SetFullstopCenteredFlag( xFontMetric->IsFullstopCentered() );
227  aMetric.SetBulletOffset( xFontMetric->GetBulletOffset() );
228  aMetric.SetAscent( ImplDevicePixelToLogicHeight( xFontMetric->GetAscent() + mnEmphasisAscent ) );
231  // OutputDevice has its own external leading function due to #i60945#
233  aMetric.SetLineHeight( ImplDevicePixelToLogicHeight( xFontMetric->GetAscent() + xFontMetric->GetDescent() + mnEmphasisAscent + mnEmphasisDescent ) );
234  aMetric.SetSlant( ImplDevicePixelToLogicHeight( xFontMetric->GetSlant() ) );
235 
236  // get miscellaneous data
237  aMetric.SetQuality( xFontMetric->GetQuality() );
238 
239  SAL_INFO("vcl.gdi.fontmetric", "OutputDevice::GetFontMetric:" << aMetric);
240 
241  xFontMetric = nullptr;
242 
243  return aMetric;
244 }
245 
247 {
248  // select font, query metrics, select original font again
249  vcl::Font aOldFont = GetFont();
250  const_cast<OutputDevice*>(this)->SetFont( rFont );
251  FontMetric aMetric( GetFontMetric() );
252  const_cast<OutputDevice*>(this)->SetFont( aOldFont );
253  return aMetric;
254 }
255 
256 bool OutputDevice::GetFontCharMap( FontCharMapRef& rxFontCharMap ) const
257 {
258  if (!InitFont())
259  return false;
260 
261  FontCharMapRef xFontCharMap ( mpGraphics->GetFontCharMap() );
262  if (!xFontCharMap.is())
263  {
264  FontCharMapRef xDefaultMap( new FontCharMap() );
265  rxFontCharMap = xDefaultMap;
266  }
267  else
268  rxFontCharMap = xFontCharMap;
269 
270  return !rxFontCharMap->IsDefaultMap();
271 }
272 
274 {
275  if (!InitFont())
276  return false;
277  return mpGraphics->GetFontCapabilities(rFontCapabilities);
278 }
279 
280 #if ENABLE_CAIRO_CANVAS
281 
282 SystemFontData OutputDevice::GetSysFontData(int nFallbacklevel) const
283 {
284  SystemFontData aSysFontData;
285 
286  if (!mpGraphics)
287  (void) AcquireGraphics();
288 
289  if (mpGraphics)
290  aSysFontData = mpGraphics->GetSysFontData(nFallbacklevel);
291 
292  return aSysFontData;
293 }
294 
295 #endif // ENABLE_CAIRO_CANVAS
296 
297 void OutputDevice::ImplGetEmphasisMark( tools::PolyPolygon& rPolyPoly, bool& rPolyLine,
298  tools::Rectangle& rRect1, tools::Rectangle& rRect2,
299  long& rYOff, long& rWidth,
300  FontEmphasisMark eEmphasis,
301  long nHeight )
302 {
303  static const PolyFlags aAccentPolyFlags[24] =
304  {
305  PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
306  PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
307  PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
308  PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
309  PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
310  PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control,
311  PolyFlags::Normal, PolyFlags::Normal, PolyFlags::Control,
312  PolyFlags::Normal, PolyFlags::Control, PolyFlags::Control
313  };
314 
315  static const long aAccentPos[48] =
316  {
317  78, 0,
318  348, 79,
319  599, 235,
320  843, 469,
321  938, 574,
322  990, 669,
323  990, 773,
324  990, 843,
325  964, 895,
326  921, 947,
327  886, 982,
328  860, 999,
329  825, 999,
330  764, 999,
331  721, 964,
332  686, 895,
333  625, 791,
334  556, 660,
335  469, 504,
336  400, 400,
337  261, 252,
338  61, 61,
339  0, 27,
340  9, 0
341  };
342 
343  rWidth = 0;
344  rYOff = 0;
345  rPolyLine = false;
346 
347  if ( !nHeight )
348  return;
349 
350  FontEmphasisMark nEmphasisStyle = eEmphasis & FontEmphasisMark::Style;
351  long nDotSize = 0;
352  switch ( nEmphasisStyle )
353  {
354  case FontEmphasisMark::Dot:
355  // Dot has 55% of the height
356  nDotSize = (nHeight*550)/1000;
357  if ( !nDotSize )
358  nDotSize = 1;
359  if ( nDotSize <= 2 )
360  rRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
361  else
362  {
363  long nRad = nDotSize/2;
364  tools::Polygon aPoly( Point( nRad, nRad ), nRad, nRad );
365  rPolyPoly.Insert( aPoly );
366  }
367  rYOff = ((nHeight*250)/1000)/2; // Center to the another EmphasisMarks
368  rWidth = nDotSize;
369  break;
370 
371  case FontEmphasisMark::Circle:
372  // Dot has 80% of the height
373  nDotSize = (nHeight*800)/1000;
374  if ( !nDotSize )
375  nDotSize = 1;
376  if ( nDotSize <= 2 )
377  rRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
378  else
379  {
380  long nRad = nDotSize/2;
381  tools::Polygon aPoly( Point( nRad, nRad ), nRad, nRad );
382  rPolyPoly.Insert( aPoly );
383  // BorderWidth is 15%
384  long nBorder = (nDotSize*150)/1000;
385  if ( nBorder <= 1 )
386  rPolyLine = true;
387  else
388  {
389  tools::Polygon aPoly2( Point( nRad, nRad ),
390  nRad-nBorder, nRad-nBorder );
391  rPolyPoly.Insert( aPoly2 );
392  }
393  }
394  rWidth = nDotSize;
395  break;
396 
397  case FontEmphasisMark::Disc:
398  // Dot has 80% of the height
399  nDotSize = (nHeight*800)/1000;
400  if ( !nDotSize )
401  nDotSize = 1;
402  if ( nDotSize <= 2 )
403  rRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
404  else
405  {
406  long nRad = nDotSize/2;
407  tools::Polygon aPoly( Point( nRad, nRad ), nRad, nRad );
408  rPolyPoly.Insert( aPoly );
409  }
410  rWidth = nDotSize;
411  break;
412 
413  case FontEmphasisMark::Accent:
414  // Dot has 80% of the height
415  nDotSize = (nHeight*800)/1000;
416  if ( !nDotSize )
417  nDotSize = 1;
418  if ( nDotSize <= 2 )
419  {
420  if ( nDotSize == 1 )
421  {
422  rRect1 = tools::Rectangle( Point(), Size( nDotSize, nDotSize ) );
423  rWidth = nDotSize;
424  }
425  else
426  {
427  rRect1 = tools::Rectangle( Point(), Size( 1, 1 ) );
428  rRect2 = tools::Rectangle( Point( 1, 1 ), Size( 1, 1 ) );
429  }
430  }
431  else
432  {
433  tools::Polygon aPoly( SAL_N_ELEMENTS( aAccentPos ) / 2,
434  reinterpret_cast<const Point*>(aAccentPos),
435  aAccentPolyFlags );
436  double dScale = static_cast<double>(nDotSize)/1000.0;
437  aPoly.Scale( dScale, dScale );
438  tools::Polygon aTemp;
439  aPoly.AdaptiveSubdivide( aTemp );
440  tools::Rectangle aBoundRect = aTemp.GetBoundRect();
441  rWidth = aBoundRect.GetWidth();
442  nDotSize = aBoundRect.GetHeight();
443  rPolyPoly.Insert( aTemp );
444  }
445  break;
446  default: break;
447  }
448 
449  // calculate position
450  long nOffY = 1+(mnDPIY/300); // one visible pixel space
451  long nSpaceY = nHeight-nDotSize;
452  if ( nSpaceY >= nOffY*2 )
453  rYOff += nOffY;
454  if ( !(eEmphasis & FontEmphasisMark::PosBelow) )
455  rYOff += nDotSize;
456 }
457 
459 {
460  FontEmphasisMark nEmphasisMark = rFont.GetEmphasisMark();
461 
462  // If no Position is set, then calculate the default position, which
463  // depends on the language
464  if ( !(nEmphasisMark & (FontEmphasisMark::PosAbove | FontEmphasisMark::PosBelow)) )
465  {
466  LanguageType eLang = rFont.GetLanguage();
467  // In Chinese Simplified the EmphasisMarks are below/left
469  nEmphasisMark |= FontEmphasisMark::PosBelow;
470  else
471  {
472  eLang = rFont.GetCJKContextLanguage();
473  // In Chinese Simplified the EmphasisMarks are below/left
475  nEmphasisMark |= FontEmphasisMark::PosBelow;
476  else
477  nEmphasisMark |= FontEmphasisMark::PosAbove;
478  }
479  }
480 
481  return nEmphasisMark;
482 }
483 
485 {
486  return mpFontInstance->mxFontMetric->GetExternalLeading();
487 }
488 
489 void OutputDevice::ImplClearFontData( const bool bNewFontLists )
490 {
491  // the currently selected logical font is no longer needed
492  mpFontInstance.clear();
493 
494  mbInitFont = true;
495  mbNewFont = true;
496 
497  if ( bNewFontLists )
498  {
499  mpDeviceFontList.reset();
500  mpDeviceFontSizeList.reset();
501 
502  // release all physically selected fonts on this device
503  if( AcquireGraphics() )
505  }
506 
507  ImplSVData* pSVData = ImplGetSVData();
508 
510  mxFontCache->Invalidate();
511 
512  if (bNewFontLists && AcquireGraphics())
513  {
515  mxFontCollection->Clear();
516  }
517 }
518 
519 void OutputDevice::RefreshFontData( const bool bNewFontLists )
520 {
521  ImplRefreshFontData( bNewFontLists );
522 }
523 
524 void OutputDevice::ImplRefreshFontData( const bool bNewFontLists )
525 {
526  if (bNewFontLists && AcquireGraphics())
528 }
529 
531 {
532  ImplClearFontData( true/*bNewFontLists*/ );
533  ImplRefreshFontData( true/*bNewFontLists*/ );
534 }
535 
536 void OutputDevice::ImplClearAllFontData(bool bNewFontLists)
537 {
538  ImplSVData* pSVData = ImplGetSVData();
539 
541 
542  // clear global font lists to have them updated
543  pSVData->maGDIData.mxScreenFontCache->Invalidate();
544  if ( bNewFontLists )
545  {
546  pSVData->maGDIData.mxScreenFontList->Clear();
547  vcl::Window * pFrame = pSVData->maWinData.mpFirstFrame;
548  if ( pFrame )
549  {
550  if ( pFrame->AcquireGraphics() )
551  {
552  OutputDevice *pDevice = pFrame;
553  pDevice->mpGraphics->ClearDevFontCache();
554  pDevice->mpGraphics->GetDevFontList(pFrame->mpWindowImpl->mpFrameData->mxFontCollection.get());
555  }
556  }
557  }
558 }
559 
560 void OutputDevice::ImplRefreshAllFontData(bool bNewFontLists)
561 {
562  auto svdata = ImplGetSVData();
564  if (!svdata->mnFontUpdatesLockCount)
566  else
567  {
568  svdata->mbFontUpdatesPending = true;
569  if (bNewFontLists)
570  svdata->mbFontUpdatesNewLists = true;
571  }
572 }
573 
574 void OutputDevice::ImplUpdateAllFontData(bool bNewFontLists)
575 {
576  OutputDevice::ImplClearAllFontData(bNewFontLists);
578 }
579 
580 void OutputDevice::ImplUpdateFontDataForAllFrames( const FontUpdateHandler_t pHdl, const bool bNewFontLists )
581 {
582  ImplSVData* const pSVData = ImplGetSVData();
583 
584  // update all windows
585  vcl::Window* pFrame = pSVData->maWinData.mpFirstFrame;
586  while ( pFrame )
587  {
588  ( pFrame->*pHdl )( bNewFontLists );
589 
590  vcl::Window* pSysWin = pFrame->mpWindowImpl->mpFrameData->mpFirstOverlap;
591  while ( pSysWin )
592  {
593  ( pSysWin->*pHdl )( bNewFontLists );
594  pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
595  }
596 
597  pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
598  }
599 
600  // update all virtual devices
601  VirtualDevice* pVirDev = pSVData->maGDIData.mpFirstVirDev;
602  while ( pVirDev )
603  {
604  ( pVirDev->*pHdl )( bNewFontLists );
605  pVirDev = pVirDev->mpNext;
606  }
607 
608  // update all printers
609  Printer* pPrinter = pSVData->maGDIData.mpFirstPrinter;
610  while ( pPrinter )
611  {
612  ( pPrinter->*pHdl )( bNewFontLists );
613  pPrinter = pPrinter->mpNext;
614  }
615 }
616 
618 {
619  auto svdata = ImplGetSVData();
621  if (bLock)
622  {
623  ++svdata->mnFontUpdatesLockCount;
624  }
625  else if (svdata->mnFontUpdatesLockCount > 0)
626  {
627  --svdata->mnFontUpdatesLockCount;
628  if (!svdata->mnFontUpdatesLockCount && svdata->mbFontUpdatesPending)
629  {
630  ImplRefreshAllFontData(svdata->mbFontUpdatesNewLists);
631 
632  svdata->mbFontUpdatesPending = false;
633  svdata->mbFontUpdatesNewLists = false;
634  }
635  }
636 }
637 
639 {
640  ImplSVData* pSVData = ImplGetSVData();
641  pSVData->maGDIData.mbFontSubChanged = false;
642 }
643 
645 {
646  ImplSVData* pSVData = ImplGetSVData();
647  if ( pSVData->maGDIData.mbFontSubChanged )
648  {
649  ImplUpdateAllFontData( false );
650 
654  pSVData->maGDIData.mbFontSubChanged = false;
655  }
656 }
657 
658 void OutputDevice::AddFontSubstitute( const OUString& rFontName,
659  const OUString& rReplaceFontName,
660  AddFontSubstituteFlags nFlags )
661 {
663  if( !rpSubst )
664  rpSubst = new ImplDirectFontSubstitution;
665  rpSubst->AddFontSubstitute( rFontName, rReplaceFontName, nFlags );
667 }
668 
669 void ImplDirectFontSubstitution::AddFontSubstitute( const OUString& rFontName,
670  const OUString& rSubstFontName, AddFontSubstituteFlags nFlags )
671 {
672  maFontSubstList.emplace_back( rFontName, rSubstFontName, nFlags );
673 }
674 
675 ImplFontSubstEntry::ImplFontSubstEntry( const OUString& rFontName,
676  const OUString& rSubstFontName, AddFontSubstituteFlags nSubstFlags )
677 : mnFlags( nSubstFlags )
678 {
679  maSearchName = GetEnglishSearchFontName( rFontName );
680  maSearchReplaceName = GetEnglishSearchFontName( rSubstFontName );
681 }
682 
684 {
686  if( pSubst )
687  pSubst->RemoveFontsSubstitute();
688 }
689 
691 {
692  maFontSubstList.clear();
693 }
694 
696  const OUString& rSearchName ) const
697 {
698  // TODO: get rid of O(N) searches
699  std::vector<ImplFontSubstEntry>::const_iterator it = std::find_if (
700  maFontSubstList.begin(), maFontSubstList.end(),
701  [&] (const ImplFontSubstEntry& s) { return (s.mnFlags & AddFontSubstituteFlags::ALWAYS)
702  && (s.maSearchName == rSearchName); } );
703  if (it != maFontSubstList.end())
704  {
705  rSubstName = it->maSearchReplaceName;
706  return true;
707  }
708  return false;
709 }
710 
711 void ImplFontSubstitute( OUString& rFontName )
712 {
713  // must be canonicalised
714  assert( GetEnglishSearchFontName( rFontName ) == rFontName );
715 
716  OUString aSubstFontName;
717 
718  // apply user-configurable font replacement (eg, from the list in Tools->Options)
720  if( pSubst && pSubst->FindFontSubstitute( aSubstFontName, rFontName ) )
721  {
722  rFontName = aSubstFontName;
723  return;
724  }
725 }
726 
727 //hidpi TODO: This routine has hard-coded font-sizes that break places such as DialControl
729  GetDefaultFontFlags nFlags, const OutputDevice* pOutDev )
730 {
731  if (!pOutDev && !utl::ConfigManager::IsFuzzing()) // default is NULL
732  pOutDev = Application::GetDefaultDevice();
733 
734  OUString aSearch;
736  {
737  LanguageTag aLanguageTag(
738  ( eLang == LANGUAGE_NONE || eLang == LANGUAGE_SYSTEM || eLang == LANGUAGE_DONTKNOW ) ?
739  Application::GetSettings().GetUILanguageTag() :
740  LanguageTag( eLang ));
741 
743  OUString aDefault = rDefaults.getDefaultFont( aLanguageTag, nType );
744 
745  if( !aDefault.isEmpty() )
746  aSearch = aDefault;
747  else
748  aSearch = rDefaults.getUserInterfaceFont( aLanguageTag ); // use the UI font as a fallback
749  }
750  else
751  aSearch = "Liberation Serif";
752 
753  vcl::Font aFont;
754  aFont.SetPitch( PITCH_VARIABLE );
755 
756  switch ( nType )
757  {
758  case DefaultFontType::SANS_UNICODE:
759  case DefaultFontType::UI_SANS:
760  aFont.SetFamily( FAMILY_SWISS );
761  break;
762 
763  case DefaultFontType::SANS:
764  case DefaultFontType::LATIN_HEADING:
765  case DefaultFontType::LATIN_SPREADSHEET:
766  case DefaultFontType::LATIN_DISPLAY:
767  aFont.SetFamily( FAMILY_SWISS );
768  break;
769 
770  case DefaultFontType::SERIF:
771  case DefaultFontType::LATIN_TEXT:
772  case DefaultFontType::LATIN_PRESENTATION:
773  aFont.SetFamily( FAMILY_ROMAN );
774  break;
775 
776  case DefaultFontType::FIXED:
777  case DefaultFontType::LATIN_FIXED:
778  case DefaultFontType::UI_FIXED:
779  aFont.SetPitch( PITCH_FIXED );
780  aFont.SetFamily( FAMILY_MODERN );
781  break;
782 
783  case DefaultFontType::SYMBOL:
784  aFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
785  break;
786 
787  case DefaultFontType::CJK_TEXT:
788  case DefaultFontType::CJK_PRESENTATION:
789  case DefaultFontType::CJK_SPREADSHEET:
790  case DefaultFontType::CJK_HEADING:
791  case DefaultFontType::CJK_DISPLAY:
792  aFont.SetFamily( FAMILY_SYSTEM ); // don't care, but don't use font subst config later...
793  break;
794 
795  case DefaultFontType::CTL_TEXT:
796  case DefaultFontType::CTL_PRESENTATION:
797  case DefaultFontType::CTL_SPREADSHEET:
798  case DefaultFontType::CTL_HEADING:
799  case DefaultFontType::CTL_DISPLAY:
800  aFont.SetFamily( FAMILY_SYSTEM ); // don't care, but don't use font subst config later...
801  break;
802  }
803 
804  if ( !aSearch.isEmpty() )
805  {
806  aFont.SetFontHeight( 12 ); // corresponds to nDefaultHeight
807  aFont.SetWeight( WEIGHT_NORMAL );
808  aFont.SetLanguage( eLang );
809 
810  if ( aFont.GetCharSet() == RTL_TEXTENCODING_DONTKNOW )
811  aFont.SetCharSet( osl_getThreadTextEncoding() );
812 
813  // Should we only return available fonts on the given device
814  if ( pOutDev )
815  {
816  pOutDev->ImplInitFontList();
817 
818  // Search Font in the FontList
819  OUString aName;
820  sal_Int32 nIndex = 0;
821  do
822  {
823  PhysicalFontFamily* pFontFamily = pOutDev->mxFontCollection->FindFontFamily( GetNextFontToken( aSearch, nIndex ) );
824  if( pFontFamily )
825  {
826  AddTokenFontName( aName, pFontFamily->GetFamilyName() );
827  if( nFlags & GetDefaultFontFlags::OnlyOne )
828  break;
829  }
830  }
831  while ( nIndex != -1 );
832  aFont.SetFamilyName( aName );
833  }
834 
835  // No Name, then set all names
836  if ( aFont.GetFamilyName().isEmpty() )
837  {
838  if ( nFlags & GetDefaultFontFlags::OnlyOne )
839  {
840  if( !pOutDev )
841  {
842  SAL_WARN_IF(!utl::ConfigManager::IsFuzzing(), "vcl.gdi", "No default window has been set for the application - we really shouldn't be able to get here");
843  aFont.SetFamilyName( aSearch.getToken( 0, ';' ) );
844  }
845  else
846  {
847  pOutDev->ImplInitFontList();
848 
849  aFont.SetFamilyName( aSearch );
850 
851  // convert to pixel height
852  Size aSize = pOutDev->ImplLogicToDevicePixel( aFont.GetFontSize() );
853  if ( !aSize.Height() )
854  {
855  // use default pixel height only when logical height is zero
856  if ( aFont.GetFontHeight() )
857  aSize.setHeight( 1 );
858  else
859  aSize.setHeight( (12*pOutDev->mnDPIY)/72 );
860  }
861 
862  // use default width only when logical width is zero
863  if( (0 == aSize.Width()) && (0 != aFont.GetFontSize().Width()) )
864  aSize.setWidth( 1 );
865 
866  // get the name of the first available font
867  float fExactHeight = static_cast<float>(aSize.Height());
868  rtl::Reference<LogicalFontInstance> pFontInstance = pOutDev->mxFontCache->GetFontInstance( pOutDev->mxFontCollection.get(), aFont, aSize, fExactHeight );
869  if (pFontInstance)
870  {
871  assert(pFontInstance->GetFontFace());
872  aFont.SetFamilyName(pFontInstance->GetFontFace()->GetFamilyName());
873  }
874  }
875  }
876  else
877  aFont.SetFamilyName( aSearch );
878  }
879  }
880 
881 #if OSL_DEBUG_LEVEL > 2
882  const char* s = "SANS_UNKNOWN";
883  switch ( nType )
884  {
885  case DefaultFontType::SANS_UNICODE: s = "SANS_UNICODE"; break;
886  case DefaultFontType::UI_SANS: s = "UI_SANS"; break;
887 
888  case DefaultFontType::SANS: s = "SANS"; break;
889  case DefaultFontType::LATIN_HEADING: s = "LATIN_HEADING"; break;
890  case DefaultFontType::LATIN_SPREADSHEET: s = "LATIN_SPREADSHEET"; break;
891  case DefaultFontType::LATIN_DISPLAY: s = "LATIN_DISPLAY"; break;
892 
893  case DefaultFontType::SERIF: s = "SERIF"; break;
894  case DefaultFontType::LATIN_TEXT: s = "LATIN_TEXT"; break;
895  case DefaultFontType::LATIN_PRESENTATION: s = "LATIN_PRESENTATION"; break;
896 
897  case DefaultFontType::FIXED: s = "FIXED"; break;
898  case DefaultFontType::LATIN_FIXED: s = "LATIN_FIXED"; break;
899  case DefaultFontType::UI_FIXED: s = "UI_FIXED"; break;
900 
901  case DefaultFontType::SYMBOL: s = "SYMBOL"; break;
902 
903  case DefaultFontType::CJK_TEXT: s = "CJK_TEXT"; break;
904  case DefaultFontType::CJK_PRESENTATION: s = "CJK_PRESENTATION"; break;
905  case DefaultFontType::CJK_SPREADSHEET: s = "CJK_SPREADSHEET"; break;
906  case DefaultFontType::CJK_HEADING: s = "CJK_HEADING"; break;
907  case DefaultFontType::CJK_DISPLAY: s = "CJK_DISPLAY"; break;
908 
909  case DefaultFontType::CTL_TEXT: s = "CTL_TEXT"; break;
910  case DefaultFontType::CTL_PRESENTATION: s = "CTL_PRESENTATION"; break;
911  case DefaultFontType::CTL_SPREADSHEET: s = "CTL_SPREADSHEET"; break;
912  case DefaultFontType::CTL_HEADING: s = "CTL_HEADING"; break;
913  case DefaultFontType::CTL_DISPLAY: s = "CTL_DISPLAY"; break;
914  }
915  SAL_INFO("vcl.gdi",
916  "OutputDevice::GetDefaultFont() Type=" << s
917  << " lang=" << eLang
918  << " flags=" << static_cast<int>(nFlags)
919  << " family=\"" << aFont.GetFamilyName() << "\"");
920 #endif
921 
922  return aFont;
923 }
924 
926 {
927  if( !mxFontCollection->Count() )
928  {
929  if( mpGraphics || AcquireGraphics() )
930  {
931  SAL_INFO( "vcl.gdi", "OutputDevice::ImplInitFontList()" );
933 
934  // There is absolutely no way there should be no fonts available on the device
935  if( !mxFontCollection->Count() )
936  {
937  OUString aError( "Application error: no fonts and no vcl resource found on your system" );
938  OUString aResStr(VclResId(SV_ACCESSERROR_NO_FONTS));
939  if (!aResStr.isEmpty())
940  aError = aResStr;
941  Application::Abort(aError);
942  }
943  }
944  }
945 }
946 
948 {
950 
951  if (!ImplNewFont())
952  return false;
953  if (!mpFontInstance)
954  return false;
955  if (!mpGraphics)
956  {
957  if (!AcquireGraphics())
958  return false;
959  }
960  else if (!mbInitFont)
961  return true;
962 
963  mpGraphics->SetFont(mpFontInstance.get(), 0);
964  mbInitFont = false;
965  return true;
966 }
967 
969 {
970  if (!InitFont())
971  return nullptr;
972  return mpFontInstance.get();
973 }
974 
976 {
978 
979  // get correct font list on the PDF writer if necessary
980  if (GetOutDevType() == OUTDEV_PDF)
981  {
982  const ImplSVData* pSVData = ImplGetSVData();
984  || mxFontCache == pSVData->maGDIData.mxScreenFontCache )
985  const_cast<OutputDevice&>(*this).ImplUpdateFontData();
986  }
987 
988  if ( !mbNewFont )
989  return true;
990 
991  // we need a graphics
992  if ( !mpGraphics && !AcquireGraphics() )
993  {
994  SAL_WARN("vcl.gdi", "OutputDevice::ImplNewFont(): no Graphics, no Font");
995  return false;
996  }
997 
999 
1000  // convert to pixel height
1001  // TODO: replace integer based aSize completely with subpixel accurate type
1002  float fExactHeight = ImplFloatLogicHeightToDevicePixel( static_cast<float>(maFont.GetFontHeight()) );
1004  if ( !aSize.Height() )
1005  {
1006  // use default pixel height only when logical height is zero
1007  if ( maFont.GetFontSize().Height() )
1008  aSize.setHeight( 1 );
1009  else
1010  aSize.setHeight( (12*mnDPIY)/72 );
1011  fExactHeight = static_cast<float>(aSize.Height());
1012  }
1013 
1014  // select the default width only when logical width is zero
1015  if( (0 == aSize.Width()) && (0 != maFont.GetFontSize().Width()) )
1016  aSize.setWidth( 1 );
1017 
1018  // decide if antialiasing is appropriate
1019  bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
1021  {
1022  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1023  bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
1024  bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > maFont.GetFontSize().Height());
1025  }
1026 
1027  // get font entry
1029  mpFontInstance = mxFontCache->GetFontInstance(mxFontCollection.get(), maFont, aSize, fExactHeight, bNonAntialiased);
1030  const bool bNewFontInstance = pOldFontInstance.get() != mpFontInstance.get();
1031  pOldFontInstance.clear();
1032 
1033  LogicalFontInstance* pFontInstance = mpFontInstance.get();
1034 
1035  if (!pFontInstance)
1036  {
1037  SAL_WARN("vcl.gdi", "OutputDevice::ImplNewFont(): no LogicalFontInstance, no Font");
1038  return false;
1039  }
1040 
1041  // mark when lower layers need to get involved
1042  mbNewFont = false;
1043  if( bNewFontInstance )
1044  mbInitFont = true;
1045 
1046  // select font when it has not been initialized yet
1047  if (!pFontInstance->mbInit && InitFont())
1048  {
1049  // get metric data from device layers
1050  pFontInstance->mbInit = true;
1051 
1052  pFontInstance->mxFontMetric->SetOrientation( sal::static_int_cast<short>(mpFontInstance->GetFontSelectPattern().mnOrientation) );
1053  mpGraphics->GetFontMetric( pFontInstance->mxFontMetric, 0 );
1054 
1055  pFontInstance->mxFontMetric->ImplInitTextLineSize( this );
1056  pFontInstance->mxFontMetric->ImplInitAboveTextLineSize();
1057  pFontInstance->mxFontMetric->ImplInitFlags( this );
1058 
1059  pFontInstance->mnLineHeight = pFontInstance->mxFontMetric->GetAscent() + pFontInstance->mxFontMetric->GetDescent();
1060 
1061  SetFontOrientation( pFontInstance );
1062  }
1063 
1064  // calculate EmphasisArea
1065  mnEmphasisAscent = 0;
1066  mnEmphasisDescent = 0;
1067  if ( maFont.GetEmphasisMark() & FontEmphasisMark::Style )
1068  {
1070  long nEmphasisHeight = (pFontInstance->mnLineHeight*250)/1000;
1071  if ( nEmphasisHeight < 1 )
1072  nEmphasisHeight = 1;
1073  if ( nEmphasisMark & FontEmphasisMark::PosBelow )
1074  mnEmphasisDescent = nEmphasisHeight;
1075  else
1076  mnEmphasisAscent = nEmphasisHeight;
1077  }
1078 
1079  // calculate text offset depending on TextAlignment
1080  TextAlign eAlign = maFont.GetAlignment();
1081  if ( eAlign == ALIGN_BASELINE )
1082  {
1083  mnTextOffX = 0;
1084  mnTextOffY = 0;
1085  }
1086  else if ( eAlign == ALIGN_TOP )
1087  {
1088  mnTextOffX = 0;
1089  mnTextOffY = +pFontInstance->mxFontMetric->GetAscent() + mnEmphasisAscent;
1090  if ( pFontInstance->mnOrientation )
1091  {
1092  Point aOriginPt(0, 0);
1093  aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
1094  }
1095  }
1096  else // eAlign == ALIGN_BOTTOM
1097  {
1098  mnTextOffX = 0;
1099  mnTextOffY = -pFontInstance->mxFontMetric->GetDescent() + mnEmphasisDescent;
1100  if ( pFontInstance->mnOrientation )
1101  {
1102  Point aOriginPt(0, 0);
1103  aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
1104  }
1105  }
1106 
1112 
1113 
1114  bool bRet = true;
1115 
1116  // #95414# fix for OLE objects which use scale factors very creatively
1117  if( mbMap && !aSize.Width() )
1118  {
1119  int nOrigWidth = pFontInstance->mxFontMetric->GetWidth();
1120  float fStretch = static_cast<float>(maMapRes.mnMapScNumX) * maMapRes.mnMapScDenomY;
1121  fStretch /= static_cast<float>(maMapRes.mnMapScNumY) * maMapRes.mnMapScDenomX;
1122  int nNewWidth = static_cast<int>(nOrigWidth * fStretch + 0.5);
1123  if( (nNewWidth != nOrigWidth) && (nNewWidth != 0) )
1124  {
1125  Size aOrigSize = maFont.GetFontSize();
1126  const_cast<vcl::Font&>(maFont).SetFontSize( Size( nNewWidth, aSize.Height() ) );
1127  mbMap = false;
1128  mbNewFont = true;
1129  bRet = ImplNewFont(); // recurse once using stretched width
1130  mbMap = true;
1131  const_cast<vcl::Font&>(maFont).SetFontSize( aOrigSize );
1132  }
1133  }
1134 
1135  return bRet;
1136 }
1137 
1138 void OutputDevice::SetFontOrientation( LogicalFontInstance* const pFontInstance ) const
1139 {
1140  if( pFontInstance->GetFontSelectPattern().mnOrientation && !pFontInstance->mxFontMetric->GetOrientation() )
1141  {
1142  pFontInstance->mnOwnOrientation = sal::static_int_cast<short>(pFontInstance->GetFontSelectPattern().mnOrientation);
1143  pFontInstance->mnOrientation = pFontInstance->mnOwnOrientation;
1144  }
1145  else
1146  {
1147  pFontInstance->mnOrientation = pFontInstance->mxFontMetric->GetOrientation();
1148  }
1149 }
1150 
1151 void OutputDevice::ImplDrawEmphasisMark( long nBaseX, long nX, long nY,
1152  const tools::PolyPolygon& rPolyPoly, bool bPolyLine,
1153  const tools::Rectangle& rRect1, const tools::Rectangle& rRect2 )
1154 {
1155  if( IsRTLEnabled() )
1156  nX = nBaseX - (nX - nBaseX - 1);
1157 
1158  nX -= mnOutOffX;
1159  nY -= mnOutOffY;
1160 
1161  if ( rPolyPoly.Count() )
1162  {
1163  if ( bPolyLine )
1164  {
1165  tools::Polygon aPoly = rPolyPoly.GetObject( 0 );
1166  aPoly.Move( nX, nY );
1167  DrawPolyLine( aPoly );
1168  }
1169  else
1170  {
1171  tools::PolyPolygon aPolyPoly = rPolyPoly;
1172  aPolyPoly.Move( nX, nY );
1173  DrawPolyPolygon( aPolyPoly );
1174  }
1175  }
1176 
1177  if ( !rRect1.IsEmpty() )
1178  {
1179  tools::Rectangle aRect( Point( nX+rRect1.Left(),
1180  nY+rRect1.Top() ), rRect1.GetSize() );
1181  DrawRect( aRect );
1182  }
1183 
1184  if ( !rRect2.IsEmpty() )
1185  {
1186  tools::Rectangle aRect( Point( nX+rRect2.Left(),
1187  nY+rRect2.Top() ), rRect2.GetSize() );
1188 
1189  DrawRect( aRect );
1190  }
1191 }
1192 
1194 {
1195  Color aOldLineColor = GetLineColor();
1196  Color aOldFillColor = GetFillColor();
1197  bool bOldMap = mbMap;
1198  GDIMetaFile* pOldMetaFile = mpMetaFile;
1199  mpMetaFile = nullptr;
1200  EnableMapMode( false );
1201 
1203  tools::PolyPolygon aPolyPoly;
1204  tools::Rectangle aRect1;
1205  tools::Rectangle aRect2;
1206  long nEmphasisYOff;
1207  long nEmphasisWidth;
1208  long nEmphasisHeight;
1209  bool bPolyLine;
1210 
1211  if ( nEmphasisMark & FontEmphasisMark::PosBelow )
1212  nEmphasisHeight = mnEmphasisDescent;
1213  else
1214  nEmphasisHeight = mnEmphasisAscent;
1215 
1216  ImplGetEmphasisMark( aPolyPoly, bPolyLine,
1217  aRect1, aRect2,
1218  nEmphasisYOff, nEmphasisWidth,
1219  nEmphasisMark,
1220  nEmphasisHeight );
1221 
1222  if ( bPolyLine )
1223  {
1225  SetFillColor();
1226  }
1227  else
1228  {
1229  SetLineColor();
1231  }
1232 
1233  Point aOffset(0,0);
1234 
1235  if ( nEmphasisMark & FontEmphasisMark::PosBelow )
1236  aOffset.AdjustY(mpFontInstance->mxFontMetric->GetDescent() + nEmphasisYOff );
1237  else
1238  aOffset.AdjustY( -(mpFontInstance->mxFontMetric->GetAscent() + nEmphasisYOff) );
1239 
1240  long nEmphasisWidth2 = nEmphasisWidth / 2;
1241  long nEmphasisHeight2 = nEmphasisHeight / 2;
1242  aOffset += Point( nEmphasisWidth2, nEmphasisHeight2 );
1243 
1244  Point aOutPoint;
1245  tools::Rectangle aRectangle;
1246  const GlyphItem* pGlyph;
1247  int nStart = 0;
1248  while (rSalLayout.GetNextGlyph(&pGlyph, aOutPoint, nStart))
1249  {
1250  if (!pGlyph->GetGlyphBoundRect(aRectangle))
1251  continue;
1252 
1253  if (!pGlyph->IsSpacing())
1254  {
1255  Point aAdjPoint = aOffset;
1256  aAdjPoint.AdjustX(aRectangle.Left() + (aRectangle.GetWidth() - nEmphasisWidth) / 2 );
1257  if ( mpFontInstance->mnOrientation )
1258  {
1259  Point aOriginPt(0, 0);
1260  aOriginPt.RotateAround( aAdjPoint, mpFontInstance->mnOrientation );
1261  }
1262  aOutPoint += aAdjPoint;
1263  aOutPoint -= Point( nEmphasisWidth2, nEmphasisHeight2 );
1264  ImplDrawEmphasisMark( rSalLayout.DrawBase().X(),
1265  aOutPoint.X(), aOutPoint.Y(),
1266  aPolyPoly, bPolyLine, aRect1, aRect2 );
1267  }
1268  }
1269 
1270  SetLineColor( aOldLineColor );
1271  SetFillColor( aOldFillColor );
1272  EnableMapMode( bOldMap );
1273  mpMetaFile = pOldMetaFile;
1274 }
1275 
1276 std::unique_ptr<SalLayout> OutputDevice::getFallbackLayout(
1277  LogicalFontInstance* pLogicalFont, int nFallbackLevel,
1278  ImplLayoutArgs& rLayoutArgs) const
1279 {
1280  // we need a graphics
1281  if (!mpGraphics && !AcquireGraphics())
1282  return nullptr;
1283 
1284  assert(mpGraphics != nullptr);
1285  mpGraphics->SetFont( pLogicalFont, nFallbackLevel );
1286 
1287  rLayoutArgs.ResetPos();
1288  std::unique_ptr<GenericSalLayout> pFallback = mpGraphics->GetTextLayout(nFallbackLevel);
1289 
1290  if (!pFallback)
1291  return nullptr;
1292 
1293  if (!pFallback->LayoutText(rLayoutArgs, nullptr))
1294  {
1295  // there is no need for a font that couldn't resolve anything
1296  return nullptr;
1297  }
1298 
1299  return pFallback;
1300 }
1301 
1302 std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_ptr<SalLayout> pSalLayout, ImplLayoutArgs& rLayoutArgs ) const
1303 {
1304  // This function relies on a valid mpFontInstance, if it doesn't exist bail out
1305  // - we'd have crashed later on anyway. At least here we can catch the error in debug
1306  // mode.
1307  if ( !mpFontInstance )
1308  {
1309  SAL_WARN ("vcl.gdi", "No font entry set in OutputDevice");
1310  assert(mpFontInstance);
1311  return nullptr;
1312  }
1313 
1314  // prepare multi level glyph fallback
1315  std::unique_ptr<MultiSalLayout> pMultiSalLayout;
1316  ImplLayoutRuns aLayoutRuns = rLayoutArgs.maRuns;
1317  rLayoutArgs.PrepareFallback();
1318  rLayoutArgs.mnFlags |= SalLayoutFlags::ForFallback;
1319 
1320  // get list of code units that need glyph fallback
1321  int nCharPos = -1;
1322  bool bRTL = false;
1323  OUStringBuffer aMissingCodeBuf(512);
1324  while (rLayoutArgs.GetNextPos( &nCharPos, &bRTL))
1325  aMissingCodeBuf.append(rLayoutArgs.mrStr[nCharPos]);
1326  rLayoutArgs.ResetPos();
1327  OUString aMissingCodes = aMissingCodeBuf.makeStringAndClear();
1328 
1329  FontSelectPattern aFontSelData(mpFontInstance->GetFontSelectPattern());
1330 
1331  // try if fallback fonts support the missing code units
1332  for( int nFallbackLevel = 1; nFallbackLevel < MAX_FALLBACK; ++nFallbackLevel )
1333  {
1334  // find a font family suited for glyph fallback
1335  // GetGlyphFallbackFont() needs a valid FontInstance
1336  // if the system-specific glyph fallback is active
1337  rtl::Reference<LogicalFontInstance> pFallbackFont = mxFontCache->GetGlyphFallbackFont( mxFontCollection.get(),
1338  aFontSelData, mpFontInstance.get(), nFallbackLevel, aMissingCodes );
1339  if( !pFallbackFont )
1340  break;
1341 
1342  if( nFallbackLevel < MAX_FALLBACK-1)
1343  {
1344  // ignore fallback font if it is the same as the original font
1345  // unless we are looking for a substitution for 0x202F, in which
1346  // case we'll just use a normal space
1347  if( mpFontInstance->GetFontFace() == pFallbackFont->GetFontFace() &&
1348  aMissingCodes.indexOf(0x202F) == -1 )
1349  {
1350  continue;
1351  }
1352  }
1353 
1354  // create and add glyph fallback layout to multilayout
1355  std::unique_ptr<SalLayout> pFallback = getFallbackLayout(pFallbackFont.get(),
1356  nFallbackLevel, rLayoutArgs);
1357  if (pFallback)
1358  {
1359  if( !pMultiSalLayout )
1360  pMultiSalLayout.reset( new MultiSalLayout( std::move(pSalLayout) ) );
1361  pMultiSalLayout->AddFallback(std::move(pFallback), rLayoutArgs.maRuns);
1362  if (nFallbackLevel == MAX_FALLBACK-1)
1363  pMultiSalLayout->SetIncomplete(true);
1364  }
1365 
1366  // break when this fallback was sufficient
1367  if( !rLayoutArgs.PrepareFallback() )
1368  break;
1369  }
1370 
1371  if( pMultiSalLayout && pMultiSalLayout->LayoutText( rLayoutArgs, nullptr ) )
1372  pSalLayout = std::move(pMultiSalLayout);
1373 
1374  // restore orig font settings
1375  pSalLayout->InitFont();
1376  rLayoutArgs.maRuns = aLayoutRuns;
1377 
1378  return pSalLayout;
1379 }
1380 
1382 {
1383  if (!ImplNewFont())
1384  return 0;
1385 
1386  return ImplDevicePixelToLogicWidth( mpFontInstance->mxFontMetric->GetMinKashida() );
1387 }
1388 
1389 sal_Int32 OutputDevice::ValidateKashidas ( const OUString& rTxt,
1390  sal_Int32 nIdx, sal_Int32 nLen,
1391  sal_Int32 nKashCount,
1392  const sal_Int32* pKashidaPos,
1393  sal_Int32* pKashidaPosDropped ) const
1394 {
1395  // do layout
1396  std::unique_ptr<SalLayout> pSalLayout = ImplLayout( rTxt, nIdx, nLen );
1397  if( !pSalLayout )
1398  return 0;
1399  sal_Int32 nDropped = 0;
1400  for( int i = 0; i < nKashCount; ++i )
1401  {
1402  if( !pSalLayout->IsKashidaPosValid( pKashidaPos[ i ] ))
1403  {
1404  pKashidaPosDropped[ nDropped ] = pKashidaPos [ i ];
1405  ++nDropped;
1406  }
1407  }
1408  return nDropped;
1409 }
1410 
1411 bool OutputDevice::GetGlyphBoundRects( const Point& rOrigin, const OUString& rStr,
1412  int nIndex, int nLen, MetricVector& rVector )
1413 {
1414  rVector.clear();
1415 
1416  if( nIndex >= rStr.getLength() )
1417  return false;
1418 
1419  if( nLen < 0 || nIndex + nLen >= rStr.getLength() )
1420  {
1421  nLen = rStr.getLength() - nIndex;
1422  }
1423 
1424  tools::Rectangle aRect;
1425  for( int i = 0; i < nLen; i++ )
1426  {
1427  if( !GetTextBoundRect( aRect, rStr, nIndex, nIndex + i, 1 ) )
1428  break;
1429  aRect.Move( rOrigin.X(), rOrigin.Y() );
1430  rVector.push_back( aRect );
1431  }
1432 
1433  return (nLen == static_cast<int>(rVector.size()));
1434 }
1435 
1436 sal_Int32 OutputDevice::HasGlyphs( const vcl::Font& rTempFont, const OUString& rStr,
1437  sal_Int32 nIndex, sal_Int32 nLen ) const
1438 {
1439  if( nIndex >= rStr.getLength() )
1440  return nIndex;
1441  sal_Int32 nEnd;
1442  if( nLen == -1 )
1443  nEnd = rStr.getLength();
1444  else
1445  nEnd = std::min( rStr.getLength(), nIndex + nLen );
1446 
1447  SAL_WARN_IF( nIndex >= nEnd, "vcl.gdi", "StartPos >= EndPos?" );
1448  SAL_WARN_IF( nEnd > rStr.getLength(), "vcl.gdi", "String too short" );
1449 
1450  // to get the map temporarily set font
1451  const vcl::Font aOrigFont = GetFont();
1452  const_cast<OutputDevice&>(*this).SetFont( rTempFont );
1453  FontCharMapRef xFontCharMap ( new FontCharMap() );
1454  bool bRet = GetFontCharMap( xFontCharMap );
1455  const_cast<OutputDevice&>(*this).SetFont( aOrigFont );
1456 
1457  // if fontmap is unknown assume it doesn't have the glyphs
1458  if( !bRet )
1459  return nIndex;
1460 
1461  for( sal_Int32 i = nIndex; nIndex < nEnd; ++i, ++nIndex )
1462  if( ! xFontCharMap->HasChar( rStr[i] ) )
1463  return nIndex;
1464 
1465  return -1;
1466 }
1467 
1469 
1471 
1473 {
1475 }
1476 
1478 {
1479  mxFontCache.reset(new ImplFontCache{});
1480 }
1481 
1482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetFamily(FontFamily)
Definition: font/font.cxx:123
SAL_DLLPRIVATE std::unique_ptr< SalLayout > ImplGlyphFallbackLayout(std::unique_ptr< SalLayout >, ImplLayoutArgs &) const
sal_uInt16 Count() const
long Width() const
const Color & GetTextColor() const
Definition: outdev.hxx:1110
void SetLineHeight(long nHeight)
Definition: metric.hxx:52
OutDevType GetOutDevType() const
Definition: outdev.hxx:522
long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:342
bool HasChar(sal_UCS4) const
Does the font character map include the UCS4 character?
#define LANGUAGE_NONE
virtual void ClearDevFontCache()=0
long GetWidth() const
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
bool GetFontCharMap(FontCharMapRef &rxFontCharMap) const
const tools::Polygon & GetObject(sal_uInt16 nPos) const
void SetFontSize(const Size &)
Definition: font/font.cxx:117
const OUString & GetStyleName() const
static void AddFontSubstitute(const OUString &rFontName, const OUString &rReplaceFontName, AddFontSubstituteFlags nFlags)
long GetHeight() const
const OUString & GetFamilyName() const
Definition: font/font.cxx:670
std::vector< tools::Rectangle > MetricVector
Definition: outdev.hxx:139
bool mbFontSubChanged
Definition: svdata.hxx:189
void SetBulletOffset(long nOffset)
Definition: metric.hxx:54
long GetFontHeight() const
Definition: font/font.cxx:675
long AdjustX(long nHorzMove)
static void NotifyAllWindows(DataChangedEvent &rDCEvt)
Notify all windows that the application has changed data.
Definition: svapp.cxx:731
FAMILY_MODERN
virtual void ImplRefreshFontData(bool bNewFontLists)
VclPtr< VirtualDevice > mpNext
Definition: virdev.hxx:50
bool IsDefaultMap() const
Determines if the font character map is the "default".
long mnEmphasisAscent
Definition: outdev.hxx:353
long Height() const
long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:344
bool GetNextPos(int *nCharPos, bool *bRTL)
Definition: sallayout.hxx:108
bool IsOutline() const
Definition: font/font.cxx:707
LanguageType getLanguageType(bool bResolveSystem=true) const
sal_Int32 HasGlyphs(const vcl::Font &rFont, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1) const
bool mbTextSpecial
Definition: outdev.hxx:392
FontLineStyle GetOverline() const
Definition: font/font.cxx:711
static SAL_DLLPRIVATE void ImplUpdateFontDataForAllFrames(FontUpdateHandler_t pHdl, bool bNewFontLists)
void SetInternalLeading(long nIntLeading)
Definition: metric.hxx:51
LanguageType GetCJKContextLanguage() const
Definition: font/font.cxx:684
#define MAX_FALLBACK
Definition: sallayout.hxx:41
bool FindFontSubstitute(OUString &rSubstName, const OUString &rFontName) const
static void EndFontSubstitution()
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:704
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const =0
FontEmphasisMark
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
OUString maSearchReplaceName
Definition: outdev.h:88
SAL_DLLPRIVATE std::unique_ptr< SalLayout > getFallbackLayout(LogicalFontInstance *pLogicalFont, int nFallbackLevel, ImplLayoutArgs &rLayoutArgs) const
void SetDescent(long nDescent)
Definition: metric.hxx:49
void SetWeight(FontWeight)
Definition: font/font.cxx:215
void DrawPolyLine(const tools::Polygon &rPoly)
Render the given polygon as a line stroke.
Definition: polyline.cxx:33
std::shared_ptr< PhysicalFontCollection > mxFontCollection
Definition: outdev.hxx:322
sal_Int32 mnDPIY
Definition: outdev.hxx:348
hb_font_t * GetHbFont()
std::unique_ptr< ImplDeviceFontSizeList > mpDeviceFontSizeList
Definition: outdev.hxx:324
static void LockFontUpdates(bool bLock)
void SetCharSet(rtl_TextEncoding)
Definition: font/font.cxx:129
void ReleaseFontCollection()
void ImplInitAboveTextLineSize()
Definition: fontmetric.cxx:216
FAMILY_ROMAN
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:647
bool IsSpacing() const
bool mbMap
Definition: outdev.hxx:376
SAL_DLLPRIVATE const LogicalFontInstance * GetFontInstance() const
ImplFontMetricDataRef mxFontMetric
void SetOrientation(short nLineOrientation)
Definition: font/font.cxx:192
AntialiasingFlags GetAntialiasing() const
Definition: outdev.hxx:592
ImplSVGDIData maGDIData
Definition: svdata.hxx:348
virtual std::unique_ptr< GenericSalLayout > GetTextLayout(int nFallbackLevel)=0
void ImplInitTextLineSize(const OutputDevice *pDev)
Definition: fontmetric.cxx:126
void Scale(double fScaleX, double fScaleY)
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, const long *pDXArray=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
Return the exact bounding rectangle of rStr.
Definition: text.cxx:2307
FontAlign GetAlignment() const
Definition: font/font.cxx:668
void SetQuality(int)
Definition: font/font.cxx:703
void Move(long nHorzMoveDelta, long nVertMoveDelta)
virtual FontCharMapRef GetFontCharMap() const =0
OUString maSearchName
Definition: outdev.h:87
static OutputDevice * GetDefaultDevice()
Get the default "device" (in this case the default window).
Definition: svapp.cxx:1054
bool IsEmpty() const
SAL_DLLPRIVATE void ImplInitFontList() const
LanguageType GetLanguage() const
Definition: font/font.cxx:683
VclPtr< Printer > mpNext
Definition: print.hxx:182
void SetExternalLeading(long nExtLeading)
Definition: metric.hxx:50
static void ImplCallEventListenersApplicationDataChanged(void *pData)
Send event to all VCL application event listeners.
Definition: svapp.cxx:750
AddFontSubstituteFlags
Definition: outdev.hxx:244
LINESTYLE_NONE
OUString GetEnglishSearchFontName(const OUString &rInName)
const vcl::Font & GetFont() const
Definition: outdev.hxx:637
ImplLayoutRuns maRuns
Definition: sallayout.hxx:94
static bool IsFuzzing()
void RefreshFontData(const bool bNewFontLists)
void Insert(const tools::Polygon &rPoly, sal_uInt16 nPos=POLYPOLY_APPEND)
FontMetric GetFontMetric() const
VclPtr< VirtualDevice > mpFirstVirDev
Definition: svdata.hxx:178
long Top() const
PITCH_VARIABLE
SAL_DLLPRIVATE bool ImplNewFont() const
void SetFontCollectionFromSVData()
FontItalic GetItalic() const
bool GetFontFeatures(std::vector< vcl::font::Feature > &rFontFeatures) const
rtl_TextEncoding GetCharSet() const
void ReleaseFontCache()
static void BeginFontSubstitution()
void AddTokenFontName(OUString &rName, const OUString &rNewToken)
GetDefaultFontFlags
Definition: outdev.hxx:256
FontEmphasisMark GetEmphasisMark() const
Definition: font/font.cxx:713
void SetLanguage(LanguageType)
Definition: font/font.cxx:174
bool AddTempDevFont(const OUString &rFileURL, const OUString &rFontName)
OUString getDefaultFont(const LanguageTag &rLanguageTag, DefaultFontType nType) const
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:32
void SetPitch(FontPitch ePitch)
Definition: font/font.cxx:186
const LanguageTag & GetLanguageTag() const
void Move(long nHorzMove, long nVertMove)
#define SAL_N_ELEMENTS(arr)
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:316
abstract base class for physical font faces
const OUString & mrStr
Definition: sallayout.hxx:81
FontFamily GetFamilyType() const
FontMetric GetDevFont(int nDevFontIndex) const
Definition: outdev/font.cxx:46
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:67
VclPtr< Printer > mpFirstPrinter
Definition: svdata.hxx:180
void Move(long nHorzMove, long nVertMove)
void SetAlignment(FontAlign)
Definition: font/font.cxx:101
ImplFontSubstEntry(const OUString &rFontName, const OUString &rSubstFontName, AddFontSubstituteFlags nSubstFlags)
static SAL_DLLPRIVATE void ImplRefreshAllFontData(bool bNewFontLists)
void SetLineColor()
void SetOrientation(short nOrientation)
ALIGN_BASELINE
virtual long GetFontExtLeading() const
bool IsRTLEnabled() const
Definition: outdev.hxx:1354
void SetFamilyName(const OUString &rFamilyName)
Definition: font/font.cxx:107
SAL_DLLPRIVATE float ImplFloatLogicHeightToDevicePixel(float fLogicHeight) const
Convert logical height to device pixels, with exact sub-pixel value.
Definition: map.cxx:450
long GetDescent() const
bool PrepareFallback()
Definition: sallayout.cxx:489
long AdjustY(long nVertMove)
FontWeight GetWeight() const
PITCH_FIXED
#define LANGUAGE_SYSTEM
void ImplInitFlags(const OutputDevice *pDev)
Definition: fontmetric.cxx:266
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
DisplayOptions GetDisplayOptions() const
std::unique_ptr< ImplDeviceFontList > mpDeviceFontList
Definition: outdev.hxx:323
int i
virtual void SetFontOrientation(LogicalFontInstance *const pFontInstance) const
long mnMapScNumX
Definition: outdevmap.hxx:27
void SetFillColor()
bool mbNewFont
Definition: outdev.hxx:390
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:304
WEIGHT_NORMAL
const Color & GetLineColor() const
Definition: outdev.hxx:618
bool mbTextLines
Definition: outdev.hxx:391
bool IsFontAvailable(const OUString &rFontName) const
Definition: outdev/font.cxx:91
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:511
static SAL_DLLPRIVATE FontEmphasisMark ImplGetEmphasisMarkStyle(const vcl::Font &rFont)
long const nBorder
bool IsShadow() const
Definition: font/font.cxx:708
#define LANGUAGE_DONTKNOW
const Size & GetFontSize() const
Definition: font/font.cxx:673
vcl::Font maFont
Definition: outdev.hxx:364
FontStrikeout GetStrikeout() const
Definition: font/font.cxx:712
int GetQuality() const
void SetWidthType(FontWidth)
Definition: font/font.cxx:221
SystemFontData GetSysFontData(int nFallbacklevel) const
Retrieve detailed font information in platform independent structure.
const AllSettings & GetSettings() const
Definition: outdev.hxx:420
std::unique_ptr< SalLayout > ImplLayout(const OUString &, sal_Int32 nIndex, sal_Int32 nLen, const Point &rLogicPos=Point(0, 0), long nLogicWidth=0, const long *pLogicDXArray=nullptr, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
Definition: text.cxx:1234
LINESTYLE_DONTKNOW
long X() const
void ReleaseFonts()
Definition: salgdi.hxx:131
Size GetSize() const
static bool isSimplifiedChinese(LanguageType nLang)
Point & DrawBase()
Definition: vcllayout.hxx:69
bool GetGlyphBoundRects(const Point &rOrigin, const OUString &rStr, int nIndex, int nLen, MetricVector &rVector)
Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1185
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:940
FAMILY_SYSTEM
static DefaultFontConfiguration & get()
ImplSVWinData maWinData
Definition: svdata.hxx:349
FontRelief GetRelief() const
Definition: font/font.cxx:709
SAL_DLLPRIVATE void ImplDrawEmphasisMark(long nBaseX, long nX, long nY, const tools::PolyPolygon &rPolyPoly, bool bPolyLine, const tools::Rectangle &rRect1, const tools::Rectangle &rRect2)
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:331
ALIGN_TOP
const FontSelectPattern & GetFontSelectPattern() const
void SetStyleName(const OUString &rStyleName)
Definition: font/font.cxx:112
long mnMapScDenomY
Definition: outdevmap.hxx:30
void SetAscent(long nAscent)
Definition: metric.hxx:48
static void Abort(const OUString &rErrorText)
Ends the program prematurely with an error message.
Definition: svapp.cxx:256
ImplMapRes maMapRes
Definition: outdev.hxx:357
bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
FuncFlags const mnFlags
#define SAL_WARN_IF(condition, area, stream)
void ResetNewFontCache()
bool IsFullstopCentered() const
void SetFont(const vcl::Font &rNewFont)
#define SAL_INFO(area, stream)
SAL_DLLPRIVATE void ImplDrawEmphasisMarks(SalLayout &)
FAMILY_SWISS
void ImplFontSubstitute(OUString &rFontName)
SAL_DLLPRIVATE void ImplUpdateFontData()
void RotateAround(long &rX, long &rY, short nOrientation) const
SAL_DLLPRIVATE long ImplDevicePixelToLogicHeight(long nHeight) const
Convert device pixels to a height in logical units.
Definition: map.cxx:468
OUString getUserInterfaceFont(const LanguageTag &rLanguageTag) const
std::shared_ptr< ImplFontCache > mxScreenFontCache
Definition: svdata.hxx:183
short GetOrientation() const
ImplDirectFontSubstitution * mpDirectFontSubst
Definition: svdata.hxx:185
void SetFontHeight(long nHeight)
Definition: font/font.cxx:674
void DrawPolyPolygon(const tools::PolyPolygon &rPolyPoly)
Render the given poly-polygon.
Definition: polygon.cxx:36
int GetDevFontSizeCount(const vcl::Font &) const
Definition: outdev/font.cxx:98
SAL_DLLPRIVATE void ImplGetEmphasisMark(tools::PolyPolygon &rPolyPoly, bool &rPolyLine, tools::Rectangle &rRect1, tools::Rectangle &rRect2, long &rYOff, long &rWidth, FontEmphasisMark eEmphasis, long nHeight)
virtual void ImplClearFontData(bool bNewFontLists)
bool mbInitFont
Definition: outdev.hxx:386
static SAL_DLLPRIVATE void ImplUpdateAllFontData(bool bNewFontLists)
long mnMapScDenomX
Definition: outdevmap.hxx:29
long Left() const
rtl::Reference< LogicalFontInstance > mpFontInstance
Definition: outdev.hxx:320
virtual bool GetNextGlyph(const GlyphItem **pGlyph, Point &rPos, int &nStart, const PhysicalFontFace **pFallbackFont=nullptr, int *const pFallbackLevel=nullptr) const =0
SalLayoutFlags mnFlags
Definition: sallayout.hxx:80
Size GetDevFontSize(const vcl::Font &rFont, int nSizeIndex) const
DefaultFontType
sal_Int32 ValidateKashidas(const OUString &rTxt, sal_Int32 nIdx, sal_Int32 nLen, sal_Int32 nKashCount, const sal_Int32 *pKashidaPos, sal_Int32 *pKashidaPosDropped) const
VclPtr< vcl::Window > mpFirstFrame
Definition: svdata.hxx:198
long mnTextOffX
font specific text alignment offsets in pixel units
Definition: outdev.hxx:351
std::vector< ImplFontSubstEntry > maFontSubstList
Definition: outdev.h:98
long GetBulletOffset() const
int GetDevFontCount() const
Definition: outdev/font.cxx:71
void SetItalic(FontItalic)
Definition: font/font.cxx:227
long mnEmphasisDescent
Definition: outdev.hxx:354
void AdaptiveSubdivide(tools::Polygon &rResult, const double d=1.0) const
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Definition: map.cxx:504
STRIKEOUT_DONTKNOW
OString const aName
FontLineStyle GetUnderline() const
Definition: font/font.cxx:710
SAL_DLLPRIVATE long ImplDevicePixelToLogicWidth(long nWidth) const
Convert device pixels to a width in logical units.
Definition: map.cxx:458
OUString GetNextFontToken(const OUString &rTokenStr, sal_Int32 &rIndex)
virtual void GetFontMetric(ImplFontMetricDataRef &, int nFallbackLevel)=0
std::shared_ptr< ImplFontCache > mxFontCache
Definition: outdev.hxx:321
FontWidth GetWidthType() const
long GetMinKashida() const
#define SAL_WARN(area, stream)
bool IsSymbolFont() const
OUString VclResId(const char *pId)
Definition: svdata.cxx:258
virtual bool AddTempDevFont(PhysicalFontCollection *, const OUString &rFileURL, const OUString &rFontName)=0
static void RemoveFontsSubstitute()
#define DBG_TESTSOLARMUTEX()
tools::Rectangle GetBoundRect() const
void SetFullstopCenteredFlag(bool bCentered)
Definition: metric.hxx:58
FontPitch GetPitch() const
virtual bool AcquireGraphics() const override
Acquire a graphics device that the output device uses to draw on.
Definition: window.cxx:814
virtual void SetFont(LogicalFontInstance *, int nFallbackLevel)=0
STRIKEOUT_NONE
long mnMapScNumY
Definition: outdevmap.hxx:28
void SetSlant(long nSlant)
Definition: metric.hxx:53
bool GetGlyphBoundRect(tools::Rectangle &) const
static SAL_DLLPRIVATE void ImplClearAllFontData(bool bNewFontLists)
const OUString & GetFamilyName() const
void setWidth(long nWidth)
std::shared_ptr< PhysicalFontCollection > mxScreenFontList
Definition: svdata.hxx:182
void AddFontSubstitute(const OUString &rFontName, const OUString &rSubstName, AddFontSubstituteFlags nFlags)
sal_uLong GetAntialiasingMinPixelHeight() const
long mnTextOffY
Definition: outdev.hxx:352
TextAlign
rtl_TextEncoding GetCharSet() const
Definition: font/font.cxx:679
long Y() const
const Color & GetFillColor() const
Definition: outdev.hxx:623
long GetInternalLeading() const
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:319
PolyFlags
virtual void GetDevFontList(PhysicalFontCollection *)=0
SAL_DLLPRIVATE bool InitFont() const
void setHeight(long nHeight)
const OUString & GetFamilyName() const
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo