HbFontCache.cpp revision fb0d396929e534a3686469b474d4f670864aa5ac
1fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka/* 2fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * Copyright (C) 2015 The Android Open Source Project 3fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * 4fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License"); 5fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * you may not use this file except in compliance with the License. 6fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * You may obtain a copy of the License at 7fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * 8fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * http://www.apache.org/licenses/LICENSE-2.0 9fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * 10fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * Unless required by applicable law or agreed to in writing, software 11fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS, 12fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * See the License for the specific language governing permissions and 14fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka * limitations under the License. 15fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka */ 16fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 17fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#define LOG_TAG "Minikin" 18fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 19fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#include "HbFaceCache.h" 20fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 21fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#include <hb.h> 22fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#include <utils/LruCache.h> 23fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 24fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#include <minikin/MinikinFont.h> 25fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#include "MinikinInternal.h" 26fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 27fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakanamespace android { 28fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 29fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakastatic hb_blob_t* referenceTable(hb_face_t* face, hb_tag_t tag, void* userData) { 30fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka MinikinFont* font = reinterpret_cast<MinikinFont*>(userData); 31fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka size_t length = 0; 32fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka bool ok = font->GetTable(tag, NULL, &length); 33fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka if (!ok) { 34fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return 0; 35fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 36fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka char* buffer = reinterpret_cast<char*>(malloc(length)); 37fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka if (!buffer) { 38fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return 0; 39fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 40fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka ok = font->GetTable(tag, reinterpret_cast<uint8_t*>(buffer), &length); 41fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#ifdef VERBOSE_DEBUG 42fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka ALOGD("referenceTable %c%c%c%c length=%d %d", 43fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka (tag >>24)&0xff, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, length, ok); 44fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka#endif 45fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka if (!ok) { 46fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka free(buffer); 47fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return 0; 48fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 49fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return hb_blob_create(const_cast<char*>(buffer), length, 50fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka HB_MEMORY_MODE_WRITABLE, buffer, free); 51fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka} 52fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 53fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakastatic unsigned int disabledDecomposeCompatibility( 54fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka hb_unicode_funcs_t*, hb_codepoint_t, hb_codepoint_t*, void*) { 55fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return 0; 56fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka} 57fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 58fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakaclass HbFaceCache : private OnEntryRemoved<int32_t, hb_face_t*> { 59fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakapublic: 60fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka HbFaceCache() : mCache(kMaxEntries) { 61fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka mCache.setOnEntryRemovedListener(this); 62fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 63fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 64fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka // callback for OnEntryRemoved 65fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka void operator()(int32_t& key, hb_face_t*& value) { 66fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka hb_face_destroy(value); 67fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 68fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 69fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka hb_face_t* get(int32_t fontId) { 70fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return mCache.get(fontId); 71fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 72fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 73fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka void put(int32_t fontId, hb_face_t* face) { 74fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka mCache.put(fontId, face); 75fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 76fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 77fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka void clear() { 78fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka mCache.clear(); 79fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 80fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 81fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakaprivate: 82fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka static const size_t kMaxEntries = 100; 83fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 84fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka LruCache<int32_t, hb_face_t*> mCache; 85fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka}; 86fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 87fb0d396929e534a3686469b474d4f670864aa5acSeigo NonakaHbFaceCache* getFaceCacheLocked() { 88fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka assertMinikinLocked(); 89fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka static HbFaceCache* cache = nullptr; 90fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka if (cache == nullptr) { 91fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka cache = new HbFaceCache(); 92fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 93fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return cache; 94fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka} 95fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 96fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakavoid purgeHbFaceCacheLocked() { 97fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka assertMinikinLocked(); 98fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka getFaceCacheLocked()->clear(); 99fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka} 100fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 101fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonakahb_face_t* getHbFaceLocked(MinikinFont* minikinFont) { 102fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka assertMinikinLocked(); 103fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka if (minikinFont == nullptr) { 104fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return nullptr; 105fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 106fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 107fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka HbFaceCache* faceCache = getFaceCacheLocked(); 108fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka const int32_t fontId = minikinFont->GetUniqueId(); 109fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka hb_face_t* face = faceCache->get(fontId); 110fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka if (face != nullptr) { 111fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return face; 112fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka } 113fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 114fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka face = hb_face_create_for_tables(referenceTable, minikinFont, nullptr); 115fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka faceCache->put(fontId, face); 116fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka return face; 117fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka} 118fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka 119fb0d396929e534a3686469b474d4f670864aa5acSeigo Nonaka} // namespace android 120