Created
November 17, 2025 05:40
-
-
Save usernameak/bd12296574cf7ce0bd07446c8dc0c796 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/old/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.cpp b/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.cpp | |
| index 7d350c2..0bc0e1a 100644 | |
| --- a/old/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.cpp | |
| +++ b/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.cpp | |
| @@ -54,14 +54,14 @@ FontGeometry &FontGeometry::operator=(FontGeometry &&orig) { | |
| return *this; | |
| } | |
| -int FontGeometry::loadGlyphRange(msdfgen::FontHandle *font, double fontScale, unsigned rangeStart, unsigned rangeEnd, bool preprocessGeometry, bool enableKerning) { | |
| +int FontGeometry::loadGlyphRange(msdfgen::FontHandle *font, double fontScale, unsigned rangeStart, unsigned rangeEnd, bool preprocessGeometry, bool enableKerning, bool loadCompositeGlyphs) { | |
| if (!(glyphs->size() == this->rangeEnd && loadMetrics(font, fontScale))) | |
| return -1; | |
| glyphs->reserve(glyphs->size()+(rangeEnd-rangeStart)); | |
| int loaded = 0; | |
| for (unsigned index = rangeStart; index < rangeEnd; ++index) { | |
| GlyphGeometry glyph; | |
| - if (glyph.load(font, geometryScale, msdfgen::GlyphIndex(index), preprocessGeometry)) { | |
| + if (glyph.load(font, geometryScale, msdfgen::GlyphIndex(index), preprocessGeometry, loadCompositeGlyphs)) { | |
| addGlyph((GlyphGeometry &&) glyph); | |
| ++loaded; | |
| } | |
| @@ -72,14 +72,14 @@ int FontGeometry::loadGlyphRange(msdfgen::FontHandle *font, double fontScale, un | |
| return loaded; | |
| } | |
| -int FontGeometry::loadGlyphset(msdfgen::FontHandle *font, double fontScale, const Charset &glyphset, bool preprocessGeometry, bool enableKerning) { | |
| +int FontGeometry::loadGlyphset(msdfgen::FontHandle *font, double fontScale, const Charset &glyphset, bool preprocessGeometry, bool enableKerning, bool loadCompositeGlyphs) { | |
| if (!(glyphs->size() == rangeEnd && loadMetrics(font, fontScale))) | |
| return -1; | |
| glyphs->reserve(glyphs->size()+glyphset.size()); | |
| int loaded = 0; | |
| for (unicode_t index : glyphset) { | |
| GlyphGeometry glyph; | |
| - if (glyph.load(font, geometryScale, msdfgen::GlyphIndex(index), preprocessGeometry)) { | |
| + if (glyph.load(font, geometryScale, msdfgen::GlyphIndex(index), preprocessGeometry, loadCompositeGlyphs)) { | |
| addGlyph((GlyphGeometry &&) glyph); | |
| ++loaded; | |
| } | |
| @@ -90,14 +90,14 @@ int FontGeometry::loadGlyphset(msdfgen::FontHandle *font, double fontScale, cons | |
| return loaded; | |
| } | |
| -int FontGeometry::loadCharset(msdfgen::FontHandle *font, double fontScale, const Charset &charset, bool preprocessGeometry, bool enableKerning) { | |
| +int FontGeometry::loadCharset(msdfgen::FontHandle *font, double fontScale, const Charset &charset, bool preprocessGeometry, bool enableKerning, bool loadCompositeGlyphs) { | |
| if (!(glyphs->size() == rangeEnd && loadMetrics(font, fontScale))) | |
| return -1; | |
| glyphs->reserve(glyphs->size()+charset.size()); | |
| int loaded = 0; | |
| for (unicode_t cp : charset) { | |
| GlyphGeometry glyph; | |
| - if (glyph.load(font, geometryScale, cp, preprocessGeometry)) { | |
| + if (glyph.load(font, geometryScale, cp, preprocessGeometry, loadCompositeGlyphs)) { | |
| addGlyph((GlyphGeometry &&) glyph); | |
| ++loaded; | |
| } | |
| diff --git a/old/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.h b/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.h | |
| index 8dc758f..65d495e 100644 | |
| --- a/old/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.h | |
| +++ b/msdf-atlas-gen/msdf-atlas-gen/FontGeometry.h | |
| @@ -36,11 +36,11 @@ public: | |
| FontGeometry &operator=(FontGeometry &&orig); | |
| /// Loads the consecutive range of glyphs between rangeStart (inclusive) and rangeEnd (exclusive), returns the number of successfully loaded glyphs | |
| - int loadGlyphRange(msdfgen::FontHandle *font, double fontScale, unsigned rangeStart, unsigned rangeEnd, bool preprocessGeometry = true, bool enableKerning = true); | |
| + int loadGlyphRange(msdfgen::FontHandle *font, double fontScale, unsigned rangeStart, unsigned rangeEnd, bool preprocessGeometry = true, bool enableKerning = true, bool loadCompositeGlyphs = false); | |
| /// Loads all glyphs in a glyphset (Charset elements are glyph indices), returns the number of successfully loaded glyphs | |
| - int loadGlyphset(msdfgen::FontHandle *font, double fontScale, const Charset &glyphset, bool preprocessGeometry = true, bool enableKerning = true); | |
| + int loadGlyphset(msdfgen::FontHandle *font, double fontScale, const Charset &glyphset, bool preprocessGeometry = true, bool enableKerning = true, bool loadCompositeGlyphs = false); | |
| /// Loads all glyphs in a charset (Charset elements are Unicode codepoints), returns the number of successfully loaded glyphs | |
| - int loadCharset(msdfgen::FontHandle *font, double fontScale, const Charset &charset, bool preprocessGeometry = true, bool enableKerning = true); | |
| + int loadCharset(msdfgen::FontHandle *font, double fontScale, const Charset &charset, bool preprocessGeometry = true, bool enableKerning = true, bool loadCompositeGlyphs = false); | |
| /// Only loads font metrics and geometry scale from font | |
| bool loadMetrics(msdfgen::FontHandle *font, double fontScale); | |
| diff --git a/old/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.cpp b/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.cpp | |
| index 1e30df7..0988f37 100644 | |
| --- a/old/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.cpp | |
| +++ b/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.cpp | |
| @@ -8,38 +8,47 @@ namespace msdf_atlas { | |
| GlyphGeometry::GlyphGeometry() : index(), codepoint(), geometryScale(), bounds(), advance(), box() { } | |
| -bool GlyphGeometry::load(msdfgen::FontHandle *font, double geometryScale, msdfgen::GlyphIndex index, bool preprocessGeometry) { | |
| - if (font && msdfgen::loadGlyph(shape, font, index, msdfgen::FONT_SCALING_NONE, &advance) && shape.validate()) { | |
| - this->index = index.getIndex(); | |
| - this->geometryScale = geometryScale; | |
| - codepoint = 0; | |
| - advance *= geometryScale; | |
| - #ifdef MSDFGEN_USE_SKIA | |
| - if (preprocessGeometry) | |
| - msdfgen::resolveShapeGeometry(shape); | |
| - #endif | |
| - shape.normalize(); | |
| - bounds = shape.getBounds(); | |
| - #ifdef MSDFGEN_USE_SKIA | |
| - if (!preprocessGeometry) | |
| - #endif | |
| - { | |
| - // Determine if shape is winded incorrectly and reverse it in that case | |
| - msdfgen::Point2 outerPoint(bounds.l-(bounds.r-bounds.l)-1, bounds.b-(bounds.t-bounds.b)-1); | |
| - if (msdfgen::SimpleTrueShapeDistanceFinder::oneShotDistance(shape, outerPoint) > 0) { | |
| - for (msdfgen::Contour &contour : shape.contours) | |
| - contour.reverse(); | |
| - } | |
| +bool GlyphGeometry::load(msdfgen::FontHandle *font, double geometryScale, msdfgen::GlyphIndex index, bool preprocessGeometry, bool loadCompositeGlyphs) { | |
| + if (!font) | |
| + return false; | |
| + if (loadCompositeGlyphs) { | |
| + if (!msdfgen::loadCompositeGlyph(shape, font, index, msdfgen::FONT_SCALING_NONE, subGlyphs, &advance)) | |
| + return false; | |
| + } else { | |
| + if (!msdfgen::loadGlyph(shape, font, index, msdfgen::FONT_SCALING_NONE, &advance)) | |
| + return false; | |
| + } | |
| + if (!shape.validate()) | |
| + return false; | |
| + | |
| + this->index = index.getIndex(); | |
| + this->geometryScale = geometryScale; | |
| + codepoint = 0; | |
| + advance *= geometryScale; | |
| + #ifdef MSDFGEN_USE_SKIA | |
| + if (preprocessGeometry) | |
| + msdfgen::resolveShapeGeometry(shape); | |
| + #endif | |
| + shape.normalize(); | |
| + bounds = shape.getBounds(); | |
| + #ifdef MSDFGEN_USE_SKIA | |
| + if (!preprocessGeometry) | |
| + #endif | |
| + { | |
| + // Determine if shape is winded incorrectly and reverse it in that case | |
| + msdfgen::Point2 outerPoint(bounds.l-(bounds.r-bounds.l)-1, bounds.b-(bounds.t-bounds.b)-1); | |
| + if (msdfgen::SimpleTrueShapeDistanceFinder::oneShotDistance(shape, outerPoint) > 0) { | |
| + for (msdfgen::Contour &contour : shape.contours) | |
| + contour.reverse(); | |
| } | |
| - return true; | |
| } | |
| - return false; | |
| + return true; | |
| } | |
| -bool GlyphGeometry::load(msdfgen::FontHandle *font, double geometryScale, unicode_t codepoint, bool preprocessGeometry) { | |
| +bool GlyphGeometry::load(msdfgen::FontHandle *font, double geometryScale, unicode_t codepoint, bool preprocessGeometry, bool loadCompositeGlyphs) { | |
| msdfgen::GlyphIndex index; | |
| if (msdfgen::getGlyphIndex(index, font, codepoint)) { | |
| - if (load(font, geometryScale, index, preprocessGeometry)) { | |
| + if (load(font, geometryScale, index, preprocessGeometry, loadCompositeGlyphs)) { | |
| this->codepoint = codepoint; | |
| return true; | |
| } | |
| diff --git a/old/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.h b/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.h | |
| index 6e0c13a..2010d70 100644 | |
| --- a/old/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.h | |
| +++ b/msdf-atlas-gen/msdf-atlas-gen/GlyphGeometry.h | |
| @@ -24,8 +24,8 @@ public: | |
| GlyphGeometry(); | |
| /// Loads glyph geometry from font | |
| - bool load(msdfgen::FontHandle *font, double geometryScale, msdfgen::GlyphIndex index, bool preprocessGeometry = true); | |
| - bool load(msdfgen::FontHandle *font, double geometryScale, unicode_t codepoint, bool preprocessGeometry = true); | |
| + bool load(msdfgen::FontHandle *font, double geometryScale, msdfgen::GlyphIndex index, bool preprocessGeometry = true, bool loadCompositeGlyphs = false); | |
| + bool load(msdfgen::FontHandle *font, double geometryScale, unicode_t codepoint, bool preprocessGeometry = true, bool loadCompositeGlyphs = false); | |
| /// Applies edge coloring to glyph shape | |
| void edgeColoring(void (*fn)(msdfgen::Shape &, double, unsigned long long), double angleThreshold, unsigned long long seed); | |
| /// Computes the dimensions of the glyph's box as well as the transformation for the generator function | |
| @@ -79,6 +79,10 @@ public: | |
| /// Simplifies to GlyphBox | |
| operator GlyphBox() const; | |
| + /// Returns subGlyphs for composite glyphs | |
| + const std::vector<msdfgen::CompositeGlyphInfo> &getSubGlyphs() const { | |
| + return subGlyphs; | |
| + } | |
| private: | |
| int index; | |
| unicode_t codepoint; | |
| @@ -94,6 +98,8 @@ private: | |
| Padding outerPadding; | |
| } box; | |
| + std::vector<msdfgen::CompositeGlyphInfo> subGlyphs; | |
| + | |
| }; | |
| msdfgen::Range operator+(msdfgen::Range a, msdfgen::Range b); | |
| diff --git a/msdf-atlas-gen/msdfgen/core/GlyphInfo.h b/msdf-atlas-gen/msdfgen/core/GlyphInfo.h | |
| new file mode 100644 | |
| index 0000000..ee39ba8 | |
| --- /dev/null | |
| +++ b/msdf-atlas-gen/msdfgen/core/GlyphInfo.h | |
| @@ -0,0 +1,21 @@ | |
| +#pragma once | |
| + | |
| +#include "Vector2.hpp" | |
| + | |
| +namespace msdfgen { | |
| + class GlyphIndex { | |
| + public: | |
| + explicit GlyphIndex(unsigned index = 0); | |
| + unsigned getIndex() const; | |
| + | |
| + private: | |
| + unsigned index; | |
| + | |
| + }; | |
| + | |
| + struct CompositeGlyphInfo { | |
| + GlyphIndex glyphIndex; | |
| + Vector2 position; | |
| + double matrix[2][2] {{1, 0}, {0, 1}}; | |
| + }; | |
| +} | |
| diff --git a/old/msdf-atlas-gen/msdfgen/ext/import-font.cpp b/msdf-atlas-gen/msdfgen/ext/import-font.cpp | |
| index bbaf805..da94c4e 100644 | |
| --- a/old/msdf-atlas-gen/msdfgen/ext/import-font.cpp | |
| +++ b/msdf-atlas-gen/msdfgen/ext/import-font.cpp | |
| @@ -38,6 +38,7 @@ class FontHandle { | |
| friend bool getFontWhitespaceWidth(double &spaceAdvance, double &tabAdvance, FontHandle *font, FontCoordinateScaling coordinateScaling); | |
| friend bool getGlyphCount(unsigned &output, FontHandle *font); | |
| friend bool getGlyphIndex(GlyphIndex &glyphIndex, FontHandle *font, unicode_t unicode); | |
| + friend bool loadCompositeGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, FontCoordinateScaling coordinateScaling, std::vector<CompositeGlyphInfo> &outSubGlyphs, double *outAdvance); | |
| friend bool loadGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, FontCoordinateScaling coordinateScaling, double *outAdvance); | |
| friend bool loadGlyph(Shape &output, FontHandle *font, unicode_t unicode, FontCoordinateScaling coordinateScaling, double *outAdvance); | |
| friend bool getKerning(double &output, FontHandle *font, GlyphIndex glyphIndex0, GlyphIndex glyphIndex1, FontCoordinateScaling coordinateScaling); | |
| @@ -229,7 +230,7 @@ bool getGlyphIndex(GlyphIndex &glyphIndex, FontHandle *font, unicode_t unicode) | |
| bool loadGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, FontCoordinateScaling coordinateScaling, double *outAdvance) { | |
| if (!font) | |
| return false; | |
| - FT_Error error = FT_Load_Glyph(font->face, glyphIndex.getIndex(), FT_LOAD_NO_SCALE); | |
| + FT_Error error = FT_Load_Glyph(font->face, glyphIndex.getIndex(), FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM); | |
| if (error) | |
| return false; | |
| double scale = getFontCoordinateScale(font->face, coordinateScaling); | |
| @@ -238,6 +239,45 @@ bool loadGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, FontCoord | |
| return !readFreetypeOutline(output, &font->face->glyph->outline, scale); | |
| } | |
| +bool loadCompositeGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, FontCoordinateScaling coordinateScaling, std::vector<CompositeGlyphInfo> &outSubGlyphs, double *outAdvance) { | |
| + if (!font) | |
| + return false; | |
| + FT_Error error = FT_Load_Glyph(font->face, glyphIndex.getIndex(), FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM | FT_LOAD_NO_RECURSE); | |
| + if (error) | |
| + return false; | |
| + double scale = getFontCoordinateScale(font->face, coordinateScaling); | |
| + | |
| + if (outAdvance) | |
| + *outAdvance = scale*font->face->glyph->advance.x; | |
| + if (readFreetypeOutline(output, &font->face->glyph->outline, scale)) | |
| + return false; | |
| + | |
| + for (FT_UInt i = 0; i < font->face->glyph->num_subglyphs; i++) { | |
| + FT_Int index; | |
| + FT_UInt flags; | |
| + FT_Int arg1; | |
| + FT_Int arg2; | |
| + FT_Matrix matrix; | |
| + if (FT_Get_SubGlyph_Info(font->face->glyph, i, &index, &flags, &arg1, &arg2, &matrix)) | |
| + return false; | |
| + | |
| + if (flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES) { | |
| + CompositeGlyphInfo &info = outSubGlyphs.emplace_back(); | |
| + info.glyphIndex = GlyphIndex(index); | |
| + info.position = Vector2(F16DOT16_TO_DOUBLE(arg1), F16DOT16_TO_DOUBLE(arg2)) * scale; | |
| + info.matrix[0][0] = F16DOT16_TO_DOUBLE(matrix.xx) * scale; | |
| + info.matrix[0][1] = F16DOT16_TO_DOUBLE(matrix.xy) * scale; | |
| + info.matrix[1][0] = F16DOT16_TO_DOUBLE(matrix.yx) * scale; | |
| + info.matrix[1][1] = F16DOT16_TO_DOUBLE(matrix.yy) * scale; | |
| + } else { | |
| + // TODO: figure point snapping out | |
| + return false; | |
| + } | |
| + } | |
| + | |
| + return true; | |
| +} | |
| + | |
| bool loadGlyph(Shape &output, FontHandle *font, unicode_t unicode, FontCoordinateScaling coordinateScaling, double *outAdvance) { | |
| return loadGlyph(output, font, GlyphIndex(FT_Get_Char_Index(font->face, unicode)), coordinateScaling, outAdvance); | |
| } | |
| diff --git a/old/msdf-atlas-gen/msdfgen/ext/import-font.h b/msdf-atlas-gen/msdfgen/ext/import-font.h | |
| index c2bd81a..5c05808 100644 | |
| --- a/old/msdf-atlas-gen/msdfgen/ext/import-font.h | |
| +++ b/msdf-atlas-gen/msdfgen/ext/import-font.h | |
| @@ -2,6 +2,7 @@ | |
| #pragma once | |
| #include "../core/Shape.h" | |
| +#include "../core/GlyphInfo.h" | |
| namespace msdfgen { | |
| @@ -12,17 +13,6 @@ typedef unsigned unicode_t; | |
| class FreetypeHandle; | |
| class FontHandle; | |
| -class GlyphIndex { | |
| - | |
| -public: | |
| - explicit GlyphIndex(unsigned index = 0); | |
| - unsigned getIndex() const; | |
| - | |
| -private: | |
| - unsigned index; | |
| - | |
| -}; | |
| - | |
| /// Global metrics of a typeface (in font units). | |
| struct FontMetrics { | |
| /// The size of one EM. | |
| @@ -86,6 +76,8 @@ bool getGlyphIndex(GlyphIndex &glyphIndex, FontHandle *font, unicode_t unicode); | |
| /// Loads the geometry of a glyph from a font. | |
| bool loadGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, FontCoordinateScaling coordinateScaling, double *outAdvance = NULL); | |
| bool loadGlyph(Shape &output, FontHandle *font, unicode_t unicode, FontCoordinateScaling coordinateScaling, double *outAdvance = NULL); | |
| +/// Loads the geometry of a glyph from a font, loading every composite part separately. | |
| +bool loadCompositeGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, FontCoordinateScaling coordinateScaling, std::vector<CompositeGlyphInfo> &outSubGlyphs, double *outAdvance = NULL); | |
| // Legacy API - FontCoordinateScaling is LEGACY | |
| bool loadGlyph(Shape &output, FontHandle *font, GlyphIndex glyphIndex, double *outAdvance = NULL); | |
| bool loadGlyph(Shape &output, FontHandle *font, unicode_t unicode, double *outAdvance = NULL); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment