11e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/* 21e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Copyright (C) 2010 The Android Open Source Project 31e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * 41e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 51e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * you may not use this file except in compliance with the License. 61e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * You may obtain a copy of the License at 71e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * 81e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 91e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * 101e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Unless required by applicable law or agreed to in writing, software 111e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 121e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * See the License for the specific language governing permissions and 141e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * limitations under the License. 151e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 161e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H 185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H 191e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 201e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include <GLES2/gl2.h> 211e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 221e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include <SkPaint.h> 231e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 24059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy#include <utils/LruCache.h> 25321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy#include <utils/String16.h> 2625dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy 271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include "FontRenderer.h" 281e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include "Texture.h" 291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace android { 311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace uirenderer { 321e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 338aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyclass Caches; 348aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 351e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guystruct ShadowText { 36059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy ShadowText(): len(0), radius(0.0f), textSize(0.0f), typeface(NULL), 37059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy flags(0), italicStyle(0.0f), scaleX(0), text(NULL), positions(NULL) { 38c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy } 391e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 4069fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy // len is the number of bytes in text 41059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy ShadowText(SkPaint* paint, float radius, uint32_t len, const char* srcText, 42416a847633680d94efb926837efdc18726d54918Raph Levien const float* positions): 43059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy len(len), radius(radius), positions(positions) { 44321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy // TODO: Propagate this through the API, we should not cast here 45321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy text = (const char16_t*) srcText; 461e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 47c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy textSize = paint->getTextSize(); 48c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy typeface = paint->getTypeface(); 49cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy 50cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy flags = 0; 51cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy if (paint->isFakeBoldText()) { 52cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy flags |= Font::kFakeBold; 53cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy } 54cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy 55059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy italicStyle = paint->getTextSkewX(); 56059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy scaleX = paint->getTextScaleX(); 571e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 581e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 591e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ~ShadowText() { 601e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 611e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 62059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy hash_t hash() const; 63059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 64059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy static int compare(const ShadowText& lhs, const ShadowText& rhs); 65059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 66059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy bool operator==(const ShadowText& other) const { 67059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return compare(*this, other) == 0; 68059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy } 69059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 70059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy bool operator!=(const ShadowText& other) const { 71059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return compare(*this, other) != 0; 72059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy } 73321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy 74321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy void copyTextLocally() { 7569fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy uint32_t charCount = len / sizeof(char16_t); 7669fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy str.setTo((const char16_t*) text, charCount); 77321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy text = str.string(); 78416a847633680d94efb926837efdc18726d54918Raph Levien if (positions != NULL) { 79416a847633680d94efb926837efdc18726d54918Raph Levien positionsCopy.clear(); 8069fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy positionsCopy.appendArray(positions, charCount * 2); 81416a847633680d94efb926837efdc18726d54918Raph Levien positions = positionsCopy.array(); 82416a847633680d94efb926837efdc18726d54918Raph Levien } 83321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy } 841e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 85059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy uint32_t len; 86059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy float radius; 87059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy float textSize; 88059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy SkTypeface* typeface; 89059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy uint32_t flags; 90059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy float italicStyle; 91059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy float scaleX; 92059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy const char16_t* text; 93059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy const float* positions; 94059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 95059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy // Not directly used to compute the cache key 96059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy String16 str; 97059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy Vector<float> positionsCopy; 98059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 991e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // struct ShadowText 1001e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 101059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy// Caching support 102059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 103059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyinline int strictly_order_type(const ShadowText& lhs, const ShadowText& rhs) { 104059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return ShadowText::compare(lhs, rhs) < 0; 105059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy} 106059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 107059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyinline int compare_type(const ShadowText& lhs, const ShadowText& rhs) { 108059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return ShadowText::compare(lhs, rhs); 109059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy} 110059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 111059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyinline hash_t hash_type(const ShadowText& entry) { 112059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return entry.hash(); 113059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy} 114059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 1151e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/** 1161e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Alpha texture used to represent a shadow. 1171e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1181e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guystruct ShadowTexture: public Texture { 1198aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy ShadowTexture(Caches& caches): Texture(caches) { 1201e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1211e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1221e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy float left; 1231e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy float top; 1241e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // struct ShadowTexture 1251e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1261e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyclass TextDropShadowCache: public OnEntryRemoved<ShadowText, ShadowTexture*> { 1271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guypublic: 128fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy TextDropShadowCache(); 1291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy TextDropShadowCache(uint32_t maxByteSize); 1301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ~TextDropShadowCache(); 1311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1321e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1331e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Used as a callback when an entry is removed from the cache. 1341e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Do not invoke directly. 1351e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1361e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void operator()(ShadowText& text, ShadowTexture*& texture); 1371e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1381e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len, 139059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy int numGlyphs, float radius, const float* positions); 1401e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1411e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1421e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Clears the cache. This causes all textures to be deleted. 1431e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1441e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void clear(); 1451e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1461e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void setFontRenderer(FontRenderer& fontRenderer) { 1471e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mRenderer = &fontRenderer; 1481e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1491e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1501e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1511e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Sets the maximum size of the cache in bytes. 1521e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1531e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void setMaxSize(uint32_t maxSize); 1541e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1551e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Returns the maximum size of the cache in bytes. 1561e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1571e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t getMaxSize(); 1581e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1591e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Returns the current size of the cache in bytes. 1601e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1611e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t getSize(); 1621e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1631e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyprivate: 16425dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy void init(); 16525dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy 166059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy LruCache<ShadowText, ShadowTexture*> mCache; 1671e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1681e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t mSize; 1691e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t mMaxSize; 1701e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy FontRenderer* mRenderer; 17125dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy bool mDebugEnabled; 1721e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // class TextDropShadowCache 1731e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1741e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace uirenderer 1751e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace android 1761e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1775b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H 178