diff options
-rw-r--r-- | include/minikin/MinikinFont.h | 28 | ||||
-rw-r--r-- | include/minikin/MinikinFontFreeType.h | 6 | ||||
-rw-r--r-- | include/minikin/MinikinRefCounted.h | 17 | ||||
-rw-r--r-- | libs/minikin/FontFamily.cpp | 25 | ||||
-rw-r--r-- | libs/minikin/HbFontCache.cpp | 51 | ||||
-rw-r--r-- | libs/minikin/HbFontCache.h | 2 | ||||
-rw-r--r-- | libs/minikin/Layout.cpp | 1 | ||||
-rw-r--r-- | libs/minikin/MinikinFont.cpp | 2 | ||||
-rw-r--r-- | libs/minikin/MinikinFontFreeType.cpp | 36 | ||||
-rw-r--r-- | libs/minikin/MinikinInternal.cpp | 10 | ||||
-rw-r--r-- | libs/minikin/MinikinInternal.h | 33 | ||||
-rw-r--r-- | sample/MinikinSkia.cpp | 27 | ||||
-rw-r--r-- | sample/MinikinSkia.h | 5 | ||||
-rw-r--r-- | tests/FontFamilyTest.cpp | 37 | ||||
-rw-r--r-- | tests/MinikinFontForTest.cpp | 36 | ||||
-rw-r--r-- | tests/MinikinFontForTest.h | 4 | ||||
-rw-r--r-- | tests/how_to_run.txt | 2 |
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 |