のねのBlog

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

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 }