提交 919a4892 编写于 作者: T TreeHugger Robot 提交者: Android (Google) Code Review

Merge "Serialize and deserialize supported axes."

......@@ -110,10 +110,8 @@ struct Font {
std::shared_ptr<MinikinFont> typeface;
FontStyle style;
std::unordered_set<AxisTag> supportedAxes;
private:
void loadAxes();
std::unordered_set<AxisTag> getSupportedAxesLocked() const;
};
struct FontVariation {
......@@ -181,6 +179,12 @@ private:
void computeCoverage();
void readAcceleratorTable(const uint8_t* data, size_t size);
size_t writeSupportedAxes(uint8_t* out) const;
// Reads supported axes values from 'in' buffer. This method reads up to
// 'inSize' bytes and returns the number of bytes read.
size_t readSupportedAxes(const uint8_t* in, size_t inSize);
uint32_t mLangId;
int mVariant;
std::vector<Font> mFonts;
......
......@@ -67,36 +67,33 @@ uint32_t FontStyle::pack(int variant, int weight, bool italic) {
Font::Font(const std::shared_ptr<MinikinFont>& typeface, FontStyle style)
: typeface(typeface), style(style) {
loadAxes();
}
Font::Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style)
: typeface(typeface), style(style) {
loadAxes();
}
void Font::loadAxes() {
android::AutoMutex _l(gMinikinLock);
std::unordered_set<AxisTag> Font::getSupportedAxesLocked() const {
const uint32_t fvarTag = MinikinFont::MakeTag('f', 'v', 'a', 'r');
HbBlob fvarTable(getFontTable(typeface.get(), fvarTag));
if (fvarTable.size() == 0) {
return;
return std::unordered_set<AxisTag>();
}
std::unordered_set<AxisTag> supportedAxes;
analyzeAxes(fvarTable.get(), fvarTable.size(), &supportedAxes);
return supportedAxes;
}
Font::Font(Font&& o) {
typeface = std::move(o.typeface);
style = o.style;
o.typeface = nullptr;
supportedAxes = std::move(o.supportedAxes);
}
Font::Font(const Font& o) {
typeface = o.typeface;
style = o.style;
supportedAxes = o.supportedAxes;
}
// static
......@@ -201,7 +198,8 @@ void FontFamily::computeCoverage() {
CmapCoverage::getCoverage(mCoverage, cmapTable.get(), cmapTable.size(), &mHasVSTable);
for (size_t i = 0; i < mFonts.size(); ++i) {
mSupportedAxes.insert(mFonts[i].supportedAxes.begin(), mFonts[i].supportedAxes.end());
std::unordered_set<AxisTag> supportedAxes = mFonts[i].getSupportedAxesLocked();
mSupportedAxes.insert(supportedAxes.begin(), supportedAxes.end());
}
}
......@@ -242,9 +240,11 @@ std::shared_ptr<FontFamily> FontFamily::createFamilyWithVariation(
std::vector<Font> fonts;
for (const Font& font : mFonts) {
bool supportedVariations = false;
if (!font.supportedAxes.empty()) {
android::AutoMutex _l(gMinikinLock);
std::unordered_set<AxisTag> supportedAxes = font.getSupportedAxesLocked();
if (!supportedAxes.empty()) {
for (const FontVariation& variation : variations) {
if (font.supportedAxes.find(variation.axisTag) != font.supportedAxes.end()) {
if (supportedAxes.find(variation.axisTag) != supportedAxes.end()) {
supportedVariations = true;
break;
}
......@@ -264,11 +264,46 @@ std::shared_ptr<FontFamily> FontFamily::createFamilyWithVariation(
}
size_t FontFamily::writeAcceleratorTable(uint8_t* out) const {
return mCoverage.writeToBuffer(out);
const size_t axesTableSize = writeSupportedAxes(out);
if (out != nullptr) {
out += axesTableSize;
}
const size_t coverageTableSize = mCoverage.writeToBuffer(out);
return axesTableSize + coverageTableSize;
}
void FontFamily::readAcceleratorTable(const uint8_t* data, size_t size) {
const size_t readSize = readSupportedAxes(data, size);
data += readSize;
size -= readSize;
bool result = mCoverage.initFromBuffer(data, size);
LOG_ALWAYS_FATAL_IF(!result, "Failed to reconstruct accelerator table from buffer");
}
size_t FontFamily::writeSupportedAxes(uint8_t* out) const {
LOG_ALWAYS_FATAL_IF(mSupportedAxes.size() > 255, "System fonts may only use up to 255 axes.");
const uint8_t axesCount = static_cast<uint8_t>(mSupportedAxes.size());
if (out != nullptr) {
out[0] = axesCount;
AxisTag* axisTags = reinterpret_cast<AxisTag*>(out + 1);
for (const auto& tag : mSupportedAxes) {
*axisTags++ = tag;
}
}
const size_t axesSizeInbytes = sizeof(AxisTag) * axesCount;
return axesSizeInbytes + 1 /* 1 for axes count */;
}
size_t FontFamily::readSupportedAxes(const uint8_t* in, size_t inSize) {
LOG_ALWAYS_FATAL_IF(inSize == 0);
const uint8_t axesCount = in[0];
const size_t totalSize = sizeof(AxisTag) * axesCount + 1 /* 1 for axes Count */;
LOG_ALWAYS_FATAL_IF(inSize < totalSize);
const AxisTag* axisTags = reinterpret_cast<const AxisTag*>(in + 1);
mSupportedAxes.clear();
for (uint8_t i = 0; i < axesCount; ++i) {
mSupportedAxes.insert(axisTags[i]);
}
return totalSize;
}
} // namespace minikin
......@@ -656,4 +656,50 @@ TEST_F(FontFamilyTest, createFamilyWithVariationTest) {
}
}
TEST_F(FontFamilyTest, supportedAxesRestoreFromSerializedBuffer) {
const char kFontPath[] = kTestFontDir "/MultiAxis.ttf";
std::shared_ptr<MinikinFont> font(new MinikinFontForTest(kFontPath));
std::shared_ptr<FontFamily> family =
std::make_shared<FontFamily>(std::vector<Font>({Font(font, FontStyle())}));
size_t necessaryBytes = family->writeAcceleratorTable(nullptr);
ASSERT_NE(0U, necessaryBytes);
std::vector<uint8_t> buffer;
buffer.resize(necessaryBytes);
family->writeAcceleratorTable(buffer.data());
std::shared_ptr<FontFamily> restoredMultiAxisFamily =
std::make_shared<FontFamily>(std::vector<Font>({Font(font, FontStyle())}),
buffer.data(), buffer.size());
// This font has 'wdth' and 'wght' axes.
const std::unordered_set<AxisTag>& supportedAxes = family->supportedAxes();
ASSERT_EQ(2U, supportedAxes.size());
EXPECT_NE(supportedAxes.end(), supportedAxes.find(MinikinFont::MakeTag('w', 'd', 't', 'h')));
EXPECT_NE(supportedAxes.end(), supportedAxes.find(MinikinFont::MakeTag('w', 'g', 'h', 't')));
}
TEST_F(FontFamilyTest, supportedAxesRestoreFromSerializedBuffer_NoAxisFont) {
const char kFontPath[] = kTestFontDir "/Regular.ttf";
std::shared_ptr<MinikinFont> font(new MinikinFontForTest(kFontPath));
std::shared_ptr<FontFamily> family =
std::make_shared<FontFamily>(std::vector<Font>({Font(font, FontStyle())}));
size_t necessaryBytes = family->writeAcceleratorTable(nullptr);
ASSERT_NE(0U, necessaryBytes);
std::vector<uint8_t> buffer;
buffer.resize(necessaryBytes);
family->writeAcceleratorTable(buffer.data());
std::shared_ptr<FontFamily> restoredMultiAxisFamily =
std::make_shared<FontFamily>(std::vector<Font>({Font(font, FontStyle())}),
buffer.data(), buffer.size());
// This font supports no axes.
const std::unordered_set<AxisTag>& supportedAxes = family->supportedAxes();
EXPECT_TRUE(supportedAxes.empty());
}
} // namespace minikin
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册