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>
26#include <i18nlangtag/lang.h>
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 <window.h>
38#include <font/EmphasisMark.hxx>
39
40#include <ImplLayoutArgs.hxx>
41#include <drawmode.hxx>
42#include <impfontcache.hxx>
47#include <impglyphitem.hxx>
48#include <sallayout.hxx>
49#include <salgdi.hxx>
50#include <svdata.hxx>
51
52#include <unicode/uchar.h>
53
54#include <strings.hrc>
55
56void OutputDevice::SetFont( const vcl::Font& rNewFont )
57{
58 vcl::Font aFont = vcl::drawmode::GetFont(rNewFont, GetDrawMode(), GetSettings().GetStyleSettings());
59
60 if ( mpMetaFile )
61 {
62 mpMetaFile->AddAction( new MetaFontAction( aFont ) );
63 // the color and alignment actions don't belong here
64 // TODO: get rid of them without breaking anything...
67 }
68
69 if ( maFont.IsSameInstance( aFont ) )
70 return;
71
72 // Optimization MT/HDU: COL_TRANSPARENT means SetFont should ignore the font color,
73 // because SetTextColor() is used for this.
74 // #i28759# maTextColor might have been changed behind our back, commit then, too.
75 if( aFont.GetColor() != COL_TRANSPARENT
76 && (aFont.GetColor() != maFont.GetColor() || aFont.GetColor() != maTextColor ) )
77 {
78 maTextColor = aFont.GetColor();
79 mbInitTextColor = true;
80 if( mpMetaFile )
82 }
83 maFont = aFont;
84 mbNewFont = true;
85
86 if( !mpAlphaVDev )
87 return;
88
89 // #i30463#
90 // Since SetFont might change the text color, apply that only
91 // selectively to alpha vdev (which normally paints opaque text
92 // with COL_BLACK)
93 if( aFont.GetColor() != COL_TRANSPARENT )
94 {
97 }
98
99 mpAlphaVDev->SetFont( aFont );
100}
101
103{
105
106 if (nDevFontIndex < GetFontFaceCollectionCount())
107 return FontMetric(*mpFontFaceCollection->Get(nDevFontIndex));
108
109 return FontMetric();
110}
111
113{
115 {
116 if (!mxFontCollection)
117 {
118 return 0;
119 }
120
121 mpFontFaceCollection = mxFontCollection->GetFontFaceCollection();
122
123 if (!mpFontFaceCollection->Count())
124 {
125 mpFontFaceCollection.reset();
126 return 0;
127 }
128 }
129 return mpFontFaceCollection->Count();
130}
131
132bool OutputDevice::IsFontAvailable( std::u16string_view rFontName ) const
133{
135 vcl::font::PhysicalFontFamily* pFound = mxFontCollection->FindFontFamily( rFontName );
136 return (pFound != nullptr);
137}
138
139bool OutputDevice::AddTempDevFont( const OUString& rFileURL, const OUString& rFontName )
140{
142
143 if( !mpGraphics && !AcquireGraphics() )
144 return false;
145 assert(mpGraphics);
146
147 bool bRC = mpGraphics->AddTempDevFont( mxFontCollection.get(), rFileURL, rFontName );
148 if( !bRC )
149 return false;
150
151 if( mpAlphaVDev )
152 mpAlphaVDev->AddTempDevFont( rFileURL, rFontName );
153
154 return true;
155}
156
157bool OutputDevice::GetFontFeatures(std::vector<vcl::font::Feature>& rFontFeatures) const
158{
159 if (!ImplNewFont())
160 return false;
161
162 LogicalFontInstance* pFontInstance = mpFontInstance.get();
163 if (!pFontInstance)
164 return false;
165
166 const LanguageTag& rOfficeLanguage = Application::GetSettings().GetUILanguageTag();
167
168 vcl::font::FeatureCollector aFeatureCollector(pFontInstance->GetFontFace(), rFontFeatures, rOfficeLanguage);
169 aFeatureCollector.collect();
170
171 return true;
172}
173
175{
176 FontMetric aMetric;
177 if (!ImplNewFont())
178 return aMetric;
179
180 LogicalFontInstance* pFontInstance = mpFontInstance.get();
181 FontMetricDataRef xFontMetric = pFontInstance->mxFontMetric;
182
183 // prepare metric
184 aMetric = maFont;
185
186 // set aMetric with info from font
188 aMetric.SetStyleName( xFontMetric->GetStyleName() );
189 aMetric.SetFontSize( PixelToLogic( Size( xFontMetric->GetWidth(), xFontMetric->GetAscent() + xFontMetric->GetDescent() - xFontMetric->GetInternalLeading() ) ) );
190 aMetric.SetCharSet( xFontMetric->IsMicrosoftSymbolEncoded() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE );
191 aMetric.SetFamily( xFontMetric->GetFamilyType() );
192 aMetric.SetPitch( xFontMetric->GetPitch() );
193 aMetric.SetWeight( xFontMetric->GetWeight() );
194 aMetric.SetItalic( xFontMetric->GetItalic() );
195 aMetric.SetAlignment( TextAlign::ALIGN_TOP );
196 aMetric.SetWidthType( xFontMetric->GetWidthType() );
197 if ( pFontInstance->mnOwnOrientation )
198 aMetric.SetOrientation( pFontInstance->mnOwnOrientation );
199 else
200 aMetric.SetOrientation( xFontMetric->GetOrientation() );
201
202 // set remaining metric fields
203 aMetric.SetFullstopCenteredFlag( xFontMetric->IsFullstopCentered() );
204 aMetric.SetBulletOffset( xFontMetric->GetBulletOffset() );
205 aMetric.SetAscent( ImplDevicePixelToLogicHeight( xFontMetric->GetAscent() + mnEmphasisAscent ) );
206 aMetric.SetDescent( ImplDevicePixelToLogicHeight( xFontMetric->GetDescent() + mnEmphasisDescent ) );
207 aMetric.SetInternalLeading( ImplDevicePixelToLogicHeight( xFontMetric->GetInternalLeading() + mnEmphasisAscent ) );
208 // OutputDevice has its own external leading function due to #i60945#
210 aMetric.SetLineHeight( ImplDevicePixelToLogicHeight( xFontMetric->GetAscent() + xFontMetric->GetDescent() + mnEmphasisAscent + mnEmphasisDescent ) );
211 aMetric.SetSlant( ImplDevicePixelToLogicHeight( xFontMetric->GetSlant() ) );
212 aMetric.SetHangingBaseline( ImplDevicePixelToLogicHeight( xFontMetric->GetHangingBaseline() ) );
213
214 // get miscellaneous data
215 aMetric.SetQuality( xFontMetric->GetQuality() );
216
217 SAL_INFO("vcl.gdi.fontmetric", "OutputDevice::GetFontMetric:" << aMetric);
218
219 xFontMetric = nullptr;
220
221 return aMetric;
222}
223
225{
226 // select font, query metrics, select original font again
227 vcl::Font aOldFont = GetFont();
228 const_cast<OutputDevice*>(this)->SetFont( rFont );
229 FontMetric aMetric( GetFontMetric() );
230 const_cast<OutputDevice*>(this)->SetFont( aOldFont );
231 return aMetric;
232}
233
235{
236 if (!InitFont())
237 return false;
238
239 FontCharMapRef xFontCharMap ( mpGraphics->GetFontCharMap() );
240 if (!xFontCharMap.is())
241 {
242 FontCharMapRef xDefaultMap( new FontCharMap() );
243 rxFontCharMap = xDefaultMap;
244 }
245 else
246 rxFontCharMap = xFontCharMap;
247
248 return !rxFontCharMap->IsDefaultMap();
249}
250
252{
253 if (!InitFont())
254 return false;
255 return mpGraphics->GetFontCapabilities(rFontCapabilities);
256}
257
259{
260 return mpFontInstance->mxFontMetric->GetExternalLeading();
261}
262
263void OutputDevice::ImplClearFontData( const bool bNewFontLists )
264{
265 // the currently selected logical font is no longer needed
266 mpFontInstance.clear();
267
268 mbInitFont = true;
269 mbNewFont = true;
270
271 if ( bNewFontLists )
272 {
273 mpFontFaceCollection.reset();
274
275 // release all physically selected fonts on this device
276 if( AcquireGraphics() )
278 }
279
280 ImplSVData* pSVData = ImplGetSVData();
281
283 mxFontCache->Invalidate();
284
285 if (bNewFontLists && AcquireGraphics())
286 {
288 mxFontCollection->Clear();
289 }
290}
291
292void OutputDevice::RefreshFontData( const bool bNewFontLists )
293{
294 ImplRefreshFontData( bNewFontLists );
295}
296
297void OutputDevice::ImplRefreshFontData( const bool bNewFontLists )
298{
299 if (bNewFontLists && AcquireGraphics())
301}
302
304{
305 ImplClearFontData( true/*bNewFontLists*/ );
306 ImplRefreshFontData( true/*bNewFontLists*/ );
307}
308
310{
311 ImplSVData* pSVData = ImplGetSVData();
312
314
315 // clear global font lists to have them updated
316 pSVData->maGDIData.mxScreenFontCache->Invalidate();
317 if ( !bNewFontLists )
318 return;
319
320 pSVData->maGDIData.mxScreenFontList->Clear();
321 vcl::Window * pFrame = pSVData->maFrameData.mpFirstFrame;
322 if ( pFrame )
323 {
324 if ( pFrame->GetOutDev()->AcquireGraphics() )
325 {
326 OutputDevice *pDevice = pFrame->GetOutDev();
327 pDevice->mpGraphics->ClearDevFontCache();
328 pDevice->mpGraphics->GetDevFontList(pFrame->mpWindowImpl->mpFrameData->mxFontCollection.get());
329 }
330 }
331}
332
334{
336}
337
339{
342}
343
344void OutputDevice::ImplUpdateFontDataForAllFrames( const FontUpdateHandler_t pHdl, const bool bNewFontLists )
345{
346 ImplSVData* const pSVData = ImplGetSVData();
347
348 // update all windows
349 vcl::Window* pFrame = pSVData->maFrameData.mpFirstFrame;
350 while ( pFrame )
351 {
352 ( pFrame->GetOutDev()->*pHdl )( bNewFontLists );
353
354 vcl::Window* pSysWin = pFrame->mpWindowImpl->mpFrameData->mpFirstOverlap;
355 while ( pSysWin )
356 {
357 ( pSysWin->GetOutDev()->*pHdl )( bNewFontLists );
358 pSysWin = pSysWin->mpWindowImpl->mpNextOverlap;
359 }
360
361 pFrame = pFrame->mpWindowImpl->mpFrameData->mpNextFrame;
362 }
363
364 // update all virtual devices
365 VirtualDevice* pVirDev = pSVData->maGDIData.mpFirstVirDev;
366 while ( pVirDev )
367 {
368 ( pVirDev->*pHdl )( bNewFontLists );
369 pVirDev = pVirDev->mpNext;
370 }
371
372 // update all printers
373 Printer* pPrinter = pSVData->maGDIData.mpFirstPrinter;
374 while ( pPrinter )
375 {
376 ( pPrinter->*pHdl )( bNewFontLists );
377 pPrinter = pPrinter->mpNext;
378 }
379}
380
382{
383 ImplSVData* pSVData = ImplGetSVData();
384 pSVData->maGDIData.mbFontSubChanged = false;
385}
386
388{
389 ImplSVData* pSVData = ImplGetSVData();
390 if ( pSVData->maGDIData.mbFontSubChanged )
391 {
392 ImplUpdateAllFontData( false );
393
397 pSVData->maGDIData.mbFontSubChanged = false;
398 }
399}
400
401void OutputDevice::AddFontSubstitute( const OUString& rFontName,
402 const OUString& rReplaceFontName,
404{
406 if( !rpSubst )
408 rpSubst->AddFontSubstitute( rFontName, rReplaceFontName, nFlags );
410}
411
413{
415 if( pSubst )
416 pSubst->RemoveFontsSubstitute();
417}
418
419//hidpi TODO: This routine has hard-coded font-sizes that break places such as DialControl
421 GetDefaultFontFlags nFlags, const OutputDevice* pOutDev )
422{
423 static bool bFuzzing = utl::ConfigManager::IsFuzzing();
424 static bool bAbortOnFontSubstitute = [] {
425 const char* pEnv = getenv("SAL_NON_APPLICATION_FONT_USE");
426 return pEnv && strcmp(pEnv, "abort") == 0;
427 }();
428
429 if (!pOutDev && !bFuzzing) // default is NULL
431
432 OUString aSearch;
433 if (!bFuzzing)
434 {
435 LanguageTag aLanguageTag(
436 ( eLang == LANGUAGE_NONE || eLang == LANGUAGE_SYSTEM || eLang == LANGUAGE_DONTKNOW ) ?
437 Application::GetSettings().GetUILanguageTag() :
438 LanguageTag( eLang ));
439
441 OUString aDefault = rDefaults.getDefaultFont( aLanguageTag, nType );
442
443 if( !aDefault.isEmpty() )
444 aSearch = aDefault;
445 else
446 aSearch = rDefaults.getUserInterfaceFont( aLanguageTag ); // use the UI font as a fallback
447
448 // during cppunit tests with SAL_NON_APPLICATION_FONT_USE set we don't have any bundled fonts
449 // that support the default CTL and CJK languages of Hindi and Chinese, so just pick something
450 // (unsuitable) that does exist, if they get used with SAL_NON_APPLICATION_FONT_USE=abort then
451 // glyph fallback will trigger std::abort
452 if (bAbortOnFontSubstitute)
453 {
454 if (eLang == LANGUAGE_HINDI || eLang == LANGUAGE_CHINESE_SIMPLIFIED)
455 aSearch = "DejaVu Sans";
456 }
457 }
458 else
459 aSearch = "Liberation Serif";
460
461 vcl::Font aFont;
462 aFont.SetPitch( PITCH_VARIABLE );
463
464 switch ( nType )
465 {
466 case DefaultFontType::SANS_UNICODE:
467 case DefaultFontType::UI_SANS:
468 aFont.SetFamily( FAMILY_SWISS );
469 break;
470
471 case DefaultFontType::SANS:
472 case DefaultFontType::LATIN_HEADING:
473 case DefaultFontType::LATIN_SPREADSHEET:
474 case DefaultFontType::LATIN_DISPLAY:
475 aFont.SetFamily( FAMILY_SWISS );
476 break;
477
478 case DefaultFontType::SERIF:
479 case DefaultFontType::LATIN_TEXT:
480 case DefaultFontType::LATIN_PRESENTATION:
481 aFont.SetFamily( FAMILY_ROMAN );
482 break;
483
484 case DefaultFontType::FIXED:
485 case DefaultFontType::LATIN_FIXED:
486 case DefaultFontType::UI_FIXED:
487 aFont.SetPitch( PITCH_FIXED );
488 aFont.SetFamily( FAMILY_MODERN );
489 break;
490
491 case DefaultFontType::SYMBOL:
492 aFont.SetCharSet( RTL_TEXTENCODING_SYMBOL );
493 break;
494
495 case DefaultFontType::CJK_TEXT:
496 case DefaultFontType::CJK_PRESENTATION:
497 case DefaultFontType::CJK_SPREADSHEET:
498 case DefaultFontType::CJK_HEADING:
499 case DefaultFontType::CJK_DISPLAY:
500 aFont.SetFamily( FAMILY_SYSTEM ); // don't care, but don't use font subst config later...
501 break;
502
503 case DefaultFontType::CTL_TEXT:
504 case DefaultFontType::CTL_PRESENTATION:
505 case DefaultFontType::CTL_SPREADSHEET:
506 case DefaultFontType::CTL_HEADING:
507 case DefaultFontType::CTL_DISPLAY:
508 aFont.SetFamily( FAMILY_SYSTEM ); // don't care, but don't use font subst config later...
509 break;
510 }
511
512 if ( !aSearch.isEmpty() )
513 {
514 aFont.SetFontHeight( 12 ); // corresponds to nDefaultHeight
515 aFont.SetWeight( WEIGHT_NORMAL );
516 aFont.SetLanguage( eLang );
517
518 if ( aFont.GetCharSet() == RTL_TEXTENCODING_DONTKNOW )
519 aFont.SetCharSet( osl_getThreadTextEncoding() );
520
521 // Should we only return available fonts on the given device
522 if ( pOutDev )
523 {
524 pOutDev->ImplInitFontList();
525
526 // Search Font in the FontList
527 OUString aName;
528 sal_Int32 nIndex = 0;
529 do
530 {
531 vcl::font::PhysicalFontFamily* pFontFamily = pOutDev->mxFontCollection->FindFontFamily( GetNextFontToken( aSearch, nIndex ) );
532 if( pFontFamily )
533 {
534 AddTokenFontName( aName, pFontFamily->GetFamilyName() );
535 if( nFlags & GetDefaultFontFlags::OnlyOne )
536 break;
537 }
538 }
539 while ( nIndex != -1 );
540 aFont.SetFamilyName( aName );
541 }
542
543 // No Name, then set all names
544 if ( aFont.GetFamilyName().isEmpty() )
545 {
546 if ( nFlags & GetDefaultFontFlags::OnlyOne )
547 {
548 if( !pOutDev )
549 {
550 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");
551 aFont.SetFamilyName( aSearch.getToken( 0, ';' ) );
552 }
553 else
554 {
555 pOutDev->ImplInitFontList();
556
557 aFont.SetFamilyName( aSearch );
558
559 // convert to pixel height
560 Size aSize = pOutDev->ImplLogicToDevicePixel( aFont.GetFontSize() );
561 if ( !aSize.Height() )
562 {
563 // use default pixel height only when logical height is zero
564 if ( aFont.GetFontHeight() )
565 aSize.setHeight( 1 );
566 else
567 aSize.setHeight( (12*pOutDev->mnDPIY)/72 );
568 }
569
570 // use default width only when logical width is zero
571 if( (0 == aSize.Width()) && (0 != aFont.GetFontSize().Width()) )
572 aSize.setWidth( 1 );
573
574 // get the name of the first available font
575 float fExactHeight = static_cast<float>(aSize.Height());
576 rtl::Reference<LogicalFontInstance> pFontInstance = pOutDev->mxFontCache->GetFontInstance( pOutDev->mxFontCollection.get(), aFont, aSize, fExactHeight );
577 if (pFontInstance)
578 {
579 assert(pFontInstance->GetFontFace());
580 aFont.SetFamilyName(pFontInstance->GetFontFace()->GetFamilyName());
581 }
582 }
583 }
584 else
585 aFont.SetFamilyName( aSearch );
586 }
587 }
588
589#if OSL_DEBUG_LEVEL > 2
590 const char* s = "SANS_UNKNOWN";
591 switch ( nType )
592 {
593 case DefaultFontType::SANS_UNICODE: s = "SANS_UNICODE"; break;
594 case DefaultFontType::UI_SANS: s = "UI_SANS"; break;
595
596 case DefaultFontType::SANS: s = "SANS"; break;
597 case DefaultFontType::LATIN_HEADING: s = "LATIN_HEADING"; break;
598 case DefaultFontType::LATIN_SPREADSHEET: s = "LATIN_SPREADSHEET"; break;
599 case DefaultFontType::LATIN_DISPLAY: s = "LATIN_DISPLAY"; break;
600
601 case DefaultFontType::SERIF: s = "SERIF"; break;
602 case DefaultFontType::LATIN_TEXT: s = "LATIN_TEXT"; break;
603 case DefaultFontType::LATIN_PRESENTATION: s = "LATIN_PRESENTATION"; break;
604
605 case DefaultFontType::FIXED: s = "FIXED"; break;
606 case DefaultFontType::LATIN_FIXED: s = "LATIN_FIXED"; break;
607 case DefaultFontType::UI_FIXED: s = "UI_FIXED"; break;
608
609 case DefaultFontType::SYMBOL: s = "SYMBOL"; break;
610
611 case DefaultFontType::CJK_TEXT: s = "CJK_TEXT"; break;
612 case DefaultFontType::CJK_PRESENTATION: s = "CJK_PRESENTATION"; break;
613 case DefaultFontType::CJK_SPREADSHEET: s = "CJK_SPREADSHEET"; break;
614 case DefaultFontType::CJK_HEADING: s = "CJK_HEADING"; break;
615 case DefaultFontType::CJK_DISPLAY: s = "CJK_DISPLAY"; break;
616
617 case DefaultFontType::CTL_TEXT: s = "CTL_TEXT"; break;
618 case DefaultFontType::CTL_PRESENTATION: s = "CTL_PRESENTATION"; break;
619 case DefaultFontType::CTL_SPREADSHEET: s = "CTL_SPREADSHEET"; break;
620 case DefaultFontType::CTL_HEADING: s = "CTL_HEADING"; break;
621 case DefaultFontType::CTL_DISPLAY: s = "CTL_DISPLAY"; break;
622 }
623 SAL_INFO("vcl.gdi",
624 "OutputDevice::GetDefaultFont() Type=" << s
625 << " lang=" << eLang
626 << " flags=" << static_cast<int>(nFlags)
627 << " family=\"" << aFont.GetFamilyName() << "\"");
628#endif
629
630 return aFont;
631}
632
634{
635 if( mxFontCollection->Count() )
636 return;
637
638 if( !(mpGraphics || AcquireGraphics()) )
639 return;
640 assert(mpGraphics);
641
642 SAL_INFO( "vcl.gdi", "OutputDevice::ImplInitFontList()" );
644
645 // There is absolutely no way there should be no fonts available on the device
646 if( !mxFontCollection->Count() )
647 {
648 OUString aError( "Application error: no fonts and no vcl resource found on your system" );
649 OUString aResStr(VclResId(SV_ACCESSERROR_NO_FONTS));
650 if (!aResStr.isEmpty())
651 aError = aResStr;
652 Application::Abort(aError);
653 }
654}
655
657{
659
660 if (!ImplNewFont())
661 return false;
662 if (!mpFontInstance)
663 return false;
664 if (!mpGraphics)
665 {
666 if (!AcquireGraphics())
667 return false;
668 }
669 else if (!mbInitFont)
670 return true;
671
672 assert(mpGraphics);
674 mbInitFont = false;
675 return true;
676}
677
679{
680 if (!InitFont())
681 return nullptr;
682 return mpFontInstance.get();
683}
684
686{
688
689 if ( !mbNewFont )
690 return true;
691
692 // we need a graphics
693 if ( !mpGraphics && !AcquireGraphics() )
694 {
695 SAL_WARN("vcl.gdi", "OutputDevice::ImplNewFont(): no Graphics, no Font");
696 return false;
697 }
698 assert(mpGraphics);
699
701
702 // convert to pixel height
703 // TODO: replace integer based aSize completely with subpixel accurate type
706 if ( !aSize.Height() )
707 {
708 // use default pixel height only when logical height is zero
709 if ( maFont.GetFontSize().Height() )
710 aSize.setHeight( 1 );
711 else
712 aSize.setHeight( (12*mnDPIY)/72 );
713 fExactHeight = static_cast<float>(aSize.Height());
714 }
715
716 // select the default width only when logical width is zero
717 if( (0 == aSize.Width()) && (0 != maFont.GetFontSize().Width()) )
718 aSize.setWidth( 1 );
719
720 // decide if antialiasing is appropriate
721 bool bNonAntialiased(GetAntialiasing() & AntialiasingFlags::DisableText);
723 {
724 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
725 bNonAntialiased |= bool(rStyleSettings.GetDisplayOptions() & DisplayOptions::AADisable);
726 bNonAntialiased |= (int(rStyleSettings.GetAntialiasingMinPixelHeight()) > maFont.GetFontSize().Height());
727 }
728
729 // get font entry
731 mpFontInstance = mxFontCache->GetFontInstance(mxFontCollection.get(), maFont, aSize, fExactHeight, bNonAntialiased);
732 const bool bNewFontInstance = pOldFontInstance.get() != mpFontInstance.get();
733 pOldFontInstance.clear();
734
735 LogicalFontInstance* pFontInstance = mpFontInstance.get();
736
737 if (!pFontInstance)
738 {
739 SAL_WARN("vcl.gdi", "OutputDevice::ImplNewFont(): no LogicalFontInstance, no Font");
740 return false;
741 }
742
743 // mark when lower layers need to get involved
744 mbNewFont = false;
745 if( bNewFontInstance )
746 mbInitFont = true;
747
748 // select font when it has not been initialized yet
749 if (!pFontInstance->mbInit && InitFont())
750 {
751 // get metric data from device layers
752 pFontInstance->mbInit = true;
753
754 pFontInstance->mxFontMetric->SetOrientation( mpFontInstance->GetFontSelectPattern().mnOrientation );
755 mpGraphics->GetFontMetric( pFontInstance->mxFontMetric, 0 );
756
757 pFontInstance->mxFontMetric->ImplInitTextLineSize( this );
758 pFontInstance->mxFontMetric->ImplInitAboveTextLineSize( this );
759 pFontInstance->mxFontMetric->ImplInitFlags( this );
760
761 pFontInstance->mnLineHeight = pFontInstance->mxFontMetric->GetAscent() + pFontInstance->mxFontMetric->GetDescent();
762
763 SetFontOrientation( pFontInstance );
764 }
765
766 // calculate EmphasisArea
769 if ( maFont.GetEmphasisMark() & FontEmphasisMark::Style )
770 {
772 tools::Long nEmphasisHeight = (pFontInstance->mnLineHeight*250)/1000;
773 if ( nEmphasisHeight < 1 )
774 nEmphasisHeight = 1;
775 if ( nEmphasisMark & FontEmphasisMark::PosBelow )
776 mnEmphasisDescent = nEmphasisHeight;
777 else
778 mnEmphasisAscent = nEmphasisHeight;
779 }
780
781 // calculate text offset depending on TextAlignment
782 TextAlign eAlign = maFont.GetAlignment();
783 if ( eAlign == ALIGN_BASELINE )
784 {
785 mnTextOffX = 0;
786 mnTextOffY = 0;
787 }
788 else if ( eAlign == ALIGN_TOP )
789 {
790 mnTextOffX = 0;
791 mnTextOffY = +pFontInstance->mxFontMetric->GetAscent() + mnEmphasisAscent;
792 if ( pFontInstance->mnOrientation )
793 {
794 Point aOriginPt(0, 0);
795 aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
796 }
797 }
798 else // eAlign == ALIGN_BOTTOM
799 {
800 mnTextOffX = 0;
801 mnTextOffY = -pFontInstance->mxFontMetric->GetDescent() + mnEmphasisDescent;
802 if ( pFontInstance->mnOrientation )
803 {
804 Point aOriginPt(0, 0);
805 aOriginPt.RotateAround( mnTextOffX, mnTextOffY, pFontInstance->mnOrientation );
806 }
807 }
808
814
815
816 bool bRet = true;
817
818 // #95414# fix for OLE objects which use scale factors very creatively
819 if (mbMap && !aSize.Width())
820 bRet = AttemptOLEFontScaleFix(const_cast<vcl::Font&>(maFont), aSize.Height());
821
822 return bRet;
823}
824
826{
827 const float fDenominator = static_cast<float>(maMapRes.mnMapScNumY) * maMapRes.mnMapScDenomX;
828 if (fDenominator == 0.0)
829 return false;
830 const float fNumerator = static_cast<float>(maMapRes.mnMapScNumX) * maMapRes.mnMapScDenomY;
831 float fStretch = fNumerator / fDenominator;
832 int nOrigWidth = mpFontInstance->mxFontMetric->GetWidth();
833 int nNewWidth = static_cast<int>(nOrigWidth * fStretch + 0.5);
834 bool bRet = true;
835 if (nNewWidth != nOrigWidth && nNewWidth != 0)
836 {
837 Size aOrigSize = rFont.GetFontSize();
838 rFont.SetFontSize(Size(nNewWidth, nHeight));
839 mbMap = false;
840 mbNewFont = true;
841 bRet = ImplNewFont(); // recurse once using stretched width
842 mbMap = true;
843 rFont.SetFontSize(aOrigSize);
844 }
845 return bRet;
846}
847
849{
850 if( pFontInstance->GetFontSelectPattern().mnOrientation && !pFontInstance->mxFontMetric->GetOrientation() )
851 {
852 pFontInstance->mnOwnOrientation = pFontInstance->GetFontSelectPattern().mnOrientation;
853 pFontInstance->mnOrientation = pFontInstance->mnOwnOrientation;
854 }
855 else
856 {
857 pFontInstance->mnOrientation = pFontInstance->mxFontMetric->GetOrientation();
858 }
859}
860
862 const tools::PolyPolygon& rPolyPoly, bool bPolyLine,
863 const tools::Rectangle& rRect1, const tools::Rectangle& rRect2 )
864{
865 if( IsRTLEnabled() )
866 nX = nBaseX - (nX - nBaseX - 1);
867
868 nX -= mnOutOffX;
869 nY -= mnOutOffY;
870
871 if ( rPolyPoly.Count() )
872 {
873 if ( bPolyLine )
874 {
875 tools::Polygon aPoly = rPolyPoly.GetObject( 0 );
876 aPoly.Move( nX, nY );
877 DrawPolyLine( aPoly );
878 }
879 else
880 {
881 tools::PolyPolygon aPolyPoly = rPolyPoly;
882 aPolyPoly.Move( nX, nY );
883 DrawPolyPolygon( aPolyPoly );
884 }
885 }
886
887 if ( !rRect1.IsEmpty() )
888 {
889 tools::Rectangle aRect( Point( nX+rRect1.Left(),
890 nY+rRect1.Top() ), rRect1.GetSize() );
891 DrawRect( aRect );
892 }
893
894 if ( !rRect2.IsEmpty() )
895 {
896 tools::Rectangle aRect( Point( nX+rRect2.Left(),
897 nY+rRect2.Top() ), rRect2.GetSize() );
898
899 DrawRect( aRect );
900 }
901}
902
904{
905 Color aOldLineColor = GetLineColor();
906 Color aOldFillColor = GetFillColor();
907 bool bOldMap = mbMap;
908 GDIMetaFile* pOldMetaFile = mpMetaFile;
909 mpMetaFile = nullptr;
910 EnableMapMode( false );
911
913 tools::Long nEmphasisHeight;
914
915 if ( nEmphasisMark & FontEmphasisMark::PosBelow )
916 nEmphasisHeight = mnEmphasisDescent;
917 else
918 nEmphasisHeight = mnEmphasisAscent;
919
920 vcl::font::EmphasisMark aEmphasisMark(nEmphasisMark, nEmphasisHeight, GetDPIY());
921
922 if (aEmphasisMark.IsShapePolyLine())
923 {
925 SetFillColor();
926 }
927 else
928 {
929 SetLineColor();
931 }
932
933 Point aOffset(0,0);
934 Point aOffsetVert(0,0);
935
936 if ( nEmphasisMark & FontEmphasisMark::PosBelow )
937 {
938 aOffset.AdjustY(mpFontInstance->mxFontMetric->GetDescent() + aEmphasisMark.GetYOffset());
939 aOffsetVert = aOffset;
940 }
941 else
942 {
943 aOffset.AdjustY(-(mpFontInstance->mxFontMetric->GetAscent() + aEmphasisMark.GetYOffset()));
944 // Todo: use ideographic em-box or ideographic character face information.
945 aOffsetVert.AdjustY(-(mpFontInstance->mxFontMetric->GetAscent() +
946 mpFontInstance->mxFontMetric->GetDescent() + aEmphasisMark.GetYOffset()));
947 }
948
949 tools::Long nEmphasisWidth2 = aEmphasisMark.GetWidth() / 2;
950 tools::Long nEmphasisHeight2 = nEmphasisHeight / 2;
951 aOffset += Point( nEmphasisWidth2, nEmphasisHeight2 );
952
953 basegfx::B2DPoint aOutPoint;
954 tools::Rectangle aRectangle;
955 const GlyphItem* pGlyph;
956 const LogicalFontInstance* pGlyphFont;
957 int nStart = 0;
958 while (rSalLayout.GetNextGlyph(&pGlyph, aOutPoint, nStart, &pGlyphFont))
959 {
960 if (!pGlyph->GetGlyphBoundRect(pGlyphFont, aRectangle))
961 continue;
962
963 if (!pGlyph->IsSpacing())
964 {
965 Point aAdjPoint;
966 if (pGlyph->IsVertical())
967 {
968 aAdjPoint = aOffsetVert;
969 aAdjPoint.AdjustX((-pGlyph->origWidth() + aEmphasisMark.GetWidth()) / 2);
970 }
971 else
972 {
973 aAdjPoint = aOffset;
974 aAdjPoint.AdjustX(aRectangle.Left() + (aRectangle.GetWidth() - aEmphasisMark.GetWidth()) / 2 );
975 }
976
977 if ( mpFontInstance->mnOrientation )
978 {
979 Point aOriginPt(0, 0);
980 aOriginPt.RotateAround( aAdjPoint, mpFontInstance->mnOrientation );
981 }
982 aOutPoint.adjustX(aAdjPoint.X() - nEmphasisWidth2);
983 aOutPoint.adjustY(aAdjPoint.Y() - nEmphasisHeight2);
984 ImplDrawEmphasisMark( rSalLayout.DrawBase().getX(),
985 aOutPoint.getX(), aOutPoint.getY(),
986 aEmphasisMark.GetShape(), aEmphasisMark.IsShapePolyLine(),
987 aEmphasisMark.GetRect1(), aEmphasisMark.GetRect2() );
988 }
989 }
990
991 SetLineColor( aOldLineColor );
992 SetFillColor( aOldFillColor );
993 EnableMapMode( bOldMap );
994 mpMetaFile = pOldMetaFile;
995}
996
997std::unique_ptr<SalLayout> OutputDevice::getFallbackLayout(
998 LogicalFontInstance* pLogicalFont, int nFallbackLevel,
999 vcl::text::ImplLayoutArgs& rLayoutArgs, const SalLayoutGlyphs* pGlyphs) const
1000{
1001 // we need a graphics
1002 if (!mpGraphics && !AcquireGraphics())
1003 return nullptr;
1004
1005 assert(mpGraphics != nullptr);
1006 mpGraphics->SetFont( pLogicalFont, nFallbackLevel );
1007
1008 rLayoutArgs.ResetPos();
1009 std::unique_ptr<GenericSalLayout> pFallback = mpGraphics->GetTextLayout(nFallbackLevel);
1010
1011 if (!pFallback)
1012 return nullptr;
1013
1014 if (!pFallback->LayoutText(rLayoutArgs, pGlyphs ? pGlyphs->Impl(nFallbackLevel) : nullptr))
1015 {
1016 // there is no need for a font that couldn't resolve anything
1017 return nullptr;
1018 }
1019
1020 return pFallback;
1021}
1022
1023std::unique_ptr<SalLayout> OutputDevice::ImplGlyphFallbackLayout( std::unique_ptr<SalLayout> pSalLayout,
1024 vcl::text::ImplLayoutArgs& rLayoutArgs, const SalLayoutGlyphs* pGlyphs ) const
1025{
1026 // This function relies on a valid mpFontInstance, if it doesn't exist bail out
1027 // - we'd have crashed later on anyway. At least here we can catch the error in debug
1028 // mode.
1029 if ( !mpFontInstance )
1030 {
1031 SAL_WARN ("vcl.gdi", "No font entry set in OutputDevice");
1032 assert(mpFontInstance);
1033 return nullptr;
1034 }
1035
1036 // prepare multi level glyph fallback
1037 std::unique_ptr<MultiSalLayout> pMultiSalLayout;
1038 ImplLayoutRuns aLayoutRuns = rLayoutArgs.maRuns;
1039 rLayoutArgs.PrepareFallback(nullptr);
1040 rLayoutArgs.mnFlags |= SalLayoutFlags::ForFallback;
1041
1042 // get list of code units that need glyph fallback
1043 bool bRTL;
1044 int nMinRunPos, nEndRunPos;
1045 OUStringBuffer aMissingCodeBuf(512);
1046 while (rLayoutArgs.GetNextRun(&nMinRunPos, &nEndRunPos, &bRTL))
1047 aMissingCodeBuf.append(rLayoutArgs.mrStr.subView(nMinRunPos, nEndRunPos - nMinRunPos));
1048 rLayoutArgs.ResetPos();
1049 OUString aMissingCodes = aMissingCodeBuf.makeStringAndClear();
1050
1051 vcl::font::FontSelectPattern aFontSelData(mpFontInstance->GetFontSelectPattern());
1052 SalLayoutGlyphsImpl* pGlyphsImpl = pGlyphs ? pGlyphs->Impl(1) : nullptr;
1053
1054 // try if fallback fonts support the missing code units
1055 for( int nFallbackLevel = 1; nFallbackLevel < MAX_FALLBACK; ++nFallbackLevel )
1056 {
1058 if(pGlyphsImpl != nullptr)
1059 pFallbackFont = pGlyphsImpl->GetFont();
1060 // find a font family suited for glyph fallback
1061 // GetGlyphFallbackFont() needs a valid FontInstance
1062 // if the system-specific glyph fallback is active
1063 OUString oldMissingCodes = aMissingCodes;
1064 if( !pFallbackFont )
1065 pFallbackFont = mxFontCache->GetGlyphFallbackFont( mxFontCollection.get(),
1066 aFontSelData, mpFontInstance.get(), nFallbackLevel, aMissingCodes );
1067 if( !pFallbackFont )
1068 break;
1069
1070 if( nFallbackLevel < MAX_FALLBACK-1)
1071 {
1072 // ignore fallback font if it is the same as the original font
1073 // TODO: This seems broken. Either the font does not provide any of the missing
1074 // codes, in which case the fallback should not select it. Or it does provide
1075 // some of the missing codes, and then why weren't they used the first time?
1076 // This will just loop repeatedly finding the same font (it used to remove
1077 // the found font from mxFontCache, but doesn't do that anymore and I don't
1078 // see how doing that would remove the font from consideration for fallback).
1079 if( mpFontInstance->GetFontFace() == pFallbackFont->GetFontFace())
1080 {
1081 if(aMissingCodes != oldMissingCodes)
1082 {
1083 SAL_WARN("vcl.gdi", "Font fallback to the same font, but has missing codes");
1084 // Restore the missing codes if we're not going to use this font.
1085 aMissingCodes = oldMissingCodes;
1086 }
1087 continue;
1088 }
1089 }
1090
1091 // create and add glyph fallback layout to multilayout
1092 std::unique_ptr<SalLayout> pFallback = getFallbackLayout(pFallbackFont.get(),
1093 nFallbackLevel, rLayoutArgs, pGlyphs);
1094 if (pFallback)
1095 {
1096 if( !pMultiSalLayout )
1097 pMultiSalLayout.reset( new MultiSalLayout( std::move(pSalLayout) ) );
1098 pMultiSalLayout->AddFallback(std::move(pFallback), rLayoutArgs.maRuns);
1099 if (nFallbackLevel == MAX_FALLBACK-1)
1100 pMultiSalLayout->SetIncomplete(true);
1101 }
1102
1103 if (pGlyphs != nullptr)
1104 pGlyphsImpl = pGlyphs->Impl(nFallbackLevel + 1);
1105
1106 // break when this fallback was sufficient
1107 if( !rLayoutArgs.PrepareFallback(pGlyphsImpl) )
1108 break;
1109 }
1110
1111 if (pMultiSalLayout) // due to missing glyphs, multilevel layout fallback attempted
1112 {
1113 // if it works, use that Layout
1114 if (pMultiSalLayout->LayoutText(rLayoutArgs, nullptr))
1115 pSalLayout = std::move(pMultiSalLayout);
1116 else
1117 {
1118 // if it doesn't, give up and restore ownership of the pSalLayout
1119 // back to its original state
1120 pSalLayout = pMultiSalLayout->ReleaseBaseLayout();
1121 }
1122 }
1123
1124 // restore orig font settings
1125 pSalLayout->InitFont();
1126 rLayoutArgs.maRuns = aLayoutRuns;
1127
1128 return pSalLayout;
1129}
1130
1132{
1133 if (!ImplNewFont())
1134 return 0;
1135
1136 auto nKashidaWidth = mpFontInstance->mxFontMetric->GetMinKashida();
1137 if (!mbMap)
1138 nKashidaWidth = std::ceil(nKashidaWidth);
1139
1140 return ImplDevicePixelToLogicWidth(nKashidaWidth);
1141}
1142
1143sal_Int32 OutputDevice::ValidateKashidas ( const OUString& rTxt,
1144 sal_Int32 nIdx, sal_Int32 nLen,
1145 sal_Int32 nKashCount,
1146 const sal_Int32* pKashidaPos,
1147 sal_Int32* pKashidaPosDropped ) const
1148{
1149 // do layout
1150 std::unique_ptr<SalLayout> pSalLayout = ImplLayout( rTxt, nIdx, nLen );
1151 if( !pSalLayout )
1152 return 0;
1153
1154 auto nEnd = nIdx + nLen - 1;
1155 sal_Int32 nDropped = 0;
1156 for( int i = 0; i < nKashCount; ++i )
1157 {
1158 auto nPos = pKashidaPos[i];
1159 auto nNextPos = nPos + 1;
1160
1161 // Skip combining marks to find the next character after this position.
1162 while (nNextPos <= nEnd &&
1163 u_getIntPropertyValue(rTxt[nNextPos], UCHAR_JOINING_TYPE) == U_JT_TRANSPARENT)
1164 nNextPos++;
1165
1166 // The next position is past end of the layout, it would happen if we
1167 // changed the text styling in the middle of a word. Since we don’t do
1168 // apply OpenType features across different layouts, this can’t be an
1169 // invalid place to insert Kashida.
1170 if (nNextPos > nEnd)
1171 continue;
1172
1173 if (!pSalLayout->IsKashidaPosValid(nPos, nNextPos))
1174 pKashidaPosDropped[nDropped++] = nPos;
1175 }
1176 return nDropped;
1177}
1178
1179bool OutputDevice::GetGlyphBoundRects( const Point& rOrigin, const OUString& rStr,
1180 int nIndex, int nLen, std::vector< tools::Rectangle >& rVector ) const
1181{
1182 rVector.clear();
1183
1184 if( nIndex >= rStr.getLength() )
1185 return false;
1186
1187 if( nLen < 0 || nIndex + nLen >= rStr.getLength() )
1188 {
1189 nLen = rStr.getLength() - nIndex;
1190 }
1191
1192 tools::Rectangle aRect;
1193 for( int i = 0; i < nLen; i++ )
1194 {
1195 if( !GetTextBoundRect( aRect, rStr, nIndex, nIndex + i, 1 ) )
1196 break;
1197 aRect.Move( rOrigin.X(), rOrigin.Y() );
1198 rVector.push_back( aRect );
1199 }
1200
1201 return (nLen == static_cast<int>(rVector.size()));
1202}
1203
1204sal_Int32 OutputDevice::HasGlyphs( const vcl::Font& rTempFont, std::u16string_view rStr,
1205 sal_Int32 nIndex, sal_Int32 nLen ) const
1206{
1207 if( nIndex >= static_cast<sal_Int32>(rStr.size()) )
1208 return nIndex;
1209 sal_Int32 nEnd;
1210 if( nLen == -1 )
1211 nEnd = rStr.size();
1212 else
1213 nEnd = std::min<sal_Int32>( rStr.size(), nIndex + nLen );
1214
1215 SAL_WARN_IF( nIndex >= nEnd, "vcl.gdi", "StartPos >= EndPos?" );
1216 SAL_WARN_IF( nEnd > static_cast<sal_Int32>(rStr.size()), "vcl.gdi", "String too short" );
1217
1218 // to get the map temporarily set font
1219 const vcl::Font aOrigFont = GetFont();
1220 const_cast<OutputDevice&>(*this).SetFont( rTempFont );
1221 FontCharMapRef xFontCharMap;
1222 bool bRet = GetFontCharMap( xFontCharMap );
1223 const_cast<OutputDevice&>(*this).SetFont( aOrigFont );
1224
1225 // if fontmap is unknown assume it doesn't have the glyphs
1226 if( !bRet )
1227 return nIndex;
1228
1229 for( sal_Int32 i = nIndex; nIndex < nEnd; ++i, ++nIndex )
1230 if( ! xFontCharMap->HasChar( rStr[i] ) )
1231 return nIndex;
1232
1233 return -1;
1234}
1235
1237
1239
1241{
1243}
1244
1246{
1247 mxFontCache = std::make_shared<ImplFontCache>();
1248}
1249
1251{
1253
1254 mbNewFont = true;
1255 mbInitFont = true;
1256
1257 mpFontInstance.clear();
1258 mpFontFaceCollection.reset();
1259}
1260
1261/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
AddFontSubstituteFlags
GetDefaultFontFlags
const LanguageTag & GetUILanguageTag() const
const StyleSettings & GetStyleSettings() const
static void ImplCallEventListenersApplicationDataChanged(void *pData)
Send event to all VCL application event listeners.
Definition: svapp.cxx:684
static OutputDevice * GetDefaultDevice()
Get the default "device" (in this case the default window).
Definition: svapp.cxx:1043
static void Abort(const OUString &rErrorText)
Ends the program prematurely with an error message.
Definition: svapp.cxx:259
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:638
static void NotifyAllWindows(DataChangedEvent &rDCEvt)
Notify all windows that the application has changed data.
Definition: svapp.cxx:665
void SetDescent(tools::Long nDescent)
Definition: metric.hxx:53
void SetFullstopCenteredFlag(bool bCentered)
Definition: metric.hxx:63
void SetAscent(tools::Long nAscent)
Definition: metric.hxx:52
void SetExternalLeading(tools::Long nExtLeading)
Definition: metric.hxx:54
void SetLineHeight(tools::Long nHeight)
Definition: metric.hxx:56
void SetHangingBaseline(tools::Long nBaseline)
Definition: metric.hxx:59
void SetSlant(tools::Long nSlant)
Definition: metric.hxx:57
void SetInternalLeading(tools::Long nIntLeading)
Definition: metric.hxx:55
void SetBulletOffset(tools::Long nOffset)
Definition: metric.hxx:58
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:585
bool GetGlyphBoundRect(const LogicalFontInstance *, tools::Rectangle &) const
bool IsSpacing() const
double origWidth() const
bool IsVertical() const
const vcl::font::PhysicalFontFace * GetFontFace() const
FontMetricDataRef mxFontMetric
const vcl::font::FontSelectPattern & GetFontSelectPattern() const
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:170
tools::Long mnEmphasisAscent
Definition: outdev.hxx:218
ImplMapRes maMapRes
Definition: outdev.hxx:222
static SAL_DLLPRIVATE void ImplUpdateAllFontData(bool bNewFontLists)
LogicalFontInstance const * GetFontInstance() const
bool GetGlyphBoundRects(const Point &rOrigin, const OUString &rStr, int nIndex, int nLen, std::vector< tools::Rectangle > &rVector) const
SAL_DLLPRIVATE std::unique_ptr< SalLayout > ImplGlyphFallbackLayout(std::unique_ptr< SalLayout >, vcl::text::ImplLayoutArgs &, const SalLayoutGlyphs *) const
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:589
static void ImplClearAllFontData(bool bNewFontLists)
sal_Int32 ValidateKashidas(const OUString &rTxt, sal_Int32 nIdx, sal_Int32 nLen, sal_Int32 nKashCount, const sal_Int32 *pKashidaPos, sal_Int32 *pKashidaPosDropped) const
const vcl::Font & GetFont() const
Definition: outdev.hxx:529
sal_Int32 mnDPIY
Definition: outdev.hxx:213
tools::Long mnTextOffY
Definition: outdev.hxx:217
virtual tools::Long GetFontExtLeading() const
void DrawPolyLine(const tools::Polygon &rPoly)
Render the given polygon as a line stroke.
Definition: polyline.cxx:31
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames)
Definition: outdev.hxx:209
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicHeight(tools::Long nHeight) const
Convert device pixels to a height in logical units.
Definition: map.cxx:304
void SetFont(const vcl::Font &rNewFont)
Definition: outdev/font.cxx:56
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:334
std::shared_ptr< ImplFontCache > mxFontCache
Definition: outdev.hxx:262
SAL_DLLPRIVATE sal_Int32 GetDPIY() const
Get the output device's DPI y-axis value.
Definition: outdev.hxx:391
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)
virtual bool ImplNewFont() const
SAL_DLLPRIVATE double ImplLogicHeightToDeviceSubPixel(tools::Long nHeight) const
Definition: map.cxx:1846
virtual bool AcquireGraphics() const =0
Acquire a graphics device that the output device uses to draw on.
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames)
Definition: outdev.hxx:207
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1110
std::shared_ptr< vcl::font::PhysicalFontCollection > mxFontCollection
Definition: outdev.hxx:261
void ReleaseFontCollection()
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:50
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:185
SAL_DLLPRIVATE std::unique_ptr< SalLayout > getFallbackLayout(LogicalFontInstance *pLogicalFont, int nFallbackLevel, vcl::text::ImplLayoutArgs &rLayoutArgs, const SalLayoutGlyphs *) const
void ResetNewFontCache()
static void EndFontSubstitution()
bool mbMap
Definition: outdev.hxx:240
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, KernArraySpan aDXArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, const SalLayoutGlyphs *pGlyphs=nullptr) const
Return the exact bounding rectangle of rStr.
Definition: text.cxx:2307
void SetLineColor()
Definition: line.cxx:37
Color maTextColor
Definition: outdev.hxx:229
virtual void ImplReleaseFonts()
bool mbNewFont
Definition: outdev.hxx:254
void RefreshFontData(const bool bNewFontLists)
bool AddTempDevFont(const OUString &rFileURL, const OUString &rFontName)
tools::Long mnEmphasisDescent
Definition: outdev.hxx:219
bool mbTextSpecial
Definition: outdev.hxx:256
SalGraphics * mpGraphics
Graphics context to draw on.
Definition: outdev.hxx:182
bool mbInitFont
Definition: outdev.hxx:250
bool mbInitTextColor
Definition: outdev.hxx:251
void SetTextColor(const Color &rColor)
Definition: text.cxx:716
vcl::Font maFont
Definition: outdev.hxx:228
bool GetFontCharMap(FontCharMapRef &rxFontCharMap) const
rtl::Reference< LogicalFontInstance > mpFontInstance
Definition: outdev.hxx:186
SAL_DLLPRIVATE void ImplDrawEmphasisMarks(SalLayout &)
static void ImplRefreshAllFontData(bool bNewFontLists)
bool IsRTLEnabled() const
Definition: outdev.hxx:1269
bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const
void SetFillColor()
Definition: fill.cxx:29
virtual void ImplClearFontData(bool bNewFontLists)
static void AddFontSubstitute(const OUString &rFontName, const OUString &rReplaceFontName, AddFontSubstituteFlags nFlags)
int GetFontFaceCollectionCount() const
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicWidth(tools::Long nWidth) const
Convert device pixels to a width in logical units.
Definition: map.cxx:296
FontMetric GetFontMetric() const
const Color & GetLineColor() const
Definition: outdev.hxx:510
bool mbTextLines
Definition: outdev.hxx:255
static SAL_DLLPRIVATE void ImplUpdateFontDataForAllFrames(FontUpdateHandler_t pHdl, bool bNewFontLists)
sal_Int32 HasGlyphs(const vcl::Font &rFont, std::u16string_view rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1) const
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:196
const Color & GetTextColor() const
Definition: outdev.hxx:1003
tools::Long GetMinKashida() const
void ReleaseFontCache()
static void BeginFontSubstitution()
SAL_DLLPRIVATE void ImplInitFontList() const
void DrawPolyPolygon(const tools::PolyPolygon &rPolyPoly)
Render the given poly-polygon.
Definition: polygon.cxx:34
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
std::unique_ptr< vcl::font::PhysicalFontFaceCollection > mpFontFaceCollection
Definition: outdev.hxx:187
FontMetric GetFontMetricFromCollection(int nDevFontIndex) const
std::unique_ptr< SalLayout > ImplLayout(const OUString &, sal_Int32 nIndex, sal_Int32 nLen, const Point &rLogicPos=Point(0, 0), tools::Long nLogicWidth=0, KernArraySpan aKernArray=KernArraySpan(), o3tl::span< const sal_Bool > pKashidaArray={}, SalLayoutFlags flags=SalLayoutFlags::NONE, vcl::text::TextLayoutCache const *=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr) const
Definition: text.cxx:1292
virtual void ImplRefreshFontData(bool bNewFontLists)
AntialiasingFlags GetAntialiasing() const
Definition: outdev.hxx:484
tools::Long mnTextOffX
font specific text alignment offsets in pixel units
Definition: outdev.hxx:216
virtual void SetFontOrientation(LogicalFontInstance *const pFontInstance) const
DrawModeFlags GetDrawMode() const
Definition: outdev.hxx:487
const AllSettings & GetSettings() const
Definition: outdev.hxx:288
SAL_DLLPRIVATE bool AttemptOLEFontScaleFix(vcl::Font &rFont, tools::Long nHeight) const
bool GetFontFeatures(std::vector< vcl::font::Feature > &rFontFeatures) const
void SetFontCollectionFromSVData()
bool IsFontAvailable(std::u16string_view rFontName) const
SAL_DLLPRIVATE bool InitFont() const
static void RemoveFontsSubstitute()
SAL_DLLPRIVATE void ImplUpdateFontData()
const Color & GetFillColor() const
Definition: outdev.hxx:515
constexpr tools::Long Y() const
void RotateAround(tools::Long &rX, tools::Long &rY, Degree10 nOrientation) const
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
VclPtr< Printer > mpNext
Definition: print.hxx:74
virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const =0
virtual FontCharMapRef GetFontCharMap() const =0
virtual void ClearDevFontCache()=0
virtual bool AddTempDevFont(vcl::font::PhysicalFontCollection *, const OUString &rFileURL, const OUString &rFontName)=0
virtual void GetDevFontList(vcl::font::PhysicalFontCollection *)=0
virtual std::unique_ptr< GenericSalLayout > GetTextLayout(int nFallbackLevel)=0
virtual void SetFont(LogicalFontInstance *, int nFallbackLevel)=0
void ReleaseFonts()
Definition: salgdi.hxx:141
virtual void GetFontMetric(FontMetricDataRef &, int nFallbackLevel)=0
const rtl::Reference< LogicalFontInstance > & GetFont() const
SalLayoutGlyphsImpl * Impl(unsigned int nLevel) const
basegfx::B2DPoint & DrawBase()
Definition: vcllayout.hxx:72
virtual bool GetNextGlyph(const GlyphItem **pGlyph, basegfx::B2DPoint &rPos, int &nStart, const LogicalFontInstance **ppGlyphFont=nullptr) const =0
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
DisplayOptions GetDisplayOptions() const
sal_Int32 GetAntialiasingMinPixelHeight() const
VclPtr< VirtualDevice > mpNext
Definition: virdev.hxx:50
void adjustY(TYPE fY)
TYPE getX() const
void adjustX(TYPE fX)
TYPE getY() const
sal_uInt16 Count() const
void Move(tools::Long nHorzMove, tools::Long nVertMove)
const tools::Polygon & GetObject(sal_uInt16 nPos) const
void Move(tools::Long nHorzMove, tools::Long nVertMove)
constexpr tools::Long GetWidth() const
constexpr tools::Long Top() const
constexpr Size GetSize() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr tools::Long Left() const
constexpr bool IsEmpty() const
bool is() const
static bool IsFuzzing()
OUString getUserInterfaceFont(const LanguageTag &rLanguageTag) const
OUString getDefaultFont(const LanguageTag &rLanguageTag, DefaultFontType nType) const
static DefaultFontConfiguration & get()
tools::Long GetFontHeight() const
Definition: font/font.cxx:909
void SetFontSize(const Size &)
Definition: font/font.cxx:149
void SetOrientation(Degree10 nLineOrientation)
Definition: font/font.cxx:197
bool IsSameInstance(const Font &) const
Definition: font/font.cxx:949
void SetWidthType(FontWidth)
Definition: font/font.cxx:242
void SetStyleName(const OUString &rStyleName)
Definition: font/font.cxx:143
void SetQuality(int)
Definition: font/font.cxx:937
void SetPitch(FontPitch ePitch)
Definition: font/font.cxx:191
void SetColor(const Color &)
Definition: font/font.cxx:107
FontStrikeout GetStrikeout() const
Definition: font/font.cxx:946
bool IsShadow() const
Definition: font/font.cxx:942
FontLineStyle GetOverline() const
Definition: font/font.cxx:945
FontRelief GetRelief() const
Definition: font/font.cxx:943
FontEmphasisMark GetEmphasisMark() const
Definition: font/font.cxx:947
void SetItalic(FontItalic)
Definition: font/font.cxx:248
void SetWeight(FontWeight)
Definition: font/font.cxx:236
void SetFontHeight(tools::Long nHeight)
Definition: font/font.cxx:908
bool IsTransparent() const
Definition: font/font.cxx:900
const OUString & GetFamilyName() const
Definition: font/font.cxx:904
void SetFamily(FontFamily)
Definition: font/font.cxx:155
TextAlign GetAlignment() const
Definition: font/font.cxx:902
void SetCharSet(rtl_TextEncoding)
Definition: font/font.cxx:161
const Size & GetFontSize() const
Definition: font/font.cxx:907
const Color & GetColor() const
Definition: font/font.cxx:898
void SetAlignment(TextAlign)
Definition: font/font.cxx:131
void SetFamilyName(const OUString &rFamilyName)
Definition: font/font.cxx:137
FontLineStyle GetUnderline() const
Definition: font/font.cxx:944
rtl_TextEncoding GetCharSet() const
Definition: font/font.cxx:913
void SetLanguage(LanguageType)
Definition: font/font.cxx:179
bool IsOutline() const
Definition: font/font.cxx:941
FontEmphasisMark GetEmphasisMarkStyle() const
Definition: font/font.cxx:314
const Color & GetFillColor() const
Definition: font/font.cxx:899
::OutputDevice const * GetOutDev() const
Definition: window.cxx:567
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:484
DirectFontSubstitution is for Tools->Options->FontReplacement and PsPrinter substitutions The class i...
void AddFontSubstitute(const OUString &rFontName, const OUString &rSubstName, AddFontSubstituteFlags nFlags)
tools::Long GetYOffset() const
tools::Rectangle GetRect1() const
tools::PolyPolygon GetShape() const
tools::Rectangle GetRect2() const
tools::Long GetWidth() const
bool IsShapePolyLine() const
const OUString & GetFamilyName() const
bool GetNextRun(int *nMinRunPos, int *nEndRunPos, bool *bRTL)
bool PrepareFallback(const SalLayoutGlyphsImpl *pGlyphsImpl)
constexpr ::Color COL_ALPHA_OPAQUE(0xff, 0xff, 0xff)
constexpr ::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
#define DBG_TESTSOLARMUTEX()
void AddTokenFontName(OUString &rName, std::u16string_view rNewToken)
DefaultFontType
UNOTOOLS_DLLPUBLIC std::u16string_view GetNextFontToken(std::u16string_view rTokenStr, sal_Int32 &rIndex)
LINESTYLE_NONE
LINESTYLE_DONTKNOW
STRIKEOUT_NONE
STRIKEOUT_DONTKNOW
PITCH_VARIABLE
PITCH_FIXED
FontEmphasisMark
ALIGN_TOP
ALIGN_BASELINE
FAMILY_SYSTEM
FAMILY_SWISS
FAMILY_MODERN
FAMILY_ROMAN
WEIGHT_NORMAL
sal_Int32 nIndex
OUString aName
#define LANGUAGE_SYSTEM
#define LANGUAGE_NONE
#define LANGUAGE_CHINESE_SIMPLIFIED
#define LANGUAGE_DONTKNOW
#define LANGUAGE_HINDI
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
int i
TextAlign
long Long
vcl::Font GetFont(vcl::Font const &rFont, DrawModeFlags nDrawMode, StyleSettings const &rStyleSettings)
Definition: drawmode.cxx:171
QPRO_FUNC_TYPE nType
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
#define MAX_FALLBACK
Definition: sallayout.hxx:46
tools::Long mnMapScDenomX
Scaling factor - denominator in X direction.
Definition: ImplMapRes.hxx:32
tools::Long mnMapScDenomY
Scaling factor - denominator in Y direction.
Definition: ImplMapRes.hxx:33
tools::Long mnMapScNumY
Scaling factor - numerator in Y direction.
Definition: ImplMapRes.hxx:31
tools::Long mnMapScNumX
Scaling factor - numerator in X direction.
Definition: ImplMapRes.hxx:30
ImplSVFrameData maFrameData
Definition: svdata.hxx:399
ImplSVGDIData maGDIData
Definition: svdata.hxx:398
VclPtr< vcl::Window > mpFirstFrame
Definition: svdata.hxx:241
std::shared_ptr< vcl::font::PhysicalFontCollection > mxScreenFontList
Definition: svdata.hxx:225
VclPtr< Printer > mpFirstPrinter
Definition: svdata.hxx:223
std::shared_ptr< ImplFontCache > mxScreenFontCache
Definition: svdata.hxx:226
bool mbFontSubChanged
Definition: svdata.hxx:232
VclPtr< VirtualDevice > mpFirstVirDev
Definition: svdata.hxx:221
vcl::font::DirectFontSubstitution * mpDirectFontSubst
Definition: svdata.hxx:228
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:77
OUString VclResId(TranslateId aId)
Definition: svdata.cxx:261