HbFontCache.cpp revision bae347682989d2627081310129a5b60541ed6ad0
16df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui/* 26df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * Copyright (C) 2015 The Android Open Source Project 36df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * 46df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * Licensed under the Apache License, Version 2.0 (the "License"); 56df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * you may not use this file except in compliance with the License. 66df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * You may obtain a copy of the License at 76df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * 86df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * http://www.apache.org/licenses/LICENSE-2.0 96df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * 106df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * Unless required by applicable law or agreed to in writing, software 116df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * distributed under the License is distributed on an "AS IS" BASIS, 126df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * See the License for the specific language governing permissions and 146df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui * limitations under the License. 156df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui */ 166df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 176df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui#define LOG_TAG "Minikin" 186df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 19377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include "HbFaceCache.h" 20c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen 21c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen#include <cutils/log.h> 22c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen#include <hb.h> 236df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui#include <utils/LruCache.h> 246df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 256df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui#include <minikin/MinikinFont.h> 261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include "MinikinInternal.h" 276df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 286df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghuinamespace android { 296df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 306df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghuistatic hb_blob_t* referenceTable(hb_face_t* /* face */, hb_tag_t tag, void* userData) { 316df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui MinikinFont* font = reinterpret_cast<MinikinFont*>(userData); 326df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui size_t length = 0; 336df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui bool ok = font->GetTable(tag, NULL, &length); 346df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui if (!ok) { 356df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return 0; 366df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 376df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui char* buffer = reinterpret_cast<char*>(malloc(length)); 386df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui if (!buffer) { 396df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return 0; 406df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 416df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui ok = font->GetTable(tag, reinterpret_cast<uint8_t*>(buffer), &length); 426df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui#ifdef VERBOSE_DEBUG 436df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui ALOGD("referenceTable %c%c%c%c length=%zd %d", 446df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui (tag >>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, length, ok); 456df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui#endif 460ce6e969ccce7b5826630484c5574252c4ca6acdLajos Molnar if (!ok) { 476df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui free(buffer); 486df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return 0; 496df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 506df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return hb_blob_create(const_cast<char*>(buffer), length, 516df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui HB_MEMORY_MODE_WRITABLE, buffer, free); 526df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui} 536df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 546df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghuiclass HbFaceCache : private OnEntryRemoved<int32_t, hb_face_t*> { 556df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghuipublic: 566df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui HbFaceCache() : mCache(kMaxEntries) { 576df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui mCache.setOnEntryRemovedListener(this); 586df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 596df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 606df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui // callback for OnEntryRemoved 616df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui void operator()(int32_t& /* key */, hb_face_t*& value) { 626df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui hb_face_destroy(value); 63e0fb528f8e3bbab04620c8534177168b358e837bztenghui } 640ce6e969ccce7b5826630484c5574252c4ca6acdLajos Molnar 650ce6e969ccce7b5826630484c5574252c4ca6acdLajos Molnar hb_face_t* get(int32_t fontId) { 666df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return mCache.get(fontId); 671b86fe063badb5f28c467ade39be0f4008688947Andreas Huber } 686df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 696df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui void put(int32_t fontId, hb_face_t* face) { 706df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui mCache.put(fontId, face); 716df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 726df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 736df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui void clear() { 746df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui mCache.clear(); 756df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 766df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 776df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghuiprivate: 786df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui static const size_t kMaxEntries = 100; 79c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen 80c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen LruCache<int32_t, hb_face_t*> mCache; 81c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen}; 82c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen 83c6ac859f5a82ea8642bc6351a45508a15f224f32Marco NelissenHbFaceCache* getFaceCacheLocked() { 84c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen assertMinikinLocked(); 850ce6e969ccce7b5826630484c5574252c4ca6acdLajos Molnar static HbFaceCache* cache = nullptr; 86c6ac859f5a82ea8642bc6351a45508a15f224f32Marco Nelissen if (cache == nullptr) { 876df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui cache = new HbFaceCache(); 886df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 896df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return cache; 906df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui} 916df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 926df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghuivoid purgeHbFaceCacheLocked() { 936df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui assertMinikinLocked(); 946df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui getFaceCacheLocked()->clear(); 956df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui} 966df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 976df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghuihb_face_t* getHbFaceLocked(MinikinFont* minikinFont) { 986df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui assertMinikinLocked(); 996df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui if (minikinFont == nullptr) { 1006df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return nullptr; 1016df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 1026df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 1036df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui HbFaceCache* faceCache = getFaceCacheLocked(); 1046df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui const int32_t fontId = minikinFont->GetUniqueId(); 1056df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui hb_face_t* face = faceCache->get(fontId); 1066df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui if (face != nullptr) { 1076df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return face; 1086df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui } 1096df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 1106df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui face = hb_face_create_for_tables(referenceTable, minikinFont, nullptr); 1116df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui faceCache->put(fontId, face); 1126df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui return face; 1136df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui} 1146df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui 1156df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui} // namespace android 1166df48bfe8cccdfec58f5f94be3cf3a2c64697e56ztenghui