提交 fc119c68 编写于 作者: S Seigo Nonaka

Search all families instead of using mRanges for variation sequence.

To optimize the font family search, mRanges is used for narrowing down
the search range. However, mRanges is constructed from format 4 or
format 12 entries. So, if the font supports a variation sequence but doesn't
support the base character of the sequence, the font may not be listed in
mRanges.

The proper way to fix this issue is using format 14 subtable information
for mRanges construction. However, this is not a trivial work since currently
we rely on HarfBuzz for variation sequence lookup and it doesn't provide any
API for retrieving coverage information.

Thus, as the quick fix, iterate all font families in font fallback chain if
the variation sequence is specified.

Change-Id: I278da84be8fb8f553590e2e42ed450b7e4a34eca
上级 3dd8757f
......@@ -108,14 +108,25 @@ FontFamily* FontCollection::getFamilyForChar(uint32_t ch, uint32_t vs,
if (ch >= mMaxChar) {
return NULL;
}
const Range& range = mRanges[ch >> kLogCharsPerPage];
// Even if the font supports variation sequence, mRanges isn't aware of the base character of
// the sequence. Search all FontFamilies if variation sequence is specified.
// TODO: Always use mRanges for font search.
const std::vector<FontFamily*>& familyVec = (vs == 0) ? mFamilyVec : mFamilies;
Range range;
if (vs == 0) {
range = mRanges[ch >> kLogCharsPerPage];
} else {
range = { 0, mFamilies.size() };
}
#ifdef VERBOSE_DEBUG
ALOGD("querying range %zd:%zd\n", range.start, range.end);
#endif
FontFamily* bestFamily = nullptr;
int bestScore = -1;
for (size_t i = range.start; i < range.end; i++) {
FontFamily* family = mFamilyVec[i];
FontFamily* family = familyVec[i];
if (vs == 0 ? family->getCoverage()->get(ch) : family->hasVariationSelector(ch, vs)) {
// First font family in collection always matches
if (mFamilies[0] == family) {
......
......@@ -21,6 +21,7 @@
#include "UnicodeUtils.h"
using android::FontCollection;
using android::FontFamily;
using android::FontLanguage;
using android::FontStyle;
......@@ -614,3 +615,31 @@ TEST(FontCollectionItemizeTest, itemize_fakery) {
EXPECT_TRUE(runs[0].fakedFont.fakery.isFakeItalic());
}
TEST(FontCollectionItemizeTest, itemize_vs_sequence_but_no_base_char) {
// kVSTestFont supports U+717D U+FE02 but doesn't support U+717D.
// kVSTestFont should be selected for U+717D U+FE02 even if it does not support the base code
// point.
const std::string kVSTestFont = kTestFontDir "VarioationSelectorTest-Regular.ttf";
std::vector<android::FontFamily*> families;
FontFamily* family1 = new FontFamily(FontLanguage(), android::VARIANT_DEFAULT);
family1->addFont(new MinikinFontForTest(kLatinFont));
families.push_back(family1);
FontFamily* family2 = new FontFamily(FontLanguage(), android::VARIANT_DEFAULT);
family2->addFont(new MinikinFontForTest(kVSTestFont));
families.push_back(family2);
FontCollection collection(families);
std::vector<FontCollection::Run> runs;
itemize(&collection, "U+717D U+FE02", FontStyle(), &runs);
ASSERT_EQ(1U, runs.size());
EXPECT_EQ(0, runs[0].start);
EXPECT_EQ(2, runs[0].end);
EXPECT_EQ(kVSTestFont, getFontPath(runs[0]));
family1->Unref();
family2->Unref();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册