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 24321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy#include <utils/String16.h> 2525dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy 2625dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy#include "utils/Compare.h" 2721b028a44f3e0bd9b0f0432b8b92c45f661d22a4Romain Guy#include "utils/GenerationCache.h" 281e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include "FontRenderer.h" 291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include "Texture.h" 301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace android { 321e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace uirenderer { 331e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 341e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guystruct ShadowText { 352fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy ShadowText(): radius(0), len(0), textSize(0.0f), typeface(NULL) { 36c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy } 371e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 38416a847633680d94efb926837efdc18726d54918Raph Levien ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText, 39416a847633680d94efb926837efdc18726d54918Raph Levien const float* positions): 40416a847633680d94efb926837efdc18726d54918Raph Levien radius(radius), len(len), positions(positions) { 41321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy // TODO: Propagate this through the API, we should not cast here 42321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy text = (const char16_t*) srcText; 431e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 44c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy textSize = paint->getTextSize(); 45c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy typeface = paint->getTypeface(); 46cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy 47cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy flags = 0; 48cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy if (paint->isFakeBoldText()) { 49cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy flags |= Font::kFakeBold; 50cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy } 51cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy 52cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy const float skewX = paint->getTextSkewX(); 53cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy italicStyle = *(uint32_t*) &skewX; 54cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy 55cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy const float scaleXFloat = paint->getTextScaleX(); 56cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy scaleX = *(uint32_t*) &scaleXFloat; 571e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 581e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 591e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ~ShadowText() { 601e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 611e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 621e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t radius; 631e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t len; 64c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy float textSize; 65c4d8eb6fb7c88c5c4da38b0b113c24cc4b78c0b7Romain Guy SkTypeface* typeface; 66cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy uint32_t flags; 67cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy uint32_t italicStyle; 68cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy uint32_t scaleX; 69321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy const char16_t* text; 70416a847633680d94efb926837efdc18726d54918Raph Levien const float* positions; 71321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy String16 str; 72416a847633680d94efb926837efdc18726d54918Raph Levien Vector<float> positionsCopy; 73321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy 74321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy void copyTextLocally() { 75321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy str.setTo((const char16_t*) text, len >> 1); 76321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy text = str.string(); 77416a847633680d94efb926837efdc18726d54918Raph Levien if (positions != NULL) { 78416a847633680d94efb926837efdc18726d54918Raph Levien positionsCopy.clear(); 79416a847633680d94efb926837efdc18726d54918Raph Levien positionsCopy.appendArray(positions, len); 80416a847633680d94efb926837efdc18726d54918Raph Levien positions = positionsCopy.array(); 81416a847633680d94efb926837efdc18726d54918Raph Levien } 82321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy } 831e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 841e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy bool operator<(const ShadowText& rhs) const { 852fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy LTE_INT(len) { 862fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy LTE_INT(radius) { 872fc941e4650d618ff6e122f28b616d9032ffa134Romain Guy LTE_FLOAT(textSize) { 88321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy LTE_INT(typeface) { 89cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy LTE_INT(flags) { 90cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy LTE_INT(italicStyle) { 91cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy LTE_INT(scaleX) { 92416a847633680d94efb926837efdc18726d54918Raph Levien int cmp = memcmp(text, rhs.text, len); 93416a847633680d94efb926837efdc18726d54918Raph Levien if (cmp < 0) return true; 94416a847633680d94efb926837efdc18726d54918Raph Levien if (cmp == 0 && rhs.positions != NULL) { 95416a847633680d94efb926837efdc18726d54918Raph Levien if (positions == NULL) return true; 96416a847633680d94efb926837efdc18726d54918Raph Levien return memcmp(positions, rhs.positions, len << 2) < 0; 97416a847633680d94efb926837efdc18726d54918Raph Levien } 98cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy } 99cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy } 100cabfcc1364eb7e4de0b15b3574fba45027b45cfcRomain Guy } 1011e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1021e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1031e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1041e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1051e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy return false; 1061e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1071e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // struct ShadowText 1081e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1091e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/** 1101e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Alpha texture used to represent a shadow. 1111e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1121e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guystruct ShadowTexture: public Texture { 1131e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ShadowTexture(): Texture() { 1141e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1151e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1161e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy float left; 1171e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy float top; 1181e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // struct ShadowTexture 1191e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1201e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyclass TextDropShadowCache: public OnEntryRemoved<ShadowText, ShadowTexture*> { 1211e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guypublic: 122fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy TextDropShadowCache(); 1231e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy TextDropShadowCache(uint32_t maxByteSize); 1241e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ~TextDropShadowCache(); 1251e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1261e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Used as a callback when an entry is removed from the cache. 1281e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Do not invoke directly. 1291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void operator()(ShadowText& text, ShadowTexture*& texture); 1311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1321e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len, 133416a847633680d94efb926837efdc18726d54918Raph Levien int numGlyphs, uint32_t radius, const float* positions); 1341e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1351e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1361e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Clears the cache. This causes all textures to be deleted. 1371e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1381e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void clear(); 1391e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1401e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void setFontRenderer(FontRenderer& fontRenderer) { 1411e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy mRenderer = &fontRenderer; 1421e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy } 1431e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1441e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1451e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Sets the maximum size of the cache in bytes. 1461e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1471e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy void setMaxSize(uint32_t maxSize); 1481e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1491e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Returns the maximum size of the cache in bytes. 1501e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1511e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t getMaxSize(); 1521e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy /** 1531e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Returns the current size of the cache in bytes. 1541e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */ 1551e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t getSize(); 1561e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1571e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyprivate: 15825dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy void init(); 15925dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy 1601e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy GenerationCache<ShadowText, ShadowTexture*> mCache; 1611e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1621e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t mSize; 1631e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy uint32_t mMaxSize; 1641e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy FontRenderer* mRenderer; 16525dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy bool mDebugEnabled; 1661e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // class TextDropShadowCache 1671e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1681e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace uirenderer 1691e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace android 1701e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy 1715b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H 172