LibreOffice Module vcl (master) 1
fontmetric.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
23#include <officecfg/Office/Common.hxx>
24#include <sal/log.hxx>
25#include <tools/stream.hxx>
27#include <vcl/metric.hxx>
28#include <vcl/outdev.hxx>
29
33#include <impfontmetricdata.hxx>
34#include <sft.hxx>
35
36#include <com/sun/star/uno/Sequence.hxx>
38#include <hb-ot.h>
39
40using namespace ::com::sun::star;
41using namespace ::com::sun::star::uno;
42using namespace ::rtl;
43using namespace ::utl;
44
46: mnAscent( 0 ),
47 mnDescent( 0 ),
48 mnIntLeading( 0 ),
49 mnExtLeading( 0 ),
50 mnLineHeight( 0 ),
51 mnSlant( 0 ),
52 mnBulletOffset( 0 ),
53 mnHangingBaseline( 0 ),
54 mbFullstopCentered( false )
55{}
56
57FontMetric::FontMetric( const FontMetric& rFontMetric ) = default;
58
60 : FontMetric()
61{
64 SetCharSet(rFace.IsMicrosoftSymbolEncoded() ? RTL_TEXTENCODING_SYMBOL : RTL_TEXTENCODING_UNICODE);
65 SetFamily(rFace.GetFamilyType());
66 SetPitch(rFace.GetPitch());
67 SetWeight(rFace.GetWeight());
68 SetItalic(rFace.GetItalic());
69 SetAlignment(TextAlign::ALIGN_TOP);
71 SetQuality(rFace.GetQuality() );
72}
73
75{
76}
77
78FontMetric& FontMetric::operator=(const FontMetric& rFontMetric) = default;
79
80FontMetric& FontMetric::operator=(FontMetric&& rFontMetric) = default;
81
82bool FontMetric::EqualNoBase( const FontMetric& r ) const
83{
85 return false;
86 if( mnAscent != r.mnAscent )
87 return false;
88 if( mnDescent != r.mnDescent )
89 return false;
90 if( mnIntLeading != r.mnIntLeading )
91 return false;
92 if( mnExtLeading != r.mnExtLeading )
93 return false;
94 if( mnSlant != r.mnSlant )
95 return false;
96
97 return true;
98}
99
100bool FontMetric::operator==( const FontMetric& r ) const
101{
102 if( Font::operator!=(r) )
103 return false;
104 return EqualNoBase(r);
105}
106
108{
109 if( !Font::EqualIgnoreColor(r) )
110 return false;
111 return EqualNoBase(r);
112}
113
115{
116 size_t hash = 0;
123 return hash;
124}
125
127{
128 size_t hash = GetHashValueNoBase();
129 o3tl::hash_combine( hash, Font::GetHashValueIgnoreColor());
130 return hash;
131}
132
134 : FontAttributes( rFontSelData )
135 , mnHeight ( rFontSelData.mnHeight )
136 , mnWidth ( rFontSelData.mnWidth )
137 , mnOrientation( static_cast<short>(rFontSelData.mnOrientation) )
138 , mnAscent( 0 )
139 , mnDescent( 0 )
140 , mnIntLeading( 0 )
141 , mnExtLeading( 0 )
142 , mnSlant( 0 )
143 , mnMinKashida( 0 )
144 , mnHangingBaseline( 0 )
145 , mbFullstopCentered( false )
146 , mnBulletOffset( 0 )
147 , mnUnderlineSize( 0 )
148 , mnUnderlineOffset( 0 )
149 , mnBUnderlineSize( 0 )
150 , mnBUnderlineOffset( 0 )
151 , mnDUnderlineSize( 0 )
152 , mnDUnderlineOffset1( 0 )
153 , mnDUnderlineOffset2( 0 )
154 , mnWUnderlineSize( 0 )
155 , mnWUnderlineOffset( 0 )
156 , mnAboveUnderlineSize( 0 )
157 , mnAboveUnderlineOffset( 0 )
158 , mnAboveBUnderlineSize( 0 )
159 , mnAboveBUnderlineOffset( 0 )
160 , mnAboveDUnderlineSize( 0 )
161 , mnAboveDUnderlineOffset1( 0 )
162 , mnAboveDUnderlineOffset2( 0 )
163 , mnAboveWUnderlineSize( 0 )
164 , mnAboveWUnderlineOffset( 0 )
165 , mnStrikeoutSize( 0 )
166 , mnStrikeoutOffset( 0 )
167 , mnBStrikeoutSize( 0 )
168 , mnBStrikeoutOffset( 0 )
169 , mnDStrikeoutSize( 0 )
170 , mnDStrikeoutOffset1( 0 )
171 , mnDStrikeoutOffset2( 0 )
172{
173 // initialize the used font name
174 sal_Int32 nTokenPos = 0;
175 SetFamilyName( OUString(GetNextFontToken( rFontSelData.GetFamilyName(), nTokenPos )) );
176 SetStyleName( rFontSelData.GetStyleName() );
177}
178
180{
181 auto* pHbFont = pFont->GetHbFont();
182 double fScale = 0;
183 pFont->GetScale(nullptr, &fScale);
184
185 hb_position_t nUnderlineSize, nUnderlineOffset, nStrikeoutSize, nStrikeoutOffset;
186 if (hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_UNDERLINE_SIZE, &nUnderlineSize)
187 && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_UNDERLINE_OFFSET,
188 &nUnderlineOffset)
189 && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_STRIKEOUT_SIZE, &nStrikeoutSize)
190 && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET,
191 &nStrikeoutOffset))
192 {
193 double nOffset = -nUnderlineOffset;
194 double nSize = nUnderlineSize;
195 double nSize2 = nSize / 2.;
196 double nBSize = nSize * 2.;
197 double n2Size = nBSize / 3.;
198
199 mnUnderlineSize = round(nSize * fScale);
200 mnUnderlineOffset = round(nOffset * fScale);
201
202 mnBUnderlineSize = round(nBSize * fScale);
203 mnBUnderlineOffset = round((nOffset - nSize2) * fScale);
204
205 mnDUnderlineSize = round(n2Size * fScale);
207 mnDUnderlineOffset2 = round((nOffset - nSize2 - n2Size + nBSize) * fScale);
208
210 mnWUnderlineOffset = round((nOffset + nSize) * fScale);
211
212 nOffset = -nStrikeoutOffset;
213 nSize = nStrikeoutSize;
214 nSize2 = nSize / 2.;
215 nBSize = nSize * 2.;
216 n2Size = nBSize / 3.;
217
218 mnStrikeoutSize = round(nSize * fScale);
219 mnStrikeoutOffset = round(nOffset * fScale);
220
221 mnBStrikeoutSize = round(nBSize * fScale);
222 mnBStrikeoutOffset = round((nOffset - nSize2) * fScale);
223
224 mnDStrikeoutSize = round(n2Size * fScale);
226 mnDStrikeoutOffset2 = round((nOffset - nSize2 - n2Size + nBSize) * fScale);
227
228 return true;
229 }
230 return false;
231}
232
234{
235 mnBulletOffset = ( pDev->GetTextWidth( OUString( u' ' ) ) - pDev->GetTextWidth( OUString( u'\x00b7' ) ) ) >> 1 ;
236
238 return;
239
240 tools::Long nDescent = mnDescent;
241 if ( nDescent <= 0 )
242 {
243 nDescent = mnAscent / 10;
244 if ( !nDescent )
245 nDescent = 1;
246 }
247
248 // #i55341# for some fonts it is not a good idea to calculate
249 // their text line metrics from the real font descent
250 // => work around this problem just for these fonts
251 if( 3*nDescent > mnAscent )
252 nDescent = mnAscent / 3;
253
254 tools::Long nLineHeight = ((nDescent*25)+50) / 100;
255 if ( !nLineHeight )
256 nLineHeight = 1;
257 tools::Long nLineHeight2 = nLineHeight / 2;
258 if ( !nLineHeight2 )
259 nLineHeight2 = 1;
260
261 tools::Long nBLineHeight = ((nDescent*50)+50) / 100;
262 if ( nBLineHeight == nLineHeight )
263 nBLineHeight++;
264 tools::Long nBLineHeight2 = nBLineHeight/2;
265 if ( !nBLineHeight2 )
266 nBLineHeight2 = 1;
267
268 tools::Long n2LineHeight = ((nDescent*16)+50) / 100;
269 if ( !n2LineHeight )
270 n2LineHeight = 1;
271 tools::Long n2LineDY = n2LineHeight;
272 /* #117909#
273 * add some pixels to minimum double line distance on higher resolution devices
274 */
275 tools::Long nMin2LineDY = 1 + pDev->GetDPIY()/150;
276 if ( n2LineDY < nMin2LineDY )
277 n2LineDY = nMin2LineDY;
278 tools::Long n2LineDY2 = n2LineDY/2;
279 if ( !n2LineDY2 )
280 n2LineDY2 = 1;
281
282 const vcl::Font& rFont ( pDev->GetFont() );
283 bool bCJKVertical = MsLangId::isCJK(rFont.GetLanguage()) && rFont.IsVertical();
284 tools::Long nUnderlineOffset = bCJKVertical ? mnDescent : (mnDescent/2 + 1);
285 tools::Long nStrikeoutOffset = rFont.IsVertical() ? -((mnAscent - mnDescent) / 2) : -((mnAscent - mnIntLeading) / 3);
286
287 mnUnderlineSize = nLineHeight;
288 mnUnderlineOffset = nUnderlineOffset - nLineHeight2;
289
290 mnBUnderlineSize = nBLineHeight;
291 mnBUnderlineOffset = nUnderlineOffset - nBLineHeight2;
292
293 mnDUnderlineSize = n2LineHeight;
294 mnDUnderlineOffset1 = nUnderlineOffset - n2LineDY2 - n2LineHeight;
295 mnDUnderlineOffset2 = mnDUnderlineOffset1 + n2LineDY + n2LineHeight;
296
297 tools::Long nWCalcSize = mnDescent;
298 if ( nWCalcSize < 6 )
299 {
300 if ( (nWCalcSize == 1) || (nWCalcSize == 2) )
301 mnWUnderlineSize = nWCalcSize;
302 else
304 }
305 else
306 mnWUnderlineSize = ((nWCalcSize*50)+50) / 100;
307
308
309 // Don't assume that wavelines are never placed below the descent, because for most fonts the waveline
310 // is drawn into the text
311 mnWUnderlineOffset = nUnderlineOffset;
312
313 mnStrikeoutSize = nLineHeight;
314 mnStrikeoutOffset = nStrikeoutOffset - nLineHeight2;
315
316 mnBStrikeoutSize = nBLineHeight;
317 mnBStrikeoutOffset = nStrikeoutOffset - nBLineHeight2;
318
319 mnDStrikeoutSize = n2LineHeight;
320 mnDStrikeoutOffset1 = nStrikeoutOffset - n2LineDY2 - n2LineHeight;
321 mnDStrikeoutOffset2 = mnDStrikeoutOffset1 + n2LineDY + n2LineHeight;
322
323}
324
325
327{
329
330 tools::Long nIntLeading = mnIntLeading;
331 // TODO: assess usage of nLeading below (changed in extleading CWS)
332 // if no leading is available, we assume 15% of the ascent
333 if ( nIntLeading <= 0 )
334 {
335 nIntLeading = mnAscent*15/100;
336 if ( !nIntLeading )
337 nIntLeading = 1;
338 }
339
340 tools::Long nCeiling = -mnAscent;
341
343 mnAboveUnderlineOffset = nCeiling + (nIntLeading - mnUnderlineSize + 1) / 2;
344
346 mnAboveBUnderlineOffset = nCeiling + (nIntLeading - mnBUnderlineSize + 1) / 2;
347
349 mnAboveDUnderlineOffset1 = nCeiling + (nIntLeading - 3*mnDUnderlineSize + 1) / 2;
350 mnAboveDUnderlineOffset2 = nCeiling + (nIntLeading + mnDUnderlineSize + 1) / 2;
351
353 mnAboveWUnderlineOffset = nCeiling + (nIntLeading + 1) / 2;
354}
355
357{
358 const vcl::Font& rFont ( pDev->GetFont() );
359 bool bCentered = true;
360 if (MsLangId::isCJK(rFont.GetLanguage()))
361 {
362 tools::Rectangle aRect;
363 pDev->GetTextBoundRect( aRect, u"\x3001" ); // Fullwidth fullstop
364 const auto nH = rFont.GetFontSize().Height();
365 const auto nB = aRect.Left();
366 // Use 18.75% as a threshold to define a centered fullwidth fullstop.
367 // In general, nB/nH < 5% for most Japanese fonts.
368 bCentered = nB > (((nH >> 1)+nH)>>3);
369 }
370 SetFullstopCenteredFlag( bCentered );
371}
372
373bool ImplFontMetricData::ShouldUseWinMetrics(int nAscent, int nDescent, int nTypoAscent,
374 int nTypoDescent, int nWinAscent,
375 int nWinDescent) const
376{
378 return false;
379
380 OUString aFontIdentifier(
381 GetFamilyName() + ","
382 + OUString::number(nAscent) + "," + OUString::number(nDescent) + ","
383 + OUString::number(nTypoAscent) + "," + OUString::number(nTypoDescent) + ","
384 + OUString::number(nWinAscent) + "," + OUString::number(nWinDescent));
385
386 css::uno::Sequence<OUString> rWinMetricFontList(
387 officecfg::Office::Common::Misc::FontsUseWinMetrics::get());
388 if (comphelper::findValue(rWinMetricFontList, aFontIdentifier) != -1)
389 {
390 SAL_INFO("vcl.gdi.fontmetric", "Using win metrics for: " << aFontIdentifier);
391 return true;
392 }
393 return false;
394}
395
396// These are “private” HarfBuzz metrics tags, they are supported by not exposed
397// in the public header. They are safe to use, HarfBuzz just does not want to
398// advertise them.
399constexpr auto ASCENT_OS2 = static_cast<hb_ot_metrics_tag_t>(HB_TAG('O', 'a', 's', 'c'));
400constexpr auto DESCENT_OS2 = static_cast<hb_ot_metrics_tag_t>(HB_TAG('O', 'd', 's', 'c'));
401constexpr auto LINEGAP_OS2 = static_cast<hb_ot_metrics_tag_t>(HB_TAG('O', 'l', 'g', 'p'));
402constexpr auto ASCENT_HHEA = static_cast<hb_ot_metrics_tag_t>(HB_TAG('H', 'a', 's', 'c'));
403constexpr auto DESCENT_HHEA = static_cast<hb_ot_metrics_tag_t>(HB_TAG('H', 'd', 's', 'c'));
404constexpr auto LINEGAP_HHEA = static_cast<hb_ot_metrics_tag_t>(HB_TAG('H', 'l', 'g', 'p'));
405
407{
409 auto* pFace = pFontInstance->GetFontFace();
410 auto* pHbFont = pFontInstance->GetHbFont();
411
412 double fScale = 0;
413 pFontInstance->GetScale(nullptr, &fScale);
414 double fAscent = 0, fDescent = 0, fExtLeading = 0;
415
416 auto aFvar(pFace->GetRawFontData(HB_TAG('f', 'v', 'a', 'r')));
417 if (!aFvar.empty())
418 {
419 // This is a variable font, trust HarfBuzz to give us the right metrics
420 // and apply variations to them.
421 hb_position_t nAscent, nDescent, nLineGap;
422 if (hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, &nAscent)
423 && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER,
424 &nDescent)
425 && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP,
426 &nLineGap))
427 {
428 fAscent = nAscent * fScale;
429 fDescent = -nDescent * fScale;
430 fExtLeading = nLineGap * fScale;
431 }
432 }
433 else
434 {
435 // This is not a variable font, we try to choose the best metrics
436 // ourselves for backward comparability:
437 //
438 // - hhea metrics should be used, since hhea is a mandatory font table
439 // and should always be present.
440 // - But if OS/2 is present, it should be used since it is mandatory in
441 // Windows.
442 // OS/2 has Typo and Win metrics, but the later was meant to control
443 // text clipping not line spacing and can be ridiculously large.
444 // Unfortunately many Windows application incorrectly use the Win
445 // metrics (thanks to GDI’s TEXTMETRIC) and old fonts might be
446 // designed with this in mind, so OpenType introduced a flag for
447 // fonts to indicate that they really want to use Typo metrics. So
448 // for best backward compatibility:
449 // - Use Win metrics if available.
450 // - Unless USE_TYPO_METRICS flag is set, in which case use Typo
451 // metrics.
452
453 // Try hhea table first.
454 hb_position_t nAscent = 0, nDescent = 0, nLineGap = 0;
455 if (hb_ot_metrics_get_position(pHbFont, ASCENT_HHEA, &nAscent)
456 && hb_ot_metrics_get_position(pHbFont, DESCENT_HHEA, &nDescent)
457 && hb_ot_metrics_get_position(pHbFont, LINEGAP_HHEA, &nLineGap))
458 {
459 // tdf#107605: Some fonts have weird values here, so check that
460 // ascender is +ve and descender is -ve as they normally should.
461 if (nAscent >= 0 && nDescent <= 0)
462 {
463 fAscent = nAscent * fScale;
464 fDescent = -nDescent * fScale;
465 fExtLeading = nLineGap * fScale;
466 }
467 }
468
469 // But if OS/2 is present, prefer it.
470 hb_position_t nTypoAscent, nTypoDescent, nTypoLineGap, nWinAscent, nWinDescent;
471 if (hb_ot_metrics_get_position(pHbFont, ASCENT_OS2, &nTypoAscent)
472 && hb_ot_metrics_get_position(pHbFont, DESCENT_OS2, &nTypoDescent)
473 && hb_ot_metrics_get_position(pHbFont, LINEGAP_OS2, &nTypoLineGap)
474 && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT,
475 &nWinAscent)
476 && hb_ot_metrics_get_position(pHbFont, HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT,
477 &nWinDescent))
478 {
479 if ((fAscent == 0.0 && fDescent == 0.0)
480 || ShouldUseWinMetrics(nAscent, nDescent, nTypoAscent, nTypoDescent, nWinAscent,
481 nWinDescent))
482 {
483 fAscent = nWinAscent * fScale;
484 fDescent = nWinDescent * fScale;
485 fExtLeading = 0;
486 }
487
488 bool bUseTypoMetrics = false;
489 {
490 // TODO: Use HarfBuzz API instead of raw access
491 // https://github.com/harfbuzz/harfbuzz/issues/1920
492 sal_uInt16 fsSelection = 0;
493 auto aOS2(pFace->GetRawFontData(HB_TAG('O', 'S', '/', '2')));
494 SvMemoryStream aStream(const_cast<uint8_t*>(aOS2.data()), aOS2.size(),
495 StreamMode::READ);
497 aStream.ReadUInt16(fsSelection);
498 bUseTypoMetrics = fsSelection & (1 << 7);
499 }
500 if (bUseTypoMetrics && nTypoAscent >= 0 && nTypoDescent <= 0)
501 {
502 fAscent = nTypoAscent * fScale;
503 fDescent = -nTypoDescent * fScale;
504 fExtLeading = nTypoLineGap * fScale;
505 }
506 }
507 }
508
509 mnAscent = round(fAscent);
510 mnDescent = round(fDescent);
511 mnExtLeading = round(fExtLeading);
512
513 if (mnAscent || mnDescent)
515}
516
518{
519 hb_font_t* pHbFont = pFontInstance->GetHbFont();
520 double fScale = 0;
521 pFontInstance->GetScale(nullptr, &fScale);
522 hb_position_t nBaseline = 0;
523
524 if (hb_ot_layout_get_baseline(pHbFont,
525 HB_OT_LAYOUT_BASELINE_TAG_HANGING,
526 HB_DIRECTION_INVALID,
527 HB_SCRIPT_UNKNOWN,
528 HB_TAG_NONE,
529 &nBaseline))
530 {
531 mnHangingBaseline = nBaseline * fScale;
532 }
533 else
534 {
536 }
537}
538
539/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
int GetQuality() const
bool IsMicrosoftSymbolEncoded() const
FontFamily GetFamilyType() const
FontItalic GetItalic() const
FontWeight GetWeight() const
void SetStyleName(const OUString &sStyleName)
const OUString & GetFamilyName() const
void SetFamilyName(const OUString &sFamilyName)
FontPitch GetPitch() const
const OUString & GetStyleName() const
FontWidth GetWidthType() const
FontMetric & operator=(const FontMetric &rMetric)
size_t GetHashValueNoBase() const
Definition: fontmetric.cxx:114
bool operator==(const FontMetric &rMetric) const
Definition: fontmetric.cxx:100
tools::Long mnAscent
Definition: metric.hxx:80
tools::Long mnDescent
Definition: metric.hxx:81
tools::Long mnSlant
Definition: metric.hxx:85
tools::Long mnExtLeading
Definition: metric.hxx:83
size_t GetHashValueIgnoreColor() const
Definition: fontmetric.cxx:126
tools::Long mnIntLeading
Definition: metric.hxx:82
bool EqualIgnoreColor(const FontMetric &) const
Definition: fontmetric.cxx:107
bool mbFullstopCentered
Definition: metric.hxx:89
bool EqualNoBase(const FontMetric &) const
Definition: fontmetric.cxx:82
~FontMetric() override
Definition: fontmetric.cxx:74
tools::Long mnAboveBUnderlineOffset
tools::Long mnDUnderlineOffset1
tools::Long mnDStrikeoutOffset2
tools::Long mnAboveUnderlineSize
tools::Long mnBStrikeoutOffset
tools::Long mnAboveUnderlineOffset
tools::Long mnAboveWUnderlineSize
tools::Long mnDStrikeoutOffset1
tools::Long mnAboveDUnderlineSize
tools::Long mnWUnderlineOffset
void ImplInitBaselines(LogicalFontInstance *pFontInstance)
Definition: fontmetric.cxx:517
void ImplInitAboveTextLineSize(const OutputDevice *pDev)
Definition: fontmetric.cxx:326
tools::Long mnBUnderlineOffset
void ImplCalcLineSpacing(LogicalFontInstance *pFontInstance)
Definition: fontmetric.cxx:406
tools::Long mnAboveWUnderlineOffset
void ImplInitTextLineSize(const OutputDevice *pDev)
Definition: fontmetric.cxx:233
ImplFontMetricData(const vcl::font::FontSelectPattern &)
Definition: fontmetric.cxx:133
void SetFullstopCenteredFlag(bool bFullstopCentered)
tools::Long mnAboveDUnderlineOffset2
tools::Long mnAboveBUnderlineSize
bool ImplInitTextLineSizeHarfBuzz(LogicalFontInstance *pFontInstance)
Definition: fontmetric.cxx:179
tools::Long mnAboveDUnderlineOffset1
void ImplInitFlags(const OutputDevice *pDev)
Definition: fontmetric.cxx:356
tools::Long mnDUnderlineOffset2
bool ShouldUseWinMetrics(int, int, int, int, int, int) const
Definition: fontmetric.cxx:373
void GetScale(double *nXScale, double *nYScale) const
const vcl::font::PhysicalFontFace * GetFontFace() const
static bool isCJK(LanguageType nLang)
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:171
SAL_DLLPRIVATE const LogicalFontInstance * GetFontInstance() const
const vcl::Font & GetFont() const
Definition: outdev.hxx:530
SAL_DLLPRIVATE sal_Int32 GetDPIY() const
Get the output device's DPI y-axis value.
Definition: outdev.hxx:392
bool GetTextBoundRect(tools::Rectangle &rRect, const OUString &rStr, sal_Int32 nBase=0, sal_Int32 nIndex=0, sal_Int32 nLen=-1, sal_uLong nLayoutWidth=0, o3tl::span< const sal_Int32 > pDXArray={}, o3tl::span< const sal_Bool > pKashidaArray={}, const SalLayoutGlyphs *pGlyphs=nullptr) const
Return the exact bounding rectangle of rStr.
Definition: text.cxx:2339
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
Width of the text.
Definition: text.cxx:886
constexpr tools::Long Height() const
sal_uInt64 Seek(sal_uInt64 nPos)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
constexpr tools::Long Left() const
static bool IsFuzzing()
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:936
void SetPitch(FontPitch ePitch)
Definition: font/font.cxx:191
void SetItalic(FontItalic)
Definition: font/font.cxx:248
void SetWeight(FontWeight)
Definition: font/font.cxx:236
void SetFamily(FontFamily)
Definition: font/font.cxx:155
void SetCharSet(rtl_TextEncoding)
Definition: font/font.cxx:161
const Size & GetFontSize() const
Definition: font/font.cxx:906
LanguageType GetLanguage() const
Definition: font/font.cxx:916
void SetAlignment(TextAlign)
Definition: font/font.cxx:131
void SetFamilyName(const OUString &rFamilyName)
Definition: font/font.cxx:137
bool IsVertical() const
Definition: font/font.cxx:920
abstract base class for physical font faces
float u
UNOTOOLS_DLLPUBLIC std::u16string_view GetNextFontToken(std::u16string_view rTokenStr, sal_Int32 &rIndex)
constexpr auto ASCENT_OS2
Definition: fontmetric.cxx:399
constexpr auto LINEGAP_HHEA
Definition: fontmetric.cxx:404
constexpr auto ASCENT_HHEA
Definition: fontmetric.cxx:402
constexpr auto DESCENT_OS2
Definition: fontmetric.cxx:400
constexpr auto LINEGAP_OS2
Definition: fontmetric.cxx:401
constexpr auto DESCENT_HHEA
Definition: fontmetric.cxx:403
#define SAL_INFO(area, stream)
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
std::enable_if_t<(sizeof(N)==4)> hash_combine(N &nSeed, T const *pValue, size_t nCount)
long Long
constexpr int OS2_fsSelection_offset
Definition: sft.hxx:275
Sun Font Tools.
double mnWidth
double mnHeight