TextLayoutCache.h revision aabe537f1ed3b64f755af9fc62022d6074eec169
1d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio/* 2d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Copyright (C) 2011 The Android Open Source Project 3d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * 4d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License"); 5d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * you may not use this file except in compliance with the License. 6d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * You may obtain a copy of the License at 7d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * 8d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * http://www.apache.org/licenses/LICENSE-2.0 9d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * 10d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software 11d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS, 12d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * See the License for the specific language governing permissions and 14d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * limitations under the License. 15d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 16d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 17d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#ifndef ANDROID_TEXT_LAYOUT_CACHE_H 18d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define ANDROID_TEXT_LAYOUT_CACHE_H 19d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 20d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#include "RtlProperties.h" 21d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 22eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <stddef.h> 23d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#include <utils/threads.h> 24d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#include <utils/String16.h> 25eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <utils/GenerationCache.h> 26eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <utils/Compare.h> 27d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 28eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkPaint.h> 29eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkTemplates.h> 30eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkUtils.h> 31eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkScalerContext.h> 32eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkAutoKern.h> 33d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 34eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <unicode/ubidi.h> 35eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <unicode/ushape.h> 369f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#include "HarfbuzzSkia.h" 379f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#include "harfbuzz-shaper.h" 38d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 39d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#include <android_runtime/AndroidRuntime.h> 40d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 41d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_NOT_A_CHAR 0xffff 42d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_ZWSP 0x200b 43d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_LOW_SURROGATE 0xdc00 44d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_HIGH_SURROGATE 0xd800 45d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_PRIVATE_USE 0xe000 46d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_RTL_CHAR 0x0590 47d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 48d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Temporary buffer size 49d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define CHAR_BUFFER_SIZE 80 50d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 51d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Converts a number of mega-bytes into bytes 52d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define MB(s) s * 1024 * 1024 53d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 54d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Define the default cache size in Mb 55d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB 0.125f 56d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 57d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Define the interval in number of cache hits between two statistics dump 58d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL 100 59d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 60d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglionamespace android { 61d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 62d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio/** 63d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * TextLayoutCacheKey is the Cache key 64d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 65d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioclass TextLayoutCacheKey { 66d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic: 67d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio TextLayoutCacheKey() : text(NULL), start(0), count(0), contextCount(0), 68aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0), 69aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio hinting(SkPaint::kNo_Hinting) { 70d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 71d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 72d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio TextLayoutCacheKey(const SkPaint* paint, 73d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio const UChar* text, size_t start, size_t count, 74d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t contextCount, int dirFlags) : 75d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text(text), start(start), count(count), contextCount(contextCount), 76d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio dirFlags(dirFlags) { 77d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio typeface = paint->getTypeface(); 78aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio textSize = paint->getTextSize(); 79d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio textSkewX = paint->getTextSkewX(); 80aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio textScaleX = paint->getTextScaleX(); 81aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio flags = paint->getFlags(); 82aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio hinting = paint->getHinting(); 83d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 84d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 85d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio bool operator<(const TextLayoutCacheKey& rhs) const { 86d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio LTE_INT(count) { 87d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio LTE_INT(contextCount) { 88d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio LTE_INT(start) { 89aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio LTE_INT(typeface) { 90aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio LTE_FLOAT(textSize) { 91aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio LTE_FLOAT(textSkewX) { 92aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio LTE_FLOAT(textScaleX) { 93aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio LTE_INT(flags) { 94aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio LTE_INT(hinting) { 95aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio LTE_INT(dirFlags) { 96aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio return strncmp16(text, rhs.text, contextCount) < 0; 97aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio } 98aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio } 99d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 100d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 101d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 102d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 103d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 104d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 105d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 106d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 107d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio return false; 108d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 109d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 110d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // We need to copy the text when we insert the key into the cache itself. 111d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // We don't need to copy the text when we are only comparing keys. 112d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void internalTextCopy() { 113d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio textCopy.setTo(text, contextCount); 114d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text = textCopy.string(); 115d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 116d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 117d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 118d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Get the size of the Cache key. 119d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 120d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t getSize() { 121d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount; 122d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 123d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 124d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioprivate: 125d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio const UChar* text; 126d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio String16 textCopy; 127d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t start; 128d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t count; 129d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t contextCount; 130d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio int dirFlags; 131d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio SkTypeface* typeface; 132aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio SkScalar textSize; 133aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio SkScalar textSkewX; 134aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio SkScalar textScaleX; 135aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio uint32_t flags; 136aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio SkPaint::Hinting hinting; 137d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio}; // TextLayoutCacheKey 138d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 139d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio/* 140d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * RunAdvanceDescription is the Cache entry 141d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 142d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioclass RunAdvanceDescription { 143d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic: 144d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio RunAdvanceDescription() { 145d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio advances = NULL; 146d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio totalAdvance = 0; 147d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 148d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 149d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio ~RunAdvanceDescription() { 150d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio delete[] advances; 151d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 152d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 153d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void setElapsedTime(uint32_t time) { 154d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio elapsedTime = time; 155d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 156d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 157d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint32_t getElapsedTime() { 158d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio return elapsedTime; 159d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 160d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 161d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void computeAdvances(SkPaint* paint, const UChar* chars, size_t start, size_t count, 162d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t contextCount, int dirFlags) { 163d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio advances = new float[count]; 164d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio this->count = count; 165d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 1669f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if RTL_USE_HARFBUZZ 1679f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio computeAdvancesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, 168d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio advances, &totalAdvance); 1699f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#else 1709f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, 1719f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio advances, &totalAdvance); 1729f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 1739f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if DEBUG_ADVANCES 1749f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - " 1759f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, totalAdvance, 1769f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio advances[0], advances[1], advances[2], advances[3]); 1779f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 178d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 179d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 180d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void copyResult(jfloat* outAdvances, jfloat* outTotalAdvance) { 181d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio memcpy(outAdvances, advances, count * sizeof(jfloat)); 182d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio *outTotalAdvance = totalAdvance; 183d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 184d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 185d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 186d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Get the size of the Cache entry 187d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 188d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t getSize() { 189d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio return sizeof(RunAdvanceDescription) + sizeof(jfloat) * count; 190d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 191d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 1929f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, 1939f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, 1949f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio int dirFlags) { 1959f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio bool isRTL = dirFlags & 0x1; 1969f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 1979f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio font->klass = &harfbuzzSkiaClass; 1989f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio font->userData = 0; 1999f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // The values which harfbuzzSkiaClass returns are already scaled to 2009f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // pixel units, so we just set all these to one to disable further 2019f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // scaling. 2029f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio font->x_ppem = 1; 2039f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio font->y_ppem = 1; 2049f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio font->x_scale = 1; 2059f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio font->y_scale = 1; 2069f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2079f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio memset(shaperItem, 0, sizeof(*shaperItem)); 2089f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->font = font; 2099f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable); 2109f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 211eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio shaperItem->kerning_applied = false; 212eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio 2139f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // We cannot know, ahead of time, how many glyphs a given script run 2149f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // will produce. We take a guess that script runs will not produce more 2159f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // than twice as many glyphs as there are code points plus a bit of 2169f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // padding and fallback if we find that we are wrong. 2179f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio createGlyphArrays(shaperItem, (contextCount + 2) * 2); 2189f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2199f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // Free memory for clusters if needed and recreate the clusters array 2209f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio if (shaperItem->log_clusters) { 2219f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio delete shaperItem->log_clusters; 2229f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 2239f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->log_clusters = new unsigned short[contextCount]; 2249f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2259f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->item.pos = start; 2269f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->item.length = count; 2279f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->item.bidiLevel = isRTL; 2289f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common; 2299f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2309f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->string = chars; 2319f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->stringLength = contextCount; 2329f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2339f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio fontData->typeFace = paint->getTypeface(); 234eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio fontData->textSize = paint->getTextSize(); 235eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio fontData->textSkewX = paint->getTextSkewX(); 236eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio fontData->textScaleX = paint->getTextScaleX(); 237eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio fontData->flags = paint->getFlags(); 238eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio fontData->hinting = paint->getHinting(); 2399f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2409f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->font->userData = fontData; 2419f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 2429f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2439f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, 2449f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, 2459f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio int dirFlags) { 2469f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // Setup Harfbuzz Shaper 2479f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio setupShaperItem(shaperItem, font, fontData, paint, chars, start, count, 2489f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio contextCount, dirFlags); 2499f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2509f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // Shape 2519f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio resetGlyphArrays(shaperItem); 2529f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio while (!HB_ShapeItem(shaperItem)) { 2539f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // We overflowed our arrays. Resize and retry. 2549f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // HB_ShapeItem fills in shaperItem.num_glyphs with the needed size. 2559f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio deleteGlyphArrays(shaperItem); 2569f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1); 2579f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio resetGlyphArrays(shaperItem); 2589f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 2599f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 2609f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 261eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#define SkAutoKern_AdjustF(prev, next) (((next) - (prev) + 32) >> 6 << 16) 262eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio 263eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio static int adjust(int prev, int next) { 264eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio int delta = next - prev; 265eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio if (delta >= 32) { 266eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio return -1; 267eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 268eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio else if (delta < -32) { 269eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio return +1; 270eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 271eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio else { 272eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio return 0; 273eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 274eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio } 275eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio 2769f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio static void computeAdvancesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start, 2779f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio size_t count, size_t contextCount, int dirFlags, 2789f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio jfloat* outAdvances, jfloat* outTotalAdvance) { 2799f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2809f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio bool isRTL = dirFlags & 0x1; 2819f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2829f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio HB_ShaperItem shaperItem; 2839f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio HB_FontRec font; 2849f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio FontData fontData; 2859f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count, 2869f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio contextCount, dirFlags); 2879f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2889f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if DEBUG_ADVANCES 289eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs, shaperItem.kerning_applied); 290eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio LOGD(" -- string= '%s'", String8(chars, contextCount).string()); 291eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio LOGD(" -- isDevKernText=%d", paint->isDevKernText()); 2929f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 2939f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2949f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio jfloat totalAdvance = 0; 295eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio 2969f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio for (size_t i = 0; i < count; i++) { 297eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio totalAdvance += outAdvances[i] = HBFixedToFloat(shaperItem.advances[i]); 2989f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 2999f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if DEBUG_ADVANCES 3009f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio LOGD("hb-adv = %d - rebased = %f - total = %f", shaperItem.advances[i], outAdvances[i], 3019f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio totalAdvance); 3029f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 3039f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 3049f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 3059f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio deleteGlyphArrays(&shaperItem); 3069f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio HB_FreeFace(shaperItem.face); 3079f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 3089f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio *outTotalAdvance = totalAdvance; 3099f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 3109f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 3119f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start, 3129f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio size_t count, size_t contextCount, int dirFlags, 3139f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio jfloat* outAdvances, jfloat* outTotalAdvance) { 3149f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 315d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount); 316d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio jchar* buffer = tempBuffer.get(); 317d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 318d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio SkScalar* scalarArray = (SkScalar*)outAdvances; 319d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 320d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // this is where we'd call harfbuzz 321d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // for now we just use ushape.c 322d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t widths; 323d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio const jchar* text; 324d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio if (dirFlags & 0x1) { // rtl, call arabic shaping in case 325d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio UErrorCode status = U_ZERO_ERROR; 326d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // Use fixed length since we need to keep start and count valid 327d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio u_shapeArabic(chars, contextCount, buffer, contextCount, 328d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio U_SHAPE_LENGTH_FIXED_SPACES_NEAR | 329d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE | 330d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status); 331d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // we shouldn't fail unless there's an out of memory condition, 332d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // in which case we're hosed anyway 333d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio for (int i = start, e = i + count; i < e; ++i) { 334d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio if (buffer[i] == UNICODE_NOT_A_CHAR) { 335d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio buffer[i] = UNICODE_ZWSP; // zero-width-space for skia 336d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 337d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 338d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text = buffer + start; 339d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio widths = paint->getTextWidths(text, count << 1, scalarArray); 340d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } else { 341d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text = chars + start; 342d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio widths = paint->getTextWidths(text, count << 1, scalarArray); 343d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 344d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 345d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio jfloat totalAdvance = 0; 346d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio if (widths < count) { 3479f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if DEBUG_ADVANCES 3489f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio LOGD("ICU -- count=%d", widths); 3499f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 350d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // Skia operates on code points, not code units, so surrogate pairs return only 351d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // one value. Expand the result so we have one value per UTF-16 code unit. 352d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 353d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // Note, skia's getTextWidth gets confused if it encounters a surrogate pair, 354d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio // leaving the remaining widths zero. Not nice. 355d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio for (size_t i = 0, p = 0; i < widths; ++i) { 356d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]); 357d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio if (p < count && 358d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text[p] >= UNICODE_FIRST_LOW_SURROGATE && 359d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text[p] < UNICODE_FIRST_PRIVATE_USE && 360d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE && 361d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio text[p-1] < UNICODE_FIRST_LOW_SURROGATE) { 362d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio outAdvances[p++] = 0; 363d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 3649f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if DEBUG_ADVANCES 3659f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); 3669f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 367d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 368d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } else { 3699f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if DEBUG_ADVANCES 3709f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio LOGD("ICU -- count=%d", count); 3719f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 372d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio for (size_t i = 0; i < count; i++) { 373d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]); 3749f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#if DEBUG_ADVANCES 3759f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); 3769f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#endif 377d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 378d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 379d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio *outTotalAdvance = totalAdvance; 380d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 381d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 382d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioprivate: 383d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio jfloat* advances; 384d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio jfloat totalAdvance; 385d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio size_t count; 386d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 387d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint32_t elapsedTime; 3889f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 3899f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio static void deleteGlyphArrays(HB_ShaperItem* shaperItem) { 3909f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio delete[] shaperItem->glyphs; 3919f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio delete[] shaperItem->attributes; 3929f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio delete[] shaperItem->advances; 3939f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio delete[] shaperItem->offsets; 3949f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 3959f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 3969f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio static void createGlyphArrays(HB_ShaperItem* shaperItem, int size) { 3979f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->glyphs = new HB_Glyph[size]; 3989f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->attributes = new HB_GlyphAttributes[size]; 3999f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->advances = new HB_Fixed[size]; 4009f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->offsets = new HB_FixedPoint[size]; 4019f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio shaperItem->num_glyphs = size; 4029f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 4039f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 4049f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio static void resetGlyphArrays(HB_ShaperItem* shaperItem) { 4059f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio int size = shaperItem->num_glyphs; 4069f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // All the types here don't have pointers. It is safe to reset to 4079f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio // zero unless Harfbuzz breaks the compatibility in the future. 4089f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0])); 4099f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0])); 4109f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0])); 4119f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0])); 4129f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio } 4139f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio 414d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio}; // RunAdvanceDescription 415d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 416d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 417d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioclass TextLayoutCache: public OnEntryRemoved<TextLayoutCacheKey, RunAdvanceDescription*> 418d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio{ 419d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic: 420d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio TextLayoutCache(); 421d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio TextLayoutCache(uint32_t maxByteSize); 422d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 423d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio virtual ~TextLayoutCache(); 424d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 425d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio bool isInitialized() { 426d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio return mInitialized; 427d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio } 428d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 429d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 430d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Used as a callback when an entry is removed from the cache. 431d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Do not invoke directly. 432d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 433d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void operator()(TextLayoutCacheKey& text, RunAdvanceDescription*& desc); 434d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 435d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 436d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Get cache entries 437d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 438d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void getRunAdvances(SkPaint* paint, const jchar* text, 439d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio jint start, jint count, jint contextCount, jint dirFlags, 440d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio jfloat* outAdvances, jfloat* outTotalAdvance); 441d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 442d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 443d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Clear the cache 444d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 445d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void clear(); 446d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 447d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 448d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Sets the maximum size of the cache in bytes. 449d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 450d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void setMaxSize(uint32_t maxSize); 451d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 452d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 453d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Returns the maximum size of the cache in bytes. 454d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 455d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint32_t getMaxSize(); 456d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 457d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 458d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Returns the current size of the cache in bytes. 459d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 460d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint32_t getSize(); 461d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 462d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioprivate: 463d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio Mutex mLock; 464d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio bool mInitialized; 465d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 466d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio GenerationCache<TextLayoutCacheKey, RunAdvanceDescription*> mCache; 467d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 468d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint32_t mSize; 469d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint32_t mMaxSize; 470d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 471d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint32_t mCacheHitCount; 472d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint64_t mNanosecondsSaved; 473d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 474d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio uint64_t mCacheStartTime; 475d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 476d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio RtlDebugLevel mDebugLevel; 477d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio bool mDebugEnabled; 478d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 479d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /* 480d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Class initialization 481d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 482d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void init(); 483d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 484d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 485d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Remove oldest entries until we are having enough space 486d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 487d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void removeOldests(); 488d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 489d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio /** 490d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * Dump Cache statistics 491d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */ 492d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio void dumpCacheStats(); 493d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio}; // TextLayoutCache 494d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 495d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio} // namespace android 496d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#endif /* ANDROID_TEXT_LAYOUT_CACHE_H */ 497d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio 498