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 }
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