diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp | 174 |
1 files changed, 102 insertions, 72 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp index 630570046f9..ca942a0fb9d 100644 --- a/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp +++ b/Build/source/texk/dvisvgm/dvisvgm-src/src/FontEngine.cpp @@ -2,7 +2,7 @@ ** FontEngine.cpp ** ** ** ** This file is part of dvisvgm -- a fast DVI to SVG converter ** -** Copyright (C) 2005-2022 Martin Gieseking <martin.gieseking@uos.de> ** +** Copyright (C) 2005-2023 Martin Gieseking <martin.gieseking@uos.de> ** ** ** ** This program is free software; you can redistribute it and/or ** ** modify it under the terms of the GNU General Public License as ** @@ -29,6 +29,7 @@ #include "Font.hpp" #include "FontEngine.hpp" #include "FontStyle.hpp" +#include "fonts/Base14Fonts.hpp" #include "Message.hpp" #include "utility.hpp" @@ -88,7 +89,19 @@ string FontEngine::version () { bool FontEngine::setFont (const string &fname, int fontindex, const CharMapID &charMapID) { if (_currentFace && FT_Done_Face(_currentFace)) Message::estream(true) << "failed to release font\n"; - if (FT_New_Face(_library, fname.c_str(), fontindex, &_currentFace)) { + if (fname.size() <= 6 || fname.substr(0, 6) == "sys://") { + if (const MemoryFontData *data = find_base14_font(fname.substr(6))) { + FT_Open_Args args; + args.flags = FT_OPEN_MEMORY; + args.memory_base = reinterpret_cast<const FT_Byte*>(data->data); + args.memory_size = FT_Long(data->size); + if (FT_Open_Face(_library, &args, fontindex, &_currentFace)) { + Message::estream(true) << "can't read memory font " << fname << '\n'; + return false; + } + } + } + else if (FT_New_Face(_library, fname.c_str(), fontindex, &_currentFace)) { Message::estream(true) << "can't read font file " << fname << '\n'; return false; } @@ -115,16 +128,24 @@ bool FontEngine::setFont (const Font &font) { bool FontEngine::isCIDFont() const { FT_Bool cid_keyed; - return FT_Get_CID_Is_Internally_CID_Keyed(_currentFace, &cid_keyed) == 0 && cid_keyed; + return _currentFace && FT_Get_CID_Is_Internally_CID_Keyed(_currentFace, &cid_keyed) == 0 && cid_keyed; +} + + +/** Returns true if the current font contains vertical layout data. */ +bool FontEngine::hasVerticalMetrics () const { + return _currentFace && FT_HAS_VERTICAL(_currentFace); } bool FontEngine::setCharMap (const CharMapID &charMapID) { - for (int i=0; i < _currentFace->num_charmaps; i++) { - FT_CharMap ft_cmap = _currentFace->charmaps[i]; - if (ft_cmap->platform_id == charMapID.platform_id && ft_cmap->encoding_id == charMapID.encoding_id) { - FT_Set_Charmap(_currentFace, ft_cmap); - return true; + if (_currentFace) { + for (int i = 0; i < _currentFace->num_charmaps; i++) { + FT_CharMap ft_cmap = _currentFace->charmaps[i]; + if (ft_cmap->platform_id == charMapID.platform_id && ft_cmap->encoding_id == charMapID.encoding_id) { + FT_Set_Charmap(_currentFace, ft_cmap); + return true; + } } } return false; @@ -149,22 +170,24 @@ void FontEngine::buildGidToCharCodeMap (RangeMap &charmap) { /** Creates a charmap that maps from the custom character encoding to Unicode. * @return pointer to charmap if it could be created, 0 otherwise */ unique_ptr<const RangeMap> FontEngine::createCustomToUnicodeMap () { - FT_CharMap ftcharmap = _currentFace->charmap; - if (FT_Select_Charmap(_currentFace, FT_ENCODING_ADOBE_CUSTOM) != 0) - return nullptr; - RangeMap gidToCharCodeMap; - buildGidToCharCodeMap(gidToCharCodeMap); - if (FT_Select_Charmap(_currentFace, FT_ENCODING_UNICODE) != 0) - return nullptr; auto charmap = util::make_unique<RangeMap>(); - FT_UInt gid; // index of current glyph - uint32_t ucCharcode = FT_Get_First_Char(_currentFace, &gid); // Unicode code point - while (gid) { - uint32_t customCharcode = gidToCharCodeMap.valueAt(gid); - charmap->addRange(customCharcode, customCharcode, ucCharcode); - ucCharcode = FT_Get_Next_Char(_currentFace, ucCharcode, &gid); + if (_currentFace) { + FT_CharMap ftcharmap = _currentFace->charmap; + if (FT_Select_Charmap(_currentFace, FT_ENCODING_ADOBE_CUSTOM) != 0) + return nullptr; + RangeMap gidToCharCodeMap; + buildGidToCharCodeMap(gidToCharCodeMap); + if (FT_Select_Charmap(_currentFace, FT_ENCODING_UNICODE) != 0) + return nullptr; + FT_UInt gid; // index of current glyph + uint32_t ucCharcode = FT_Get_First_Char(_currentFace, &gid); // Unicode code point + while (gid) { + uint32_t customCharcode = gidToCharCodeMap.valueAt(gid); + charmap->addRange(customCharcode, customCharcode, ucCharcode); + ucCharcode = FT_Get_Next_Char(_currentFace, ucCharcode, &gid); + } + FT_Set_Charmap(_currentFace, ftcharmap); } - FT_Set_Charmap(_currentFace, ftcharmap); return std::move(charmap); } @@ -179,6 +202,27 @@ const char* FontEngine::getStyleName () const { } +/** Returns the PS name of the current font. */ +const char* FontEngine::getPSName () const { + return _currentFace ? FT_Get_Postscript_Name(_currentFace) : nullptr; +} + + +/** Returns the PS name of a font given by a file. + * @param[in] fname name/path of the font file + * @return the PS name */ +string FontEngine::getPSName (const string &fname) const { + string psname; + FT_Face face; + if (FT_New_Face(_library, fname.c_str(), 0, &face) == 0) { + if (const char *ptr = FT_Get_Postscript_Name(face)) + psname = ptr; + FT_Done_Face(face); + } + return psname; +} + + int FontEngine::getUnitsPerEM () const { return _currentFace ? _currentFace->units_per_EM : 0; } @@ -200,16 +244,6 @@ int FontEngine::getDescender () const { } -int FontEngine::getAdvance (int c) const { - if (_currentFace) { - FT_Fixed adv=0; - FT_Get_Advance(_currentFace, c, FT_LOAD_NO_SCALE, &adv); - return adv; - } - return 0; -} - - int FontEngine::getHAdvance () const { if (_currentFace) { auto table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(_currentFace, ft_sfnt_os2)); @@ -219,21 +253,26 @@ int FontEngine::getHAdvance () const { } +/** Returns the horizontal advance width of a given character in font units. */ int FontEngine::getHAdvance (const Character &c) const { if (_currentFace) { - FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE); - return _currentFace->glyph->metrics.horiAdvance; + FT_Fixed adv=0; + FT_Get_Advance(_currentFace, charIndex(c), FT_LOAD_NO_SCALE, &adv); + return adv; } return 0; } +/** Returns the vertical advance width of a given character in font units. */ int FontEngine::getVAdvance (const Character &c) const { if (_currentFace) { - FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE); + FT_Fixed adv=0; + auto flags = FT_LOAD_NO_SCALE; if (FT_HAS_VERTICAL(_currentFace)) - return _currentFace->glyph->metrics.vertAdvance; - return _currentFace->glyph->metrics.horiAdvance; + flags |= FT_LOAD_VERTICAL_LAYOUT; + FT_Get_Advance(_currentFace, charIndex(c), flags, &adv); + return adv; } return 0; } @@ -241,8 +280,8 @@ int FontEngine::getVAdvance (const Character &c) const { int FontEngine::getWidth (const Character &c) const { if (_currentFace) { - FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE); - return _currentFace->glyph->metrics.width; + if (FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE) == 0) + return _currentFace->glyph->metrics.width; } return 0; } @@ -250,8 +289,8 @@ int FontEngine::getWidth (const Character &c) const { int FontEngine::getHeight (const Character &c) const { if (_currentFace) { - FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE); - return _currentFace->glyph->metrics.horiBearingY; + if (FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE) == 0) + return _currentFace->glyph->metrics.horiBearingY; } return 0; } @@ -259,13 +298,18 @@ int FontEngine::getHeight (const Character &c) const { int FontEngine::getDepth (const Character &c) const { if (_currentFace) { - FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE); - return _currentFace->glyph->metrics.height - _currentFace->glyph->metrics.horiBearingY; + if (FT_Load_Glyph(_currentFace, charIndex(c), FT_LOAD_NO_SCALE) == 0) + return _currentFace->glyph->metrics.height - _currentFace->glyph->metrics.horiBearingY; } return 0; } +int FontEngine::getCharIndexByGlyphName(const char *name) const { + return _currentFace ? int(FT_Get_Name_Index(_currentFace, name)) : 0; +} + + int FontEngine::charIndex (const Character &c) const { if (!_currentFace || !_currentFace->charmap) return c.type() == Character::NAME ? 0 : c.number(); @@ -280,22 +324,6 @@ int FontEngine::charIndex (const Character &c) const { } -/** Get first available character of the current font face. */ -int FontEngine::getFirstChar () const { - if (_currentFace) - return _currentChar = FT_Get_First_Char(_currentFace, &_currentGlyphIndex); - return 0; -} - - -/** Get the next available character of the current font face. */ -int FontEngine::getNextChar () const { - if (_currentFace && _currentGlyphIndex) - return _currentChar = FT_Get_Next_Char(_currentFace, _currentChar, &_currentGlyphIndex); - return getFirstChar(); -} - - /** Returns the number of glyphs present in the current font face. */ int FontEngine::getNumGlyphs () const { return _currentFace ? _currentFace->num_glyphs : 0; @@ -306,15 +334,15 @@ int FontEngine::getNumGlyphs () const { * @param[in] c char code * @return glyph name */ string FontEngine::getGlyphName (const Character &c) const { + string ret; if (c.type() == Character::NAME) - return c.name(); - - if (_currentFace && FT_HAS_GLYPH_NAMES(_currentFace)) { + ret = c.name(); + else if (_currentFace && FT_HAS_GLYPH_NAMES(_currentFace)) { char buf[256]; FT_Get_Glyph_Name(_currentFace, charIndex(c), buf, 256); - return string(buf); + ret = string(buf); } - return ""; + return ret; } @@ -335,7 +363,7 @@ int FontEngine::getCharMapIDs (vector<CharMapID> &charmapIDs) const { if (_currentFace) { for (int i=0; i < _currentFace->num_charmaps; i++) { FT_CharMap charmap = _currentFace->charmaps[i]; - charmapIDs.emplace_back(charmap->platform_id, charmap->encoding_id); + charmapIDs.emplace_back(uint8_t(charmap->platform_id), uint8_t(charmap->encoding_id)); } } return charmapIDs.size(); @@ -344,14 +372,14 @@ int FontEngine::getCharMapIDs (vector<CharMapID> &charmapIDs) const { CharMapID FontEngine::setUnicodeCharMap () { if (_currentFace && FT_Select_Charmap(_currentFace, FT_ENCODING_UNICODE) == 0) - return CharMapID(_currentFace->charmap->platform_id, _currentFace->charmap->encoding_id); + return CharMapID(uint8_t(_currentFace->charmap->platform_id), uint8_t(_currentFace->charmap->encoding_id)); return CharMapID(); } CharMapID FontEngine::setCustomCharMap () { if (_currentFace && FT_Select_Charmap(_currentFace, FT_ENCODING_ADOBE_CUSTOM) == 0) - return CharMapID(_currentFace->charmap->platform_id, _currentFace->charmap->encoding_id); + return CharMapID(uint8_t(_currentFace->charmap->platform_id), uint8_t(_currentFace->charmap->encoding_id)); return CharMapID(); } @@ -414,11 +442,13 @@ static bool trace_outline (FT_Face face, const Font *font, int index, Glyph &gly } FT_Outline outline = face->glyph->outline; // apply style parameters if set - if (const FontStyle *style = font->style()) { - FT_Matrix matrix = {to_16dot16(style->extend), to_16dot16(style->slant), 0, to_16dot16(1)}; - FT_Outline_Transform(&outline, &matrix); - if (style->bold != 0) - FT_Outline_Embolden(&outline, style->bold/font->scaledSize()*face->units_per_EM); + if (font) { + if (const FontStyle *style = font->style()) { + FT_Matrix matrix = {to_16dot16(style->extend), to_16dot16(style->slant), 0, to_16dot16(1)}; + FT_Outline_Transform(&outline, &matrix); + if (style->bold != 0) + FT_Outline_Embolden(&outline, style->bold/font->scaledSize()*face->units_per_EM); + } } const FT_Outline_Funcs funcs = {moveto, lineto, quadto, cubicto, 0, 0}; FT_Outline_Decompose(&outline, &funcs, &glyph); |