/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
FontAttributes DevFontFromCTFontDescriptor( CTFontDescriptorRef pFD, bool* bFontEnabled )
{ // all CoreText fonts are device fonts that can rotate just fine
FontAttributes rDFA;
rDFA.SetQuality( 0 );
// get font style
CFStringRef pStyleName = static_cast<CFStringRef>(CTFontDescriptorCopyAttribute( pFD, kCTFontStyleNameAttribute ));
rDFA.SetStyleName( GetOUString( pStyleName ) );
// get font-enabled status if( bFontEnabled )
{ int bEnabled = TRUE; // by default (and when we're on macOS < 10.6) it's "enabled"
CFNumberRef pEnabled = static_cast<CFNumberRef>(CTFontDescriptorCopyAttribute( pFD, kCTFontEnabledAttribute ));
CFNumberGetValue( pEnabled, kCFNumberIntType, &bEnabled );
*bFontEnabled = bEnabled;
}
// get font attributes
CFDictionaryRef pAttrDict = static_cast<CFDictionaryRef>(CTFontDescriptorCopyAttribute( pFD, kCTFontTraitsAttribute ));
if (bFontEnabled && *bFontEnabled)
{ // Ignore font formats not supported. int nFormat;
CFNumberRef pFormat = static_cast<CFNumberRef>(CTFontDescriptorCopyAttribute(pFD, kCTFontFormatAttribute));
CFNumberGetValue(pFormat, kCFNumberIntType, &nFormat); if (nFormat == kCTFontFormatUnrecognized || nFormat == kCTFontFormatPostScript || nFormat == kCTFontFormatBitmap)
{
SAL_INFO("vcl.fonts", "Ignoring font with unsupported format: " << rDFA.GetFamilyName());
*bFontEnabled = false;
}
CFRelease(pFormat);
}
// get symbolic trait // TODO: use other traits such as MonoSpace/Condensed/Expanded or Vertical too
SInt64 nSymbolTrait = 0;
CFNumberRef pSymbolNum = nullptr; if( CFDictionaryGetValueIfPresent( pAttrDict, kCTFontSymbolicTrait, reinterpret_cast<constvoid**>(&pSymbolNum) ) )
{
CFNumberGetValue( pSymbolNum, kCFNumberSInt64Type, &nSymbolTrait ); if (nSymbolTrait & kCTFontMonoSpaceTrait)
rDFA.SetPitch(PITCH_FIXED);
}
// get the font weight double fWeight = 0;
CFNumberRef pWeightNum = static_cast<CFNumberRef>(CFDictionaryGetValue( pAttrDict, kCTFontWeightTrait )); // tdf#140401 check if attribute is a nullptr if( pWeightNum )
CFNumberGetValue( pWeightNum, kCFNumberDoubleType, &fWeight ); int nInt = WEIGHT_NORMAL;
// Special case fixes
// tdf#67744: Courier Std Medium is always bold. We get a kCTFontWeightTrait of 0.23 which // surely must be wrong. if (rDFA.GetFamilyName() == "Courier Std" &&
(rDFA.GetStyleName() == "Medium" || rDFA.GetStyleName() == "Medium Oblique") &&
fWeight > 0.2)
{
fWeight = 0;
}
// tdf#68889: Ditto for Gill Sans MT Pro. Here I can kinda understand it, maybe the // kCTFontWeightTrait is intended to give a subjective "optical" impression of how the font // looks, and Gill Sans MT Pro Medium is kinda heavy. But with the way LibreOffice uses fonts, // we still should think of it as being "medium" weight. if (rDFA.GetFamilyName() == "Gill Sans MT Pro" &&
(rDFA.GetStyleName() == "Medium" || rDFA.GetStyleName() == "Medium Italic") &&
fWeight > 0.2)
{
fWeight = 0;
}
// release the attribute dict that we had copied
CFRelease( pAttrDict );
// TODO? also use the HEAD table if available to get more attributes // CFDataRef CTFontCopyTable( CTFontRef, kCTFontTableHead, /*kCTFontTableOptionNoOptions*/kCTFontTableOptionExcludeSynthetic );
// tdf#163000 don't add any fonts with an 'hvgl' font table // macOS Sequoia added a new PingFangUI.ttc font file which // contains all of the PingFang font families. However, any // fonts loaded from this font file result in the following // failures: // - Skia renders font with wrong glyphs // - Export to PDF contain a damaged embedded font // Despite the fact that the fonts in this new font file have // a TrueType font type, they are missing a 'glyf' font table // and, instead, have a new, undefined 'hvgl' font table. See // the following link for more details about the new 'hvgl' // font table: // https://gitlab.freedesktop.org/freetype/freetype/-/issues/1281
CFNumberRef pFontFormat = static_cast<CFNumberRef>(CTFontDescriptorCopyAttribute(pFD, kCTFontFormatAttribute)); if (pFontFormat)
{ bool bSkipFont = false; int nFontFormat; // At least for the PingFangUI.ttc font file, the font format is // different on macOS and iOS if (CFNumberGetValue(pFontFormat, kCFNumberIntType, &nFontFormat) && (nFontFormat == kCTFontFormatOpenTypeTrueType || nFontFormat == kCTFontFormatTrueType))
{
CTFontRef pFont = CTFontCreateWithFontDescriptor(pFD, 0.0, nullptr); if (pFont)
{
CFArrayRef pFontTableTags = CTFontCopyAvailableTables(pFont, kCTFontTableOptionNoOptions); if (pFontTableTags)
{ bool bGlyfTableFound = false; bool bHvglTableFound = false;
CFIndex nFontTableTagCount = CFArrayGetCount(pFontTableTags); for (CFIndex i = 0; i < nFontTableTagCount; i++)
{
CTFontTableTag nTag = reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(pFontTableTags, i)); if (nTag == kCTFontTableGlyf)
{
bGlyfTableFound = true; break;
} elseif (nTag == 'hvgl')
{
bHvglTableFound = true;
}
}
bSkipFont = !bGlyfTableFound && bHvglTableFound;
CFRelease(pFontTableTags);
}
CFRelease(pFont);
}
}
CFRelease(pFontFormat);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.