diff options
author | Seigo Nonaka <nona@google.com> | 2023-05-25 19:45:14 +0900 |
---|---|---|
committer | Seigo Nonaka <nona@google.com> | 2023-05-26 17:52:37 +0900 |
commit | 84095b265c788323ea997518fdba9606b6709ca9 (patch) | |
tree | 78af77bf5bbecba45dd4f4de1617dbdf8108a125 /libs/minikin | |
parent | 8f0f791cf4b08c3ef950856d5d2ac20330d8a4ca (diff) | |
download | minikin-84095b265c788323ea997518fdba9606b6709ca9.tar.gz |
Support variable font family
A variable font family adjust wght and ital axis based on request.
Bug: 281769620
Test: minikin_tests
Change-Id: I1ed6a780eec9d1404449fdd4289913a02ef0c8e5
Diffstat (limited to 'libs/minikin')
-rw-r--r-- | libs/minikin/FontFamily.cpp | 35 | ||||
-rw-r--r-- | libs/minikin/LayoutCore.cpp | 11 |
2 files changed, 35 insertions, 11 deletions
diff --git a/libs/minikin/FontFamily.cpp b/libs/minikin/FontFamily.cpp index 09d2281..e6da84e 100644 --- a/libs/minikin/FontFamily.cpp +++ b/libs/minikin/FontFamily.cpp @@ -45,21 +45,23 @@ std::shared_ptr<FontFamily> FontFamily::create(std::vector<std::shared_ptr<Font> std::shared_ptr<FontFamily> FontFamily::create(FamilyVariant variant, std::vector<std::shared_ptr<Font>>&& fonts) { return create(kEmptyLocaleListId, variant, std::move(fonts), false /* isCustomFallback */, - false /* isDefaultFallback */); + false /* isDefaultFallback */, VariationFamilyType::None); } // static std::shared_ptr<FontFamily> FontFamily::create(uint32_t localeListId, FamilyVariant variant, std::vector<std::shared_ptr<Font>>&& fonts, - bool isCustomFallback, bool isDefaultFallback) { + bool isCustomFallback, bool isDefaultFallback, + VariationFamilyType varFamilyType) { // TODO(b/174672300): Revert back to make_shared. return std::shared_ptr<FontFamily>(new FontFamily(localeListId, variant, std::move(fonts), - isCustomFallback, isDefaultFallback)); + isCustomFallback, isDefaultFallback, + varFamilyType)); } FontFamily::FontFamily(uint32_t localeListId, FamilyVariant variant, std::vector<std::shared_ptr<Font>>&& fonts, bool isCustomFallback, - bool isDefaultFallback) + bool isDefaultFallback, VariationFamilyType varFamilyType) : mFonts(std::make_unique<std::shared_ptr<Font>[]>(fonts.size())), // computeCoverage may update supported axes and coverages later. mSupportedAxes(nullptr), @@ -73,7 +75,8 @@ FontFamily::FontFamily(uint32_t localeListId, FamilyVariant variant, mIsColorEmoji(LocaleListCache::getById(localeListId).getEmojiStyle() == EmojiStyle::EMOJI), mIsCustomFallback(isCustomFallback), - mIsDefaultFallback(isDefaultFallback) { + mIsDefaultFallback(isDefaultFallback), + mVarFamilyType(varFamilyType) { MINIKIN_ASSERT(!fonts.empty(), "FontFamily must contain at least one font."); MINIKIN_ASSERT(fonts.size() <= std::numeric_limits<uint32_t>::max(), "Number of fonts must be less than 2^32."); @@ -108,6 +111,7 @@ FontFamily::FontFamily(BufferReader* reader, const std::shared_ptr<std::vector<F mIsColorEmoji = static_cast<bool>(reader->read<uint8_t>()); mIsCustomFallback = static_cast<bool>(reader->read<uint8_t>()); mIsDefaultFallback = static_cast<bool>(reader->read<uint8_t>()); + mVarFamilyType = reader->read<VariationFamilyType>(); mCoverage = SparseBitSet(reader); // Read mCmapFmt14Coverage. As it can have null entries, it is stored in the buffer as a sparse // array (size, non-null entry count, array of (index, entry)). @@ -134,6 +138,7 @@ void FontFamily::writeTo(BufferWriter* writer, uint32_t* fontIndex) const { writer->write<uint8_t>(mIsColorEmoji); writer->write<uint8_t>(mIsCustomFallback); writer->write<uint8_t>(mIsDefaultFallback); + writer->write<VariationFamilyType>(mVarFamilyType); mCoverage.writeTo(writer); // Write mCmapFmt14Coverage as a sparse array (size, non-null entry count, // array of (index, entry)) @@ -224,6 +229,9 @@ static FontFakery computeFakery(FontStyle wanted, FontStyle actual) { } FakedFont FontFamily::getClosestMatch(FontStyle style) const { + if (mVarFamilyType != VariationFamilyType::None) { + return getVariationFamilyAdjustment(style); + } int bestIndex = 0; Font* bestFont = mFonts[bestIndex].get(); int bestMatch = computeMatch(bestFont->style(), style); @@ -239,6 +247,20 @@ FakedFont FontFamily::getClosestMatch(FontStyle style) const { return FakedFont{mFonts[bestIndex], computeFakery(style, bestFont->style())}; } +FakedFont FontFamily::getVariationFamilyAdjustment(FontStyle style) const { + const bool italic = style.slant() == FontStyle::Slant::ITALIC; + switch (mVarFamilyType) { + case VariationFamilyType::SingleFont_wghtOnly: + return FakedFont{mFonts[0], FontFakery(false, italic, style.weight(), -1)}; + case VariationFamilyType::SingleFont_wght_ital: + return FakedFont{mFonts[0], FontFakery(false, false, style.weight(), italic ? 1 : 0)}; + case VariationFamilyType::TwoFont_wght: + return FakedFont{mFonts[italic ? 1 : 0], FontFakery(false, false, style.weight(), -1)}; + case VariationFamilyType::None: + return FakedFont{mFonts[0], FontFakery()}; + } +} + void FontFamily::computeCoverage() { const std::shared_ptr<Font>& font = getClosestMatch(FontStyle()).font; HbBlob cmapTable(font->baseFont(), MakeTag('c', 'm', 'a', 'p')); @@ -343,7 +365,8 @@ std::shared_ptr<FontFamily> FontFamily::createFamilyWithVariation( } } - return create(mLocaleListId, mVariant, std::move(fonts), mIsCustomFallback, mIsDefaultFallback); + return create(mLocaleListId, mVariant, std::move(fonts), mIsCustomFallback, mIsDefaultFallback, + VariationFamilyType::None); } } // namespace minikin diff --git a/libs/minikin/LayoutCore.cpp b/libs/minikin/LayoutCore.cpp index 901397d..edebd29 100644 --- a/libs/minikin/LayoutCore.cpp +++ b/libs/minikin/LayoutCore.cpp @@ -349,7 +349,7 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool double size = paint.size; double scaleX = paint.scaleX; - std::unordered_map<const Font*, uint32_t> fontMap; + std::unordered_map<const MinikinFont*, uint32_t> fontMap; float x = 0; float y = 0; @@ -358,16 +358,17 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool isRtl ? --run_ix : ++run_ix) { FontCollection::Run& run = items[run_ix]; FakedFont fakedFont = paint.font->getBestFont(substr, run, paint.fontStyle); - auto it = fontMap.find(fakedFont.font.get()); + const std::shared_ptr<MinikinFont>& typeface = fakedFont.typeface(); + auto it = fontMap.find(typeface.get()); uint8_t font_ix; if (it == fontMap.end()) { // First time to see this font. font_ix = mFonts.size(); mFonts.push_back(fakedFont); - fontMap.insert(std::make_pair(fakedFont.font.get(), font_ix)); + fontMap.insert(std::make_pair(typeface.get(), font_ix)); // We override some functions which are not thread safe. - HbFontUniquePtr font(hb_font_create_sub_font(fakedFont.font->baseFont().get())); + HbFontUniquePtr font(hb_font_create_sub_font(fakedFont.hbFont().get())); hb_font_set_funcs( font.get(), isColorBitmapFont(font) ? getFontFuncsForEmoji() : getFontFuncs(), new SkiaArguments({fakedFont.typeface().get(), &paint, fakedFont.fakery}), @@ -387,7 +388,7 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool } if (needExtent) { MinikinExtent verticalExtent; - fakedFont.typeface()->GetFontExtent(&verticalExtent, paint, fakedFont.fakery); + typeface->GetFontExtent(&verticalExtent, paint, fakedFont.fakery); mExtent.extendBy(verticalExtent); } |