のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

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

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

FF14 パッチ3.4 水槽用のさかな

エリア 釣り場 餌売り場 その他
銅魚 忘れられたオアシス ハニーワーム キャンプ・ブロンズレイク
カラードカープ 中央森林 鏡池 バターワーム ホウソーン家の山塞
ダークバス 高地ラノシア 愚か者の滝 フェザントフライ 高知ラノシア よろず屋
クラウンローチ 忘れられたオアシス ハニーワーム キャンプ・ブロンズレイク
アカザ 高地ドラヴァニア ウィロームリバー ブレーデットジグ マーケット 砂塵、霧、曇り
血紅龍 モードゥナ 唄う裂谷 ハニーワーム 銀魚泳がせ釣り 4:00-11:59
バイオピラルク アジス・ラー デルタ管区 ブルートリーチ 18:00-03:00 曇り
コーラルバタフライ 中央ラノシア ゼファードリフト沿岸 ピルバグ リムサ道具屋
ブローフィッシュ コスタデルソル フローティングミノー 西ザナラーン ベスパーベイ
シーラカンス 西ラノシア 幻影島北岸(夜) ヘリングボール コスタ・デル・ソル フルムーンサーディンの泳がせ釣り
シルバーシャーク 東ラノシア 南ブラッドショア ラグワーム リムサ道具屋 メルトコビー泳がせ釣り
マズラヤマーリン 東ラノシア 北ブラッドショア ピルバグ リムサ道具屋 ハーバーへリングHQ>オーガバラクーダHQの泳がせ釣り
ヘルムズマンズハンド 西ラノシア 幻影諸島北岸 ピルバグ リムサ道具屋 曇り9時~15時 オーシャンクラウド泳がせ釣り

カラードカープ - とてとて〜エオルゼア釣り紀行 Wiki*
ダークバス - とてとて〜エオルゼア釣り紀行 Wiki*
クラウンローチ - とてとて〜エオルゼア釣り紀行 Wiki*
Danmark Momozima 日記「たまには釣りでもいかが?」 | FINAL FANTASY XIV, The Lodestone
Hyakki Daigo 日記「ヌシ釣り(第3期=パッチ2.4) 釣り上げ条件一覧【最終版】」 | FINAL FANTASY XIV, The Lodestone
Seori Mikumari 日記「ヘルムズマンズハンド ━ 【ヌシ釣り Ver 2.3】9:00~14:59 」 | FINAL FANTASY XIV, The Lodestone
マズラヤマーリン FF14 ERIONES - エリオネス
新生FF14 ギャザクラ生活: よろず屋等で売っている釣り餌


銅魚 - 猫はお腹がすいた
カラードカープ - 猫はお腹がすいた
ダークバス - 猫はお腹がすいた
クラウンローチ - 猫はお腹がすいた
アカザ - 猫はお腹がすいた
血紅龍 - 猫はお腹がすいた
バイオピラルク - 猫はお腹がすいた
コーラルバタフライ - 猫はお腹がすいた
ブローフィッシュ - 猫はお腹がすいた
シーラカンス - 猫はお腹がすいた
シルバーシャーク - 猫はお腹がすいた
マズラヤマーリン - 猫はお腹がすいた
ヘルムズマンズハンド - 猫はお腹がすいた