MinikinFont
100 class MinikinFont : public MinikinRefCounted { 101 public: 102 MinikinFont(int32_t uniqueId) : mUniqueId(uniqueId) {} 103 104 virtual ~MinikinFont(); 105 106 virtual float GetHorizontalAdvance(uint32_t glyph_id, 107 const MinikinPaint &paint) const = 0; 108 109 virtual void GetBounds(MinikinRect* bounds, uint32_t glyph_id, 110 const MinikinPaint &paint) const = 0; 111 112 virtual const void* GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) = 0; 113 114 // Override if font can provide access to raw data 115 virtual const void* GetFontData() const { 116 return nullptr; 117 } 118 119 // Override if font can provide access to raw data 120 virtual size_t GetFontSize() const { 121 return 0; 122 } 123 124 // Override if font can provide access to raw data. 125 // Returns index within OpenType collection 126 virtual int GetFontIndex() const { 127 return 0; 128 } 129 130 static uint32_t MakeTag(char c1, char c2, char c3, char c4) { 131 return ((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | 132 ((uint32_t)c3 << 8) | (uint32_t)c4; 133 } 134 135 int32_t GetUniqueId() const { return mUniqueId; } 136 private: 137 const int32_t mUniqueId; <==IDしかないのか。 138 };
Cross Reference: /frameworks/minikin/include/minikin/MinikinFont.h
28 class ANDROID_API MinikinFontSkia : public MinikinFont { 29 public: 30 // Note: this takes ownership of the reference (will unref on dtor) 31 explicit MinikinFontSkia(SkTypeface *typeface, const void* fontData, size_t fontSize, 32 int ttcIndex); 33 34 ~MinikinFontSkia(); 35 36 float GetHorizontalAdvance(uint32_t glyph_id, 37 const MinikinPaint &paint) const; 38 39 void GetBounds(MinikinRect* bounds, uint32_t glyph_id, 40 const MinikinPaint &paint) const; 41 42 const void* GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy); 43 44 SkTypeface* GetSkTypeface() const; 45 46 // Access to underlying raw font bytes 47 const void* GetFontData() const; 48 size_t GetFontSize() const; 49 int GetFontIndex() const; 50 51 static uint32_t packPaintFlags(const SkPaint* paint); 52 static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags); 53 54 // set typeface and fake bold/italic parameters 55 static void populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery); 56 private: 57 SkTypeface* mTypeface; 58 59 // A raw pointer to the font data - it should be owned by some other object with 60 // lifetime at least as long as this object. 61 const void* mFontData; 62 size_t mFontSize; 63 int mTtcIndex; 64 };
Cross Reference: /frameworks/base/libs/hwui/hwui/MinikinSkia.h
MinikinFontSkiaを使っているところ、その1
56 static jboolean addSkTypeface( FontFamily* family, SkTypeface* face, const void* fontData, 57 size_t fontSize, int ttcIndex) { 58 MinikinFont* minikinFont = new MinikinFontSkia( face, fontData, fontSize, ttcIndex); 59 bool result = family->addFont(minikinFont); 60 minikinFont->Unref(); 61 return result; 62 }
Cross Reference: /frameworks/base/core/jni/android/graphics/FontFamily.cpp
MinikinFontSkiaを使っているところ、その2
128 static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong familyPtr, 129 jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) { 130 NPE_CHECK_RETURN_ZERO(env, font); 131 132 // Declare axis native type. 133 std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes; 134 int skiaAxesLength = 0; 135 if (listOfAxis) { 136 jint listSize = env->CallIntMethod(listOfAxis, gListClassInfo.mSize); 137 138 skiaAxes.reset(new SkFontMgr::FontParameters::Axis[listSize]); 139 skiaAxesLength = listSize; 140 for (jint i = 0; i < listSize; ++i) { 141 jobject axisObject = env->CallObjectMethod(listOfAxis, gListClassInfo.mGet, i); 142 if (!axisObject) { 143 skiaAxes[i].fTag = 0; 144 skiaAxes[i].fStyleValue = 0; 145 continue; 146 } 147 148 jint tag = env->GetIntField(axisObject, gAxisClassInfo.mTag); 149 jfloat stylevalue = env->GetFloatField(axisObject, gAxisClassInfo.mStyleValue); 150 skiaAxes[i].fTag = tag; 151 skiaAxes[i].fStyleValue = SkFloatToScalar(stylevalue); 152 } 153 } 154 155 const void* fontPtr = env->GetDirectBufferAddress(font); 156 if (fontPtr == NULL) { 157 ALOGE("addFont failed to create font, buffer invalid"); 158 return false; 159 } 160 jlong fontSize = env->GetDirectBufferCapacity(font); 161 if (fontSize < 0) { 162 ALOGE("addFont failed to create font, buffer size invalid"); 163 return false; 164 } 165 jobject fontRef = MakeGlobalRefOrDie(env, font); 166 SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize, 167 release_global_ref, reinterpret_cast<void*>(fontRef))); 168 std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(data)); 169 170 SkFontMgr::FontParameters params; 171 params.setCollectionIndex(ttcIndex); 172 params.setAxes(skiaAxes.get(), skiaAxesLength); 173 174 SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); 175 SkTypeface* face = fm->createFromStream(fontData.release(), params); 176 if (face == NULL) { 177 ALOGE("addFont failed to create font, invalid request"); 178 return false; 179 } 180 FontFamily* fontFamily = reinterpret_cast<FontFamily*>(familyPtr); 181 MinikinFont* minikinFont = new MinikinFontSkia( face, fontPtr, (size_t)fontSize, ttcIndex); 182 fontFamily->addFont(minikinFont, FontStyle(weight / 100, isItalic)); 183 minikinFont->Unref(); 184 return true; 185 }
Cross Reference: /frameworks/base/core/jni/android/graphics/FontFamily.cpp
96 struct hb_font_t { 97 hb_object_header_t header; 98 ASSERT_POD (); 99 100 hb_bool_t immutable; 101 102 hb_font_t *parent; 103 hb_face_t *face; 104 105 int x_scale; 106 int y_scale; 107 108 unsigned int x_ppem; 109 unsigned int y_ppem; 110 111 hb_font_funcs_t *klass; 112 void *user_data; 113 hb_destroy_func_t destroy; 114 115 struct hb_shaper_data_t shaper_data;
Cross Reference: /external/harfbuzz_ng/src/hb-font-private.hh
minikin HbFontCache
bFontCache* getFontCacheLocked() { ALOGD("[S] minikin/HbFontCache.cpp getFontCacheLocked"); assertMinikinLocked(); static HbFontCache* cache = nullptr; if (cache == nullptr) { cache = new HbFontCache(); } ALOGD("[E] minikin/HbFontCache.cpp getFontCacheLocked"); return cache; }
Cross Reference: /frameworks/minikin/libs/minikin/HbFontCache.cpp
47 class HbFontCache : private OnEntryRemoved<int32_t, hb_font_t*> { 48 public: 49 HbFontCache() : mCache(kMaxEntries) { <=コンストラクタ 50 mCache.setOnEntryRemovedListener(this); <=削除時の関数を登録 51 } 52 53 // callback for OnEntryRemoved 54 void operator()(int32_t& /* key */, hb_font_t*& value) { 55 hb_font_destroy(value); 56 } 57 58 hb_font_t* get(int32_t fontId) { 59 return mCache.get(fontId); 60 } 61 62 void put(int32_t fontId, hb_font_t* font) { 63 mCache.put(fontId, font); 64 } 65 66 void clear() { 67 mCache.clear(); 68 } 69 70 void remove(int32_t fontId) { 71 mCache.remove(fontId); 72 } 73 74 private: 75 static const size_t kMaxEntries = 100;<==最大100なのかな? 76 77 LruCache<int32_t, hb_font_t*> mCache; <==key:font_idとvalue:hb_font_tのキャッシュ 78 }; 79
Cross Reference: /frameworks/minikin/libs/minikin/HbFontCache.cpp
100 // Returns a new reference to a hb_font_t object, caller is 101 // responsible for calling hb_font_destroy() on it. 102 hb_font_t* getHbFontLocked(MinikinFont* minikinFont) { 103 assertMinikinLocked(); 104 // TODO: get rid of nullFaceFont 105 static hb_font_t* nullFaceFont = nullptr; 106 if (minikinFont == nullptr) { 107 if (nullFaceFont == nullptr) { 108 nullFaceFont = hb_font_create(nullptr); 109 } 110 return hb_font_reference(nullFaceFont); 111 } 112 /***** キャッシュ取得 *****/ 113 HbFontCache* fontCache = getFontCacheLocked(); /***** KeyのfontId取得 *****/ 114 const int32_t fontId = minikinFont->GetUniqueId(); /***** fontIdでキャッシュにあるか確認 *****/ 115 hb_font_t* font = fontCache->get(fontId); 116 if (font != nullptr) { /***** キャッシュにあったとき *****/ 117 return hb_font_reference(font); 118 } 119 /***** キャッシュにないとき *****/ 120 hb_face_t* face; /***** 生データ取得 *****/ 121 const void* buf = minikinFont->GetFontData(); 122 if (buf == nullptr) { /***** データがない(NULL)とき *****/ 123 face = hb_face_create_for_tables(referenceTable, minikinFont, nullptr); 124 } else { /***** データがあるとき *****/ 125 size_t size = minikinFont->GetFontSize(); 126 hb_blob_t* blob = hb_blob_create( reinterpret_cast<const char*>(buf), size, 127 HB_MEMORY_MODE_READONLY, nullptr, nullptr); 128 face = hb_face_create(blob, minikinFont->GetFontIndex()); 129 hb_blob_destroy(blob); 130 } /*** なんで親なんだろう? *****/ 131 hb_font_t* parent_font = hb_font_create(face); 132 hb_ot_font_set_funcs(parent_font); 133 134 unsigned int upem = hb_face_get_upem(face); 135 hb_font_set_scale(parent_font, upem, upem); 136 /***** こっちは、子供だ。*****/ 137 font = hb_font_create_sub_font(parent_font); 138 hb_font_destroy(parent_font); 139 hb_face_destroy(face); 140 fontCache->put(fontId, font); 141 return hb_font_reference(font); 142 }
Cross Reference: /frameworks/minikin/libs/minikin/HbFontCache.cpp
/***** 親の作成 *****/ 1121 hb_font_t * 1122 hb_font_create (hb_face_t *face) /* <=== hbのface */ 1123 { 1124 hb_font_t *font; 1125 1126 if (unlikely (!face)) { /*** faceがNULLのとき ***/ 1127 face = hb_face_get_empty (); } /* font オブジェクト作成 */ 1128 if (!(font = hb_object_create<hb_font_t> ())) { /*** fontオブジェクトの作成失敗の時 ***/ 1129 return hb_font_get_empty (); } 1130 1131 hb_face_make_immutable (face); 1132 font->parent = hb_font_get_empty (); 1133 font->face = hb_face_reference (face); 1134 font->klass = hb_font_funcs_get_empty (); 1135 1136 font->x_scale = font->y_scale = hb_face_get_upem (face); 1137 1138 return font; 1139 }
Cross Reference: /external/harfbuzz_ng/src/hb-font.cc
分岐予測のためのマクロらしい。
77 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) 78 #define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) 79 #define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) /* 0との比較 */ 80 #define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) 81 #else 82 #define likely(expr) (expr) 83 #define unlikely(expr) (expr) 84 #endif
Cross Reference: /external/harfbuzz_ng/src/hb-private.hh
ほげほげまん: likely / unlikely
子供の作成
1152 hb_font_create_sub_font (hb_font_t *parent) 1153 { 1154 if (unlikely (!parent)) { 1155 parent = hb_font_get_empty (); } 1156 1157 hb_font_t *font = hb_font_create (parent->face); 1158 1159 if (unlikely (hb_object_is_inert (font))) { 1160 return font; } 1161 1162 font->parent = hb_font_reference (parent); 1163 1164 font->x_scale = parent->x_scale; 1165 font->y_scale = parent->y_scale; 1166 font->x_ppem = parent->x_ppem; 1167 font->y_ppem = parent->y_ppem; 1168 1169 return font; 1170 }
144 template <typename Type> 145 static inline bool hb_object_is_inert (const Type *obj) 146 { 147 return unlikely (obj->header.ref_count.is_inert ()); 148 }
Cross Reference: /external/harfbuzz_ng/src/hb-object-private.hh
ejje.weblio.jp
54 struct hb_reference_count_t 55 { 56 hb_atomic_int_t ref_count; 57 58 inline void init (int v) { ref_count.set_unsafe (v); } 59 inline int get_unsafe (void) const { return ref_count.get_unsafe (); } 60 inline int inc (void) { return ref_count.inc (); } 61 inline int dec (void) { return ref_count.dec (); } 62 inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); } 63 64 inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; } 65 inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; } 66 }; 67 48 /* reference_count */ 49 50 #define HB_REFERENCE_COUNT_INERT_VALUE -1 51 #define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD 52 #define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)} 53
Cross Reference: /external/harfbuzz_ng/src/hb-object-private.hh
174 struct hb_atomic_int_t 175 { 176 hb_atomic_int_impl_t v; 177 178 inline void set_unsafe (int v_) { v = v_; } 179 inline int get_unsafe (void) const { return v; } 180 inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), 1); } 181 inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); } 182 }; 183
Cross Reference: /external/harfbuzz_ng/src/hb-atomic-private.hh
Minikin getFontTable
80 bool FontFamily::addFont(MinikinFont* typeface) { 81 AutoMutex _l(gMinikinLock); 82 const uint32_t os2Tag = MinikinFont::MakeTag('O', 'S', '/', '2'); 83 HbBlob os2Table(getFontTable(typeface, os2Tag)); 84 if (os2Table.get() == nullptr) return false; 85 int weight; 86 bool italic; 87 if (analyzeStyle(os2Table.get(), os2Table.size(), &weight, &italic)) { 88 //ALOGD("analyzed weight = %d, italic = %s", weight, italic ? "true" : "false"); 89 FontStyle style(weight, italic); 90 addFontLocked(typeface, style); 91 return true; 92 } else { 93 ALOGD("failed to analyze style"); 94 } 95 return false; 96 }
Cross Reference: /frameworks/minikin/libs/minikin/FontFamily.cpp
172 const SparseBitSet* FontFamily::getCoverage() { 173 if (!mCoverageValid) { 174 const FontStyle defaultStyle; 175 MinikinFont* typeface = getClosestMatch(defaultStyle).font; 176 const uint32_t cmapTag = MinikinFont::MakeTag('c', 'm', 'a', 'p'); 177 HbBlob cmapTable(getFontTable(typeface, cmapTag)); 178 if (cmapTable.get() == nullptr) { 179 ALOGE("Could not get cmap table size!\n"); 180 // Note: This means we will retry on the next call to getCoverage, as we can't store 181 // the failure. This is fine, as we assume this doesn't really happen in practice. 182 return nullptr; 183 } 184 // TODO: Error check? 185 CmapCoverage::getCoverage(mCoverage, cmapTable.get(), cmapTable.size(), &mHasVSTable); 186 #ifdef VERBOSE_DEBUG 187 ALOGD("font coverage length=%d, first ch=%x\n", mCoverage.length(), 188 mCoverage.nextSetBit(0)); 189 #endif 190 mCoverageValid = true; 191 } 192 return &mCoverage; 193 }
Cross Reference: /frameworks/minikin/libs/minikin/FontFamily.cpp