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>
260af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio#include <utils/KeyedVector.h>
27eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <utils/Compare.h>
28fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio#include <utils/RefBase.h>
29163268b3a8d4dd7e650e6c540f832bf60f6bf4c9Fabrice Di Meglio#include <utils/Singleton.h>
30d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
31eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkPaint.h>
32eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkTemplates.h>
33eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkUtils.h>
34eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <SkAutoKern.h>
35ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett#include <SkLanguage.h>
36d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
37eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <unicode/ubidi.h>
38eee49c699c035ffba188417489f40d34f587d65cFabrice Di Meglio#include <unicode/ushape.h>
39902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio#include <unicode/unistr.h>
40902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio
419f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#include "HarfbuzzSkia.h"
429f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio#include "harfbuzz-shaper.h"
43d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
44d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#include <android_runtime/AndroidRuntime.h>
45d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
46d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_NOT_A_CHAR              0xffff
47d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_ZWSP                    0x200b
48d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_LOW_SURROGATE     0xdc00
49d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_HIGH_SURROGATE    0xd800
50d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_PRIVATE_USE       0xe000
51d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define UNICODE_FIRST_RTL_CHAR          0x0590
52d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
53d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Temporary buffer size
54d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define CHAR_BUFFER_SIZE 80
55d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
56d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Converts a number of mega-bytes into bytes
57d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define MB(s) s * 1024 * 1024
58d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
59d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Define the default cache size in Mb
60161ebab85d976320f156cb4e55140533ae15f92dRaph Levien#define DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB 0.500f
61d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
62d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio// Define the interval in number of cache hits between two statistics dump
63d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#define DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL 100
64d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
65d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglionamespace android {
66d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
67d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio/**
68d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio * TextLayoutCacheKey is the Cache key
69d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */
70d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioclass TextLayoutCacheKey {
71d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic:
7248796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    TextLayoutCacheKey();
73d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
745c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t start, size_t count,
755c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio            size_t contextCount, int dirFlags);
76d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
77e74fef3b55dc1b5daf40b3a6aea857582071560fFabrice Di Meglio    TextLayoutCacheKey(const TextLayoutCacheKey& other);
78e74fef3b55dc1b5daf40b3a6aea857582071560fFabrice Di Meglio
7948796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    /**
80d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio     * Get the size of the Cache key.
81d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio     */
8206daa7b6b2186cf1e83e14d2adbb0d2050b79c39Jeff Brown    size_t getSize() const;
83d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
84717060b076350ea811153290281075396a554fedFabrice Di Meglio    static int compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs);
85717060b076350ea811153290281075396a554fedFabrice Di Meglio
86832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien    inline const UChar* getText() const { return textCopy.string(); }
87832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien
88d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglioprivate:
89d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio    String16 textCopy;
905c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    size_t start;
919c418dbc56efd334c68872d281f75138e16eae46Fabrice Di Meglio    size_t count;
925c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    size_t contextCount;
93d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio    int dirFlags;
94d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio    SkTypeface* typeface;
95aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkScalar textSize;
96aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkScalar textSkewX;
97aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkScalar textScaleX;
98aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    uint32_t flags;
99aabe537f1ed3b64f755af9fc62022d6074eec169Fabrice Di Meglio    SkPaint::Hinting hinting;
100ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    SkPaint::FontVariant variant;
101ac1cbaf2e5575ac75a0160e13089d51a0bb232faBilly Hewlett    SkLanguage language;
102e74fef3b55dc1b5daf40b3a6aea857582071560fFabrice Di Meglio
103d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio}; // TextLayoutCacheKey
104d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
105717060b076350ea811153290281075396a554fedFabrice Di Meglioinline int strictly_order_type(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
106717060b076350ea811153290281075396a554fedFabrice Di Meglio    return TextLayoutCacheKey::compare(lhs, rhs) < 0;
107717060b076350ea811153290281075396a554fedFabrice Di Meglio}
108717060b076350ea811153290281075396a554fedFabrice Di Meglio
109717060b076350ea811153290281075396a554fedFabrice Di Meglioinline int compare_type(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) {
110717060b076350ea811153290281075396a554fedFabrice Di Meglio    return TextLayoutCacheKey::compare(lhs, rhs);
111717060b076350ea811153290281075396a554fedFabrice Di Meglio}
112717060b076350ea811153290281075396a554fedFabrice Di Meglio
113d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio/*
114a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * TextLayoutValue is the Cache value
115d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio */
116a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutValue : public RefBase {
117d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic:
118a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutValue(size_t contextCount);
119d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
12048796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    void setElapsedTime(uint32_t time);
12148796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio    uint32_t getElapsedTime();
122d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
1235c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline const jfloat* getAdvances() const { return mAdvances.array(); }
1245c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline size_t getAdvancesCount() const { return mAdvances.size(); }
1255c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline jfloat getTotalAdvance() const { return mTotalAdvance; }
1265c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline const jchar* getGlyphs() const { return mGlyphs.array(); }
1275c863f741e8e484bb39decd516c9fa4c6322e671Fabrice Di Meglio    inline size_t getGlyphsCount() const { return mGlyphs.size(); }
1282301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    inline const jfloat* getPos() const { return mPos.array(); }
1292301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    inline size_t getPosCount() const { return mPos.size(); }
130d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
131d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio    /**
1324dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio     * Advances vector
133fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
1344dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio    Vector<jfloat> mAdvances;
135d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
136fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    /**
137fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     * Total number of advances
138fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
139fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    jfloat mTotalAdvance;
140fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio
141fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    /**
1424dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio     * Glyphs vector
143fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
1444dd99e5912c73d5a9db165cefd4852b51ea438e8Fabrice Di Meglio    Vector<jchar> mGlyphs;
145fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio
146fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    /**
1472301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien     * Pos vector (2 * i is x pos, 2 * i + 1 is y pos, same as drawPosText)
1482301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien     */
1492301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    Vector<jfloat> mPos;
1502301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien
1512301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien    /**
1520af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     * Get the size of the Cache entry
1530af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
1540af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    size_t getSize() const;
1550af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
1560af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglioprivate:
1570af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
158fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     * Time for computing the values (in milliseconds)
159fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio     */
160fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio    uint32_t mElapsedTime;
1619f82b580d744ce4baf057b061994394dcf239eedFabrice Di Meglio
16248796a81be31e42ee267347156c94445cb9fb67aFabrice Di Meglio}; // TextLayoutCacheValue
163d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
164fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio/**
165a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * The TextLayoutShaper is responsible for shaping (with the Harfbuzz library)
166fcf2be1846935e7983ea2fe87fdd4d7af27764b6Fabrice Di Meglio */
167a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutShaper {
168d313c665e618af3194f504064bcd284fe5368682Fabrice Di Megliopublic:
169a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutShaper();
170a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    virtual ~TextLayoutShaper();
171d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
172a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
1730af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio            size_t start, size_t count, size_t contextCount, int dirFlags);
1740af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
17515cc68ced062a0dbd174718abfb1c783ac1aa433Fabrice Di Meglio    void purgeCaches();
17615cc68ced062a0dbd174718abfb1c783ac1aa433Fabrice Di Meglio
1770af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglioprivate:
1780af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
1790af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     * Harfbuzz shaper item
1800af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
1810af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    HB_ShaperItem mShaperItem;
1820af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
1830af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
1840af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     * Harfbuzz font
1850af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
1860af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    HB_FontRec mFontRec;
1870af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
1880af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
1890af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     * Skia Paint used for shaping
1900af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
1910af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    SkPaint mShapingPaint;
1920af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
1930af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    /**
194d6deccb346e913d906f484d279b19e0f6ea18d94Billy Hewlett     * Skia default typeface to be returned if we cannot resolve script
1950af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio     */
1960af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    SkTypeface* mDefaultTypeface;
1970af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
198902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio    /**
199902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     * Cache of Harfbuzz faces
200902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     */
2010af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    KeyedVector<SkFontID, HB_Face> mCachedHBFaces;
2020af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
203902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio    /**
204902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     * Cache of glyph array size
205902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     */
2060af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    size_t mShaperItemGlyphArraySize;
2070af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
208902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio    /**
209902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     * Buffer for containing the ICU normalized form of a run
210902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     */
211902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio    UnicodeString mNormalizedString;
212902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio
213902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio    /**
214902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     * Buffer for normalizing a piece of a run with ICU
215902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio     */
216902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio    UnicodeString mBuffer;
217902a5b31c50022a1b7707be4d333e4ce6ec4a8faFabrice Di Meglio
21815cc68ced062a0dbd174718abfb1c783ac1aa433Fabrice Di Meglio    void init();
21915cc68ced062a0dbd174718abfb1c783ac1aa433Fabrice Di Meglio    void unrefTypefaces();
22015cc68ced062a0dbd174718abfb1c783ac1aa433Fabrice Di Meglio
221d6deccb346e913d906f484d279b19e0f6ea18d94Billy Hewlett    SkTypeface* typefaceForScript(const SkPaint* paint, SkTypeface* typeface,
222d6deccb346e913d906f484d279b19e0f6ea18d94Billy Hewlett        HB_Script script);
2231637dcd16cd314574a58602337a2c7222130b1b9Raph Levien
224bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio    size_t shapeFontRun(const SkPaint* paint, bool isRTL);
2250af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
226bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio    void computeValues(const SkPaint* paint, const UChar* chars,
2270af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio            size_t start, size_t count, size_t contextCount, int dirFlags,
2280af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
2292301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien            Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
2300af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
231bd901dee317d10c6a921922c3d7d788b90306c82Fabrice Di Meglio    void computeRunValues(const SkPaint* paint, const UChar* chars,
2320af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio            size_t count, bool isRTL,
2330af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
2342301d32f7e2ba584abc31ac177dde754385d3c04Raph Levien            Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);
2350af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
236960511848ade732f7dab838a1625729698c7c952Billy Hewlett    SkTypeface* getCachedTypeface(SkTypeface** typeface, HB_Script script, SkTypeface::Style style);
2370af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    HB_Face getCachedHBFace(SkTypeface* typeface);
2380af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
239f62034d89611fbd3e1d41413847241757acd0c10Raph Levien    bool doShaping(size_t size);
2400af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    void createShaperItemGlyphArrays(size_t size);
2410af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio    void deleteShaperItemGlyphArrays();
242d6deccb346e913d906f484d279b19e0f6ea18d94Billy Hewlett    bool isComplexScript(HB_Script script);
2430af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
244a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio}; // TextLayoutShaper
2450af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
246a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio/**
247a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * Cache of text layout information.
248a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio */
249a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutCache : private OnEntryRemoved<TextLayoutCacheKey, sp<TextLayoutValue> >
250a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio{
251a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Megliopublic:
252a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutCache(TextLayoutShaper* shaper);
253a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
254a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    ~TextLayoutCache();
255a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
256a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    bool isInitialized() {
257a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio        return mInitialized;
258a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    }
259a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
260a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /**
261a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Used as a callback when an entry is removed from the cache
262a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Do not invoke directly
263a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
264a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void operator()(TextLayoutCacheKey& text, sp<TextLayoutValue>& desc);
265a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
266a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
267a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio            jint count, jint contextCount, jint dirFlags);
268a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
269a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /**
270a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Clear the cache
271a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
27213ba4e478d19001ddb6828bd1fd8fbc1e0cb208fRaph Levien    void purgeCaches();
273a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
274a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioprivate:
275a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutShaper* mShaper;
276a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    Mutex mLock;
277a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    bool mInitialized;
278a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
279a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    GenerationCache<TextLayoutCacheKey, sp<TextLayoutValue> > mCache;
280a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
281a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint32_t mSize;
282a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint32_t mMaxSize;
283a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
284a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint32_t mCacheHitCount;
285a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint64_t mNanosecondsSaved;
286a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
287a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    uint64_t mCacheStartTime;
288a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
289a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    RtlDebugLevel mDebugLevel;
290a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    bool mDebugEnabled;
291a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
292a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /*
293a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Class initialization
294a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
295a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void init();
296a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
297a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    /**
298a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     * Dump Cache statistics
299a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio     */
300a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    void dumpCacheStats();
301a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
302a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio}; // TextLayoutCache
303a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
304a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio/**
305a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio * The TextLayoutEngine is reponsible for computing TextLayoutValues
306a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio */
307a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioclass TextLayoutEngine : public Singleton<TextLayoutEngine> {
308a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Megliopublic:
309a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutEngine();
310a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    virtual ~TextLayoutEngine();
311a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio
312832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien    /**
313832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * Note: this method currently does a defensive copy of the text argument, in case
314832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * there is concurrent mutation of it. The contract may change, and may in the
315832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * future require the caller to guarantee that the contents will not change during
316832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     * the call. Be careful of this when doing optimization.
317832815cb53e951485ff5a0e6c705446d0bfb5883Raph Levien     **/
318a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
319a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio            jint count, jint contextCount, jint dirFlags);
32030ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio
32130ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio    void purgeCaches();
32230ca5cd11a23f06f2f8eeaa587685450826f800fFabrice Di Meglio
323a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglioprivate:
324a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutCache* mTextLayoutCache;
325a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio    TextLayoutShaper* mShaper;
326a731b082b2c43204e6e9f927ab82fb732934a83bFabrice Di Meglio}; // TextLayoutEngine
3270af10b54bf110653b74cb92793484b412a90b657Fabrice Di Meglio
328d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio} // namespace android
329d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio#endif /* ANDROID_TEXT_LAYOUT_CACHE_H */
330d313c665e618af3194f504064bcd284fe5368682Fabrice Di Meglio
331