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 35725b3e03acb91dc69296554932624b36612bd189Billy Hewlett#include "SkLanguage.h" 3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC fGenerationID++ 3787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } 3887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#else 3987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC 4087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression) 4187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 4287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 43c1c43a17e7f2a87951739691056728a80e9aef6bMike ReedSkPaint::SkPaint() { 44c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // since we may have padding, we zero everything so that our memcmp() call 45c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // in operator== will work correctly. 46c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // with this, we can skip 0 and null individual initializations 47c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed sk_bzero(this, sizeof(*this)); 48c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed 49c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#if 0 // not needed with the bzero call above 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTypeface = NULL; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextSkewX = 0; 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPathEffect = NULL; 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader = NULL; 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXfermode = NULL; 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMaskFilter = NULL; 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColorFilter = NULL; 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRasterizer = NULL; 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fLooper = NULL; 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fImageFilter = NULL; 60c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed fWidth = 0; 61c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#endif 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fTextSize = SkPaintDefaults_TextSize; 64c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed fTextScaleX = SK_Scalar1; 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColor = SK_ColorBLACK; 664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fMiterLimit = SkPaintDefaults_MiterLimit; 674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fFlags = SkPaintDefaults_Flags; 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCapType = kDefault_Cap; 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fJoinType = kDefault_Join; 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextAlign = kLeft_Align; 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStyle = kFill_Style; 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextEncoding = kUTF8_TextEncoding; 734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fHinting = SkPaintDefaults_Hinting; 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 75725b3e03acb91dc69296554932624b36612bd189Billy Hewlett fLanguage = SkLanguage(); 76212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett fFontVariant = kDefault_Variant; 7795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase fGenerationID = 0; 7887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::SkPaint(const SkPaint& src) { 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(this, &src, sizeof(src)); 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fTypeface); 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fPathEffect); 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fShader); 8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fXfermode); 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fMaskFilter); 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fColorFilter); 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fRasterizer); 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fLooper); 921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeRef(fImageFilter); 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::~SkPaint() { 9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fTypeface); 9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fPathEffect); 9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fShader); 9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fXfermode); 10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fMaskFilter); 10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fColorFilter); 10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fRasterizer); 10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fLooper); 1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeUnref(fImageFilter); 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint& SkPaint::operator=(const SkPaint& src) { 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(&src); 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fTypeface); 11140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fPathEffect); 11240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fShader); 11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fXfermode); 11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fMaskFilter); 11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fColorFilter); 11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fRasterizer); 11740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fLooper); 1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeRef(src.fImageFilter); 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fTypeface); 12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fPathEffect); 12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fShader); 12340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fXfermode); 12440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fMaskFilter); 12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fColorFilter); 12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fRasterizer); 12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fLooper); 1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeUnref(fImageFilter); 1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1319f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase uint32_t oldGenerationID = fGenerationID; 13287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(this, &src, sizeof(src)); 1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1359f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase fGenerationID = oldGenerationID + 1; 13687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return *this; 1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool operator==(const SkPaint& a, const SkPaint& b) { 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger //assumes that fGenerationID is the last field in the struct 1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(&a, &b, SK_OFFSETOF(SkPaint, fGenerationID)); 1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(&a, &b, sizeof(a)); 1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::reset() { 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint init; 1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1549f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase uint32_t oldGenerationID = fGenerationID; 15587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *this = init; 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1589f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase fGenerationID = oldGenerationID + 1; 15987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 16095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase} 16195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase 1621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 16395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haaseuint32_t SkPaint::getGenerationID() const { 16495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase return fGenerationID; 1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 16687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerunsigned SkPaint::getBaseGlyphCount(SkUnichar text) const { 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoGlyphCache autoCache(*this, NULL); 1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkGlyphCache* cache = autoCache.getCache(); 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return cache->getBaseGlyphCount(text); 1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setHinting(Hinting hintingLevel) { 17787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); 17887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fHinting = hintingLevel; 1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFlags(uint32_t flags) { 18287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(fFlags != flags); 18387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fFlags = flags; 1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAntiAlias(bool doAA) { 18787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doAA != isAntiAlias()); 18887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); 1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDither(bool doDither) { 19287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doDither != isDither()); 19387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); 1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setSubpixelText(bool doSubpixel) { 19787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doSubpixel != isSubpixelText()); 19887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag)); 199af2616552738d653d5453915d3236e7154b868cdMike Reed} 200af2616552738d653d5453915d3236e7154b868cdMike Reed 20187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLCDRenderText(bool doLCDRender) { 20287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doLCDRender != isLCDRenderText()); 20387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag)); 20487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 20587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 20687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) { 20787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doEmbeddedBitmapText != isEmbeddedBitmapText()); 20887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag)); 2092cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed} 2102cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed 21187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAutohinted(bool useAutohinter) { 21287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(useAutohinter != isAutohinted()); 21340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag)); 21440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 21540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 21687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLinearText(bool doLinearText) { 21787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doLinearText != isLinearText()); 21887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag)); 2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkPaint::setVerticalText(bool doVertical) { 2221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GEN_ID_INC_EVAL(doVertical != isVerticalText()); 2231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setFlags(SkSetClearMask(fFlags, doVertical, kVerticalText_Flag)); 2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setUnderlineText(bool doUnderline) { 22787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doUnderline != isUnderlineText()); 22887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag)); 2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrikeThruText(bool doStrikeThru) { 23287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doStrikeThru != isStrikeThruText()); 23387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag)); 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFakeBoldText(bool doFakeBold) { 23787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doFakeBold != isFakeBoldText()); 23887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag)); 2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDevKernText(bool doDevKern) { 24287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doDevKern != isDevKernText()); 24387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); 2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFilterBitmap(bool doFilter) { 24787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doFilter != isFilterBitmap()); 24887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag)); 2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 25187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStyle(Style style) { 25295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)style < kStyleCount) { 25387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)style != fStyle); 25487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fStyle = style; 25587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 2581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 25905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setColor(SkColor color) { 26387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(color != fColor); 26487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fColor = color; 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAlpha(U8CPU a) { 26887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), 26987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkColorGetG(fColor), SkColorGetB(fColor))); 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 27387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setColor(SkColorSetARGB(a, r, g, b)); 2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeWidth(SkScalar width) { 27795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if (width >= 0) { 27887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(width != fWidth); 27987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fWidth = width; 28087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); 2831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 28405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 28787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeMiter(SkScalar limit) { 28895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if (limit >= 0) { 28987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(limit != fMiterLimit); 29087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fMiterLimit = limit; 29187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 2941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 29505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 29887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeCap(Cap ct) { 29995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)ct < kCapCount) { 30087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)ct != fCapType); 30187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fCapType = SkToU8(ct); 30287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 3051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 30695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 30987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeJoin(Join jt) { 31095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)jt < kJoinCount) { 31187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)jt != fJoinType); 31287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fJoinType = SkToU8(jt); 31387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 3161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 31795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextAlign(Align align) { 32395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)align < kAlignCount) { 32487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)align != fTextAlign); 32587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextAlign = SkToU8(align); 32687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 33095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 33387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSize(SkScalar ts) { 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (ts >= 0) { 33587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(ts != fTextSize); 33687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextSize = ts; 33787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextSize() called with negative value\n"); 3401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 34195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextScaleX(SkScalar scaleX) { 34587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(scaleX != fTextScaleX); 34687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextScaleX = scaleX; 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSkewX(SkScalar skewX) { 35087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(skewX != fTextSkewX); 35187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextSkewX = skewX; 3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 35487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextEncoding(TextEncoding encoding) { 35595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)encoding <= kGlyphID_TextEncoding) { 35687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); 35787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextEncoding = encoding; 35887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 3611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 36295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3655c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#ifdef SK_BUILD_FOR_ANDROID 366725b3e03acb91dc69296554932624b36612bd189Billy Hewlettvoid SkPaint::setLanguage(const SkLanguage& language) { 367725b3e03acb91dc69296554932624b36612bd189Billy Hewlett if(fLanguage != language) { 368725b3e03acb91dc69296554932624b36612bd189Billy Hewlett fLanguage = language; 3695c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio GEN_ID_INC; 3705c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio } 3715c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio} 372212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett 373212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlettvoid SkPaint::setFontVariant(FontVariant fontVariant) { 374212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett if ((unsigned)fontVariant <= kLast_Variant) { 375212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett GEN_ID_INC_EVAL((unsigned)fontVariant != fFontVariant); 376212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett fFontVariant = fontVariant; 377212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett } else { 378212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett#ifdef SK_REPORT_API_RANGE_CHECK 379212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett SkDebugf("SkPaint::setFontVariant(%d) out of range\n", fontVariant); 380212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett#endif 381212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett } 382212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett} 383212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett 3845c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#endif 3855c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio 38687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 38887b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkTypeface* SkPaint::setTypeface(SkTypeface* font) { 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fTypeface, font); 39087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return font; 3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 39440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { 3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fRasterizer, r); 39687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return r; 3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 40040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { 4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fLooper, looper); 40287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return looper; 4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4061cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { 4071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRefCnt_SafeAssign(fImageFilter, imageFilter); 4081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GEN_ID_INC; 4091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return imageFilter; 4101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 4111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h" 4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h" 4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 41740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void DetachDescProc(const SkDescriptor* desc, void* context) { 418fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc); 419fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy} 420fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy 4211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 422b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guyconst SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) { 423b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy SkGlyphCache* cache; 424b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 425b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 426b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy const SkGlyph& glyph = cache->getUnicharMetrics(text); 427b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 428b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy SkGlyphCache::AttachCache(cache); 429b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy return glyph; 430b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy} 431b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 4321bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guyconst SkGlyph& SkPaint::getGlyphMetrics(uint16_t glyphId) { 4331bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy SkGlyphCache* cache; 4341bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 4351bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 4361bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphId); 4371bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 4381bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy SkGlyphCache::AttachCache(cache); 4391bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy return glyph; 4401bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy} 4411bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 44290a1efbdde19ee56c33929592277871509c25893Romain Guyconst void* SkPaint::findImage(const SkGlyph& glyph) { 443fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy // See ::detachCache() 444fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy SkGlyphCache* cache; 445fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 44690a1efbdde19ee56c33929592277871509c25893Romain Guy 447fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy const void* image = cache->findImage(glyph); 448fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy 449fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy SkGlyphCache::AttachCache(cache); 450fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy return image; 45190a1efbdde19ee56c33929592277871509c25893Romain Guy} 452dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy 453dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guyint SkPaint::utfToGlyphs(const void* textData, TextEncoding encoding, 454dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy size_t byteLength, uint16_t glyphs[]) const { 455dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy 456dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy SkAutoGlyphCache autoCache(*this, NULL); 457dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy SkGlyphCache* cache = autoCache.getCache(); 458dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy 459dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy const char* text = (const char*) textData; 460dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy const char* stop = text + byteLength; 461dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy uint16_t* gptr = glyphs; 462dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy 463dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy switch (encoding) { 464dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy case SkPaint::kUTF8_TextEncoding: 465dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy while (text < stop) { 466dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text)); 467dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy } 468dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy break; 469dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy case SkPaint::kUTF16_TextEncoding: { 470dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy const uint16_t* text16 = (const uint16_t*)text; 471dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy const uint16_t* stop16 = (const uint16_t*)stop; 472dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy while (text16 < stop16) { 473dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); 474dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy } 475dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy break; 476dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy } 477dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy default: 478dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy SkDEBUGFAIL("unknown text encoding"); 479dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy } 480dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy return gptr - glyphs; 481dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy} 482dc7d4843a1b47c431ec5b358e8d9807e309a735eRomain Guy 48387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 48490a1efbdde19ee56c33929592277871509c25893Romain Guy 4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength, 4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t glyphs[]) const { 4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (byteLength == 0) { 4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 49040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(textData != NULL); 4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL == glyphs) { 4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getTextEncoding()) { 4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kUTF8_TextEncoding: 4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkUTF8_CountUnichars((const char*)textData, byteLength); 4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kUTF16_TextEncoding: 4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkUTF16_CountUnichars((const uint16_t*)textData, 4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project byteLength >> 1); 5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kGlyphID_TextEncoding: 5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return byteLength >> 1; 5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 5031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 50740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // if we get here, we have a valid glyphs[] array, so time to fill it in 50940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // handle this encoding before the setup for the glyphcache 5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->getTextEncoding() == kGlyphID_TextEncoding) { 5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we want to ignore the low bit of byteLength 5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(glyphs, textData, byteLength >> 1 << 1); 5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return byteLength >> 1; 5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 51640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = text + byteLength; 5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t* gptr = glyphs; 5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getTextEncoding()) { 5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkPaint::kUTF8_TextEncoding: 5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text)); 5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkPaint::kUTF16_TextEncoding: { 5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* text16 = (const uint16_t*)text; 5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* stop16 = (const uint16_t*)stop; 5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text16 < stop16) { 5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); 5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 5391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gptr - glyphs; 5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 54475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reedbool SkPaint::containsText(const void* textData, size_t byteLength) const { 54575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == byteLength) { 54675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 54775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 54840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 54975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkASSERT(textData != NULL); 55040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 55175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed // handle this encoding before the setup for the glyphcache 55275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (this->getTextEncoding() == kGlyphID_TextEncoding) { 55375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* glyphID = static_cast<const uint16_t*>(textData); 55475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed size_t count = byteLength >> 1; 55575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed for (size_t i = 0; i < count; i++) { 55675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == glyphID[i]) { 55775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 55875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 55975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 56075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 56175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 56240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 56375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkAutoGlyphCache autoCache(*this, NULL); 56475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkGlyphCache* cache = autoCache.getCache(); 56575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed 56675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed switch (this->getTextEncoding()) { 56775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed case SkPaint::kUTF8_TextEncoding: { 56875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const char* text = static_cast<const char*>(textData); 56975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const char* stop = text + byteLength; 57075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed while (text < stop) { 57175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) { 57275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 57375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 57475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 57575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed break; 57675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 57775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed case SkPaint::kUTF16_TextEncoding: { 57875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* text = static_cast<const uint16_t*>(textData); 57975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* stop = text + (byteLength >> 1); 58075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed while (text < stop) { 58175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) { 58275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 58375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 58475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 58575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed break; 58675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 58775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed default: 5881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 58975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 59075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 59175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 59275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed} 59375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed 594091f227385b467090b5a7169a8e2faf19eca7105Mike Reedvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, 595091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkUnichar textData[]) const { 596091f227385b467090b5a7169a8e2faf19eca7105Mike Reed if (count <= 0) { 597091f227385b467090b5a7169a8e2faf19eca7105Mike Reed return; 598091f227385b467090b5a7169a8e2faf19eca7105Mike Reed } 599091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 600091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkASSERT(glyphs != NULL); 601091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkASSERT(textData != NULL); 602091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 603091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkAutoGlyphCache autoCache(*this, NULL); 604091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkGlyphCache* cache = autoCache.getCache(); 605091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 606091f227385b467090b5a7169a8e2faf19eca7105Mike Reed for (int index = 0; index < count; index++) { 607091f227385b467090b5a7169a8e2faf19eca7105Mike Reed textData[index] = cache->glyphToUnichar(glyphs[index]); 608091f227385b467090b5a7169a8e2faf19eca7105Mike Reed } 609091f227385b467090b5a7169a8e2faf19eca7105Mike Reed} 610091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 61340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, 61440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 61740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 62140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, 62240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 62540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text)); 6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 62940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_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->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_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->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text)); 6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 64540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_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 const uint16_t* ptr = *(const uint16_t**)text; 6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 65740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, 65840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 66140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr -= 1; 6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 66940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, 67040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 67340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF8_NextUnichar(text)); 6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 67740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, 67840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 68140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text)); 6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 68540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, 68640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 68940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text)); 6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 69340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, 69440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 69740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text)); 6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 70140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, 70240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 70540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDAdvance(glyphID); 7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 71340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, 71440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 71740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr -= 1; 7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDAdvance(glyphID); 7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd, 72640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool needFullMetrics) const { 7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static const SkMeasureCacheProc gMeasureCacheProcs[] = { 7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_next, 7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_next, 7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_next, 73140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_prev, 7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_prev, 7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_prev, 73540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf8_next, 7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf16_next, 7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_glyph_next, 73940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf8_prev, 7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf16_prev, 7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_glyph_prev 7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 74440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned index = this->getTextEncoding(); 7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 74740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (kBackward_TextBufferDirection == tbd) { 7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 3; 74940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 75040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!needFullMetrics && !this->isDevKernText()) { 7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 6; 75240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs)); 7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gMeasureCacheProcs[index]; 7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache, 76140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 76440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache, 76940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 77240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y); 7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 77640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, 77740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 78040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache, 78540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 78840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text), 7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x, y); 7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 79340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, 79440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 79740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache, 80640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 80940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID, x, y); 8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 81740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawCacheProc SkPaint::getDrawCacheProc() const { 8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static const SkDrawCacheProc gDrawCacheProcs[] = { 8190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_00, 8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_00, 8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_00, 82240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_xy, 8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_xy, 8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_xy 8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 82740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned index = this->getTextEncoding(); 82940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fFlags & kSubpixelText_Flag) { 8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 3; 83140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 83240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs)); 8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gDrawCacheProcs[index]; 8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame { 8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 84140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint) 84240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fPaint((SkPaint*)paint) { 8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextSize = paint->getTextSize(); 8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStyle = paint->getStyle(); 8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setStyle(SkPaint::kFill_Style); 8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 84740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 84840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger ~SkAutoRestorePaintTextSizeAndFrame() { 8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setStyle(fStyle); 8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setTextSize(fTextSize); 8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 85240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint* fPaint; 8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fTextSize; 8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style fStyle; 8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 85940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds) { 8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->set(SkIntToScalar(g.fLeft), 8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop), 8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fLeft + g.fWidth), 8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop + g.fHeight)); 8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 866e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so 867e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// we don't overflow along the way 868e63c5c9f6752244ca0f39075fa148a0281593831Mike Reedtypedef int64_t Sk48Dot16; 869e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed 870e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#ifdef SK_SCALAR_IS_FLOAT 871e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed static inline float Sk48Dot16ToScalar(Sk48Dot16 x) { 87240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return (float) (x * 1.5258789e-5); // x * (1 / 65536.0f) 873e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed } 874e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#else 875e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed static inline SkFixed Sk48Dot16ToScalar(Sk48Dot16 x) { 876e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // just return the low 32bits 877e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed return static_cast<SkFixed>(x); 878e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed } 879e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#endif 880e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed 8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { 882e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed SkScalar sx = Sk48Dot16ToScalar(dx); 8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->join(SkIntToScalar(g.fLeft) + sx, 8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop), 8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fLeft + g.fWidth) + sx, 8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop + g.fHeight)); 8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) { 8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar sy = Sk48Dot16ToScalar(dy); 8911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bounds->join(SkIntToScalar(g.fLeft), 8921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fTop) + sy, 8931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fLeft + g.fWidth), 8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fTop + g.fHeight) + sy); 8951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16); 8981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY 9001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkFixed advance(const SkGlyph& glyph, int xyIndex) { 9011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(0 == xyIndex || 1 == xyIndex); 9021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return (&glyph.fAdvanceX)[xyIndex]; 9031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 9041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache, 9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text, size_t byteLength, 90740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int* count, SkRect* bounds) const { 9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count); 90940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (byteLength == 0) { 9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = 0; 91140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (bounds) { 9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->setEmpty(); 91340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc; 9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project NULL != bounds); 9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int xyIndex; 9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger JoinBoundsProc joinBoundsProc; 9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (this->isVerticalText()) { 9241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger xyIndex = 1; 9251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc = join_bounds_y; 9261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 9271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger xyIndex = 0; 9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc = join_bounds_x; 9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 9301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int n = 1; 9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = (const char*)text + byteLength; 9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph* g = &glyphCacheProc(cache, &text); 934e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // our accumulated fixed-point advances might overflow 16.16, so we use 935e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // a 48.16 (64bit) accumulator, and then convert that to scalar at the 936e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // very end. 9371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger Sk48Dot16 x = advance(*g, xyIndex); 9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 94140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == bounds) { 94240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb; 9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g->fRsbDelta; 9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex); 9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 94940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(glyphCacheProc(cache, &text), xyIndex); 9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 95440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(*g, bounds); 95640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb; 9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g->fRsbDelta; 9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x += SkAutoKern_AdjustF(rsb, g->fLsbDelta); 9621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc(*g, bounds, x); 9631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(*g, xyIndex); 9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 96540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc(*g, bounds, x); 9691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(*g, xyIndex); 9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text == stop); 9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = n; 976e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed return Sk48Dot16ToScalar(x); 9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length, 98040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkRect* bounds, SkScalar zoom) const { 9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL || length == 0); 9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 98740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 99240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 99340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix zoomMatrix, *zoomPtr = NULL; 99440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (zoom) { 9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomMatrix.setScale(zoom, zoom); 9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomPtr = &zoomMatrix; 9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, zoomPtr); 10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar width = 0; 100340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 100440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (length > 0) { 10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int tempCount; 10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = this->measure_text(cache, text, length, &tempCount, bounds); 100840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = SkScalarMul(width, scale); 101040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (bounds) { 10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fLeft = SkScalarMul(bounds->fLeft, scale); 10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fTop = SkScalarMul(bounds->fTop, scale); 10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fRight = SkScalarMul(bounds->fRight, scale); 10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fBottom = SkScalarMul(bounds->fBottom, scale); 10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return width; 10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop); 10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 102340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool forward_textBufferPred(const char* text, const char* stop) { 10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return text < stop; 10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 102740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool backward_textBufferPred(const char* text, const char* stop) { 10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return text > stop; 10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd, 103240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, size_t length, 103340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** stop) { 103440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (SkPaint::kForward_TextBufferDirection == tbd) { 10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *stop = *text + length; 10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return forward_textBufferPred; 103740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // text should point to the end of the buffer, and stop to the beginning 10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *stop = *text; 10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text += length; 10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return backward_textBufferPred; 10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth, 10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar* measuredWidth, 104740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger TextBufferDirection tbd) const { 104840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == length || 0 >= maxWidth) { 104940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (measuredWidth) { 10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *measuredWidth = 0; 105140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == fTextSize) { 10561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (measuredWidth) { 10571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *measuredWidth = 0; 10581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return length; 10601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(textD != NULL); 10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textD; 10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 106840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 10709b1cba8ccd7554cb30905711a426bd86ad8dd38cJean-Baptiste Queru maxWidth = SkScalarMulDiv(maxWidth, kCanonicalTextSizeForPaths, fTextSize); 10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 107440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false); 10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop; 10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop); 10811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int xyIndex = this->isVerticalText() ? 1 : 0; 1082e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // use 64bits for our accumulator, to avoid overflowing 16.16 1083e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed Sk48Dot16 max = SkScalarToFixed(maxWidth); 1084e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed Sk48Dot16 width = 0; 10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 108840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb = 0; 109040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (pred(text, stop)) { 10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* curr = text; 10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 10931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex); 109440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if ((width += x) > max) { 10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width -= x; 10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text = curr; 10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g.fRsbDelta; 11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 110140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 110240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (pred(text, stop)) { 11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* curr = text; 11041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex); 110540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if ((width += x) > max) { 11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width -= x; 11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text = curr; 11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 111240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 111340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (measuredWidth) { 1114e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed SkScalar scalarWidth = Sk48Dot16ToScalar(width); 111540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scalarWidth = SkScalarMul(scalarWidth, scale); 111740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *measuredWidth = scalarWidth; 11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 112040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // return the number of bytes measured 11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (kForward_TextBufferDirection == tbd) ? 11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text - stop + length : stop - text + length; 11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 112840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) { 11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *(SkPaint::FontMetrics*)context = cache->getFontMetricsY(); 11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; // don't detach the cache 11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 113340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context) { 11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context); 11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 113740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const { 11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 114140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 114640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 114740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix zoomMatrix, *zoomPtr = NULL; 114840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (zoom) { 11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomMatrix.setScale(zoom, zoom); 11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomPtr = &zoomMatrix; 11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, zoomPtr); 11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const FontMetrics& my = cache->getFontMetricsY(); 11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project FontMetrics storage; 115940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == metrics) { 11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics = &storage; 116140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 116240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 11631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics, true); 11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 116540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fTop = SkScalarMul(metrics->fTop, scale); 11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return metrics->fDescent - metrics->fAscent + metrics->fLeading; 11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 117540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 117740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) { 11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->set(g.fLeft * scale, 11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g.fTop * scale, 11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (g.fLeft + g.fWidth) * scale, 11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (g.fTop + g.fHeight) * scale); 11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 118440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerint SkPaint::getTextWidths(const void* textData, size_t byteLength, 118540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar widths[], SkRect bounds[]) const { 118640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == byteLength) { 11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 118840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(NULL != textData); 11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 119240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == widths && NULL == bounds) { 11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->countText(textData, byteLength); 119440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 119940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc; 12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project NULL != bounds); 12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = text + byteLength; 12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = 0; 12141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int xyIndex = this->isVerticalText() ? 1 : 0; 12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 121640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we adjust the widths returned here through auto-kerning 12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed prevWidth = 0; 12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (scale) { 12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed adjust = autokern.adjust(g); 12260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0) { 12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar w = SkFixedToScalar(prevWidth + adjust); 12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths++ = SkScalarMul(w, scale); 12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prevWidth = advance(g, xyIndex); 12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++, scale); 12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0 && widths) { 12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale); 12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed adjust = autokern.adjust(g); 12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0) { 12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths++ = SkFixedToScalar(prevWidth + adjust); 12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prevWidth = advance(g, xyIndex); 12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++); 12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0 && widths) { 12580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths = SkFixedToScalar(prevWidth); 12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { // no devkern 12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (scale) { 12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)), 12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale); 12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++, scale); 12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 12750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *widths++ = SkFixedToScalar(advance(g, xyIndex)); 12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++); 12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text == stop); 12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return count; 12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 129240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 12930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h" 12950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 129640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::getTextPath(const void* textData, size_t length, 129740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar x, SkScalar y, SkPath* path) const { 129840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(length == 0 || textData != NULL); 129940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 13000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 130140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (text == NULL || length == 0 || path == NULL) { 13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 130340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 13040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTextToPathIter iter(text, length, *this, false, true); 13060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMatrix matrix; 13070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar prevXPos = 0; 13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.setScale(iter.getPathScale(), iter.getPathScale()); 13100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.postTranslate(x, y); 13110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path->reset(); 13120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar xpos; 13140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPath* iterPath; 131540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while ((iterPath = iter.next(&xpos)) != NULL) { 13160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.postTranslate(xpos - prevXPos, 0); 13170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path->addPath(*iterPath, matrix); 13180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project prevXPos = xpos; 13190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 13200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 13210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag, 13230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer* buffer) { 13240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer->flatten(desc->addEntry(tag, buffer->size(), NULL)); 13250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 13260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// SkFontHost can override this choice in FilterRec() 132840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkMask::Format computeMaskFormat(const SkPaint& paint) { 13290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t flags = paint.getFlags(); 13300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1331c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed // Antialiasing being disabled trumps all other settings. 1332137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger if (!(flags & SkPaint::kAntiAlias_Flag)) { 1333c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed return SkMask::kBW_Format; 133405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 133505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 1336137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger if (flags & SkPaint::kLCDRenderText_Flag) { 1337137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger return SkMask::kLCD16_Format; 1338137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger } 1339c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed 1340c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed return SkMask::kA8_Format; 13410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 13420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 13434bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// if linear-text is on, then we force hinting to be off (since that's sort of 13444bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// the point of linear-text. 13454bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reedstatic SkPaint::Hinting computeHinting(const SkPaint& paint) { 13464bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed SkPaint::Hinting h = paint.getHinting(); 13474bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed if (paint.isLinearText()) { 13484bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed h = SkPaint::kNo_Hinting; 13494bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed } 13504bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed return h; 13514bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed} 13524bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed 13531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// return true if the paint is just a single color (i.e. not a shader). If its 13541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// a shader, then we can't compute a const luminance for it :( 13551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool justAColor(const SkPaint& paint, SkColor* color) { 13561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getShader()) { 13571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 13581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor c = paint.getColor(); 13601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getColorFilter()) { 13611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger c = paint.getColorFilter()->filterColor(c); 13621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (color) { 13641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *color = c; 13651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 13671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 13704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic SkColor computeLuminanceColor(const SkPaint& paint) { 13714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColor c; 13724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!justAColor(paint, &c)) { 13734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger c = SkColorSetRGB(0x7F, 0x80, 0x7F); 13744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return c; 13764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#define assert_byte(x) SkASSERT(0 == ((x) >> 8)) 13794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic U8CPU reduce_lumbits(U8CPU x) { 13814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger static const uint8_t gReduceBits[] = { 13824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0x0, 0x55, 0xAA, 0xFF 13834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger }; 13844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger assert_byte(x); 13854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return gReduceBits[x >> 6]; 13864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic unsigned computeLuminance(SkColor c) { 13894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int r = SkColorGetR(c); 13904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int g = SkColorGetG(c); 13914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int b = SkColorGetB(c); 13924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // compute luminance 13934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // R=0.2126 G=0.7152 B=0.0722 13944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // scaling by 127 yields 27, 92, 9 13954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int luminance = r * 27 + g * 92 + b * 9; 13964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger luminance >>= 7; 13974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger assert_byte(luminance); 13984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return luminance; 13994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 14004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 14014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 14021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// returns 0..kLuminance_Max 14031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic unsigned computeLuminance(const SkPaint& paint) { 14041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor c; 14051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (justAColor(paint, &c)) { 14061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r = SkColorGetR(c); 14071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int g = SkColorGetG(c); 14081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int b = SkColorGetB(c); 14091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // compute luminance 14101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // R=0.2126 G=0.7152 B=0.0722 14111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // scaling by 127 yields 27, 92, 9 14121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 1 14131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int luminance = r * 27 + g * 92 + b * 9; 14141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger luminance >>= 15 - SkScalerContext::kLuminance_Bits; 14151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 14161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int luminance = r * 2 + g * 5 + b * 1; 14171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger luminance >>= 11 - SkScalerContext::kLuminance_Bits; 14181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 14191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(luminance <= SkScalerContext::kLuminance_Max); 14201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return luminance; 14211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we're not a single color, return the middle of the luminance range 14231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkScalerContext::kLuminance_Max >> 1; 14241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 14261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Beyond this size, LCD doesn't appreciably improve quality, but it always 14281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// cost more RAM and draws slower, so we set a cap. 14291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifndef SK_MAX_SIZE_FOR_LCDTEXT 14301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SK_MAX_SIZE_FOR_LCDTEXT 48 14311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 14321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 14331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool tooBigForLCD(const SkScalerContext::Rec& rec) { 14341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar area = SkScalarMul(rec.fPost2x2[0][0], rec.fPost2x2[1][1]) - 14351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalarMul(rec.fPost2x2[1][0], rec.fPost2x2[0][1]); 14361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar size = SkScalarMul(area, rec.fTextSize); 14371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkScalarAbs(size) > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT); 14381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 14391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 144040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/* 144140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * Return the scalar with only limited fractional precision. Used to consolidate matrices 144240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * that vary only slightly when we create our key into the font cache, since the font scaler 144340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * typically returns the same looking resuts for tiny changes in the matrix. 144440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 144540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkScalar sk_relax(SkScalar x) { 144640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 144740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int n = sk_float_round2int(x * 1024); 144840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return n / 1024.0f; 144940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#else 145040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // round to the nearest 10 fractional bits 145140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return (x + (1 << 5)) & ~(1024 - 1); 145240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 145340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 145440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1455af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkScalerContext::MakeRec(const SkPaint& paint, 145640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkMatrix* deviceMatrix, Rec* rec) { 14570199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); 14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 145979bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease SkTypeface* typeface = paint.getTypeface(); 146079bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease rec->fOrigFontID = SkTypeface::UniqueID(typeface); 14610199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger rec->fFontID = rec->fOrigFontID; 14620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fTextSize = paint.getTextSize(); 14630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPreScaleX = paint.getTextScaleX(); 14640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPreSkewX = paint.getTextSkewX(); 14650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 146640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (deviceMatrix) { 146740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX()); 146840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX()); 146940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY()); 147040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY()); 147140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 14720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 14730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0; 14740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 147540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style style = paint.getStyle(); 14770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar strokeWidth = paint.getStrokeWidth(); 147840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned flags = 0; 14801c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 14811c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#ifdef SK_USE_FREETYPE_EMBOLDEN 148279bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // It is possible that the SkTypeface used to draw glyphs has 148379bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // different properties than the SkTypeface set in the SkPaint. 148479bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // If we are asked to render bold text with a bold font, and are 148579bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // forced to fall back to a font with normal weight for some 148679bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // glyphs, we need to use fake bold to render those glyphs. In 148779bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // order to do that, we set SkScalerContext's "embolden" flag 148879bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // here if we are trying to draw bold text via any means, and 148979bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // ignore it at the glyph outline generation stage if the font 149079bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease // actually being used is already bold. 149179bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease if (paint.isFakeBoldText() || (typeface && typeface->isBold())) { 14921c980e0d7772f05f570ae0227d91635f017c2227Mike Reed flags |= SkScalerContext::kEmbolden_Flag; 149379bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease } 14941c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#else 149579bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease if (paint.isFakeBoldText()) { 149640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(), 149740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpKeys, 149840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpValues, 149940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpLength); 15000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale); 150140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 150240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style == SkPaint::kFill_Style) { 15030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project style = SkPaint::kStrokeAndFill_Style; 15040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project strokeWidth = extra; // ignore paint's strokeWidth if it was "fill" 150540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 15060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project strokeWidth += extra; 150740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 15080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 150979bf51281ffa537ddfbb54dededdad5aa9e466e8Victoria Lease#endif 15100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 151140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isDevKernText()) { 15120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkScalerContext::kDevKernText_Flag; 151340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 151440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 151540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style != SkPaint::kFill_Style && strokeWidth > 0) { 15160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fFrameWidth = strokeWidth; 15170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMiterLimit = paint.getStrokeMiter(); 15180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fStrokeJoin = SkToU8(paint.getStrokeJoin()); 15190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 152040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style == SkPaint::kStrokeAndFill_Style) { 15210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkScalerContext::kFrameAndFill_Flag; 152240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 152340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 15240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fFrameWidth = 0; 15250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMiterLimit = 0; 15260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fStrokeJoin = 0; 15270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 15280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); 15300b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 15311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkMask::kLCD16_Format == rec->fMaskFormat || 15321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask::kLCD32_Format == rec->fMaskFormat) 15331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 15340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFontHost::LCDOrder order = SkFontHost::GetSubpixelOrder(); 15350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFontHost::LCDOrientation orient = SkFontHost::GetSubpixelOrientation(); 15361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkFontHost::kNONE_LCDOrder == order || tooBigForLCD(*rec)) { 15370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // eeek, can't support LCD 15380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->fMaskFormat = SkMask::kA8_Format; 15390b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } else { 15400b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SkFontHost::kVertical_LCDOrientation == orient) { 15410b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kLCD_Vertical_Flag; 15420b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 15430b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SkFontHost::kBGR_LCDOrder == order) { 15440b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kLCD_BGROrder_Flag; 15450b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 15460b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 15470b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 15480b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 154940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isEmbeddedBitmapText()) { 15500b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kEmbeddedBitmapText_Flag; 155140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 155240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isSubpixelText()) { 15530b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kSubpixelPositioning_Flag; 155440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 155540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isAutohinted()) { 15560b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kAutohinting_Flag; 155740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 15581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.isVerticalText()) { 15591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flags |= SkScalerContext::kVertical_Flag; 15601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { 15624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flags |= SkScalerContext::kGenA8FromLCD_Flag; 15634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15640b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->fFlags = SkToU16(flags); 15650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 15661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // these modify fFlags, so do them after assigning fFlags 15670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->setHinting(computeHinting(paint)); 15684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(computeLuminanceColor(paint)); 15704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 15711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rec->setLuminanceBits(computeLuminance(paint)); 15724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 1573212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett#ifdef SK_BUILD_FOR_ANDROID 1574725b3e03acb91dc69296554932624b36612bd189Billy Hewlett rec->fLanguage = paint.getLanguage(); 1575212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett rec->fFontVariant = paint.getFontVariant(); 1576212ef7a5d592a11522f73d858bf98f5201631b70Billy Hewlett#endif //SK_BUILD_FOR_ANDROID 1577af2616552738d653d5453915d3236e7154b868cdMike Reed 1578af2616552738d653d5453915d3236e7154b868cdMike Reed /* Allow the fonthost to modify our rec before we use it as a key into the 1579af2616552738d653d5453915d3236e7154b868cdMike Reed cache. This way if we're asking for something that they will ignore, 1580af2616552738d653d5453915d3236e7154b868cdMike Reed they can modify our rec up front, so we don't create duplicate cache 1581af2616552738d653d5453915d3236e7154b868cdMike Reed entries. 1582af2616552738d653d5453915d3236e7154b868cdMike Reed */ 1583af2616552738d653d5453915d3236e7154b868cdMike Reed SkFontHost::FilterRec(rec); 15841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // be sure to call PostMakeRec(rec) before you actually use it! 15864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 15874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/** 15894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * We ensure that the rec is self-consistent and efficient (where possible) 15904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 15914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkScalerContext::PostMakeRec(SkScalerContext::Rec* rec) { 15924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger /** 15944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * If we're asking for A8, we force the colorlum to be gray, since that 15954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * that limits the number of unique entries, and the scaler will only 15964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * look at the lum of one of them. 15974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 15984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (rec->fMaskFormat) { 15994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kLCD16_Format: 16004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kLCD32_Format: { 16014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 16024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // filter down the luminance color to a finite number of bits 16034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColor c = rec->getLuminanceColor(); 16044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger c = SkColorSetRGB(reduce_lumbits(SkColorGetR(c)), 16054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger reduce_lumbits(SkColorGetG(c)), 16064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger reduce_lumbits(SkColorGetB(c))); 16074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(c); 16084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 16094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 16104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 16114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kA8_Format: { 16124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 16134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // filter down the luminance to a single component, since A8 can't 16144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // use per-component information 16154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger unsigned lum = computeLuminance(rec->getLuminanceColor()); 16164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // reduce to our finite number of bits 16174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger lum = reduce_lumbits(lum); 16184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(SkColorSetRGB(lum, lum, lum)); 16194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 16204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 16214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 16224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kBW_Format: 16234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // No need to differentiate gamma if we're BW 16244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 16254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(0); 16264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 16274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceBits(0); 16284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 16294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 16301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 16310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 16320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER 1024 16340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 163535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef SK_DEBUG 163635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger #define TEST_DESC 163735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif 163835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 16391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 16401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * ignoreGamma tells us that the caller just wants metrics that are unaffected 16411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * by gamma correction, so we jam the luminance field to 0 (most common value 16421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * for black text) in hopes that we get a cache hit easier. A better solution 16431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * would be for the fontcache lookup to know to ignore the luminance field 16441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * entirely, but not sure how to do that and keep it fast. 16451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 16460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix, 16470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void (*proc)(const SkDescriptor*, void*), 164840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void* context, bool ignoreGamma) const { 16490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalerContext::Rec rec; 16500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalerContext::MakeRec(*this, deviceMatrix, &rec); 1652fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy if (ignoreGamma) { 16534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 16544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec.setLuminanceColor(0); 16554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 16561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rec.setLuminanceBits(0); 16574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 1658fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy } 16590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size_t descSize = sizeof(rec); 16610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int entryCount = 1; 16620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPathEffect* pe = this->getPathEffect(); 16630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMaskFilter* mf = this->getMaskFilter(); 16640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRasterizer* ra = this->getRasterizer(); 16650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 16670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 16680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 16690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (pe) { 16710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project peBuffer.writeFlattenable(pe); 16720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += peBuffer.size(); 16730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // seems like we could support kLCD as well at this point... 16760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (mf) { 16780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project mfBuffer.writeFlattenable(mf); 16790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += mfBuffer.size(); 16800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters 16820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ra) { 16840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project raBuffer.writeFlattenable(ra); 16850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += raBuffer.size(); 16860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 16914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Now that we're done tweaking the rec, call the PostMakeRec cleanup 16924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkScalerContext::PostMakeRec(&rec); 16934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += SkDescriptor::ComputeOverhead(entryCount); 16950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoDescriptor ad(descSize); 16970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDescriptor* desc = ad.getDesc(); 16980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->init(); 17000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 17010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (pe) { 17030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer); 17040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 17050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (mf) { 17060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer); 17070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 17080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ra) { 17090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer); 17100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 17110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(descSize == desc->getLength()); 17130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->computeChecksum(); 17140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 171535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef TEST_DESC 171635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger { 171735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Check that we completely write the bytes in desc (our key), and that 171835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // there are no uninitialized bytes. If there were, then we would get 171935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // false-misses (or worse, false-hits) in our fontcache. 172035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // 172135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // We do this buy filling 2 others, one with 0s and the other with 1s 172235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // and create those, and then check that all 3 are identical. 172335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkAutoDescriptor ad1(descSize); 172435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkAutoDescriptor ad2(descSize); 172535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDescriptor* desc1 = ad1.getDesc(); 172635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDescriptor* desc2 = ad2.getDesc(); 172735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 172835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger memset(desc1, 0x00, descSize); 172935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger memset(desc2, 0xFF, descSize); 173035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 173135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->init(); 173235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->init(); 173335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 173435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 173535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 173635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (pe) { 173735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer); 173835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer); 173935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 174035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (mf) { 174135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer); 174235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer); 174335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 174435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (ra) { 174535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer); 174635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer); 174735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 174835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 174935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(descSize == desc1->getLength()); 175035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(descSize == desc2->getLength()); 175135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->computeChecksum(); 175235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->computeChecksum(); 175335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(!memcmp(desc, desc1, descSize)); 175435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(!memcmp(desc, desc2, descSize)); 175535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 175635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif 175735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 17580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project proc(desc, context); 17590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 17600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 176140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const { 17620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache; 17630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->descriptorProc(deviceMatrix, DetachDescProc, &cache); 17640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache; 17650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 17660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 17680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h" 17700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uintptr_t asint(const void* p) { 17725f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return reinterpret_cast<uintptr_t>(p); 17735f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17745f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedunion Scalar32 { 17765f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkScalar fScalar; 17775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t f32; 17785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}; 17795f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) { 17815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 17825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed Scalar32 tmp; 17835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp.fScalar = value; 17845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr = tmp.f32; 17855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return ptr + 1; 17865f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17875f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17885f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic SkScalar read_scalar(const uint32_t*& ptr) { 17895f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 17905f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed Scalar32 tmp; 17915f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp.f32 = *ptr++; 17925f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return tmp.fScalar; 17935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17945f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17955f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { 17965f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(a == (uint8_t)a); 17975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(b == (uint8_t)b); 17985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(c == (uint8_t)c); 17995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(d == (uint8_t)d); 18005f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return (a << 24) | (b << 16) | (c << 8) | d; 18015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 18025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedenum FlatFlags { 18045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed kHasTypeface_FlatFlag = 0x01, 18055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed kHasEffects_FlatFlag = 0x02 18065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}; 18075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed// The size of a flat paint's POD fields 18095f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + 18105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1 * sizeof(SkColor) + 18115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1 * sizeof(uint16_t) + 18125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 6 * sizeof(uint8_t); 18135f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed/* To save space/time, we analyze the paint, and write a truncated version of 18155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed it if there are not tricky elements like shaders, etc. 18165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed */ 18170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const { 18185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint8_t flatFlags = 0; 18195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (this->getTypeface()) { 18205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed flatFlags |= kHasTypeface_FlatFlag; 18215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (asint(this->getPathEffect()) | 18235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getShader()) | 18245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getXfermode()) | 18255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getMaskFilter()) | 18265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getColorFilter()) | 18275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getRasterizer()) | 18281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger asint(this->getLooper()) | 18291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger asint(this->getImageFilter())) { 18305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed flatFlags |= kHasEffects_FlatFlag; 18315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 183240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 18335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 18345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t* ptr = buffer.reserve(kPODPaintSize); 18355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextSize()); 18375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextScaleX()); 18385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextSkewX()); 18395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getStrokeWidth()); 18405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getStrokeMiter()); 18415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr++ = this->getColor(); 18421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // previously flags:16, textAlign:8, flatFlags:8 18431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // now flags:16, hinting:4, textAlign:4, flatFlags:8 18441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *ptr++ = (this->getFlags() << 16) | 18451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // hinting added later. 0 in this nibble means use the default. 18461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ((this->getHinting()+1) << 12) | 18471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (this->getTextAlign() << 8) | 18481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flatFlags; 18495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(), 18505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->getStyle(), this->getTextEncoding()); 18515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1852725b3e03acb91dc69296554932624b36612bd189Billy Hewlett#ifdef SK_BUILD_FOR_ANDROID 1853725b3e03acb91dc69296554932624b36612bd189Billy Hewlett buffer.writeInt(this->getFontVariant()); 1854725b3e03acb91dc69296554932624b36612bd189Billy Hewlett const SkString& langTag = this->getLanguage().getTag(); 1855725b3e03acb91dc69296554932624b36612bd189Billy Hewlett buffer.writeString(langTag.c_str(), langTag.size()); 1856725b3e03acb91dc69296554932624b36612bd189Billy Hewlett#endif 1857725b3e03acb91dc69296554932624b36612bd189Billy Hewlett 18585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // now we're done with ptr and the (pre)reserved space. If we need to write 18595f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // additional fields, use the buffer directly 18605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasTypeface_FlatFlag) { 18615f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeTypeface(this->getTypeface()); 18625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasEffects_FlatFlag) { 18645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getPathEffect()); 18655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getShader()); 18665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getXfermode()); 18675f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getMaskFilter()); 18685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getColorFilter()); 18695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getRasterizer()); 18705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getLooper()); 18711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger buffer.writeFlattenable(this->getImageFilter()); 18725f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) { 18765f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 18775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed const void* podData = buffer.skip(kPODPaintSize); 18785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); 187940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 18805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // the order we read must match the order we wrote in flatten() 18815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextSize(read_scalar(pod)); 18825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextScaleX(read_scalar(pod)); 18835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextSkewX(read_scalar(pod)); 18845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeWidth(read_scalar(pod)); 188540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->setStrokeMiter(read_scalar(pod)); 18865f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setColor(*pod++); 18875f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // previously flags:16, textAlign:8, flatFlags:8 18891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // now flags:16, hinting:4, textAlign:4, flatFlags:8 18905f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t tmp = *pod++; 18915f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setFlags(tmp >> 16); 18921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) { 18944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF)); 18954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setHinting(SkPaintDefaults_Hinting); 18964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 18974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // hinting added later. 0 in this nibble means use the default. 18984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger uint32_t hinting = (tmp >> 12) & 0xF; 18994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setHinting(0 == hinting ? kNormal_Hinting : static_cast<Hinting>(hinting-1)); 19001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xF)); 19024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 19031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 19045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint8_t flatFlags = tmp & 0xFF; 19055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 19065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp = *pod++; 19075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); 19085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); 19095f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); 19105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); 19115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1912725b3e03acb91dc69296554932624b36612bd189Billy Hewlett#ifdef SK_BUILD_FOR_ANDROID 1913725b3e03acb91dc69296554932624b36612bd189Billy Hewlett this->setFontVariant(SkPaint::FontVariant(buffer.readInt())); 1914725b3e03acb91dc69296554932624b36612bd189Billy Hewlett this->setLanguage(SkLanguage(buffer.readString())); 1915725b3e03acb91dc69296554932624b36612bd189Billy Hewlett#endif 1916725b3e03acb91dc69296554932624b36612bd189Billy Hewlett 19175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasTypeface_FlatFlag) { 19185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTypeface(buffer.readTypeface()); 19195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } else { 19205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTypeface(NULL); 19215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 19225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 19235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasEffects_FlatFlag) { 192440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setPathEffect((SkPathEffect*) buffer.readFlattenable())); 192540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setShader((SkShader*) buffer.readFlattenable())); 192640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setXfermode((SkXfermode*) buffer.readFlattenable())); 192740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())); 192840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setColorFilter((SkColorFilter*) buffer.readFlattenable())); 192940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setRasterizer((SkRasterizer*) buffer.readFlattenable())); 193040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setLooper((SkDrawLooper*) buffer.readFlattenable())); 19314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (buffer.getPictureVersion() != PICTURE_VERSION_ICS) 19324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkSafeUnref(this->setImageFilter((SkImageFilter*) buffer.readFlattenable())); 19334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger else 19344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setImageFilter(NULL); 19355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } else { 19365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setPathEffect(NULL); 19375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setShader(NULL); 19385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setXfermode(NULL); 19395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setMaskFilter(NULL); 19405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setColorFilter(NULL); 19415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setRasterizer(NULL); 19425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setLooper(NULL); 19431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setImageFilter(NULL); 19445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 19450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 19480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 194987b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkShader* SkPaint::setShader(SkShader* shader) { 195087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(shader != fShader); 19510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fShader, shader); 19520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return shader; 19530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 195587b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { 195687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(filter != fColorFilter); 19570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fColorFilter, filter); 19580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return filter; 19590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 196187b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkXfermode* SkPaint::setXfermode(SkXfermode* mode) { 196287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(mode != fXfermode); 19630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fXfermode, mode); 19640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return mode; 19650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 196703f42ddd729377f21719a140c027a1f8cc5c2152Mike ReedSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { 196803f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed SkSafeUnref(fXfermode); 196903f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed fXfermode = SkXfermode::Create(mode); 197087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 197103f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed return fXfermode; 197203f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed} 197303f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed 197487b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { 197587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(effect != fPathEffect); 19760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fPathEffect, effect); 19770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return effect; 19780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 198087b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { 198187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(filter != fMaskFilter); 19820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fMaskFilter, filter); 19830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return filter; 19840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 198640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 19870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 198840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const { 19890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPath effectPath, strokePath; 19900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPath* path = &src; 19910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar width = this->getStrokeWidth(); 199340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 19940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getStyle()) { 199540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kFill_Style: 19960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; // mark it as no-stroke 199740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 199840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kStrokeAndFill_Style: 199940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width == 0) { 200040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger width = -1; // mark it as no-stroke 200140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 200240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 200340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kStroke_Style: 200440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 200540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger default: 20061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown paint style"); 20070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 200940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getPathEffect()) { 20100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill 201140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getStyle() == SkPaint::kStrokeAndFill_Style) { 20120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; // mark it as no-stroke 201340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 201540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getPathEffect()->filterPath(&effectPath, src, &width)) { 20160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path = &effectPath; 201740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 201840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 20190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // restore the width if we earlier had to lie, and if we're still set to no-stroke 20200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // note: if we're now stroke (width >= 0), then the pathEffect asked for that change 20210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // and we want to respect that (i.e. don't overwrite their setting for width) 202240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0) { 20230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = this->getStrokeWidth(); 202440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width == 0) { 20250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; 202640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 202940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 203040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width > 0 && !path->isEmpty()) { 20310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkStroke stroker(*this, width); 20320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project stroker.strokePath(*path, &strokePath); 20330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path = &strokePath; 20340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 203640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (path == &src) { 20370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = src; 203840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 20390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(path == &effectPath || path == &strokePath); 20400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->swap(*(SkPath*)path); 20410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return width != 0; // return true if we're filled, or false if we're hairline (width == 0) 20440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2046717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerconst SkRect& SkPaint::doComputeFastBounds(const SkRect& src, 2047717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect* storage) const { 20480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(storage); 2049717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2050717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getLooper()) { 2051717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkASSERT(this->getLooper()->canComputeFastBounds(*this)); 2052717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->getLooper()->computeFastBounds(*this, src, storage); 2053717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return *storage; 2054717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2055717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2056717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getStyle() != SkPaint::kFill_Style) { 2057717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger // since we're stroked, outset the rect by the radius (and join type) 2058717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkScalar radius = SkScalarHalf(this->getStrokeWidth()); 2059717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (0 == radius) { // hairline 2060717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger radius = SK_Scalar1; 2061717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { 2062717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkScalar scale = this->getStrokeMiter(); 2063717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (scale > SK_Scalar1) { 2064717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger radius = SkScalarMul(radius, scale); 2065717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 20660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2067717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger storage->set(src.fLeft - radius, src.fTop - radius, 2068717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger src.fRight + radius, src.fBottom + radius); 2069717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2070717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger *storage = src; 20710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2072717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2073717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger // check the mask filter 2074717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getMaskFilter()) { 2075717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->getMaskFilter()->computeFastBounds(*storage, storage); 2076717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2077717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 207835d15937afb7f4b3472e43ea784b02485ec910fbMike Reed return *storage; 20790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 208140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 20820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 208340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool has_thick_frame(const SkPaint& paint) { 208440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return paint.getStrokeWidth() > 0 && 208540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger paint.getStyle() != SkPaint::kFill_Style; 20860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length, 20890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint, 20900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool applyStrokeAndPathEffects, 209140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool forceLinearTextOn) : fPaint(paint) { 20920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection, 20930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project true); 20940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 209540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (forceLinearTextOn) { 20960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setLinearText(true); 209740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup 20990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 210040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { 21010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project applyStrokeAndPathEffects = false; 210240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 21030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // can't use our canonical size if we need to apply patheffects/strokes 2105b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger if (fPaint.getPathEffect() == NULL) { 21060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); 21070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; 2108b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger if (has_thick_frame(fPaint)) { 2109b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale)); 2110b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger } 211140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 21120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = SK_Scalar1; 211340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 211440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 211540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!applyStrokeAndPathEffects) { 21160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setStyle(SkPaint::kFill_Style); 21170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setPathEffect(NULL); 21180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCache = fPaint.detachCache(NULL); 21210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style style = SkPaint::kFill_Style; 21230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPathEffect* pe = NULL; 21240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 212540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!applyStrokeAndPathEffects) { 21260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project style = paint.getStyle(); // restore 21270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pe = paint.getPathEffect(); // restore 21280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setStyle(style); 21300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setPathEffect(pe); 21310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setMaskFilter(paint.getMaskFilter()); // restore 21320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // now compute fXOffset if needed 21340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar xOffset = 0; 213640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first 21370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count; 213840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, 213940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger &count, NULL), fScale); 214040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.getTextAlign() == SkPaint::kCenter_Align) { 21410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = SkScalarHalf(width); 214240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 21430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project xOffset = -width; 21440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXPos = xOffset; 21460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevAdvance = 0; 21470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fText = text; 21490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStop = text + length; 21501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fXYIndex = paint.isVerticalText() ? 1 : 0; 21520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 21530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 215440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTextToPathIter::~SkTextToPathIter() { 21550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache::AttachCache(fCache); 21560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 21570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 215840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkPath* SkTextToPathIter::next(SkScalar* xpos) { 215940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (fText < fStop) { 21600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 21610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 21620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); 21631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); 21640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 216540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (glyph.fWidth) { 216640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (xpos) { 21670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *xpos = fXPos; 216840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 21690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fCache->findPath(glyph); 21700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 21720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 21730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2174717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2175717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2176717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 21771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkPaint::nothingToDraw() const { 21781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fLooper) { 21791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Mode mode; 21821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::AsMode(fXfermode, &mode)) { 21831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (mode) { 21841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSrcOver_Mode: 21851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSrcATop_Mode: 21861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDstOut_Mode: 21871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDstOver_Mode: 21881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kPlus_Mode: 21891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 0 == this->getAlpha(); 21901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDst_Mode: 21911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 21921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 21931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 21941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////// Move these to their own file soon. 22011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, 22031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMatrix& ctm, 22041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap* result, SkIPoint* loc) { 22051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(proxy); 22061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(result); 22071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(loc); 22081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* 22091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Give the proxy first shot at the filter. If it returns false, ask 22101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the filter to do it. 22111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 22121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return proxy->filterImage(this, src, ctm, result, loc) || 22131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->onFilterImage(proxy, src, ctm, result, loc); 22141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 22151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, 22171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect* dst) { 22181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(&src); 22191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst); 22201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->onFilterBounds(src, ctm, dst); 22211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 22221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&, 22241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap*, SkIPoint*) { 22251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 22261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 22271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 22291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect* dst) { 22301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *dst = src; 22311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 22321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 22331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::asABlur(SkSize* sigma) const { 22351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 22361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 22371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asAnErode(SkISize* radius) const { 22394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 22404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 22414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 22424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asADilate(SkISize* radius) const { 22434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 22444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 22454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 22464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger////// 22474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2248717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerbool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) { 2249717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkCanvas canvas; 2250717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2251717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->init(&canvas); 2252717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger for (;;) { 2253717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkPaint p(paint); 2254717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->next(&canvas, &p)) { 2255717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.setLooper(NULL); 2256717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (!p.canComputeFastBounds()) { 2257717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return false; 2258717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2259717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2260717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger break; 2261717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2262717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2263717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return true; 2264717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 2265717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2266717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergervoid SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src, 2267717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect* dst) { 2268717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkCanvas canvas; 22694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2270717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->init(&canvas); 2271717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger for (bool firstTime = true;; firstTime = false) { 2272717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkPaint p(paint); 2273717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->next(&canvas, &p)) { 2274717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect r(src); 2275717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2276717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.setLooper(NULL); 2277717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.computeFastBounds(r, &r); 2278717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger canvas.getTotalMatrix().mapRect(&r); 2279717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2280717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (firstTime) { 2281717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger *dst = r; 2282717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2283717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger dst->join(r); 2284717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2285717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2286717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger break; 2287717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2288717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2289717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 22901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2291