summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/minikin/MinikinFont.h28
-rw-r--r--include/minikin/MinikinFontFreeType.h6
-rw-r--r--include/minikin/MinikinRefCounted.h17
-rw-r--r--libs/minikin/FontFamily.cpp25
-rw-r--r--libs/minikin/HbFontCache.cpp51
-rw-r--r--libs/minikin/HbFontCache.h2
-rw-r--r--libs/minikin/Layout.cpp1
-rw-r--r--libs/minikin/MinikinFont.cpp2
-rw-r--r--libs/minikin/MinikinFontFreeType.cpp36
-rw-r--r--libs/minikin/MinikinInternal.cpp10
-rw-r--r--libs/minikin/MinikinInternal.h33
-rw-r--r--sample/MinikinSkia.cpp27
-rw-r--r--sample/MinikinSkia.h5
-rw-r--r--tests/FontFamilyTest.cpp37
-rw-r--r--tests/MinikinFontForTest.cpp36
-rw-r--r--tests/MinikinFontForTest.h4
-rw-r--r--tests/how_to_run.txt2
17 files changed, 206 insertions, 116 deletions
diff --git a/include/minikin/MinikinFont.h b/include/minikin/MinikinFont.h
index 5c0ab0f..4951514 100644
--- a/include/minikin/MinikinFont.h
+++ b/include/minikin/MinikinFont.h
@@ -94,8 +94,13 @@ struct MinikinRect {
class MinikinFontFreeType;
+// Callback for freeing data
+typedef void (*MinikinDestroyFunc) (void* data);
+
class MinikinFont : public MinikinRefCounted {
public:
+ MinikinFont(int32_t uniqueId) : mUniqueId(uniqueId) {}
+
virtual ~MinikinFont();
virtual float GetHorizontalAdvance(uint32_t glyph_id,
@@ -104,15 +109,32 @@ public:
virtual void GetBounds(MinikinRect* bounds, uint32_t glyph_id,
const MinikinPaint &paint) const = 0;
- // If buf is NULL, just update size
- virtual bool GetTable(uint32_t tag, uint8_t *buf, size_t *size) = 0;
+ virtual const void* GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) = 0;
- virtual int32_t GetUniqueId() const = 0;
+ // Override if font can provide access to raw data
+ virtual const void* GetFontData() const {
+ return nullptr;
+ }
+
+ // Override if font can provide access to raw data
+ virtual size_t GetFontSize() const {
+ return 0;
+ }
+
+ // Override if font can provide access to raw data.
+ // Returns index within OpenType collection
+ virtual int GetFontIndex() const {
+ return 0;
+ }
static uint32_t MakeTag(char c1, char c2, char c3, char c4) {
return ((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) |
((uint32_t)c3 << 8) | (uint32_t)c4;
}
+
+ int32_t GetUniqueId() const { return mUniqueId; }
+private:
+ const int32_t mUniqueId;
};
} // namespace android
diff --git a/include/minikin/MinikinFontFreeType.h b/include/minikin/MinikinFontFreeType.h
index a957d12..baa08df 100644
--- a/include/minikin/MinikinFontFreeType.h
+++ b/include/minikin/MinikinFontFreeType.h
@@ -48,10 +48,9 @@ public:
void GetBounds(MinikinRect* bounds, uint32_t glyph_id,
const MinikinPaint& paint) const;
- // If buf is NULL, just update size
- bool GetTable(uint32_t tag, uint8_t *buf, size_t *size);
+ const void* GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy);
- int32_t GetUniqueId() const;
+ // TODO: provide access to raw data, as an optimization.
// Not a virtual method, as the protocol to access rendered
// glyph bitmaps is probably different depending on the
@@ -63,7 +62,6 @@ public:
private:
FT_Face mTypeface;
- int32_t mUniqueId;
static int32_t sIdCounter;
};
diff --git a/include/minikin/MinikinRefCounted.h b/include/minikin/MinikinRefCounted.h
index 74d27fe..603aff0 100644
--- a/include/minikin/MinikinRefCounted.h
+++ b/include/minikin/MinikinRefCounted.h
@@ -37,6 +37,23 @@ private:
int mRefcount_;
};
+// An RAII container for reference counted objects.
+// Note: this is only suitable for clients which are _not_ holding the global lock.
+template <typename T>
+class MinikinAutoUnref {
+public:
+ MinikinAutoUnref(T* obj) : mObj(obj) {
+ }
+ ~MinikinAutoUnref() {
+ mObj->Unref();
+ }
+ T& operator*() const { return *mObj; }
+ T* operator->() const { return mObj; }
+ T* get() const { return mObj; }
+private:
+ T* mObj;
+};
+
}
#endif // MINIKIN_REF_COUNTED_H \ No newline at end of file
diff --git a/libs/minikin/FontFamily.cpp b/libs/minikin/FontFamily.cpp
index 88448a1..0f71f51 100644
--- a/libs/minikin/FontFamily.cpp
+++ b/libs/minikin/FontFamily.cpp
@@ -77,15 +77,11 @@ FontFamily::~FontFamily() {
bool FontFamily::addFont(MinikinFont* typeface) {
AutoMutex _l(gMinikinLock);
const uint32_t os2Tag = MinikinFont::MakeTag('O', 'S', '/', '2');
- size_t os2Size = 0;
- bool ok = typeface->GetTable(os2Tag, NULL, &os2Size);
- if (!ok) return false;
- UniquePtr<uint8_t[]> os2Data(new uint8_t[os2Size]);
- ok = typeface->GetTable(os2Tag, os2Data.get(), &os2Size);
- if (!ok) return false;
+ HbBlob os2Table(getFontTable(typeface, os2Tag));
+ if (os2Table.get() == nullptr) return false;
int weight;
bool italic;
- if (analyzeStyle(os2Data.get(), os2Size, &weight, &italic)) {
+ if (analyzeStyle(os2Table.get(), os2Table.size(), &weight, &italic)) {
//ALOGD("analyzed weight = %d, italic = %s", weight, italic ? "true" : "false");
FontStyle style(weight, italic);
addFontLocked(typeface, style);
@@ -165,20 +161,15 @@ const SparseBitSet* FontFamily::getCoverage() {
const FontStyle defaultStyle;
MinikinFont* typeface = getClosestMatch(defaultStyle).font;
const uint32_t cmapTag = MinikinFont::MakeTag('c', 'm', 'a', 'p');
- size_t cmapSize = 0;
- if (!typeface->GetTable(cmapTag, NULL, &cmapSize)) {
+ HbBlob cmapTable(getFontTable(typeface, cmapTag));
+ if (cmapTable.get() == nullptr) {
ALOGE("Could not get cmap table size!\n");
// Note: This means we will retry on the next call to getCoverage, as we can't store
// the failure. This is fine, as we assume this doesn't really happen in practice.
return nullptr;
}
- UniquePtr<uint8_t[]> cmapData(new uint8_t[cmapSize]);
- if (!typeface->GetTable(cmapTag, cmapData.get(), &cmapSize)) {
- ALOGE("Unexpected failure to read cmap table!\n");
- return nullptr;
- }
// TODO: Error check?
- CmapCoverage::getCoverage(mCoverage, cmapData.get(), cmapSize, &mHasVSTable);
+ CmapCoverage::getCoverage(mCoverage, cmapTable.get(), cmapTable.size(), &mHasVSTable);
#ifdef VERBOSE_DEBUG
ALOGD("font coverage length=%d, first ch=%x\n", mCoverage.length(),
mCoverage.nextSetBit(0));
@@ -198,7 +189,9 @@ bool FontFamily::hasVariationSelector(uint32_t codepoint, uint32_t variationSele
MinikinFont* minikinFont = getClosestMatch(defaultStyle).font;
hb_font_t* font = getHbFontLocked(minikinFont);
uint32_t unusedGlyph;
- return hb_font_get_glyph(font, codepoint, variationSelector, &unusedGlyph);
+ bool result = hb_font_get_glyph(font, codepoint, variationSelector, &unusedGlyph);
+ hb_font_destroy(font);
+ return result;
}
bool FontFamily::hasVSTable() const {
diff --git a/libs/minikin/HbFontCache.cpp b/libs/minikin/HbFontCache.cpp
index 7a6b3c1..3be942d 100644
--- a/libs/minikin/HbFontCache.cpp
+++ b/libs/minikin/HbFontCache.cpp
@@ -30,26 +30,18 @@ namespace android {
static hb_blob_t* referenceTable(hb_face_t* /* face */, hb_tag_t tag, void* userData) {
MinikinFont* font = reinterpret_cast<MinikinFont*>(userData);
- size_t length = 0;
- bool ok = font->GetTable(tag, NULL, &length);
- if (!ok) {
- return 0;
+ MinikinDestroyFunc destroy = 0;
+ size_t size = 0;
+ const void* buffer = font->GetTable(tag, &size, &destroy);
+ if (buffer == nullptr) {
+ return nullptr;
}
- char* buffer = reinterpret_cast<char*>(malloc(length));
- if (!buffer) {
- return 0;
- }
- ok = font->GetTable(tag, reinterpret_cast<uint8_t*>(buffer), &length);
#ifdef VERBOSE_DEBUG
- ALOGD("referenceTable %c%c%c%c length=%zd %d",
- (tag >>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, length, ok);
+ ALOGD("referenceTable %c%c%c%c length=%zd",
+ (tag >>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, size);
#endif
- if (!ok) {
- free(buffer);
- return 0;
- }
- return hb_blob_create(const_cast<char*>(buffer), length,
- HB_MEMORY_MODE_WRITABLE, buffer, free);
+ return hb_blob_create(reinterpret_cast<const char*>(buffer), size,
+ HB_MEMORY_MODE_READONLY, const_cast<void*>(buffer), destroy);
}
class HbFontCache : private OnEntryRemoved<int32_t, hb_font_t*> {
@@ -99,30 +91,43 @@ void purgeHbFontCacheLocked() {
getFontCacheLocked()->clear();
}
-void purgeHbFont(const MinikinFont* minikinFont) {
- AutoMutex _l(gMinikinLock);
+void purgeHbFontLocked(const MinikinFont* minikinFont) {
+ assertMinikinLocked();
const int32_t fontId = minikinFont->GetUniqueId();
getFontCacheLocked()->remove(fontId);
}
+// Returns a new reference to a hb_font_t object, caller is
+// responsible for calling hb_font_destroy() on it.
hb_font_t* getHbFontLocked(MinikinFont* minikinFont) {
assertMinikinLocked();
+ // TODO: get rid of nullFaceFont
static hb_font_t* nullFaceFont = nullptr;
if (minikinFont == nullptr) {
if (nullFaceFont == nullptr) {
nullFaceFont = hb_font_create(nullptr);
}
- return nullFaceFont;
+ return hb_font_reference(nullFaceFont);
}
HbFontCache* fontCache = getFontCacheLocked();
const int32_t fontId = minikinFont->GetUniqueId();
hb_font_t* font = fontCache->get(fontId);
if (font != nullptr) {
- return font;
+ return hb_font_reference(font);
}
- hb_face_t* face = hb_face_create_for_tables(referenceTable, minikinFont, nullptr);
+ hb_face_t* face;
+ const void* buf = minikinFont->GetFontData();
+ if (buf == nullptr) {
+ face = hb_face_create_for_tables(referenceTable, minikinFont, nullptr);
+ } else {
+ size_t size = minikinFont->GetFontSize();
+ hb_blob_t* blob = hb_blob_create(reinterpret_cast<const char*>(buf), size,
+ HB_MEMORY_MODE_READONLY, nullptr, nullptr);
+ face = hb_face_create(blob, minikinFont->GetFontIndex());
+ hb_blob_destroy(blob);
+ }
hb_font_t* parent_font = hb_font_create(face);
hb_ot_font_set_funcs(parent_font);
@@ -133,7 +138,7 @@ hb_font_t* getHbFontLocked(MinikinFont* minikinFont) {
hb_font_destroy(parent_font);
hb_face_destroy(face);
fontCache->put(fontId, font);
- return font;
+ return hb_font_reference(font);
}
} // namespace android
diff --git a/libs/minikin/HbFontCache.h b/libs/minikin/HbFontCache.h
index 92e465a..449b354 100644
--- a/libs/minikin/HbFontCache.h
+++ b/libs/minikin/HbFontCache.h
@@ -23,7 +23,7 @@ namespace android {
class MinikinFont;
void purgeHbFontCacheLocked();
-void purgeHbFont(const MinikinFont* minikinFont);
+void purgeHbFontLocked(const MinikinFont* minikinFont);
hb_font_t* getHbFontLocked(MinikinFont* minikinFont);
} // namespace android
diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp
index 3a05acf..9c1d6a8 100644
--- a/libs/minikin/Layout.cpp
+++ b/libs/minikin/Layout.cpp
@@ -99,6 +99,7 @@ struct LayoutContext {
void clearHbFonts() {
for (size_t i = 0; i < hbFonts.size(); i++) {
hb_font_set_funcs(hbFonts[i], nullptr, nullptr, nullptr);
+ hb_font_destroy(hbFonts[i]);
}
hbFonts.clear();
}
diff --git a/libs/minikin/MinikinFont.cpp b/libs/minikin/MinikinFont.cpp
index d56ec9c..ef42e9b 100644
--- a/libs/minikin/MinikinFont.cpp
+++ b/libs/minikin/MinikinFont.cpp
@@ -20,7 +20,7 @@
namespace android {
MinikinFont::~MinikinFont() {
- purgeHbFont(this);
+ purgeHbFontLocked(this);
}
} // namespace android
diff --git a/libs/minikin/MinikinFontFreeType.cpp b/libs/minikin/MinikinFontFreeType.cpp
index c9eb456..4a1b115 100644
--- a/libs/minikin/MinikinFontFreeType.cpp
+++ b/libs/minikin/MinikinFontFreeType.cpp
@@ -30,8 +30,8 @@ namespace android {
int32_t MinikinFontFreeType::sIdCounter = 0;
MinikinFontFreeType::MinikinFontFreeType(FT_Face typeface) :
+ MinikinFont(sIdCounter++),
mTypeface(typeface) {
- mUniqueId = sIdCounter++;
}
MinikinFontFreeType::~MinikinFontFreeType() {
@@ -41,8 +41,8 @@ MinikinFontFreeType::~MinikinFontFreeType() {
float MinikinFontFreeType::GetHorizontalAdvance(uint32_t glyph_id,
const MinikinPaint &paint) const {
FT_Set_Pixel_Sizes(mTypeface, 0, paint.size);
- FT_UInt32 flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings
- FT_Fixed advance;
+ FT_UInt32 flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings
+ FT_Fixed advance;
FT_Get_Advance(mTypeface, glyph_id, flags, &advance);
return advance * (1.0 / 65536);
}
@@ -52,18 +52,24 @@ void MinikinFontFreeType::GetBounds(MinikinRect* /* bounds */, uint32_t /* glyph
// TODO: NYI
}
-bool MinikinFontFreeType::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
- FT_ULong ftsize = *size;
- FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize);
- if (error != 0) {
- return false;
- }
- *size = ftsize;
- return true;
-}
-
-int32_t MinikinFontFreeType::GetUniqueId() const {
- return mUniqueId;
+const void* MinikinFontFreeType::GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) {
+ FT_ULong ftsize = 0;
+ FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, nullptr, &ftsize);
+ if (error != 0) {
+ return nullptr;
+ }
+ FT_Byte* buf = reinterpret_cast<FT_Byte*>(malloc(ftsize));
+ if (buf == nullptr) {
+ return nullptr;
+ }
+ error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize);
+ if (error != 0) {
+ free(buf);
+ return nullptr;
+ }
+ *destroy = free;
+ *size = ftsize;
+ return buf;
}
bool MinikinFontFreeType::Render(uint32_t glyph_id, const MinikinPaint& /* paint */,
diff --git a/libs/minikin/MinikinInternal.cpp b/libs/minikin/MinikinInternal.cpp
index 175ced8..e00f639 100644
--- a/libs/minikin/MinikinInternal.cpp
+++ b/libs/minikin/MinikinInternal.cpp
@@ -17,6 +17,7 @@
// Definitions internal to Minikin
#include "MinikinInternal.h"
+#include "HbFontCache.h"
#include <cutils/log.h>
@@ -72,4 +73,13 @@ bool isEmojiBase(uint32_t c) {
}
}
+hb_blob_t* getFontTable(MinikinFont* minikinFont, uint32_t tag) {
+ assertMinikinLocked();
+ hb_font_t* font = getHbFontLocked(minikinFont);
+ hb_face_t* face = hb_font_get_face(font);
+ hb_blob_t* blob = hb_face_reference_table(face, tag);
+ hb_font_destroy(font);
+ return blob;
+}
+
}
diff --git a/libs/minikin/MinikinInternal.h b/libs/minikin/MinikinInternal.h
index 3d68691..709fb9f 100644
--- a/libs/minikin/MinikinInternal.h
+++ b/libs/minikin/MinikinInternal.h
@@ -19,8 +19,12 @@
#ifndef MINIKIN_INTERNAL_H
#define MINIKIN_INTERNAL_H
+#include <hb.h>
+
#include <utils/Mutex.h>
+#include <minikin/MinikinFont.h>
+
namespace android {
// All external Minikin interfaces are designed to be thread-safe.
@@ -38,6 +42,35 @@ bool isEmojiBase(uint32_t c);
// Returns true if c is emoji modifier.
bool isEmojiModifier(uint32_t c);
+hb_blob_t* getFontTable(MinikinFont* minikinFont, uint32_t tag);
+
+// An RAII wrapper for hb_blob_t
+class HbBlob {
+public:
+ // Takes ownership of hb_blob_t object, caller is no longer
+ // responsible for calling hb_blob_destroy().
+ HbBlob(hb_blob_t* blob) : mBlob(blob) {
+ }
+
+ ~HbBlob() {
+ hb_blob_destroy(mBlob);
+ }
+
+ const uint8_t* get() const {
+ const char* data = hb_blob_get_data(mBlob, nullptr);
+ return reinterpret_cast<const uint8_t*>(data);
+ }
+
+ size_t size() const {
+ unsigned int length = 0;
+ hb_blob_get_data(mBlob, &length);
+ return (size_t)length;
+ }
+
+private:
+ hb_blob_t* mBlob;
+};
+
}
#endif // MINIKIN_INTERNAL_H
diff --git a/sample/MinikinSkia.cpp b/sample/MinikinSkia.cpp
index feda8ad..e2ecde0 100644
--- a/sample/MinikinSkia.cpp
+++ b/sample/MinikinSkia.cpp
@@ -7,6 +7,7 @@
namespace android {
MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
+ MinikinFont(typeface->uniqueID()),
mTypeface(typeface) {
}
@@ -47,24 +48,24 @@ void MinikinFontSkia::GetBounds(MinikinRect* bounds, uint32_t glyph_id,
bounds->mBottom = skBounds.fBottom;
}
-bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
- if (buf == NULL) {
- const size_t tableSize = mTypeface->getTableSize(tag);
- *size = tableSize;
- return tableSize != 0;
- } else {
- const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf);
- *size = actualSize;
- return actualSize != 0;
+const void* MinikinFontSkia::GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) {
+ // we don't have a buffer to the font data, copy to own buffer
+ const size_t tableSize = mTypeface->getTableSize(tag);
+ *size = tableSize;
+ if (tableSize == 0) {
+ return nullptr;
}
+ void* buf = malloc(tableSize);
+ if (buf == nullptr) {
+ return nullptr;
+ }
+ mTypeface->getTableData(tag, 0, tableSize, buf);
+ *destroy = free;
+ return buf;
}
SkTypeface *MinikinFontSkia::GetSkTypeface() {
return mTypeface;
}
-int32_t MinikinFontSkia::GetUniqueId() const {
- return mTypeface->uniqueID();
-}
-
}
diff --git a/sample/MinikinSkia.h b/sample/MinikinSkia.h
index 25ac1b0..6eb9065 100644
--- a/sample/MinikinSkia.h
+++ b/sample/MinikinSkia.h
@@ -12,10 +12,7 @@ public:
void GetBounds(MinikinRect* bounds, uint32_t glyph_id,
const MinikinPaint& paint) const;
- // If buf is NULL, just update size
- bool GetTable(uint32_t tag, uint8_t *buf, size_t *size);
-
- int32_t GetUniqueId() const;
+ const void* GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy);
SkTypeface *GetSkTypeface();
diff --git a/tests/FontFamilyTest.cpp b/tests/FontFamilyTest.cpp
index 907f395..194063f 100644
--- a/tests/FontFamilyTest.cpp
+++ b/tests/FontFamilyTest.cpp
@@ -350,9 +350,9 @@ void expectVSGlyphs(FontFamily* family, uint32_t codepoint, const std::set<uint3
}
TEST_F(FontFamilyTest, hasVariationSelectorTest) {
- MinikinFontForTest minikinFont(kVsTestFont);
- FontFamily family;
- family.addFont(&minikinFont);
+ MinikinAutoUnref<MinikinFontForTest> minikinFont(new MinikinFontForTest(kVsTestFont));
+ MinikinAutoUnref<FontFamily> family(new FontFamily);
+ family->addFont(minikinFont.get());
AutoMutex _l(gMinikinLock);
@@ -365,24 +365,24 @@ TEST_F(FontFamilyTest, hasVariationSelectorTest) {
const uint32_t kVS20 = 0xE0103;
const uint32_t kSupportedChar1 = 0x82A6;
- EXPECT_TRUE(family.getCoverage()->get(kSupportedChar1));
- expectVSGlyphs(&family, kSupportedChar1, std::set<uint32_t>({kVS1, kVS17, kVS18, kVS19}));
+ EXPECT_TRUE(family->getCoverage()->get(kSupportedChar1));
+ expectVSGlyphs(family.get(), kSupportedChar1, std::set<uint32_t>({kVS1, kVS17, kVS18, kVS19}));
const uint32_t kSupportedChar2 = 0x845B;
- EXPECT_TRUE(family.getCoverage()->get(kSupportedChar2));
- expectVSGlyphs(&family, kSupportedChar2, std::set<uint32_t>({kVS2, kVS18, kVS19, kVS20}));
+ EXPECT_TRUE(family->getCoverage()->get(kSupportedChar2));
+ expectVSGlyphs(family.get(), kSupportedChar2, std::set<uint32_t>({kVS2, kVS18, kVS19, kVS20}));
const uint32_t kNoVsSupportedChar = 0x537F;
- EXPECT_TRUE(family.getCoverage()->get(kNoVsSupportedChar));
- expectVSGlyphs(&family, kNoVsSupportedChar, std::set<uint32_t>());
+ EXPECT_TRUE(family->getCoverage()->get(kNoVsSupportedChar));
+ expectVSGlyphs(family.get(), kNoVsSupportedChar, std::set<uint32_t>());
const uint32_t kVsOnlySupportedChar = 0x717D;
- EXPECT_FALSE(family.getCoverage()->get(kVsOnlySupportedChar));
- expectVSGlyphs(&family, kVsOnlySupportedChar, std::set<uint32_t>({kVS3, kVS19, kVS20}));
+ EXPECT_FALSE(family->getCoverage()->get(kVsOnlySupportedChar));
+ expectVSGlyphs(family.get(), kVsOnlySupportedChar, std::set<uint32_t>({kVS3, kVS19, kVS20}));
const uint32_t kNotSupportedChar = 0x845C;
- EXPECT_FALSE(family.getCoverage()->get(kNotSupportedChar));
- expectVSGlyphs(&family, kNotSupportedChar, std::set<uint32_t>());
+ EXPECT_FALSE(family->getCoverage()->get(kNotSupportedChar));
+ expectVSGlyphs(family.get(), kNotSupportedChar, std::set<uint32_t>());
}
TEST_F(FontFamilyTest, hasVSTableTest) {
@@ -403,12 +403,13 @@ TEST_F(FontFamilyTest, hasVSTableTest) {
"Font " + testCase.fontPath + " should have a variation sequence table." :
"Font " + testCase.fontPath + " shouldn't have a variation sequence table.");
- MinikinFontForTest minikinFont(testCase.fontPath);
- FontFamily family;
- family.addFont(&minikinFont);
- family.getCoverage();
+ MinikinAutoUnref<MinikinFontForTest> minikinFont(new MinikinFontForTest(testCase.fontPath));
+ MinikinAutoUnref<FontFamily> family(new FontFamily);
+ family->addFont(minikinFont.get());
+ AutoMutex _l(gMinikinLock);
+ family->getCoverage();
- EXPECT_EQ(testCase.hasVSTable, family.hasVSTable());
+ EXPECT_EQ(testCase.hasVSTable, family->hasVSTable());
}
}
diff --git a/tests/MinikinFontForTest.cpp b/tests/MinikinFontForTest.cpp
index ed70751..66dd4ea 100644
--- a/tests/MinikinFontForTest.cpp
+++ b/tests/MinikinFontForTest.cpp
@@ -22,8 +22,14 @@
#include <cutils/log.h>
-MinikinFontForTest::MinikinFontForTest(const std::string& font_path) : mFontPath(font_path) {
- mTypeface = SkTypeface::CreateFromFile(font_path.c_str());
+MinikinFontForTest::MinikinFontForTest(const std::string& font_path) :
+ MinikinFontForTest(font_path, SkTypeface::CreateFromFile(font_path.c_str())) {
+}
+
+MinikinFontForTest::MinikinFontForTest(const std::string& font_path, SkTypeface* typeface) :
+ MinikinFont(typeface->uniqueID()),
+ mTypeface(typeface),
+ mFontPath(font_path) {
}
MinikinFontForTest::~MinikinFontForTest() {
@@ -40,18 +46,18 @@ void MinikinFontForTest::GetBounds(android::MinikinRect* /* bounds */, uint32_t
LOG_ALWAYS_FATAL("MinikinFontForTest::GetBounds is not yet implemented");
}
-bool MinikinFontForTest::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
- if (buf == NULL) {
- const size_t tableSize = mTypeface->getTableSize(tag);
- *size = tableSize;
- return tableSize != 0;
- } else {
- const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf);
- *size = actualSize;
- return actualSize != 0;
+const void* MinikinFontForTest::GetTable(uint32_t tag, size_t* size,
+ android::MinikinDestroyFunc* destroy) {
+ const size_t tableSize = mTypeface->getTableSize(tag);
+ *size = tableSize;
+ if (tableSize == 0) {
+ return nullptr;
}
-}
-
-int32_t MinikinFontForTest::GetUniqueId() const {
- return mTypeface->uniqueID();
+ void* buf = malloc(tableSize);
+ if (buf == nullptr) {
+ return nullptr;
+ }
+ mTypeface->getTableData(tag, 0, tableSize, buf);
+ *destroy = free;
+ return buf;
}
diff --git a/tests/MinikinFontForTest.h b/tests/MinikinFontForTest.h
index 790348d..e527d21 100644
--- a/tests/MinikinFontForTest.h
+++ b/tests/MinikinFontForTest.h
@@ -24,14 +24,14 @@ class SkTypeface;
class MinikinFontForTest : public android::MinikinFont {
public:
explicit MinikinFontForTest(const std::string& font_path);
+ MinikinFontForTest(const std::string& font_path, SkTypeface* typeface);
~MinikinFontForTest();
// MinikinFont overrides.
float GetHorizontalAdvance(uint32_t glyph_id, const android::MinikinPaint &paint) const;
void GetBounds(android::MinikinRect* bounds, uint32_t glyph_id,
const android::MinikinPaint& paint) const;
- bool GetTable(uint32_t tag, uint8_t *buf, size_t *size);
- int32_t GetUniqueId() const;
+ const void* GetTable(uint32_t tag, size_t* size, android::MinikinDestroyFunc* destroy);
const std::string& fontPath() const { return mFontPath; }
private:
diff --git a/tests/how_to_run.txt b/tests/how_to_run.txt
index a135c30..bee367b 100644
--- a/tests/how_to_run.txt
+++ b/tests/how_to_run.txt
@@ -1,5 +1,5 @@
mmm -j8 frameworks/minikin/tests &&
adb push $OUT/data/nativetest/minikin_tests/minikin_tests \
/data/nativetest/minikin_tests/minikin_tests &&
-adb push frameworks/minikin/tests/data /data/nativetest/minikin_tests/data &&
+adb push frameworks/minikin/tests/data /data/nativetest/minikin_tests/ &&
adb shell /data/nativetest/minikin_tests/minikin_tests