-
Notifications
You must be signed in to change notification settings - Fork 17
Check the presence of glyphs when selecting font #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
f476d81
789e8e3
3ca988a
68a339a
0e72dee
dfc0d61
48d9fa3
258183b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -509,7 +509,9 @@ void FontCollection::itemize(const uint16_t* string, | |
| if (!shouldContinueRun) { | ||
| const std::shared_ptr<FontFamily>& family = getFamilyForChar( | ||
| ch, isVariationSelector(nextCh) ? nextCh : 0, langListId, variant); | ||
| if (utf16Pos == 0 || family.get() != lastFamily) { | ||
|
|
||
| if (utf16Pos == 0 || family.get() != lastFamily || | ||
| family.get()->getLastMatchedCodePoint() != ch) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This algorithm tries to reuse the already selected font as much as possible.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're right. Maybe I should use map for this. |
||
| size_t start = utf16Pos; | ||
| // Workaround for combining marks and emoji modifiers until we implement | ||
| // per-cluster font selection: if a combining mark or an emoji modifier | ||
|
|
@@ -528,8 +530,8 @@ void FontCollection::itemize(const uint16_t* string, | |
| } | ||
| start -= prevChLength; | ||
| } | ||
| result->push_back( | ||
| {family->getClosestMatch(style), static_cast<int>(start), 0}); | ||
| result->push_back({family->getClosestMatchWithChar(style, ch), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we also use variant to check glyphs? result = hb_font_get_glyph(hb_font, codepoint, variant, &unusedGlyph);
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't know about |
||
| static_cast<int>(start), 0}); | ||
| run = &result->back(); | ||
| lastFamily = family.get(); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -164,6 +164,46 @@ FakedFont FontFamily::getClosestMatch(FontStyle style) const { | |
| return FakedFont{nullptr, FontFakery()}; | ||
| } | ||
|
|
||
| FakedFont FontFamily::getClosestMatchWithChar(FontStyle style, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The core algorithm is similar to
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok~ Thanks! |
||
| uint32_t codepoint) { | ||
| int bestMatch = INT_MAX; | ||
| const Font* bestFont = nullptr; | ||
| if (mLastMatchedCodePoint == codepoint && style == mLastMatchedFontStyle) { | ||
| if (mFonts.size() > mLastMatchedFontIndex) { | ||
| bestFont = &mFonts[mLastMatchedFontIndex]; | ||
| return FakedFont{bestFont->typeface.get(), | ||
| computeFakery(style, bestFont->style)}; | ||
| } | ||
| } | ||
|
|
||
| for (size_t i = 0; i < mFonts.size(); i++) { | ||
| const Font& font = mFonts[i]; | ||
| int match = computeMatch(font.style, style); | ||
| bool result = false; | ||
| { | ||
| hb_font_t* hb_font = getHbFontLocked(font.typeface.get()); | ||
| uint32_t unusedGlyph; | ||
|
bwikbs marked this conversation as resolved.
Outdated
|
||
| result = hb_font_get_glyph(hb_font, codepoint, 0, &unusedGlyph); | ||
| hb_font_destroy(hb_font); | ||
| } | ||
|
|
||
| if (result) { | ||
| if (match < bestMatch) { | ||
| bestFont = &font; | ||
| bestMatch = match; | ||
| mLastMatchedFontIndex = i; | ||
| } | ||
| } | ||
| } | ||
| if (bestFont != nullptr) { | ||
| mLastMatchedFontStyle = style; | ||
| mLastMatchedCodePoint = codepoint; | ||
| return FakedFont{bestFont->typeface.get(), | ||
| computeFakery(style, bestFont->style)}; | ||
| } | ||
| return FakedFont{nullptr, FontFakery()}; | ||
| } | ||
|
|
||
| bool FontFamily::isColorEmojiFamily() const { | ||
| const FontLanguages& languageList = FontLanguageListCache::getById(mLangId); | ||
| for (size_t i = 0; i < languageList.size(); ++i) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.