summaryrefslogtreecommitdiff
path: root/libs/minikin
diff options
context:
space:
mode:
authorSeigo Nonaka <nona@google.com>2023-05-25 19:45:14 +0900
committerSeigo Nonaka <nona@google.com>2023-05-26 17:52:37 +0900
commit84095b265c788323ea997518fdba9606b6709ca9 (patch)
tree78af77bf5bbecba45dd4f4de1617dbdf8108a125 /libs/minikin
parent8f0f791cf4b08c3ef950856d5d2ac20330d8a4ca (diff)
downloadminikin-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.cpp35
-rw-r--r--libs/minikin/LayoutCore.cpp11
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);
}