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>
25d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien#include <utils/LruCache.h>
260af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio#include <utils/KeyedVector.h>
27fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio#include <utils/RefBase.h>
28163268b3a8d4dd7e650e6c540f832bf60f6bf4c9Fabrice Di Meglio#include <utils/Singleton.h>
29d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
302d76d4f35ca8d0bcb45159555aa7715b7070a751Kristian Monsen#include <SkAutoKern.h>
312d76d4f35ca8d0bcb45159555aa7715b7070a751Kristian Monsen#include <SkLanguage.h>
32eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkPaint.h>
33eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkTemplates.h>
342d76d4f35ca8d0bcb45159555aa7715b7070a751Kristian Monsen#include <SkTypeface.h>
35eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkUtils.h>
36d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
37eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <unicode/ubidi.h>
38902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio#include <unicode/unistr.h>
39902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio
40aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien#include <hb.h>
41d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
42d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#include <android_runtime/AndroidRuntime.h>
43d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
44d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_NOT_A_CHAR              0xffff
45d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_ZWSP                    0x200b
46d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_LOW_SURROGATE     0xdc00
47d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_HIGH_SURROGATE    0xd800
48d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_PRIVATE_USE       0xe000
49d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_RTL_CHAR          0x0590
50d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
51d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Temporary buffer size
52d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define CHAR_BUFFER_SIZE 80
53d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
54d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Converts a number of mega-bytes into bytes
55d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define MB(s) s * 1024 * 1024
56d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
57d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Define the default cache size in Mb
58161ebab85d976320f156cb4e55140533ae15f92dRaph Levien#define DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB 0.500f
59d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
60d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Define the interval in number of cache hits between two statistics dump
61d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL 100
62d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
63d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglionamespace android {
64d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
65d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio/**
66d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * TextLayoutCacheKey is the Cache key
67d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */
68d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioclass TextLayoutCacheKey {
69d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic:
7048796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    TextLayoutCacheKey();
71d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
725c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t start, size_t count,
73da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            size_t contextCount, int dirFlags);
74d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
75e74fef3b55dc1b5daf40b3a6aea857582071560fFabrice Di Meglio    TextLayoutCacheKey(const TextLayoutCacheKey& other);
76e74fef3b55dc1b5daf40b3a6aea857582071560fFabrice Di Meglio
7748796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    /**
78d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio     * Get the size of the Cache key.
79d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio     */
8006daa7b6b2186cf1e83e14d2adbb0d2050b79c39Jeff Brown    size_t getSize() const;
81d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
82717060b076350ea811153290281075396a554fedFabrice Di Meglio    static int compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs);
83717060b076350ea811153290281075396a554fedFabrice Di Meglio
84832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien    inline const UChar* getText() const { return textCopy.string(); }
85832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien
86d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien    bool operator==(const TextLayoutCacheKey& other) const {
87d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien        return compare(*this, other) == 0;
88d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien    }
89d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien
90d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien    bool operator!=(const TextLayoutCacheKey& other) const {
91d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien        return compare(*this, other) != 0;
92d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien    }
93d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien
94d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien    hash_t hash() const;
95d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioprivate:
96d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio    String16 textCopy;
975c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    size_t start;
989c418dbc56efd334c68872d281f75138e16eae46Fabrice Di Meglio    size_t count;
995c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    size_t contextCount;
100da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio    int dirFlags;
101d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio    SkTypeface* typeface;
102aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkScalar textSize;
103aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkScalar textSkewX;
104aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkScalar textScaleX;
105aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    uint32_t flags;
106aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkPaint::Hinting hinting;
107ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    SkPaint::FontVariant variant;
108ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    SkLanguage language;
109e74fef3b55dc1b5daf40b3a6aea857582071560fFabrice Di Meglio
110d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio}; // TextLayoutCacheKey
111d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
112717060b076350ea811153290281075396a554fedFabrice Di Meglioinline int strictly_order_type(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
113717060b076350ea811153290281075396a554fedFabrice Di Meglio    return TextLayoutCacheKey::compare(lhs, rhs) < 0;
114717060b076350ea811153290281075396a554fedFabrice Di Meglio}
115717060b076350ea811153290281075396a554fedFabrice Di Meglio
116717060b076350ea811153290281075396a554fedFabrice Di Meglioinline int compare_type(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
117717060b076350ea811153290281075396a554fedFabrice Di Meglio    return TextLayoutCacheKey::compare(lhs, rhs);
118717060b076350ea811153290281075396a554fedFabrice Di Meglio}
119717060b076350ea811153290281075396a554fedFabrice Di Meglio
120d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levieninline hash_t hash_type(const TextLayoutCacheKey& key) {
121d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien    return key.hash();
122d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien}
123d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien
124d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio/*
125a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * TextLayoutValue is the Cache value
126d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */
127a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutValue : public RefBase {
128d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic:
129a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutValue(size_t contextCount);
130d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
13148796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    void setElapsedTime(uint32_t time);
13248796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    uint32_t getElapsedTime();
133d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
1345c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline const jfloat* getAdvances() const { return mAdvances.array(); }
1355c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline size_t getAdvancesCount() const { return mAdvances.size(); }
1365c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline jfloat getTotalAdvance() const { return mTotalAdvance; }
1375c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline const jchar* getGlyphs() const { return mGlyphs.array(); }
1385c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline size_t getGlyphsCount() const { return mGlyphs.size(); }
1392301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    inline const jfloat* getPos() const { return mPos.array(); }
1402301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    inline size_t getPosCount() const { return mPos.size(); }
141d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
142d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio    /**
1434dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio     * Advances vector
144fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
1454dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio    Vector<jfloat> mAdvances;
146d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
147fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    /**
148fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     * Total number of advances
149fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
150fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    jfloat mTotalAdvance;
151fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio
152fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    /**
1534dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio     * Glyphs vector
154fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
1554dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio    Vector<jchar> mGlyphs;
156fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio
157fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    /**
1582301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien     * Pos vector (2 * i is x pos, 2 * i + 1 is y pos, same as drawPosText)
1592301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien     */
1602301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    Vector<jfloat> mPos;
1612301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien
1622301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    /**
1630af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     * Get the size of the Cache entry
1640af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
1650af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    size_t getSize() const;
1660af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
1670af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglioprivate:
1680af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
169fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     * Time for computing the values (in milliseconds)
170fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
171fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    uint32_t mElapsedTime;
1729f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio
17348796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio}; // TextLayoutCacheValue
174d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
175fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio/**
176a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * The TextLayoutShaper is responsible for shaping (with the Harfbuzz library)
177fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio */
178a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutShaper {
179d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic:
180a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutShaper();
181a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    virtual ~TextLayoutShaper();
182d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
183a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
184da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            size_t start, size_t count, size_t contextCount, int dirFlags);
1850af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
18615cc68ced062a0dbd174718abfb1c783ac1aa433Fabrice Di Meglio    void purgeCaches();
18715cc68ced062a0dbd174718abfb1c783ac1aa433Fabrice Di Meglio
1880af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglioprivate:
1890af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
190aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien     * Harfbuzz buffer for shaping
1910af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
192aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien    hb_buffer_t* mBuffer;
1930af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
1940af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
1950af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     * Skia Paint used for shaping
1960af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
1970af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    SkPaint mShapingPaint;
1980af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
1990af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
200902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     * Cache of Harfbuzz faces
201902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     */
202aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien    KeyedVector<SkFontID, hb_face_t*> mCachedHBFaces;
203902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio
204d6deccb346e913d906f484d279b19e0f6ea18d94Billy Hewlett    SkTypeface* typefaceForScript(const SkPaint* paint, SkTypeface* typeface,
205aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien        hb_script_t script);
2061637dcd16cd314574a58602337a2c7222130b1b9Raph Levien
207aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien    size_t shapeFontRun(const SkPaint* paint);
2080af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
209bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio    void computeValues(const SkPaint* paint, const UChar* chars,
210da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            size_t start, size_t count, size_t contextCount, int dirFlags,
2110af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
2122301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien            Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
2130af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
214bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio    void computeRunValues(const SkPaint* paint, const UChar* chars,
215aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien            size_t start, size_t count, size_t contextCount, bool isRTL,
2160af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
2172301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien            Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
2180af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
219aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien    SkTypeface* setCachedTypeface(SkTypeface** typeface, hb_script_t script, SkTypeface::Style style);
220aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien    hb_face_t* referenceCachedHBFace(SkTypeface* typeface);
2210af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
222aaedde51b76901ff05f2a2348eb41f0f5323d954Raph Levien    bool isComplexScript(hb_script_t script);
223a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio}; // TextLayoutShaper
2240af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
225a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio/**
226a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * Cache of text layout information.
227a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio */
228a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutCache : private OnEntryRemoved<TextLayoutCacheKey, sp<TextLayoutValue> >
229a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio{
230a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Megliopublic:
231a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutCache(TextLayoutShaper* shaper);
232a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
233a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    ~TextLayoutCache();
234a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
235a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    bool isInitialized() {
236a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio        return mInitialized;
237a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    }
238a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
239a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /**
240a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Used as a callback when an entry is removed from the cache
241a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Do not invoke directly
242a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
243a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void operator()(TextLayoutCacheKey& text, sp<TextLayoutValue>& desc);
244a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
245a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
246da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            jint count, jint contextCount, jint dirFlags);
247a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
248a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /**
249a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Clear the cache
250a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
25113ba4e478d19001ddb6828bd1fd8fbc1e0cb208fRaph Levien    void purgeCaches();
252a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
253a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioprivate:
254a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutShaper* mShaper;
255a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    Mutex mLock;
256a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    bool mInitialized;
257a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
258d98efca7383f5f3cdae438a8a8a18f78451a95baRaph Levien    LruCache<TextLayoutCacheKey, sp<TextLayoutValue> > mCache;
259a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
260a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint32_t mSize;
261a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint32_t mMaxSize;
262a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
263a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint32_t mCacheHitCount;
264a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint64_t mNanosecondsSaved;
265a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
266a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint64_t mCacheStartTime;
267a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
268a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    RtlDebugLevel mDebugLevel;
269a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    bool mDebugEnabled;
270a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
271a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /*
272a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Class initialization
273a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
274a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void init();
275a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
276a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /**
277a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Dump Cache statistics
278a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
279a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void dumpCacheStats();
280a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
281a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio}; // TextLayoutCache
282a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
283a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio/**
284a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * The TextLayoutEngine is reponsible for computing TextLayoutValues
285a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio */
286a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutEngine : public Singleton<TextLayoutEngine> {
287a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Megliopublic:
288a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutEngine();
289a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    virtual ~TextLayoutEngine();
290a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
291832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien    /**
292832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * Note: this method currently does a defensive copy of the text argument, in case
293832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * there is concurrent mutation of it. The contract may change, and may in the
294832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * future require the caller to guarantee that the contents will not change during
295832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * the call. Be careful of this when doing optimization.
296832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     **/
297a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
298da12f389eb4be0c08ca3fa9ca7663f4977858df5Fabrice Di Meglio            jint count, jint contextCount, jint dirFlags);
29930ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio
30030ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio    void purgeCaches();
30130ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio
302a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioprivate:
303a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutCache* mTextLayoutCache;
304a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutShaper* mShaper;
305a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio}; // TextLayoutEngine
3060af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
307d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio} // namespace android
308d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#endif /* ANDROID_TEXT_LAYOUT_CACHE_H */
309d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
310