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