SkPaint.cpp revision 5c7fc8f96344cc7f780558c714d3e52f0669b0b8
11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 105c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#include <new> 115c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h" 130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFontHost.h" 151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkImageFilter.h" 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h" 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPathEffect.h" 180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRasterizer.h" 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h" 2040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkScalar.h" 210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScalerContext.h" 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStroke.h" 2340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkTextFormatParams.h" 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypeface.h" 250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h" 260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAutoKern.h" 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkGlyphCache.h" 284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkPaintDefaults.h" 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// define this to get a printf for out-of-range parameter in setters 311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// e.g. setTextSize(-1) 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//#define SK_REPORT_API_RANGE_CHECK 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC fGenerationID++ 3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } 3787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#else 3887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC 3987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression) 4087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 4187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 42c1c43a17e7f2a87951739691056728a80e9aef6bMike ReedSkPaint::SkPaint() { 43c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // since we may have padding, we zero everything so that our memcmp() call 44c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // in operator== will work correctly. 45c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // with this, we can skip 0 and null individual initializations 46c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed sk_bzero(this, sizeof(*this)); 47c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed 48c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#if 0 // not needed with the bzero call above 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTypeface = NULL; 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextSkewX = 0; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPathEffect = NULL; 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader = NULL; 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXfermode = NULL; 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMaskFilter = NULL; 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColorFilter = NULL; 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRasterizer = NULL; 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fLooper = NULL; 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fImageFilter = NULL; 59c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed fWidth = 0; 60c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#endif 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fTextSize = SkPaintDefaults_TextSize; 63c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed fTextScaleX = SK_Scalar1; 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColor = SK_ColorBLACK; 654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fMiterLimit = SkPaintDefaults_MiterLimit; 664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fFlags = SkPaintDefaults_Flags; 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCapType = kDefault_Cap; 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fJoinType = kDefault_Join; 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextAlign = kLeft_Align; 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStyle = kFill_Style; 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextEncoding = kUTF8_TextEncoding; 724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fHinting = SkPaintDefaults_Hinting; 731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 745c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio new(&fTextLocale) SkString(); 7595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase fGenerationID = 0; 7687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::SkPaint(const SkPaint& src) { 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(this, &src, sizeof(src)); 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fTypeface); 8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fPathEffect); 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fShader); 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fXfermode); 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fMaskFilter); 8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fColorFilter); 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fRasterizer); 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fLooper); 901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeRef(fImageFilter); 915c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#ifdef SK_BUILD_FOR_ANDROID 925c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio new(&fTextLocale) SkString(src.fTextLocale); 935c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#endif 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::~SkPaint() { 9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fTypeface); 9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fPathEffect); 9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fShader); 10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fXfermode); 10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fMaskFilter); 10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fColorFilter); 10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fRasterizer); 10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fLooper); 1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeUnref(fImageFilter); 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint& SkPaint::operator=(const SkPaint& src) { 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(&src); 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fTypeface); 11240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fPathEffect); 11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fShader); 11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fXfermode); 11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fMaskFilter); 11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fColorFilter); 11740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fRasterizer); 11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fLooper); 1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeRef(src.fImageFilter); 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fTypeface); 12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fPathEffect); 12340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fShader); 12440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fXfermode); 12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fMaskFilter); 12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fColorFilter); 12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fRasterizer); 12840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fLooper); 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeUnref(fImageFilter); 1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1325c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio fTextLocale.~SkString(); 1339f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase uint32_t oldGenerationID = fGenerationID; 13487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(this, &src, sizeof(src)); 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1375c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio new(&fTextLocale) SkString(src.fTextLocale); 1389f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase fGenerationID = oldGenerationID + 1; 13987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return *this; 1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool operator==(const SkPaint& a, const SkPaint& b) { 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger //assumes that fGenerationID is the last field in the struct 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(&a, &b, SK_OFFSETOF(SkPaint, fGenerationID)); 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(&a, &b, sizeof(a)); 1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::reset() { 1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint init; 1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1579f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase uint32_t oldGenerationID = fGenerationID; 15887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *this = init; 1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1619f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase fGenerationID = oldGenerationID + 1; 16287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 16395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase} 16495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 16695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haaseuint32_t SkPaint::getGenerationID() const { 16795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase return fGenerationID; 1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 16987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerunsigned SkPaint::getBaseGlyphCount(SkUnichar text) const { 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoGlyphCache autoCache(*this, NULL); 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkGlyphCache* cache = autoCache.getCache(); 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return cache->getBaseGlyphCount(text); 1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setHinting(Hinting hintingLevel) { 18087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); 18187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fHinting = hintingLevel; 1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFlags(uint32_t flags) { 18587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(fFlags != flags); 18687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fFlags = flags; 1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAntiAlias(bool doAA) { 19087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doAA != isAntiAlias()); 19187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); 1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDither(bool doDither) { 19587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doDither != isDither()); 19687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); 1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setSubpixelText(bool doSubpixel) { 20087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doSubpixel != isSubpixelText()); 20187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag)); 202af2616552738d653d5453915d3236e7154b868cdMike Reed} 203af2616552738d653d5453915d3236e7154b868cdMike Reed 20487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLCDRenderText(bool doLCDRender) { 20587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doLCDRender != isLCDRenderText()); 20687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag)); 20787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 20887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 20987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) { 21087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doEmbeddedBitmapText != isEmbeddedBitmapText()); 21187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag)); 2122cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed} 2132cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed 21487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAutohinted(bool useAutohinter) { 21587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(useAutohinter != isAutohinted()); 21640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag)); 21740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 21840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 21987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLinearText(bool doLinearText) { 22087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doLinearText != isLinearText()); 22187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag)); 2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkPaint::setVerticalText(bool doVertical) { 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GEN_ID_INC_EVAL(doVertical != isVerticalText()); 2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setFlags(SkSetClearMask(fFlags, doVertical, kVerticalText_Flag)); 2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setUnderlineText(bool doUnderline) { 23087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doUnderline != isUnderlineText()); 23187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag)); 2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrikeThruText(bool doStrikeThru) { 23587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doStrikeThru != isStrikeThruText()); 23687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag)); 2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFakeBoldText(bool doFakeBold) { 24087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doFakeBold != isFakeBoldText()); 24187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag)); 2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDevKernText(bool doDevKern) { 24587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doDevKern != isDevKernText()); 24687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); 2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFilterBitmap(bool doFilter) { 25087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doFilter != isFilterBitmap()); 25187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag)); 2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 25487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStyle(Style style) { 25595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)style < kStyleCount) { 25687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)style != fStyle); 25787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fStyle = style; 25887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 26205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setColor(SkColor color) { 26687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(color != fColor); 26787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fColor = color; 2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAlpha(U8CPU a) { 27187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), 27287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkColorGetG(fColor), SkColorGetB(fColor))); 2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 27687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setColor(SkColorSetARGB(a, r, g, b)); 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeWidth(SkScalar width) { 28095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if (width >= 0) { 28187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(width != fWidth); 28287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fWidth = width; 28387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); 2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 28705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 29087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeMiter(SkScalar limit) { 29195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if (limit >= 0) { 29287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(limit != fMiterLimit); 29387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fMiterLimit = limit; 29487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 29805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 30187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeCap(Cap ct) { 30295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)ct < kCapCount) { 30387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)ct != fCapType); 30487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fCapType = SkToU8(ct); 30587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 30995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 31287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeJoin(Join jt) { 31395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)jt < kJoinCount) { 31487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)jt != fJoinType); 31587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fJoinType = SkToU8(jt); 31687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 32095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextAlign(Align align) { 32695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)align < kAlignCount) { 32787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)align != fTextAlign); 32887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextAlign = SkToU8(align); 32987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 33395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 33687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSize(SkScalar ts) { 3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (ts >= 0) { 33887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(ts != fTextSize); 33987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextSize = ts; 34087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextSize() called with negative value\n"); 3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 34495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextScaleX(SkScalar scaleX) { 34887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(scaleX != fTextScaleX); 34987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextScaleX = scaleX; 3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 35287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSkewX(SkScalar skewX) { 35387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(skewX != fTextSkewX); 35487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextSkewX = skewX; 3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 35787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextEncoding(TextEncoding encoding) { 35895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)encoding <= kGlyphID_TextEncoding) { 35987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); 36087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextEncoding = encoding; 36187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 36595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3685c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#ifdef SK_BUILD_FOR_ANDROID 3695c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Megliovoid SkPaint::setTextLocale(const SkString& locale) { 3705c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio if(!fTextLocale.equals(locale)) { 3715c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio fTextLocale.set(locale); 3725c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio GEN_ID_INC; 3735c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio } 3745c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio} 3755c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#endif 3765c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio 37787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 37987b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkTypeface* SkPaint::setTypeface(SkTypeface* font) { 3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fTypeface, font); 38187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return font; 3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 38540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { 3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fRasterizer, r); 38787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return r; 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 39140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { 3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fLooper, looper); 39387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return looper; 3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3971cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { 3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRefCnt_SafeAssign(fImageFilter, imageFilter); 3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GEN_ID_INC; 4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return imageFilter; 4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h" 4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h" 4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 40840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void DetachDescProc(const SkDescriptor* desc, void* context) { 409fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc); 410fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy} 411fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy 4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 413b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guyconst SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) { 414b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy SkGlyphCache* cache; 415b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 416b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 417b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy const SkGlyph& glyph = cache->getUnicharMetrics(text); 418b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 419b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy SkGlyphCache::AttachCache(cache); 420b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy return glyph; 421b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy} 422b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 4231bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guyconst SkGlyph& SkPaint::getGlyphMetrics(uint16_t glyphId) { 4241bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy SkGlyphCache* cache; 4251bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 4261bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 4271bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphId); 4281bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 4291bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy SkGlyphCache::AttachCache(cache); 4301bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy return glyph; 4311bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy} 4321bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 43390a1efbdde19ee56c33929592277871509c25893Romain Guyconst void* SkPaint::findImage(const SkGlyph& glyph) { 434fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy // See ::detachCache() 435fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy SkGlyphCache* cache; 436fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 43790a1efbdde19ee56c33929592277871509c25893Romain Guy 438fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy const void* image = cache->findImage(glyph); 439fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy 440fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy SkGlyphCache::AttachCache(cache); 441fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy return image; 44290a1efbdde19ee56c33929592277871509c25893Romain Guy} 44387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 44490a1efbdde19ee56c33929592277871509c25893Romain Guy 4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength, 4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t glyphs[]) const { 4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (byteLength == 0) { 4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 45040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(textData != NULL); 4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL == glyphs) { 4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getTextEncoding()) { 4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kUTF8_TextEncoding: 4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkUTF8_CountUnichars((const char*)textData, byteLength); 4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kUTF16_TextEncoding: 4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkUTF16_CountUnichars((const uint16_t*)textData, 4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project byteLength >> 1); 4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kGlyphID_TextEncoding: 4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return byteLength >> 1; 4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 46740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // if we get here, we have a valid glyphs[] array, so time to fill it in 46940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // handle this encoding before the setup for the glyphcache 4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->getTextEncoding() == kGlyphID_TextEncoding) { 4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we want to ignore the low bit of byteLength 4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(glyphs, textData, byteLength >> 1 << 1); 4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return byteLength >> 1; 4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 47640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = text + byteLength; 4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t* gptr = glyphs; 4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getTextEncoding()) { 4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkPaint::kUTF8_TextEncoding: 4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text)); 4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkPaint::kUTF16_TextEncoding: { 4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* text16 = (const uint16_t*)text; 4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* stop16 = (const uint16_t*)stop; 4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text16 < stop16) { 4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); 4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gptr - glyphs; 5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 50475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reedbool SkPaint::containsText(const void* textData, size_t byteLength) const { 50575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == byteLength) { 50675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 50775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 50840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 50975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkASSERT(textData != NULL); 51040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 51175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed // handle this encoding before the setup for the glyphcache 51275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (this->getTextEncoding() == kGlyphID_TextEncoding) { 51375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* glyphID = static_cast<const uint16_t*>(textData); 51475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed size_t count = byteLength >> 1; 51575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed for (size_t i = 0; i < count; i++) { 51675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == glyphID[i]) { 51775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 51875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 51975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 52075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 52175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 52240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 52375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkAutoGlyphCache autoCache(*this, NULL); 52475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkGlyphCache* cache = autoCache.getCache(); 52575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed 52675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed switch (this->getTextEncoding()) { 52775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed case SkPaint::kUTF8_TextEncoding: { 52875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const char* text = static_cast<const char*>(textData); 52975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const char* stop = text + byteLength; 53075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed while (text < stop) { 53175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) { 53275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 53375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 53475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 53575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed break; 53675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 53775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed case SkPaint::kUTF16_TextEncoding: { 53875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* text = static_cast<const uint16_t*>(textData); 53975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* stop = text + (byteLength >> 1); 54075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed while (text < stop) { 54175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) { 54275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 54375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 54475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 54575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed break; 54675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 54775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed default: 5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 54975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 55075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 55175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 55275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed} 55375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed 554091f227385b467090b5a7169a8e2faf19eca7105Mike Reedvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, 555091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkUnichar textData[]) const { 556091f227385b467090b5a7169a8e2faf19eca7105Mike Reed if (count <= 0) { 557091f227385b467090b5a7169a8e2faf19eca7105Mike Reed return; 558091f227385b467090b5a7169a8e2faf19eca7105Mike Reed } 559091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 560091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkASSERT(glyphs != NULL); 561091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkASSERT(textData != NULL); 562091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 563091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkAutoGlyphCache autoCache(*this, NULL); 564091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkGlyphCache* cache = autoCache.getCache(); 565091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 566091f227385b467090b5a7169a8e2faf19eca7105Mike Reed for (int index = 0; index < count; index++) { 567091f227385b467090b5a7169a8e2faf19eca7105Mike Reed textData[index] = cache->glyphToUnichar(glyphs[index]); 568091f227385b467090b5a7169a8e2faf19eca7105Mike Reed } 569091f227385b467090b5a7169a8e2faf19eca7105Mike Reed} 570091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 57340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, 57440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 57740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 58140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, 58240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 58540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text)); 5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 58940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, 59040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 59340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 59740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, 59840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 60140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text)); 6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 60540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, 60640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 60940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 61740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, 61840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 62140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr -= 1; 6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 62940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, 63040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 63340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF8_NextUnichar(text)); 6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, 63840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 64140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text)); 6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 64540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, 64640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 64940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text)); 6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 65340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, 65440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 65740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text)); 6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 66140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, 66240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 66540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDAdvance(glyphID); 6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 67340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, 67440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 67740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr -= 1; 6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDAdvance(glyphID); 6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd, 68640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool needFullMetrics) const { 6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static const SkMeasureCacheProc gMeasureCacheProcs[] = { 6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_next, 6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_next, 6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_next, 69140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_prev, 6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_prev, 6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_prev, 69540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf8_next, 6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf16_next, 6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_glyph_next, 69940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf8_prev, 7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf16_prev, 7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_glyph_prev 7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 70440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned index = this->getTextEncoding(); 7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 70740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (kBackward_TextBufferDirection == tbd) { 7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 3; 70940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 71040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!needFullMetrics && !this->isDevKernText()) { 7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 6; 71240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs)); 7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gMeasureCacheProcs[index]; 7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache, 72140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 72440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache, 72940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 73240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y); 7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 73640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, 73740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 74040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache, 74540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 74840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text), 7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x, y); 7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 75340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, 75440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 75740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache, 76640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 76940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID, x, y); 7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 77740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawCacheProc SkPaint::getDrawCacheProc() const { 7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static const SkDrawCacheProc gDrawCacheProcs[] = { 7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_00, 7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_00, 7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_00, 78240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_xy, 7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_xy, 7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_xy 7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 78740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned index = this->getTextEncoding(); 78940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fFlags & kSubpixelText_Flag) { 7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 3; 79140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 79240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs)); 7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gDrawCacheProcs[index]; 7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame { 8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 80140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint) 80240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fPaint((SkPaint*)paint) { 8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextSize = paint->getTextSize(); 8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStyle = paint->getStyle(); 8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setStyle(SkPaint::kFill_Style); 8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 80740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 80840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger ~SkAutoRestorePaintTextSizeAndFrame() { 8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setStyle(fStyle); 8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setTextSize(fTextSize); 8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 81240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint* fPaint; 8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fTextSize; 8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style fStyle; 8170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 81940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds) { 8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->set(SkIntToScalar(g.fLeft), 8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop), 8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fLeft + g.fWidth), 8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop + g.fHeight)); 8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 826e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so 827e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// we don't overflow along the way 828e63c5c9f6752244ca0f39075fa148a0281593831Mike Reedtypedef int64_t Sk48Dot16; 829e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed 830e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#ifdef SK_SCALAR_IS_FLOAT 831e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed static inline float Sk48Dot16ToScalar(Sk48Dot16 x) { 83240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return (float) (x * 1.5258789e-5); // x * (1 / 65536.0f) 833e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed } 834e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#else 835e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed static inline SkFixed Sk48Dot16ToScalar(Sk48Dot16 x) { 836e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // just return the low 32bits 837e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed return static_cast<SkFixed>(x); 838e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed } 839e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#endif 840e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed 8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { 842e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed SkScalar sx = Sk48Dot16ToScalar(dx); 8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->join(SkIntToScalar(g.fLeft) + sx, 8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop), 8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fLeft + g.fWidth) + sx, 8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop + g.fHeight)); 8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) { 8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar sy = Sk48Dot16ToScalar(dy); 8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bounds->join(SkIntToScalar(g.fLeft), 8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fTop) + sy, 8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fLeft + g.fWidth), 8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fTop + g.fHeight) + sy); 8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16); 8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY 8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkFixed advance(const SkGlyph& glyph, int xyIndex) { 8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(0 == xyIndex || 1 == xyIndex); 8621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return (&glyph.fAdvanceX)[xyIndex]; 8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache, 8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text, size_t byteLength, 86740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int* count, SkRect* bounds) const { 8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count); 86940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (byteLength == 0) { 8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = 0; 87140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (bounds) { 8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->setEmpty(); 87340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc; 8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project NULL != bounds); 8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int xyIndex; 8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger JoinBoundsProc joinBoundsProc; 8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (this->isVerticalText()) { 8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger xyIndex = 1; 8851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc = join_bounds_y; 8861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger xyIndex = 0; 8881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc = join_bounds_x; 8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int n = 1; 8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = (const char*)text + byteLength; 8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph* g = &glyphCacheProc(cache, &text); 894e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // our accumulated fixed-point advances might overflow 16.16, so we use 895e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // a 48.16 (64bit) accumulator, and then convert that to scalar at the 896e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // very end. 8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger Sk48Dot16 x = advance(*g, xyIndex); 8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 90140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == bounds) { 90240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb; 9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g->fRsbDelta; 9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex); 9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 90940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(glyphCacheProc(cache, &text), xyIndex); 9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 91440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(*g, bounds); 91640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb; 9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g->fRsbDelta; 9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x += SkAutoKern_AdjustF(rsb, g->fLsbDelta); 9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc(*g, bounds, x); 9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(*g, xyIndex); 9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 92540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc(*g, bounds, x); 9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(*g, xyIndex); 9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text == stop); 9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = n; 936e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed return Sk48Dot16ToScalar(x); 9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length, 94040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkRect* bounds, SkScalar zoom) const { 9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL || length == 0); 9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 94740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 95240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 95340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix zoomMatrix, *zoomPtr = NULL; 95440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (zoom) { 9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomMatrix.setScale(zoom, zoom); 9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomPtr = &zoomMatrix; 9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, zoomPtr); 9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar width = 0; 96340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 96440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (length > 0) { 9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int tempCount; 9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = this->measure_text(cache, text, length, &tempCount, bounds); 96840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = SkScalarMul(width, scale); 97040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (bounds) { 9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fLeft = SkScalarMul(bounds->fLeft, scale); 9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fTop = SkScalarMul(bounds->fTop, scale); 9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fRight = SkScalarMul(bounds->fRight, scale); 9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fBottom = SkScalarMul(bounds->fBottom, scale); 9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return width; 9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop); 9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 98340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool forward_textBufferPred(const char* text, const char* stop) { 9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return text < stop; 9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 98740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool backward_textBufferPred(const char* text, const char* stop) { 9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return text > stop; 9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd, 99240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, size_t length, 99340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** stop) { 99440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (SkPaint::kForward_TextBufferDirection == tbd) { 9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *stop = *text + length; 9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return forward_textBufferPred; 99740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // text should point to the end of the buffer, and stop to the beginning 9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *stop = *text; 10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text += length; 10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return backward_textBufferPred; 10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth, 10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar* measuredWidth, 100740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger TextBufferDirection tbd) const { 100840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == length || 0 >= maxWidth) { 100940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (measuredWidth) { 10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *measuredWidth = 0; 101140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == fTextSize) { 10161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (measuredWidth) { 10171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *measuredWidth = 0; 10181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return length; 10201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(textD != NULL); 10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textD; 10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 102840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 10309b1cba8ccd7554cb30905711a426bd86ad8dd38cJean-Baptiste Queru maxWidth = SkScalarMulDiv(maxWidth, kCanonicalTextSizeForPaths, fTextSize); 10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 103440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false); 10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop; 10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop); 10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int xyIndex = this->isVerticalText() ? 1 : 0; 1042e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // use 64bits for our accumulator, to avoid overflowing 16.16 1043e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed Sk48Dot16 max = SkScalarToFixed(maxWidth); 1044e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed Sk48Dot16 width = 0; 10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 104840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb = 0; 105040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (pred(text, stop)) { 10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* curr = text; 10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 10531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex); 105440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if ((width += x) > max) { 10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width -= x; 10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text = curr; 10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g.fRsbDelta; 10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 106140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 106240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (pred(text, stop)) { 10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* curr = text; 10641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex); 106540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if ((width += x) > max) { 10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width -= x; 10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text = curr; 10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 107240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 107340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (measuredWidth) { 1074e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed SkScalar scalarWidth = Sk48Dot16ToScalar(width); 107540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scalarWidth = SkScalarMul(scalarWidth, scale); 107740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *measuredWidth = scalarWidth; 10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 108040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // return the number of bytes measured 10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (kForward_TextBufferDirection == tbd) ? 10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text - stop + length : stop - text + length; 10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 108840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) { 10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *(SkPaint::FontMetrics*)context = cache->getFontMetricsY(); 10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; // don't detach the cache 10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 109340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context) { 10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context); 10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 109740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const { 10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 110140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 110640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 110740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix zoomMatrix, *zoomPtr = NULL; 110840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (zoom) { 11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomMatrix.setScale(zoom, zoom); 11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomPtr = &zoomMatrix; 11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, zoomPtr); 11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const FontMetrics& my = cache->getFontMetricsY(); 11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project FontMetrics storage; 111940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == metrics) { 11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics = &storage; 112140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 112240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 11231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics, true); 11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 112540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fTop = SkScalarMul(metrics->fTop, scale); 11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return metrics->fDescent - metrics->fAscent + metrics->fLeading; 11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 113540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 113740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) { 11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->set(g.fLeft * scale, 11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g.fTop * scale, 11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (g.fLeft + g.fWidth) * scale, 11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (g.fTop + g.fHeight) * scale); 11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 114440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerint SkPaint::getTextWidths(const void* textData, size_t byteLength, 114540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar widths[], SkRect bounds[]) const { 114640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == byteLength) { 11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 114840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(NULL != textData); 11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 115240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == widths && NULL == bounds) { 11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->countText(textData, byteLength); 115440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 115940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc; 11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project NULL != bounds); 11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = text + byteLength; 11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = 0; 11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int xyIndex = this->isVerticalText() ? 1 : 0; 11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 117640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we adjust the widths returned here through auto-kerning 11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed prevWidth = 0; 11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (scale) { 11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed adjust = autokern.adjust(g); 11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0) { 11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar w = SkFixedToScalar(prevWidth + adjust); 11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths++ = SkScalarMul(w, scale); 11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prevWidth = advance(g, xyIndex); 11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++, scale); 11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0 && widths) { 11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale); 12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed adjust = autokern.adjust(g); 12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0) { 12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths++ = SkFixedToScalar(prevWidth + adjust); 12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prevWidth = advance(g, xyIndex); 12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++); 12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0 && widths) { 12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths = SkFixedToScalar(prevWidth); 12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { // no devkern 12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (scale) { 12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)), 12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale); 12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++, scale); 12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *widths++ = SkFixedToScalar(advance(g, xyIndex)); 12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++); 12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text == stop); 12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return count; 12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 125240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h" 12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 125640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::getTextPath(const void* textData, size_t length, 125740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar x, SkScalar y, SkPath* path) const { 125840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(length == 0 || textData != NULL); 125940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 126140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (text == NULL || length == 0 || path == NULL) { 12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 126340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTextToPathIter iter(text, length, *this, false, true); 12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMatrix matrix; 12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar prevXPos = 0; 12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.setScale(iter.getPathScale(), iter.getPathScale()); 12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.postTranslate(x, y); 12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path->reset(); 12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar xpos; 12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPath* iterPath; 127540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while ((iterPath = iter.next(&xpos)) != NULL) { 12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.postTranslate(xpos - prevXPos, 0); 12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path->addPath(*iterPath, matrix); 12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project prevXPos = xpos; 12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag, 12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer* buffer) { 12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer->flatten(desc->addEntry(tag, buffer->size(), NULL)); 12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// SkFontHost can override this choice in FilterRec() 128840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkMask::Format computeMaskFormat(const SkPaint& paint) { 12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t flags = paint.getFlags(); 12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1291c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed // Antialiasing being disabled trumps all other settings. 1292137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger if (!(flags & SkPaint::kAntiAlias_Flag)) { 1293c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed return SkMask::kBW_Format; 129405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 129505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 1296137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger if (flags & SkPaint::kLCDRenderText_Flag) { 1297137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger return SkMask::kLCD16_Format; 1298137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger } 1299c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed 1300c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed return SkMask::kA8_Format; 13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13034bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// if linear-text is on, then we force hinting to be off (since that's sort of 13044bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// the point of linear-text. 13054bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reedstatic SkPaint::Hinting computeHinting(const SkPaint& paint) { 13064bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed SkPaint::Hinting h = paint.getHinting(); 13074bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed if (paint.isLinearText()) { 13084bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed h = SkPaint::kNo_Hinting; 13094bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed } 13104bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed return h; 13114bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed} 13124bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed 13131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// return true if the paint is just a single color (i.e. not a shader). If its 13141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// a shader, then we can't compute a const luminance for it :( 13151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool justAColor(const SkPaint& paint, SkColor* color) { 13161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getShader()) { 13171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 13181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor c = paint.getColor(); 13201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getColorFilter()) { 13211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger c = paint.getColorFilter()->filterColor(c); 13221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (color) { 13241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *color = c; 13251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 13271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 13304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic SkColor computeLuminanceColor(const SkPaint& paint) { 13314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColor c; 13324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!justAColor(paint, &c)) { 13334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger c = SkColorSetRGB(0x7F, 0x80, 0x7F); 13344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return c; 13364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#define assert_byte(x) SkASSERT(0 == ((x) >> 8)) 13394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic U8CPU reduce_lumbits(U8CPU x) { 13414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger static const uint8_t gReduceBits[] = { 13424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0x0, 0x55, 0xAA, 0xFF 13434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger }; 13444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger assert_byte(x); 13454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return gReduceBits[x >> 6]; 13464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic unsigned computeLuminance(SkColor c) { 13494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int r = SkColorGetR(c); 13504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int g = SkColorGetG(c); 13514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int b = SkColorGetB(c); 13524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // compute luminance 13534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // R=0.2126 G=0.7152 B=0.0722 13544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // scaling by 127 yields 27, 92, 9 13554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int luminance = r * 27 + g * 92 + b * 9; 13564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger luminance >>= 7; 13574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger assert_byte(luminance); 13584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return luminance; 13594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 13621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// returns 0..kLuminance_Max 13631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic unsigned computeLuminance(const SkPaint& paint) { 13641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor c; 13651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (justAColor(paint, &c)) { 13661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r = SkColorGetR(c); 13671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int g = SkColorGetG(c); 13681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int b = SkColorGetB(c); 13691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // compute luminance 13701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // R=0.2126 G=0.7152 B=0.0722 13711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // scaling by 127 yields 27, 92, 9 13721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 1 13731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int luminance = r * 27 + g * 92 + b * 9; 13741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger luminance >>= 15 - SkScalerContext::kLuminance_Bits; 13751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 13761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int luminance = r * 2 + g * 5 + b * 1; 13771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger luminance >>= 11 - SkScalerContext::kLuminance_Bits; 13781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 13791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(luminance <= SkScalerContext::kLuminance_Max); 13801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return luminance; 13811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we're not a single color, return the middle of the luminance range 13831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkScalerContext::kLuminance_Max >> 1; 13841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 13861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Beyond this size, LCD doesn't appreciably improve quality, but it always 13881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// cost more RAM and draws slower, so we set a cap. 13891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifndef SK_MAX_SIZE_FOR_LCDTEXT 13901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SK_MAX_SIZE_FOR_LCDTEXT 48 13911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 13921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool tooBigForLCD(const SkScalerContext::Rec& rec) { 13941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar area = SkScalarMul(rec.fPost2x2[0][0], rec.fPost2x2[1][1]) - 13951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalarMul(rec.fPost2x2[1][0], rec.fPost2x2[0][1]); 13961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar size = SkScalarMul(area, rec.fTextSize); 13971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkScalarAbs(size) > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT); 13981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 140040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/* 140140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * Return the scalar with only limited fractional precision. Used to consolidate matrices 140240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * that vary only slightly when we create our key into the font cache, since the font scaler 140340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * typically returns the same looking resuts for tiny changes in the matrix. 140440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 140540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkScalar sk_relax(SkScalar x) { 140640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 140740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int n = sk_float_round2int(x * 1024); 140840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return n / 1024.0f; 140940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#else 141040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // round to the nearest 10 fractional bits 141140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return (x + (1 << 5)) & ~(1024 - 1); 141240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 141340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 141440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1415af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkScalerContext::MakeRec(const SkPaint& paint, 141640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkMatrix* deviceMatrix, Rec* rec) { 14170199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); 14180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14190199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger rec->fOrigFontID = SkTypeface::UniqueID(paint.getTypeface()); 14200199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger rec->fFontID = rec->fOrigFontID; 14210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fTextSize = paint.getTextSize(); 14220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPreScaleX = paint.getTextScaleX(); 14230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPreSkewX = paint.getTextSkewX(); 14240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 142540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (deviceMatrix) { 142640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX()); 142740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX()); 142840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY()); 142940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY()); 143040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 14310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 14320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0; 14330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 143440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style style = paint.getStyle(); 14360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar strokeWidth = paint.getStrokeWidth(); 143740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned flags = 0; 14391c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 144040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isFakeBoldText()) { 14411c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#ifdef SK_USE_FREETYPE_EMBOLDEN 14421c980e0d7772f05f570ae0227d91635f017c2227Mike Reed flags |= SkScalerContext::kEmbolden_Flag; 14431c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#else 144440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(), 144540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpKeys, 144640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpValues, 144740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpLength); 14480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale); 144940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 145040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style == SkPaint::kFill_Style) { 14510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project style = SkPaint::kStrokeAndFill_Style; 14520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project strokeWidth = extra; // ignore paint's strokeWidth if it was "fill" 145340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 14540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project strokeWidth += extra; 145540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 14561c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#endif 14570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 145940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isDevKernText()) { 14600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkScalerContext::kDevKernText_Flag; 146140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 146240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 146340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style != SkPaint::kFill_Style && strokeWidth > 0) { 14640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fFrameWidth = strokeWidth; 14650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMiterLimit = paint.getStrokeMiter(); 14660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fStrokeJoin = SkToU8(paint.getStrokeJoin()); 14670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 146840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style == SkPaint::kStrokeAndFill_Style) { 14690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkScalerContext::kFrameAndFill_Flag; 147040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 147140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 14720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fFrameWidth = 0; 14730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMiterLimit = 0; 14740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fStrokeJoin = 0; 14750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 14760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); 14780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 14791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkMask::kLCD16_Format == rec->fMaskFormat || 14801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask::kLCD32_Format == rec->fMaskFormat) 14811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 14820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFontHost::LCDOrder order = SkFontHost::GetSubpixelOrder(); 14830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFontHost::LCDOrientation orient = SkFontHost::GetSubpixelOrientation(); 14841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkFontHost::kNONE_LCDOrder == order || tooBigForLCD(*rec)) { 14850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // eeek, can't support LCD 14860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->fMaskFormat = SkMask::kA8_Format; 14870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } else { 14880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SkFontHost::kVertical_LCDOrientation == orient) { 14890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kLCD_Vertical_Flag; 14900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SkFontHost::kBGR_LCDOrder == order) { 14920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kLCD_BGROrder_Flag; 14930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 149740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isEmbeddedBitmapText()) { 14980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kEmbeddedBitmapText_Flag; 149940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 150040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isSubpixelText()) { 15010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kSubpixelPositioning_Flag; 150240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 150340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isAutohinted()) { 15040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kAutohinting_Flag; 150540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 15061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.isVerticalText()) { 15071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flags |= SkScalerContext::kVertical_Flag; 15081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { 15104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flags |= SkScalerContext::kGenA8FromLCD_Flag; 15114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->fFlags = SkToU16(flags); 15130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 15141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // these modify fFlags, so do them after assigning fFlags 15150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->setHinting(computeHinting(paint)); 15164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(computeLuminanceColor(paint)); 15184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 15191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rec->setLuminanceBits(computeLuminance(paint)); 15204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 1521af2616552738d653d5453915d3236e7154b868cdMike Reed 1522af2616552738d653d5453915d3236e7154b868cdMike Reed /* Allow the fonthost to modify our rec before we use it as a key into the 1523af2616552738d653d5453915d3236e7154b868cdMike Reed cache. This way if we're asking for something that they will ignore, 1524af2616552738d653d5453915d3236e7154b868cdMike Reed they can modify our rec up front, so we don't create duplicate cache 1525af2616552738d653d5453915d3236e7154b868cdMike Reed entries. 1526af2616552738d653d5453915d3236e7154b868cdMike Reed */ 1527af2616552738d653d5453915d3236e7154b868cdMike Reed SkFontHost::FilterRec(rec); 15281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // be sure to call PostMakeRec(rec) before you actually use it! 15304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 15314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/** 15334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * We ensure that the rec is self-consistent and efficient (where possible) 15344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 15354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkScalerContext::PostMakeRec(SkScalerContext::Rec* rec) { 15364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger /** 15384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * If we're asking for A8, we force the colorlum to be gray, since that 15394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * that limits the number of unique entries, and the scaler will only 15404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * look at the lum of one of them. 15414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 15424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (rec->fMaskFormat) { 15434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kLCD16_Format: 15444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kLCD32_Format: { 15454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // filter down the luminance color to a finite number of bits 15474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColor c = rec->getLuminanceColor(); 15484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger c = SkColorSetRGB(reduce_lumbits(SkColorGetR(c)), 15494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger reduce_lumbits(SkColorGetG(c)), 15504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger reduce_lumbits(SkColorGetB(c))); 15514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(c); 15524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 15534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 15544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kA8_Format: { 15564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // filter down the luminance to a single component, since A8 can't 15584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // use per-component information 15594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger unsigned lum = computeLuminance(rec->getLuminanceColor()); 15604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // reduce to our finite number of bits 15614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger lum = reduce_lumbits(lum); 15624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(SkColorSetRGB(lum, lum, lum)); 15634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 15644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 15654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kBW_Format: 15674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // No need to differentiate gamma if we're BW 15684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(0); 15704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 15714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceBits(0); 15724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 15734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 15741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 15760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER 1024 15780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 157935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef SK_DEBUG 158035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger #define TEST_DESC 158135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif 158235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 15841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * ignoreGamma tells us that the caller just wants metrics that are unaffected 15851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * by gamma correction, so we jam the luminance field to 0 (most common value 15861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * for black text) in hopes that we get a cache hit easier. A better solution 15871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * would be for the fontcache lookup to know to ignore the luminance field 15881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * entirely, but not sure how to do that and keep it fast. 15891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 15900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix, 15910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void (*proc)(const SkDescriptor*, void*), 159240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void* context, bool ignoreGamma) const { 15930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalerContext::Rec rec; 15940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalerContext::MakeRec(*this, deviceMatrix, &rec); 1596fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy if (ignoreGamma) { 15974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec.setLuminanceColor(0); 15994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 16001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rec.setLuminanceBits(0); 16014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 1602fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy } 16030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size_t descSize = sizeof(rec); 16050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int entryCount = 1; 16060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPathEffect* pe = this->getPathEffect(); 16070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMaskFilter* mf = this->getMaskFilter(); 16080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRasterizer* ra = this->getRasterizer(); 16090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 16110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 16120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 16130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (pe) { 16150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project peBuffer.writeFlattenable(pe); 16160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += peBuffer.size(); 16170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // seems like we could support kLCD as well at this point... 16200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (mf) { 16220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project mfBuffer.writeFlattenable(mf); 16230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += mfBuffer.size(); 16240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters 16260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ra) { 16280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project raBuffer.writeFlattenable(ra); 16290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += raBuffer.size(); 16300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 16354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Now that we're done tweaking the rec, call the PostMakeRec cleanup 16364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkScalerContext::PostMakeRec(&rec); 16374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += SkDescriptor::ComputeOverhead(entryCount); 16390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoDescriptor ad(descSize); 16410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDescriptor* desc = ad.getDesc(); 16420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->init(); 16440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 16450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (pe) { 16470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer); 16480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (mf) { 16500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer); 16510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ra) { 16530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer); 16540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(descSize == desc->getLength()); 16570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->computeChecksum(); 16580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 165935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef TEST_DESC 166035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger { 166135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Check that we completely write the bytes in desc (our key), and that 166235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // there are no uninitialized bytes. If there were, then we would get 166335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // false-misses (or worse, false-hits) in our fontcache. 166435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // 166535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // We do this buy filling 2 others, one with 0s and the other with 1s 166635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // and create those, and then check that all 3 are identical. 166735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkAutoDescriptor ad1(descSize); 166835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkAutoDescriptor ad2(descSize); 166935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDescriptor* desc1 = ad1.getDesc(); 167035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDescriptor* desc2 = ad2.getDesc(); 167135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 167235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger memset(desc1, 0x00, descSize); 167335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger memset(desc2, 0xFF, descSize); 167435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 167535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->init(); 167635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->init(); 167735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 167835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 167935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 168035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (pe) { 168135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer); 168235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer); 168335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 168435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (mf) { 168535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer); 168635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer); 168735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 168835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (ra) { 168935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer); 169035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer); 169135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 169235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 169335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(descSize == desc1->getLength()); 169435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(descSize == desc2->getLength()); 169535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->computeChecksum(); 169635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->computeChecksum(); 169735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(!memcmp(desc, desc1, descSize)); 169835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(!memcmp(desc, desc2, descSize)); 169935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 170035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif 170135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 17020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project proc(desc, context); 17030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 17040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 170540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const { 17060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache; 17070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->descriptorProc(deviceMatrix, DetachDescProc, &cache); 17080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache; 17090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 17100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 17120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h" 17140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uintptr_t asint(const void* p) { 17165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return reinterpret_cast<uintptr_t>(p); 17175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedunion Scalar32 { 17205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkScalar fScalar; 17215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t f32; 17225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}; 17235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) { 17255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 17265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed Scalar32 tmp; 17275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp.fScalar = value; 17285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr = tmp.f32; 17295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return ptr + 1; 17305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic SkScalar read_scalar(const uint32_t*& ptr) { 17335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 17345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed Scalar32 tmp; 17355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp.f32 = *ptr++; 17365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return tmp.fScalar; 17375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { 17405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(a == (uint8_t)a); 17415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(b == (uint8_t)b); 17425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(c == (uint8_t)c); 17435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(d == (uint8_t)d); 17445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return (a << 24) | (b << 16) | (c << 8) | d; 17455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedenum FlatFlags { 17485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed kHasTypeface_FlatFlag = 0x01, 17495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed kHasEffects_FlatFlag = 0x02 17505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}; 17515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed// The size of a flat paint's POD fields 17535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + 17545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1 * sizeof(SkColor) + 17555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1 * sizeof(uint16_t) + 17565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 6 * sizeof(uint8_t); 17575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed/* To save space/time, we analyze the paint, and write a truncated version of 17595f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed it if there are not tricky elements like shaders, etc. 17605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed */ 17610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const { 17625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint8_t flatFlags = 0; 17635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (this->getTypeface()) { 17645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed flatFlags |= kHasTypeface_FlatFlag; 17655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 17665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (asint(this->getPathEffect()) | 17675f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getShader()) | 17685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getXfermode()) | 17695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getMaskFilter()) | 17705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getColorFilter()) | 17715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getRasterizer()) | 17721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger asint(this->getLooper()) | 17731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger asint(this->getImageFilter())) { 17745f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed flatFlags |= kHasEffects_FlatFlag; 17755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 177640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 17775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 17785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t* ptr = buffer.reserve(kPODPaintSize); 17795f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextSize()); 17815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextScaleX()); 17825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextSkewX()); 17835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getStrokeWidth()); 17845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getStrokeMiter()); 17855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr++ = this->getColor(); 17861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // previously flags:16, textAlign:8, flatFlags:8 17871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // now flags:16, hinting:4, textAlign:4, flatFlags:8 17881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *ptr++ = (this->getFlags() << 16) | 17891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // hinting added later. 0 in this nibble means use the default. 17901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ((this->getHinting()+1) << 12) | 17911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (this->getTextAlign() << 8) | 17921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flatFlags; 17935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(), 17945f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->getStyle(), this->getTextEncoding()); 17955f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17965f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // now we're done with ptr and the (pre)reserved space. If we need to write 17975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // additional fields, use the buffer directly 17985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasTypeface_FlatFlag) { 17995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeTypeface(this->getTypeface()); 18005f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasEffects_FlatFlag) { 18025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getPathEffect()); 18035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getShader()); 18045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getXfermode()); 18055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getMaskFilter()); 18065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getColorFilter()); 18075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getRasterizer()); 18085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getLooper()); 18091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger buffer.writeFlattenable(this->getImageFilter()); 18105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) { 18145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 18155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed const void* podData = buffer.skip(kPODPaintSize); 18165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); 181740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 18185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // the order we read must match the order we wrote in flatten() 18195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextSize(read_scalar(pod)); 18205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextScaleX(read_scalar(pod)); 18215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextSkewX(read_scalar(pod)); 18225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeWidth(read_scalar(pod)); 182340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->setStrokeMiter(read_scalar(pod)); 18245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setColor(*pod++); 18255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // previously flags:16, textAlign:8, flatFlags:8 18271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // now flags:16, hinting:4, textAlign:4, flatFlags:8 18285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t tmp = *pod++; 18295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setFlags(tmp >> 16); 18301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) { 18324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF)); 18334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setHinting(SkPaintDefaults_Hinting); 18344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 18354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // hinting added later. 0 in this nibble means use the default. 18364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger uint32_t hinting = (tmp >> 12) & 0xF; 18374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setHinting(0 == hinting ? kNormal_Hinting : static_cast<Hinting>(hinting-1)); 18381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xF)); 18404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 18411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint8_t flatFlags = tmp & 0xFF; 18435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp = *pod++; 18455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); 18465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); 18475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); 18485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); 18495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasTypeface_FlatFlag) { 18515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTypeface(buffer.readTypeface()); 18525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } else { 18535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTypeface(NULL); 18545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasEffects_FlatFlag) { 185740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setPathEffect((SkPathEffect*) buffer.readFlattenable())); 185840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setShader((SkShader*) buffer.readFlattenable())); 185940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setXfermode((SkXfermode*) buffer.readFlattenable())); 186040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())); 186140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setColorFilter((SkColorFilter*) buffer.readFlattenable())); 186240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setRasterizer((SkRasterizer*) buffer.readFlattenable())); 186340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setLooper((SkDrawLooper*) buffer.readFlattenable())); 18644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (buffer.getPictureVersion() != PICTURE_VERSION_ICS) 18654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkSafeUnref(this->setImageFilter((SkImageFilter*) buffer.readFlattenable())); 18664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger else 18674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setImageFilter(NULL); 18685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } else { 18695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setPathEffect(NULL); 18705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setShader(NULL); 18715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setXfermode(NULL); 18725f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setMaskFilter(NULL); 18735f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setColorFilter(NULL); 18745f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setRasterizer(NULL); 18755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setLooper(NULL); 18761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setImageFilter(NULL); 18775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 18810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 188287b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkShader* SkPaint::setShader(SkShader* shader) { 188387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(shader != fShader); 18840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fShader, shader); 18850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return shader; 18860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 188887b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { 188987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(filter != fColorFilter); 18900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fColorFilter, filter); 18910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return filter; 18920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 189487b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkXfermode* SkPaint::setXfermode(SkXfermode* mode) { 189587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(mode != fXfermode); 18960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fXfermode, mode); 18970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return mode; 18980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 190003f42ddd729377f21719a140c027a1f8cc5c2152Mike ReedSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { 190103f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed SkSafeUnref(fXfermode); 190203f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed fXfermode = SkXfermode::Create(mode); 190387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 190403f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed return fXfermode; 190503f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed} 190603f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed 190787b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { 190887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(effect != fPathEffect); 19090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fPathEffect, effect); 19100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return effect; 19110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 191387b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { 191487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(filter != fMaskFilter); 19150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fMaskFilter, filter); 19160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return filter; 19170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 191940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 19200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 192140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const { 19220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPath effectPath, strokePath; 19230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPath* path = &src; 19240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar width = this->getStrokeWidth(); 192640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 19270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getStyle()) { 192840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kFill_Style: 19290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; // mark it as no-stroke 193040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 193140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kStrokeAndFill_Style: 193240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width == 0) { 193340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger width = -1; // mark it as no-stroke 193440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 193540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 193640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kStroke_Style: 193740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 193840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger default: 19391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown paint style"); 19400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 194240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getPathEffect()) { 19430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill 194440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getStyle() == SkPaint::kStrokeAndFill_Style) { 19450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; // mark it as no-stroke 194640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 19470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 194840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getPathEffect()->filterPath(&effectPath, src, &width)) { 19490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path = &effectPath; 195040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 195140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 19520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // restore the width if we earlier had to lie, and if we're still set to no-stroke 19530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // note: if we're now stroke (width >= 0), then the pathEffect asked for that change 19540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // and we want to respect that (i.e. don't overwrite their setting for width) 195540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0) { 19560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = this->getStrokeWidth(); 195740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width == 0) { 19580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; 195940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 19600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 196240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 196340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width > 0 && !path->isEmpty()) { 19640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkStroke stroker(*this, width); 19650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project stroker.strokePath(*path, &strokePath); 19660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path = &strokePath; 19670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 196940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (path == &src) { 19700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = src; 197140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 19720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(path == &effectPath || path == &strokePath); 19730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->swap(*(SkPath*)path); 19740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return width != 0; // return true if we're filled, or false if we're hairline (width == 0) 19770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1979717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerconst SkRect& SkPaint::doComputeFastBounds(const SkRect& src, 1980717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect* storage) const { 19810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(storage); 1982717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 1983717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getLooper()) { 1984717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkASSERT(this->getLooper()->canComputeFastBounds(*this)); 1985717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->getLooper()->computeFastBounds(*this, src, storage); 1986717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return *storage; 1987717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 1988717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 1989717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getStyle() != SkPaint::kFill_Style) { 1990717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger // since we're stroked, outset the rect by the radius (and join type) 1991717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkScalar radius = SkScalarHalf(this->getStrokeWidth()); 1992717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (0 == radius) { // hairline 1993717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger radius = SK_Scalar1; 1994717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { 1995717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkScalar scale = this->getStrokeMiter(); 1996717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (scale > SK_Scalar1) { 1997717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger radius = SkScalarMul(radius, scale); 1998717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 19990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2000717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger storage->set(src.fLeft - radius, src.fTop - radius, 2001717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger src.fRight + radius, src.fBottom + radius); 2002717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2003717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger *storage = src; 20040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2005717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2006717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger // check the mask filter 2007717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getMaskFilter()) { 2008717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->getMaskFilter()->computeFastBounds(*storage, storage); 2009717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2010717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 201135d15937afb7f4b3472e43ea784b02485ec910fbMike Reed return *storage; 20120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 201440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 20150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 201640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool has_thick_frame(const SkPaint& paint) { 201740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return paint.getStrokeWidth() > 0 && 201840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger paint.getStyle() != SkPaint::kFill_Style; 20190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length, 20220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint, 20230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool applyStrokeAndPathEffects, 202440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool forceLinearTextOn) : fPaint(paint) { 20250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection, 20260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project true); 20270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 202840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (forceLinearTextOn) { 20290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setLinearText(true); 203040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup 20320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 203340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { 20340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project applyStrokeAndPathEffects = false; 203540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // can't use our canonical size if we need to apply patheffects/strokes 2038b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger if (fPaint.getPathEffect() == NULL) { 20390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); 20400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; 2041b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger if (has_thick_frame(fPaint)) { 2042b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale)); 2043b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger } 204440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 20450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = SK_Scalar1; 204640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 204740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 204840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!applyStrokeAndPathEffects) { 20490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setStyle(SkPaint::kFill_Style); 20500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setPathEffect(NULL); 20510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCache = fPaint.detachCache(NULL); 20540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style style = SkPaint::kFill_Style; 20560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPathEffect* pe = NULL; 20570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 205840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!applyStrokeAndPathEffects) { 20590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project style = paint.getStyle(); // restore 20600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pe = paint.getPathEffect(); // restore 20610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setStyle(style); 20630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setPathEffect(pe); 20640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setMaskFilter(paint.getMaskFilter()); // restore 20650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // now compute fXOffset if needed 20670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar xOffset = 0; 206940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first 20700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count; 207140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, 207240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger &count, NULL), fScale); 207340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.getTextAlign() == SkPaint::kCenter_Align) { 20740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = SkScalarHalf(width); 207540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project xOffset = -width; 20770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXPos = xOffset; 20790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevAdvance = 0; 20800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fText = text; 20820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStop = text + length; 20831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fXYIndex = paint.isVerticalText() ? 1 : 0; 20850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 208740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTextToPathIter::~SkTextToPathIter() { 20880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache::AttachCache(fCache); 20890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 209140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkPath* SkTextToPathIter::next(SkScalar* xpos) { 209240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (fText < fStop) { 20930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 20940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); 20961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); 20970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 209840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (glyph.fWidth) { 209940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (xpos) { 21000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *xpos = fXPos; 210140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 21020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fCache->findPath(glyph); 21030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 21060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2107717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2108717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2109717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 21101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkPaint::nothingToDraw() const { 21111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fLooper) { 21121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Mode mode; 21151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::AsMode(fXfermode, &mode)) { 21161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (mode) { 21171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSrcOver_Mode: 21181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSrcATop_Mode: 21191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDstOut_Mode: 21201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDstOver_Mode: 21211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kPlus_Mode: 21221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 0 == this->getAlpha(); 21231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDst_Mode: 21241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 21251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 21261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 21271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////// Move these to their own file soon. 21341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, 21361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMatrix& ctm, 21371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap* result, SkIPoint* loc) { 21381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(proxy); 21391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(result); 21401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(loc); 21411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* 21421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Give the proxy first shot at the filter. If it returns false, ask 21431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the filter to do it. 21441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 21451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return proxy->filterImage(this, src, ctm, result, loc) || 21461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->onFilterImage(proxy, src, ctm, result, loc); 21471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, 21501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect* dst) { 21511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(&src); 21521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst); 21531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->onFilterBounds(src, ctm, dst); 21541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&, 21571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap*, SkIPoint*) { 21581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 21621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect* dst) { 21631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *dst = src; 21641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 21651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::asABlur(SkSize* sigma) const { 21681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asAnErode(SkISize* radius) const { 21724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 21734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 21744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 21754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asADilate(SkISize* radius) const { 21764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 21774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 21784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 21794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger////// 21804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2181717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerbool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) { 2182717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkCanvas canvas; 2183717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2184717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->init(&canvas); 2185717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger for (;;) { 2186717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkPaint p(paint); 2187717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->next(&canvas, &p)) { 2188717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.setLooper(NULL); 2189717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (!p.canComputeFastBounds()) { 2190717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return false; 2191717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2192717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2193717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger break; 2194717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2195717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2196717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return true; 2197717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 2198717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2199717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergervoid SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src, 2200717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect* dst) { 2201717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkCanvas canvas; 22024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2203717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->init(&canvas); 2204717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger for (bool firstTime = true;; firstTime = false) { 2205717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkPaint p(paint); 2206717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->next(&canvas, &p)) { 2207717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect r(src); 2208717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2209717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.setLooper(NULL); 2210717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.computeFastBounds(r, &r); 2211717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger canvas.getTotalMatrix().mapRect(&r); 2212717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2213717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (firstTime) { 2214717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger *dst = r; 2215717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2216717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger dst->join(r); 2217717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2218717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2219717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger break; 2220717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2221717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2222717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 22231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2224