読者です 読者をやめる 読者になる 読者になる

のねのBlog

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

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

NewWithProc

    166     SkAutoTUnref<SkData> data(SkData::NewWithProc(fontPtr, fontSize,
    167             release_global_ref, reinterpret_cast<void*>(fontRef)));

Cross Reference: /frameworks/base/core/jni/android/graphics/FontFamily.cpp

    106 SkData* SkData::NewWithProc(
            const void* ptr,
            size_t length,
            ReleaseProc proc,
            void* context) {
    107     return new SkData(ptr, length, proc, context);
    108 }

Cross Reference: /external/skia/src/core/SkData.cpp

     15 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
     16     fPtr = const_cast<void*>(ptr);
     17     fSize = size;
     18     fReleaseProc = proc;
     19     fReleaseProcContext = context;
     20 }

Cross Reference: /external/skia/src/core/SkData.cpp

     33 SkData::~SkData() {
     34     if (fReleaseProc) {
     35         fReleaseProc(fPtr, fReleaseProcContext);
     36     }
     37 }
     38 

Cross Reference: /external/skia/src/core/SkData.cpp

     64 static void release_global_ref(const void* /*data*/, void* context) {
     65     JNIEnv* env = AndroidRuntime::getJNIEnv();
     66     bool needToAttach = (env == NULL);
     67     if (needToAttach) {
     68         JavaVMAttachArgs args;
     69         args.version = JNI_VERSION_1_4;
     70         args.name = "release_font_data";
     71         args.group = NULL;
     72         jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args);
     73         if (result != JNI_OK) {
     74             ALOGE("failed to attach to thread to release global ref.");
     75             return;
     76         }
     77     }
     78 
     79     jobject obj = reinterpret_cast<jobject>(context);
     80     env->DeleteGlobalRef(obj);
     81 
     82     if (needToAttach) {
     83        AndroidRuntime::getJavaVM()->DetachCurrentThread();
     84     }
     85 }

Cross Reference: /frameworks/base/core/jni/android/graphics/FontFamily.cpp

  165     jobject fontRef = MakeGlobalRefOrDie(env, font);

Cross Reference: /frameworks/base/core/jni/android/graphics/FontFamily.cpp

     61 template <typename T>
     62 static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
     63     jobject res = env->NewGlobalRef(in);
     64     LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference.");
     65     return static_cast<T>(res);
     66 }

Cross Reference: /frameworks/base/core/jni/core_jni_helpers.h

getFontTable

     82 hb_blob_t* getFontTable(MinikinFont* minikinFont, uint32_t tag) {
     83     assertMinikinLocked();
     84     hb_font_t* font = getHbFontLocked(minikinFont);
     85     hb_face_t* face = hb_font_get_face(font);
     86     hb_blob_t* blob = hb_face_reference_table(face, tag);
     87     hb_font_destroy(font);
     88     return blob;
     89 }

Cross Reference: /frameworks/minikin/libs/minikin/MinikinInternal.cpp

    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();
    114     const int32_t fontId = minikinFont->GetUniqueId();
    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) {
    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)
   1123 {
   1124   hb_font_t *font;
   1125 
   1126   if (unlikely (!face))
   1127     face = hb_face_get_empty ();
   1128   if (!(font = hb_object_create<hb_font_t> ()))
   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

   1181 hb_font_t *
   1182 hb_font_get_empty (void)
   1183 {
   1184   static const hb_font_t _hb_font_nil = {
   1185     HB_OBJECT_HEADER_STATIC,
   1186 
   1187     true, /* immutable */
   1188 
   1189     NULL, /* parent */
   1190     const_cast<hb_face_t *> (&_hb_face_nil),
   1191 
   1192     1000, /* x_scale */
   1193     1000, /* y_scale */
   1194 
   1195     0, /* x_ppem */
   1196     0, /* y_ppem */
   1197 
   1198     const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
   1199     NULL, /* user_data */
   1200     NULL, /* destroy */
   1201 
   1202     {
   1203 #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
   1204 #include "hb-shaper-list.hh"
   1205 #undef HB_SHAPER_IMPLEMENT
   1206     }
   1207   };
   1208 
   1209   return const_cast<hb_font_t *> (&_hb_font_nil);
   1210 }

Cross Reference: /external/harfbuzz_ng/src/hb-font.cc

   1222 hb_font_t *
   1223 hb_font_reference (hb_font_t *font)
   1224 {
   1225   return hb_object_reference (font);
   1226 }

Cross Reference: /external/harfbuzz_ng/src/hb-font.cc

    154 template <typename Type>
    155 static inline Type *hb_object_reference (Type *obj)
    156 {
    157   hb_object_trace (obj, HB_FUNC);
    158   if (unlikely (!obj || hb_object_is_inert (obj)))
    159     return obj;
    160   assert (hb_object_is_valid (obj));
    161   obj->header.ref_count.inc ();
    162   return obj;
    163 }

Cross Reference: /external/harfbuzz_ng/src/hb-object-private.hh

MinikinDestroyFunc

     31 static hb_blob_t* referenceTable(hb_face_t* /* face */, hb_tag_t tag, void* userData) {
     32     MinikinFont* font = reinterpret_cast<MinikinFont*>(userData);
     33     MinikinDestroyFunc destroy = 0;
     34     size_t size = 0;
     35     const void* buffer = font->GetTable(tag, &size, &destroy);
     36     if (buffer == nullptr) {
     37         return nullptr;
     38     }
     39 #ifdef VERBOSE_DEBUG
     40     ALOGD("referenceTable %c%c%c%c length=%zd",
     41         (tag >>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, size);
     42 #endif
     43     return hb_blob_create(reinterpret_cast<const char*>(buffer), size,
     44             HB_MEMORY_MODE_READONLY, const_cast<void*>(buffer), destroy);
     45 }

Cross Reference: /frameworks/minikin/libs/minikin/HbFontCache.cpp

getCoverage

6.0.0_r1

    188 const SparseBitSet* FontFamily::getCoverage() {
    189     if (!mCoverageValid) {
    190         const FontStyle defaultStyle;
    191         MinikinFont* typeface = getClosestMatch(defaultStyle).font;
    192         const uint32_t cmapTag = MinikinFont::MakeTag('c', 'm', 'a', 'p');

    193         size_t cmapSize = 0;
    194         if (!typeface->GetTable(cmapTag, NULL, &cmapSize)) {
    195             ALOGE("Could not get cmap table size!\n");
    196             // Note: This means we will retry on the next call 
                    // to getCoverage, as we can't store
    197             //       the failure. This is fine,
                    // as we assume this doesn't really happen in practice.
    198             return nullptr;
    199         }
    200         UniquePtr<uint8_t[]> cmapData(new uint8_t[cmapSize]);
    201         if (!typeface->GetTable(cmapTag, cmapData.get(), &cmapSize)) {
    202             ALOGE("Unexpected failure to read cmap table!\n");
    203             return nullptr;
    204         }
    205         CmapCoverage::getCoverage(
                    mCoverage, cmapData.get(), cmapSize);
                // TODO: Error check?
    206 #ifdef VERBOSE_DEBUG
    207         ALOGD("font coverage length=%d, first ch=%x\n", mCoverage->length(),
    208                 mCoverage->nextSetBit(0));
    209 #endif
    210         mCoverageValid = true;
    211     }
    212     return &mCoverage;
    213 }

Cross Reference: /frameworks/minikin/libs/minikin/FontFamily.cpp

7.0.0_r1

    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

    120 bool CmapCoverage::getCoverage(SparseBitSet& coverage, const uint8_t* cmap_data, size_t cmap_size) {
    121     vector<uint32_t> coverageVec;
    122     const size_t kHeaderSize = 4;
    123     const size_t kNumTablesOffset = 2;
    124     const size_t kTableSize = 8;
    125     const size_t kPlatformIdOffset = 0;
    126     const size_t kEncodingIdOffset = 2;
    127     const size_t kOffsetOffset = 4;
    128     const int kMicrosoftPlatformId = 3;
    129     const int kUnicodeBmpEncodingId = 1;
    130     const int kUnicodeUcs4EncodingId = 10;
    131     if (kHeaderSize > cmap_size) {
    132         return false;
    133     }
    134     int numTables = readU16(cmap_data, kNumTablesOffset);
    135     if (kHeaderSize + numTables * kTableSize > cmap_size) {
    136         return false;
    137     }
    138     int bestTable = -1;
    139     for (int i = 0; i < numTables; i++) {
    140         uint16_t platformId = readU16(cmap_data, kHeaderSize + i * kTableSize + kPlatformIdOffset);
    141         uint16_t encodingId = readU16(cmap_data, kHeaderSize + i * kTableSize + kEncodingIdOffset);
    142         if (platformId == kMicrosoftPlatformId && encodingId == kUnicodeUcs4EncodingId) {
    143             bestTable = i;
    144             break;
    145         } else if (platformId == kMicrosoftPlatformId && encodingId == kUnicodeBmpEncodingId) {
    146             bestTable = i;
    147         }
    148     }
    149 #ifdef VERBOSE_DEBUG
    150     ALOGD("best table = %d\n", bestTable);
    151 #endif
    152     if (bestTable < 0) {
    153         return false;
    154     }
    155     uint32_t offset = readU32(cmap_data, kHeaderSize + bestTable * kTableSize + kOffsetOffset);
    156     if (offset + 2 > cmap_size) {
    157         return false;
    158     }
    159     uint16_t format = readU16(cmap_data, offset);
    160     bool success = false;
    161     const uint8_t* tableData = cmap_data + offset;
    162     const size_t tableSize = cmap_size - offset;
    163     if (format == 4) {
    164         success = getCoverageFormat4(coverageVec, tableData, tableSize);
    165     } else if (format == 12) {
    166         success = getCoverageFormat12(coverageVec, tableData, tableSize);
    167     }
    168     if (success) {
    169         coverage.initFromRanges(&coverageVec.front(), coverageVec.size() >> 1);
    170     }
    171 #ifdef VERBOSE_DEBUG
    172     for (size_t i = 0; i < coverageVec.size(); i += 2) {
    173         ALOGD("%x:%x\n", coverageVec[i], coverageVec[i + 1]);
    174     }
    175     ALOGD("success = %d", success);
    176 #endif
    177     return success;
    178 }

Cross Reference: /frameworks/minikin/libs/minikin/CmapCoverage.cpp

  134 bool CmapCoverage::getCoverage(SparseBitSet& coverage, const uint8_t* cmap_data, size_t cmap_size,
    135         bool* has_cmap_format14_subtable) {
    136     vector<uint32_t> coverageVec;
    137     const size_t kHeaderSize = 4;
    138     const size_t kNumTablesOffset = 2;
    139     const size_t kTableSize = 8;
    140     const size_t kPlatformIdOffset = 0;
    141     const size_t kEncodingIdOffset = 2;
    142     const size_t kOffsetOffset = 4;
    143     const uint16_t kUnicodePlatformId = 0;
    144     const uint16_t kMicrosoftPlatformId = 3;
    145     const uint16_t kUnicodeBmpEncodingId = 1;
    146     const uint16_t kVariationSequencesEncodingId = 5;
    147     const uint16_t kUnicodeUcs4EncodingId = 10;
    148     const uint32_t kNoTable = UINT32_MAX;
    149     if (kHeaderSize > cmap_size) {
    150         return false;
    151     }
    152     uint32_t numTables = readU16(cmap_data, kNumTablesOffset);
    153     if (kHeaderSize + numTables * kTableSize > cmap_size) {
    154         return false;
    155     }
    156     uint32_t bestTable = kNoTable;
    157     bool hasCmapFormat14Subtable = false;
    158     for (uint32_t i = 0; i < numTables; i++) {
    159         uint16_t platformId = readU16(cmap_data, kHeaderSize + i * kTableSize + kPlatformIdOffset);
    160         uint16_t encodingId = readU16(cmap_data, kHeaderSize + i * kTableSize + kEncodingIdOffset);
    161         if (platformId == kMicrosoftPlatformId && encodingId == kUnicodeUcs4EncodingId) {
    162             bestTable = i;
    163             break;
    164         } else if (platformId == kMicrosoftPlatformId && encodingId == kUnicodeBmpEncodingId) {
    165             bestTable = i;
    166         } else if (platformId == kUnicodePlatformId &&
    167                 encodingId == kVariationSequencesEncodingId) {
    168             uint32_t offset = readU32(cmap_data, kHeaderSize + i * kTableSize + kOffsetOffset);
    169             if (offset <= cmap_size - 2 && readU16(cmap_data, offset) == 14) {
    170                 hasCmapFormat14Subtable = true;
    171             }
    172         }
    173     }
    174     *has_cmap_format14_subtable = hasCmapFormat14Subtable;
    175 #ifdef VERBOSE_DEBUG
    176     ALOGD("best table = %d\n", bestTable);
    177 #endif
    178     if (bestTable == kNoTable) {
    179         return false;
    180     }
    181     uint32_t offset = readU32(cmap_data, kHeaderSize + bestTable * kTableSize + kOffsetOffset);
    182     if (offset > cmap_size - 2) {
    183         return false;
    184     }
    185     uint16_t format = readU16(cmap_data, offset);
    186     bool success = false;
    187     const uint8_t* tableData = cmap_data + offset;
    188     const size_t tableSize = cmap_size - offset;
    189     if (format == 4) {
    190         success = getCoverageFormat4(coverageVec, tableData, tableSize);
    191     } else if (format == 12) {
    192         success = getCoverageFormat12(coverageVec, tableData, tableSize);
    193     }
    194     if (success) {
    195         coverage.initFromRanges(&coverageVec.front(), coverageVec.size() >> 1);
    196     }
    197 #ifdef VERBOSE_DEBUG
    198     for (size_t i = 0; i < coverageVec.size(); i += 2) {
    199         ALOGD("%x:%x\n", coverageVec[i], coverageVec[i + 1]);
    200     }
    201     ALOGD("success = %d", success);
    202 #endif
    203     return success;
    204 }

addFont

6.0.0_r1

    103 bool FontFamily::addFont(MinikinFont* typeface) {
    104     AutoMutex _l(gMinikinLock);
    105     const uint32_t os2Tag = MinikinFont::MakeTag('O', 'S', '/', '2');
    106     size_t os2Size = 0;
    107     bool ok = typeface->GetTable(os2Tag, NULL, &os2Size);
    108     if (!ok) return false;
    109     UniquePtr<uint8_t[]> os2Data(new uint8_t[os2Size]);
    110     ok = typeface->GetTable(os2Tag, os2Data.get(), &os2Size);
    111     if (!ok) return false;
    112     int weight;
    113     bool italic;
    114     if (analyzeStyle(os2Data.get(), os2Size, &weight, &italic)) {
    115         //ALOGD("analyzed weight = %d, italic = %s", weight, italic ? "true" : "false");
    116         FontStyle style(weight, italic);
    117         addFontLocked(typeface, style);
    118         return true;
    119     } else {
    120         ALOGD("failed to analyze style");
    121     }
    122     return false;
    123 }

Cross Reference: /frameworks/minikin/libs/minikin/FontFamily.cpp

     81 bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
     82     if (buf == NULL) {
     83         const size_t tableSize = mTypeface->getTableSize(tag);
     84         *size = tableSize;
     85         return tableSize != 0;
     86     } else {
     87         const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf);
     88         *size = actualSize;
     89         return actualSize != 0;
     90     }
     91 }

Cross Reference: /frameworks/base/core/jni/android/graphics/MinikinSkia.cpp

    61 bool MinikinFontFreeType::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
     62 	FT_ULong ftsize = *size;
     63 	FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize);
     64 	if (error != 0) {
     65 		return false;
     66 	}
     67 	*size = ftsize;
     68 	return true;

aosp build/envsetup.shのコマンド

Invoke ". build/envsetup.sh" from your shell to add the following functions to your environment:
- lunch:     lunch <product_name>-<build_variant>
- tapas:     tapas [<App1> <App2> ...] [arm|x86|mips|armv5|arm64|x86_64|mips64] [eng|userdebug|user]
- croot:     Changes directory to the top of the tree.
- m:         Makes from the top of the tree.
- mm:        Builds all of the modules in the current directory, but not their dependencies.
- mmm:       Builds all of the modules in the supplied directories, but not their dependencies.
             To limit the modules being built use the syntax: mmm dir/:target1,target2.
- mma:       Builds all of the modules in the current directory, and their dependencies.
- mmma:      Builds all of the modules in the supplied directories, and their dependencies.
- provision: Flash device with all required partitions. Options will be passed on to fastboot.
- cgrep:     Greps on all local C/C++ files.
- ggrep:     Greps on all local Gradle files.
- jgrep:     Greps on all local Java files.
- resgrep:   Greps on all local res/*.xml files.
- mangrep:   Greps on all local AndroidManifest.xml files.
- mgrep:     Greps on all local Makefiles files.
- sepgrep:   Greps on all local sepolicy files.
- sgrep:     Greps on all local source files.
- godir:     Go to the directory containing a file.

Environment options:
- SANITIZE_HOST: Set to 'true' to use ASAN for all host modules. Note that
                 ASAN_OPTIONS=detect_leaks=0 will be set by default until the
                 build is leak-check clean.