SkPaint.cpp revision 4f1dae40e24d57d647db01443b8bf2410514b8b5
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 100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h" 110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h" 120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFontHost.h" 131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkImageFilter.h" 140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h" 150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPathEffect.h" 160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRasterizer.h" 170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h" 1840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkScalar.h" 190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScalerContext.h" 200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStroke.h" 2140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkTextFormatParams.h" 220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypeface.h" 230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h" 240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAutoKern.h" 251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkGlyphCache.h" 264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkPaintDefaults.h" 271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// define this to get a printf for out-of-range parameter in setters 291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// e.g. setTextSize(-1) 301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//#define SK_REPORT_API_RANGE_CHECK 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 3387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC fGenerationID++ 3487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } 3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#else 3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC 3787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression) 3887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 3987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 40c1c43a17e7f2a87951739691056728a80e9aef6bMike ReedSkPaint::SkPaint() { 41c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // since we may have padding, we zero everything so that our memcmp() call 42c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // in operator== will work correctly. 43c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed // with this, we can skip 0 and null individual initializations 44c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed sk_bzero(this, sizeof(*this)); 45c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed 46c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#if 0 // not needed with the bzero call above 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTypeface = NULL; 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextSkewX = 0; 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPathEffect = NULL; 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fShader = NULL; 510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXfermode = NULL; 520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fMaskFilter = NULL; 530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColorFilter = NULL; 540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fRasterizer = NULL; 550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fLooper = NULL; 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fImageFilter = NULL; 57c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed fWidth = 0; 58c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#endif 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fTextSize = SkPaintDefaults_TextSize; 61c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed fTextScaleX = SK_Scalar1; 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fColor = SK_ColorBLACK; 634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fMiterLimit = SkPaintDefaults_MiterLimit; 644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fFlags = SkPaintDefaults_Flags; 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCapType = kDefault_Cap; 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fJoinType = kDefault_Join; 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextAlign = kLeft_Align; 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStyle = kFill_Style; 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextEncoding = kUTF8_TextEncoding; 704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger fHinting = SkPaintDefaults_Hinting; 711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 7295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase fGenerationID = 0; 7387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::SkPaint(const SkPaint& src) { 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(this, &src, sizeof(src)); 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fTypeface); 8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fPathEffect); 8140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fShader); 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fXfermode); 8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fMaskFilter); 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fColorFilter); 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fRasterizer); 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(fLooper); 871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeRef(fImageFilter); 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::~SkPaint() { 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fTypeface); 9240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fPathEffect); 9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fShader); 9440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fXfermode); 9540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fMaskFilter); 9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fColorFilter); 9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fRasterizer); 9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fLooper); 991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeUnref(fImageFilter); 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint& SkPaint::operator=(const SkPaint& src) { 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(&src); 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fTypeface); 10640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fPathEffect); 10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fShader); 10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fXfermode); 10940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fMaskFilter); 11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fColorFilter); 11140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fRasterizer); 11240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(src.fLooper); 1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeRef(src.fImageFilter); 11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fTypeface); 11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fPathEffect); 11740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fShader); 11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fXfermode); 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fMaskFilter); 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fColorFilter); 12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fRasterizer); 12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(fLooper); 1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkSafeUnref(fImageFilter); 1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1269f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase uint32_t oldGenerationID = fGenerationID; 12787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(this, &src, sizeof(src)); 1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1309f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase fGenerationID = oldGenerationID + 1; 13187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return *this; 1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool operator==(const SkPaint& a, const SkPaint& b) { 1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger //assumes that fGenerationID is the last field in the struct 1391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(&a, &b, SK_OFFSETOF(SkPaint, fGenerationID)); 1401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 1411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return !memcmp(&a, &b, sizeof(a)); 1421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::reset() { 1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint init; 1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1499f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase uint32_t oldGenerationID = fGenerationID; 15087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *this = init; 1521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1539f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase fGenerationID = oldGenerationID + 1; 15487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 15595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase} 15695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase 1571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 15895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haaseuint32_t SkPaint::getGenerationID() const { 15995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase return fGenerationID; 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 16187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 1641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerunsigned SkPaint::getBaseGlyphCount(SkUnichar text) const { 1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkAutoGlyphCache autoCache(*this, NULL); 1661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkGlyphCache* cache = autoCache.getCache(); 1671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return cache->getBaseGlyphCount(text); 1681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 1691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 1701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 17187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setHinting(Hinting hintingLevel) { 17287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); 17387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fHinting = hintingLevel; 1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFlags(uint32_t flags) { 17787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(fFlags != flags); 17887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fFlags = flags; 1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAntiAlias(bool doAA) { 18287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doAA != isAntiAlias()); 18387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); 1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDither(bool doDither) { 18787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doDither != isDither()); 18887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); 1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setSubpixelText(bool doSubpixel) { 19287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doSubpixel != isSubpixelText()); 19387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag)); 194af2616552738d653d5453915d3236e7154b868cdMike Reed} 195af2616552738d653d5453915d3236e7154b868cdMike Reed 19687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLCDRenderText(bool doLCDRender) { 19787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doLCDRender != isLCDRenderText()); 19887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag)); 19987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger} 20087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger 20187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) { 20287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doEmbeddedBitmapText != isEmbeddedBitmapText()); 20387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag)); 2042cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed} 2052cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed 20687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAutohinted(bool useAutohinter) { 20787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(useAutohinter != isAutohinted()); 20840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag)); 20940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 21040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 21187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLinearText(bool doLinearText) { 21287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doLinearText != isLinearText()); 21387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag)); 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkPaint::setVerticalText(bool doVertical) { 2171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GEN_ID_INC_EVAL(doVertical != isVerticalText()); 2181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setFlags(SkSetClearMask(fFlags, doVertical, kVerticalText_Flag)); 2191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 2201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 22187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setUnderlineText(bool doUnderline) { 22287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doUnderline != isUnderlineText()); 22387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag)); 2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 22687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrikeThruText(bool doStrikeThru) { 22787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doStrikeThru != isStrikeThruText()); 22887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag)); 2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFakeBoldText(bool doFakeBold) { 23287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doFakeBold != isFakeBoldText()); 23387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag)); 2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 23687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDevKernText(bool doDevKern) { 23787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doDevKern != isDevKernText()); 23887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); 2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFilterBitmap(bool doFilter) { 24287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(doFilter != isFilterBitmap()); 24387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag)); 2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 24687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStyle(Style style) { 24795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)style < kStyleCount) { 24887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)style != fStyle); 24987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fStyle = style; 25087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 2531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 25405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 25787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setColor(SkColor color) { 25887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(color != fColor); 25987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fColor = color; 2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAlpha(U8CPU a) { 26387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), 26487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger SkColorGetG(fColor), SkColorGetB(fColor))); 2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 26787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 26887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger this->setColor(SkColorSetARGB(a, r, g, b)); 2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 27187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeWidth(SkScalar width) { 27295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if (width >= 0) { 27387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(width != fWidth); 27487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fWidth = width; 27587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); 2781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 27905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 28287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeMiter(SkScalar limit) { 28395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if (limit >= 0) { 28487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(limit != fMiterLimit); 28587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fMiterLimit = limit; 28687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 2891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 29005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 29387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeCap(Cap ct) { 29495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)ct < kCapCount) { 29587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)ct != fCapType); 29687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fCapType = SkToU8(ct); 29787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 2981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 2991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 3001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 30195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 30487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeJoin(Join jt) { 30595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)jt < kJoinCount) { 30687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)jt != fJoinType); 30787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fJoinType = SkToU8(jt); 30887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 3111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 31295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 31587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 31787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextAlign(Align align) { 31895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)align < kAlignCount) { 31987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)align != fTextAlign); 32087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextAlign = SkToU8(align); 32187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 3241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 32595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 32887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSize(SkScalar ts) { 3291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (ts >= 0) { 33087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(ts != fTextSize); 33187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextSize = ts; 33287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextSize() called with negative value\n"); 3351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 33695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 33987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextScaleX(SkScalar scaleX) { 34087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(scaleX != fTextScaleX); 34187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextScaleX = scaleX; 3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSkewX(SkScalar skewX) { 34587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(skewX != fTextSkewX); 34687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextSkewX = skewX; 3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 34987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextEncoding(TextEncoding encoding) { 35095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase if ((unsigned)encoding <= kGlyphID_TextEncoding) { 35187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); 35287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger fTextEncoding = encoding; 35387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger } else { 3541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK 3551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 3561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 35795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase } 3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 36087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 36287b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkTypeface* SkPaint::setTypeface(SkTypeface* font) { 3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fTypeface, font); 36487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return font; 3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 36840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { 3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fRasterizer, r); 37087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return r; 3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 37440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { 3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fLooper, looper); 37687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return looper; 3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3801cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { 3811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkRefCnt_SafeAssign(fImageFilter, imageFilter); 3821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger GEN_ID_INC; 3831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return imageFilter; 3841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 3851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h" 3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h" 3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 39140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void DetachDescProc(const SkDescriptor* desc, void* context) { 392fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc); 393fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy} 394fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy 3951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID 396b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guyconst SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) { 397b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy SkGlyphCache* cache; 398b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 399b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 400b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy const SkGlyph& glyph = cache->getUnicharMetrics(text); 401b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 402b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy SkGlyphCache::AttachCache(cache); 403b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy return glyph; 404b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy} 405b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy 4061bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guyconst SkGlyph& SkPaint::getGlyphMetrics(uint16_t glyphId) { 4071bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy SkGlyphCache* cache; 4081bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 4091bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 4101bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphId); 4111bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 4121bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy SkGlyphCache::AttachCache(cache); 4131bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy return glyph; 4141bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy} 4151bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy 41690a1efbdde19ee56c33929592277871509c25893Romain Guyconst void* SkPaint::findImage(const SkGlyph& glyph) { 417fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy // See ::detachCache() 418fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy SkGlyphCache* cache; 419fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy descriptorProc(NULL, DetachDescProc, &cache, true); 42090a1efbdde19ee56c33929592277871509c25893Romain Guy 421fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy const void* image = cache->findImage(glyph); 422fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy 423fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy SkGlyphCache::AttachCache(cache); 424fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy return image; 42590a1efbdde19ee56c33929592277871509c25893Romain Guy} 42687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif 42790a1efbdde19ee56c33929592277871509c25893Romain Guy 4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength, 4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t glyphs[]) const { 4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (byteLength == 0) { 4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 43340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(textData != NULL); 4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (NULL == glyphs) { 4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getTextEncoding()) { 4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kUTF8_TextEncoding: 4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkUTF8_CountUnichars((const char*)textData, byteLength); 4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kUTF16_TextEncoding: 4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return SkUTF16_CountUnichars((const uint16_t*)textData, 4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project byteLength >> 1); 4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case kGlyphID_TextEncoding: 4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return byteLength >> 1; 4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 4461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 45040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // if we get here, we have a valid glyphs[] array, so time to fill it in 45240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // handle this encoding before the setup for the glyphcache 4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (this->getTextEncoding() == kGlyphID_TextEncoding) { 4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we want to ignore the low bit of byteLength 4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project memcpy(glyphs, textData, byteLength >> 1 << 1); 4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return byteLength >> 1; 4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 45940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = text + byteLength; 4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint16_t* gptr = glyphs; 4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getTextEncoding()) { 4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkPaint::kUTF8_TextEncoding: 4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text)); 4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project case SkPaint::kUTF16_TextEncoding: { 4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* text16 = (const uint16_t*)text; 4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* stop16 = (const uint16_t*)stop; 4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text16 < stop16) { 4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); 4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project default: 4821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gptr - glyphs; 4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 48775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reedbool SkPaint::containsText(const void* textData, size_t byteLength) const { 48875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == byteLength) { 48975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 49075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 49140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 49275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkASSERT(textData != NULL); 49340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 49475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed // handle this encoding before the setup for the glyphcache 49575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (this->getTextEncoding() == kGlyphID_TextEncoding) { 49675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* glyphID = static_cast<const uint16_t*>(textData); 49775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed size_t count = byteLength >> 1; 49875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed for (size_t i = 0; i < count; i++) { 49975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == glyphID[i]) { 50075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 50175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 50275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 50375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 50475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 50540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 50675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkAutoGlyphCache autoCache(*this, NULL); 50775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed SkGlyphCache* cache = autoCache.getCache(); 50875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed 50975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed switch (this->getTextEncoding()) { 51075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed case SkPaint::kUTF8_TextEncoding: { 51175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const char* text = static_cast<const char*>(textData); 51275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const char* stop = text + byteLength; 51375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed while (text < stop) { 51475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) { 51575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 51675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 51775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 51875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed break; 51975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 52075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed case SkPaint::kUTF16_TextEncoding: { 52175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* text = static_cast<const uint16_t*>(textData); 52275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed const uint16_t* stop = text + (byteLength >> 1); 52375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed while (text < stop) { 52475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) { 52575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 52675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 52775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 52875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed break; 52975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 53075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed default: 5311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown text encoding"); 53275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return false; 53375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed } 53475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed return true; 53575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed} 53675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed 537091f227385b467090b5a7169a8e2faf19eca7105Mike Reedvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, 538091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkUnichar textData[]) const { 539091f227385b467090b5a7169a8e2faf19eca7105Mike Reed if (count <= 0) { 540091f227385b467090b5a7169a8e2faf19eca7105Mike Reed return; 541091f227385b467090b5a7169a8e2faf19eca7105Mike Reed } 542091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 543091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkASSERT(glyphs != NULL); 544091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkASSERT(textData != NULL); 545091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 546091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkAutoGlyphCache autoCache(*this, NULL); 547091f227385b467090b5a7169a8e2faf19eca7105Mike Reed SkGlyphCache* cache = autoCache.getCache(); 548091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 549091f227385b467090b5a7169a8e2faf19eca7105Mike Reed for (int index = 0; index < count; index++) { 550091f227385b467090b5a7169a8e2faf19eca7105Mike Reed textData[index] = cache->glyphToUnichar(glyphs[index]); 551091f227385b467090b5a7169a8e2faf19eca7105Mike Reed } 552091f227385b467090b5a7169a8e2faf19eca7105Mike Reed} 553091f227385b467090b5a7169a8e2faf19eca7105Mike Reed 5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 55640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, 55740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 56040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 56440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, 56540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 56840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text)); 5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 57240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, 57340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 57640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 58040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, 58140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 58440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text)); 5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 58840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, 58940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 59240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 60040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, 60140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 60440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr -= 1; 6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 61240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, 61340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 61640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF8_NextUnichar(text)); 6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 62040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, 62140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 62440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text)); 6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 62840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, 62940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 63240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text)); 6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 63640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, 63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 64040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text)); 6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 64440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, 64540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 64840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDAdvance(glyphID); 6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 65640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, 65740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text) { 6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 66040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr -= 1; 6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDAdvance(glyphID); 6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd, 66940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool needFullMetrics) const { 6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static const SkMeasureCacheProc gMeasureCacheProcs[] = { 6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_next, 6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_next, 6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_next, 67440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_prev, 6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_prev, 6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_prev, 67840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf8_next, 6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf16_next, 6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_glyph_next, 68240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf8_prev, 6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_utf16_prev, 6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getAdvance_glyph_prev 6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 68740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned index = this->getTextEncoding(); 6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 69040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (kBackward_TextBufferDirection == tbd) { 6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 3; 69240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 69340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!needFullMetrics && !this->isDevKernText()) { 6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 6; 69540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs)); 6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gMeasureCacheProcs[index]; 6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache, 70440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 70740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache, 71240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 71540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y); 7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 71940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, 72040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 72340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache, 72840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 73140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text), 7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x, y); 7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 73640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, 73740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed, SkFixed) { 7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 74040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID); 7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache, 74940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, SkFixed x, SkFixed y) { 7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(cache != NULL); 7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL); 75240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const uint16_t* ptr = *(const uint16_t**)text; 7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned glyphID = *ptr; 7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ptr += 1; 7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text = (const char*)ptr; 7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache->getGlyphIDMetrics(glyphID, x, y); 7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 76040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawCacheProc SkPaint::getDrawCacheProc() const { 7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project static const SkDrawCacheProc gDrawCacheProcs[] = { 7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_00, 7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_00, 7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_00, 76540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf8_xy, 7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_utf16_xy, 7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project sk_getMetrics_glyph_xy 7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project }; 77040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project unsigned index = this->getTextEncoding(); 77240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fFlags & kSubpixelText_Flag) { 7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project index += 3; 77440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 77540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs)); 7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return gDrawCacheProcs[index]; 7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame { 7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic: 78440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint) 78540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger : fPaint((SkPaint*)paint) { 7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fTextSize = paint->getTextSize(); 7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStyle = paint->getStyle(); 7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setStyle(SkPaint::kFill_Style); 7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 79040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 79140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger ~SkAutoRestorePaintTextSizeAndFrame() { 7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setStyle(fStyle); 7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint->setTextSize(fTextSize); 7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 79540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate: 7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint* fPaint; 7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar fTextSize; 7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style fStyle; 8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}; 8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 80240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds) { 8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->set(SkIntToScalar(g.fLeft), 8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop), 8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fLeft + g.fWidth), 8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop + g.fHeight)); 8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 809e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so 810e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// we don't overflow along the way 811e63c5c9f6752244ca0f39075fa148a0281593831Mike Reedtypedef int64_t Sk48Dot16; 812e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed 813e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#ifdef SK_SCALAR_IS_FLOAT 814e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed static inline float Sk48Dot16ToScalar(Sk48Dot16 x) { 81540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return (float) (x * 1.5258789e-5); // x * (1 / 65536.0f) 816e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed } 817e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#else 818e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed static inline SkFixed Sk48Dot16ToScalar(Sk48Dot16 x) { 819e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // just return the low 32bits 820e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed return static_cast<SkFixed>(x); 821e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed } 822e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#endif 823e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed 8241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { 825e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed SkScalar sx = Sk48Dot16ToScalar(dx); 8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->join(SkIntToScalar(g.fLeft) + sx, 8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop), 8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fLeft + g.fWidth) + sx, 8290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkIntToScalar(g.fTop + g.fHeight)); 8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) { 8331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar sy = Sk48Dot16ToScalar(dy); 8341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bounds->join(SkIntToScalar(g.fLeft), 8351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fTop) + sy, 8361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fLeft + g.fWidth), 8371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIntToScalar(g.fTop + g.fHeight) + sy); 8381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16); 8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY 8431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkFixed advance(const SkGlyph& glyph, int xyIndex) { 8441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(0 == xyIndex || 1 == xyIndex); 8451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return (&glyph.fAdvanceX)[xyIndex]; 8461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 8471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache, 8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text, size_t byteLength, 85040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int* count, SkRect* bounds) const { 8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(count); 85240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (byteLength == 0) { 8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = 0; 85440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (bounds) { 8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->setEmpty(); 85640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc; 8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project NULL != bounds); 8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int xyIndex; 8651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger JoinBoundsProc joinBoundsProc; 8661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (this->isVerticalText()) { 8671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger xyIndex = 1; 8681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc = join_bounds_y; 8691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } else { 8701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger xyIndex = 0; 8711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc = join_bounds_x; 8721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 8731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int n = 1; 8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = (const char*)text + byteLength; 8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph* g = &glyphCacheProc(cache, &text); 877e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // our accumulated fixed-point advances might overflow 16.16, so we use 878e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // a 48.16 (64bit) accumulator, and then convert that to scalar at the 879e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // very end. 8801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger Sk48Dot16 x = advance(*g, xyIndex); 8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 88440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == bounds) { 88540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb; 8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g->fRsbDelta; 8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex); 8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 89240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 8941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(glyphCacheProc(cache, &text), xyIndex); 8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 89740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(*g, bounds); 89940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb; 9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g->fRsbDelta; 9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x += SkAutoKern_AdjustF(rsb, g->fLsbDelta); 9051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc(*g, bounds, x); 9061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(*g, xyIndex); 9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 90840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (; text < stop; n++) { 9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g = &glyphCacheProc(cache, &text); 9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger joinBoundsProc(*g, bounds, x); 9121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger x += advance(*g, xyIndex); 9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text == stop); 9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *count = n; 919e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed return Sk48Dot16ToScalar(x); 9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length, 92340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkRect* bounds, SkScalar zoom) const { 9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text != NULL || length == 0); 9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 93040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 93540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 93640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix zoomMatrix, *zoomPtr = NULL; 93740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (zoom) { 9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomMatrix.setScale(zoom, zoom); 9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomPtr = &zoomMatrix; 9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, zoomPtr); 9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar width = 0; 94640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 94740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (length > 0) { 9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int tempCount; 9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = this->measure_text(cache, text, length, &tempCount, bounds); 95140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = SkScalarMul(width, scale); 95340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (bounds) { 9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fLeft = SkScalarMul(bounds->fLeft, scale); 9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fTop = SkScalarMul(bounds->fTop, scale); 9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fRight = SkScalarMul(bounds->fRight, scale); 9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->fBottom = SkScalarMul(bounds->fBottom, scale); 9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return width; 9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop); 9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 96640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool forward_textBufferPred(const char* text, const char* stop) { 9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return text < stop; 9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 97040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool backward_textBufferPred(const char* text, const char* stop) { 9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return text > stop; 9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd, 97540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** text, size_t length, 97640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** stop) { 97740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (SkPaint::kForward_TextBufferDirection == tbd) { 9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *stop = *text + length; 9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return forward_textBufferPred; 98040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // text should point to the end of the buffer, and stop to the beginning 9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *stop = *text; 9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *text += length; 9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return backward_textBufferPred; 9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth, 9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar* measuredWidth, 99040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger TextBufferDirection tbd) const { 99140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == length || 0 >= maxWidth) { 99240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (measuredWidth) { 9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *measuredWidth = 0; 99440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 9981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (0 == fTextSize) { 9991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (measuredWidth) { 10001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *measuredWidth = 0; 10011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return length; 10031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 10041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(textD != NULL); 10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textD; 10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 101140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 10139b1cba8ccd7554cb30905711a426bd86ad8dd38cJean-Baptiste Queru maxWidth = SkScalarMulDiv(maxWidth, kCanonicalTextSizeForPaths, fTextSize); 10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 101740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false); 10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop; 10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop); 10241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int xyIndex = this->isVerticalText() ? 1 : 0; 1025e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed // use 64bits for our accumulator, to avoid overflowing 16.16 1026e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed Sk48Dot16 max = SkScalarToFixed(maxWidth); 1027e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed Sk48Dot16 width = 0; 10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 103140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int rsb = 0; 103340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (pred(text, stop)) { 10340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* curr = text; 10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 10361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex); 103740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if ((width += x) > max) { 10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width -= x; 10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text = curr; 10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rsb = g.fRsbDelta; 10430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 104440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 104540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (pred(text, stop)) { 10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* curr = text; 10471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex); 104840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if ((width += x) > max) { 10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width -= x; 10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text = curr; 10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project break; 10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 105540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 105640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (measuredWidth) { 1057e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed SkScalar scalarWidth = Sk48Dot16ToScalar(width); 105840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scalarWidth = SkScalarMul(scalarWidth, scale); 106040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *measuredWidth = scalarWidth; 10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 106340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // return the number of bytes measured 10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (kForward_TextBufferDirection == tbd) ? 10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project text - stop + length : stop - text + length; 10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 107140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) { 10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *(SkPaint::FontMetrics*)context = cache->getFontMetricsY(); 10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return false; // don't detach the cache 10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 107640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context) { 10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context); 10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 108040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const { 10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 108440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 108940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 109040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMatrix zoomMatrix, *zoomPtr = NULL; 109140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (zoom) { 10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomMatrix.setScale(zoom, zoom); 10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project zoomPtr = &zoomMatrix; 10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, zoomPtr); 10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const FontMetrics& my = cache->getFontMetricsY(); 11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project FontMetrics storage; 110240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == metrics) { 11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics = &storage; 110440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 110540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 11061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics, true); 11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 110840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (scale) { 11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fTop = SkScalarMul(metrics->fTop, scale); 11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return metrics->fDescent - metrics->fAscent + metrics->fLeading; 11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 111840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 112040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) { 11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bounds->set(g.fLeft * scale, 11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project g.fTop * scale, 11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (g.fLeft + g.fWidth) * scale, 11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project (g.fTop + g.fHeight) * scale); 11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 112740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerint SkPaint::getTextWidths(const void* textData, size_t byteLength, 112840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar widths[], SkRect bounds[]) const { 112940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == byteLength) { 11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return 0; 113140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(NULL != textData); 11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 113540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == widths && NULL == bounds) { 11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return this->countText(textData, byteLength); 113740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoRestorePaintTextSizeAndFrame restore(this); 11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar scale = 0; 11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 114240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isLinearText()) { 11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale = fTextSize / kCanonicalTextSizeForPaths; 11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // this gets restored by restore 11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths)); 11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoGlyphCache autoCache(*this, NULL); 11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache = autoCache.getCache(); 11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMeasureCacheProc glyphCacheProc; 11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project NULL != bounds); 11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* stop = text + byteLength; 11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count = 0; 11571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const int xyIndex = this->isVerticalText() ? 1 : 0; 11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 115940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->isDevKernText()) { 11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // we adjust the widths returned here through auto-kerning 11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoKern autokern; 11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed prevWidth = 0; 11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (scale) { 11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed adjust = autokern.adjust(g); 11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0) { 11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar w = SkFixedToScalar(prevWidth + adjust); 11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths++ = SkScalarMul(w, scale); 11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prevWidth = advance(g, xyIndex); 11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++, scale); 11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0 && widths) { 11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale); 11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed adjust = autokern.adjust(g); 11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0) { 11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths++ = SkFixedToScalar(prevWidth + adjust); 11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger prevWidth = advance(g, xyIndex); 11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++); 11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count > 0 && widths) { 12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *widths = SkFixedToScalar(prevWidth); 12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { // no devkern 12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (scale) { 12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)), 12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project scale); 12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++, scale); 12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } else { 12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while (text < stop) { 12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& g = glyphCacheProc(cache, &text); 12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (widths) { 12211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *widths++ = SkFixedToScalar(advance(g, xyIndex)); 12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (bounds) { 12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project set_bounds(g, bounds++); 12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project ++count; 12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(text == stop); 12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return count; 12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 123540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h" 12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 123940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::getTextPath(const void* textData, size_t length, 124040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar x, SkScalar y, SkPath* path) const { 124140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(length == 0 || textData != NULL); 124240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const char* text = (const char*)textData; 124440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (text == NULL || length == 0 || path == NULL) { 12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return; 124640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkTextToPathIter iter(text, length, *this, false, true); 12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMatrix matrix; 12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar prevXPos = 0; 12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.setScale(iter.getPathScale(), iter.getPathScale()); 12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.postTranslate(x, y); 12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path->reset(); 12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar xpos; 12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPath* iterPath; 125840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while ((iterPath = iter.next(&xpos)) != NULL) { 12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project matrix.postTranslate(xpos - prevXPos, 0); 12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path->addPath(*iterPath, matrix); 12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project prevXPos = xpos; 12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag, 12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer* buffer) { 12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project buffer->flatten(desc->addEntry(tag, buffer->size(), NULL)); 12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// SkFontHost can override this choice in FilterRec() 127140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkMask::Format computeMaskFormat(const SkPaint& paint) { 12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project uint32_t flags = paint.getFlags(); 12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1274c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed // Antialiasing being disabled trumps all other settings. 1275137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger if (!(flags & SkPaint::kAntiAlias_Flag)) { 1276c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed return SkMask::kBW_Format; 127705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger } 127805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger 1279137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger if (flags & SkPaint::kLCDRenderText_Flag) { 1280137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger return SkMask::kLCD16_Format; 1281137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger } 1282c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed 1283c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed return SkMask::kA8_Format; 12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 12864bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// if linear-text is on, then we force hinting to be off (since that's sort of 12874bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// the point of linear-text. 12884bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reedstatic SkPaint::Hinting computeHinting(const SkPaint& paint) { 12894bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed SkPaint::Hinting h = paint.getHinting(); 12904bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed if (paint.isLinearText()) { 12914bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed h = SkPaint::kNo_Hinting; 12924bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed } 12934bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed return h; 12944bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed} 12954bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed 12961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// return true if the paint is just a single color (i.e. not a shader). If its 12971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// a shader, then we can't compute a const luminance for it :( 12981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool justAColor(const SkPaint& paint, SkColor* color) { 12991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getShader()) { 13001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 13011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor c = paint.getColor(); 13031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.getColorFilter()) { 13041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger c = paint.getColorFilter()->filterColor(c); 13051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (color) { 13071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *color = c; 13081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 13101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 13134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic SkColor computeLuminanceColor(const SkPaint& paint) { 13144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColor c; 13154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (!justAColor(paint, &c)) { 13164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger c = SkColorSetRGB(0x7F, 0x80, 0x7F); 13174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 13184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return c; 13194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#define assert_byte(x) SkASSERT(0 == ((x) >> 8)) 13224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic U8CPU reduce_lumbits(U8CPU x) { 13244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger static const uint8_t gReduceBits[] = { 13254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 0x0, 0x55, 0xAA, 0xFF 13264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger }; 13274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger assert_byte(x); 13284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return gReduceBits[x >> 6]; 13294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic unsigned computeLuminance(SkColor c) { 13324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int r = SkColorGetR(c); 13334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int g = SkColorGetG(c); 13344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int b = SkColorGetB(c); 13354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // compute luminance 13364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // R=0.2126 G=0.7152 B=0.0722 13374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // scaling by 127 yields 27, 92, 9 13384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger int luminance = r * 27 + g * 92 + b * 9; 13394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger luminance >>= 7; 13404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger assert_byte(luminance); 13414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return luminance; 13424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 13434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 13444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 13451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// returns 0..kLuminance_Max 13461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic unsigned computeLuminance(const SkPaint& paint) { 13471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkColor c; 13481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (justAColor(paint, &c)) { 13491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int r = SkColorGetR(c); 13501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int g = SkColorGetG(c); 13511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int b = SkColorGetB(c); 13521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // compute luminance 13531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // R=0.2126 G=0.7152 B=0.0722 13541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // scaling by 127 yields 27, 92, 9 13551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 1 13561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int luminance = r * 27 + g * 92 + b * 9; 13571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger luminance >>= 15 - SkScalerContext::kLuminance_Bits; 13581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else 13591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger int luminance = r * 2 + g * 5 + b * 1; 13601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger luminance >>= 11 - SkScalerContext::kLuminance_Bits; 13611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 13621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(luminance <= SkScalerContext::kLuminance_Max); 13631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return luminance; 13641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 13651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // if we're not a single color, return the middle of the luminance range 13661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkScalerContext::kLuminance_Max >> 1; 13671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 13691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Beyond this size, LCD doesn't appreciably improve quality, but it always 13711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// cost more RAM and draws slower, so we set a cap. 13721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifndef SK_MAX_SIZE_FOR_LCDTEXT 13731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger #define SK_MAX_SIZE_FOR_LCDTEXT 48 13741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif 13751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 13761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool tooBigForLCD(const SkScalerContext::Rec& rec) { 13771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar area = SkScalarMul(rec.fPost2x2[0][0], rec.fPost2x2[1][1]) - 13781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalarMul(rec.fPost2x2[1][0], rec.fPost2x2[0][1]); 13791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkScalar size = SkScalarMul(area, rec.fTextSize); 13801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return SkScalarAbs(size) > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT); 13811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 13821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 138340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/* 138440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * Return the scalar with only limited fractional precision. Used to consolidate matrices 138540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * that vary only slightly when we create our key into the font cache, since the font scaler 138640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger * typically returns the same looking resuts for tiny changes in the matrix. 138740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 138840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkScalar sk_relax(SkScalar x) { 138940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#ifdef SK_SCALAR_IS_FLOAT 139040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int n = sk_float_round2int(x * 1024); 139140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return n / 1024.0f; 139240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#else 139340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // round to the nearest 10 fractional bits 139440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return (x + (1 << 5)) & ~(1024 - 1); 139540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 139640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 139740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 1398af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkScalerContext::MakeRec(const SkPaint& paint, 139940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkMatrix* deviceMatrix, Rec* rec) { 14000199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); 14010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14020199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger rec->fOrigFontID = SkTypeface::UniqueID(paint.getTypeface()); 14030199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger rec->fFontID = rec->fOrigFontID; 14040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fTextSize = paint.getTextSize(); 14050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPreScaleX = paint.getTextScaleX(); 14060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPreSkewX = paint.getTextSkewX(); 14070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 140840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (deviceMatrix) { 140940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX()); 141040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX()); 141140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY()); 141240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY()); 141340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 14140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 14150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0; 14160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 141740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style style = paint.getStyle(); 14190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar strokeWidth = paint.getStrokeWidth(); 142040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger unsigned flags = 0; 14221c980e0d7772f05f570ae0227d91635f017c2227Mike Reed 142340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isFakeBoldText()) { 14241c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#ifdef SK_USE_FREETYPE_EMBOLDEN 14251c980e0d7772f05f570ae0227d91635f017c2227Mike Reed flags |= SkScalerContext::kEmbolden_Flag; 14261c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#else 142740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(), 142840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpKeys, 142940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpValues, 143040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger kStdFakeBoldInterpLength); 14310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale); 143240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 143340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style == SkPaint::kFill_Style) { 14340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project style = SkPaint::kStrokeAndFill_Style; 14350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project strokeWidth = extra; // ignore paint's strokeWidth if it was "fill" 143640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 14370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project strokeWidth += extra; 143840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 14391c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#endif 14400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 14410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 144240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isDevKernText()) { 14430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkScalerContext::kDevKernText_Flag; 144440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 144540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 144640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style != SkPaint::kFill_Style && strokeWidth > 0) { 14470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fFrameWidth = strokeWidth; 14480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMiterLimit = paint.getStrokeMiter(); 14490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fStrokeJoin = SkToU8(paint.getStrokeJoin()); 14500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 145140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (style == SkPaint::kStrokeAndFill_Style) { 14520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project flags |= SkScalerContext::kFrameAndFill_Flag; 145340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 145440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 14550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fFrameWidth = 0; 14560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMiterLimit = 0; 14570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fStrokeJoin = 0; 14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 14590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 14600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); 14610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 14621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkMask::kLCD16_Format == rec->fMaskFormat || 14631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkMask::kLCD32_Format == rec->fMaskFormat) 14641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger { 14650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFontHost::LCDOrder order = SkFontHost::GetSubpixelOrder(); 14660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger SkFontHost::LCDOrientation orient = SkFontHost::GetSubpixelOrientation(); 14671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkFontHost::kNONE_LCDOrder == order || tooBigForLCD(*rec)) { 14680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger // eeek, can't support LCD 14690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->fMaskFormat = SkMask::kA8_Format; 14700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } else { 14710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SkFontHost::kVertical_LCDOrientation == orient) { 14720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kLCD_Vertical_Flag; 14730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14740b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger if (SkFontHost::kBGR_LCDOrder == order) { 14750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kLCD_BGROrder_Flag; 14760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger } 14790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 148040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isEmbeddedBitmapText()) { 14810b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kEmbeddedBitmapText_Flag; 148240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 148340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isSubpixelText()) { 14840b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kSubpixelPositioning_Flag; 148540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 148640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.isAutohinted()) { 14870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger flags |= SkScalerContext::kAutohinting_Flag; 148840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 14891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (paint.isVerticalText()) { 14901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flags |= SkScalerContext::kVertical_Flag; 14911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 14924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { 14934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger flags |= SkScalerContext::kGenA8FromLCD_Flag; 14944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 14950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->fFlags = SkToU16(flags); 14960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger 14971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // these modify fFlags, so do them after assigning fFlags 14980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger rec->setHinting(computeHinting(paint)); 14994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(computeLuminanceColor(paint)); 15014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 15021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rec->setLuminanceBits(computeLuminance(paint)); 15034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 1504af2616552738d653d5453915d3236e7154b868cdMike Reed 1505af2616552738d653d5453915d3236e7154b868cdMike Reed /* Allow the fonthost to modify our rec before we use it as a key into the 1506af2616552738d653d5453915d3236e7154b868cdMike Reed cache. This way if we're asking for something that they will ignore, 1507af2616552738d653d5453915d3236e7154b868cdMike Reed they can modify our rec up front, so we don't create duplicate cache 1508af2616552738d653d5453915d3236e7154b868cdMike Reed entries. 1509af2616552738d653d5453915d3236e7154b868cdMike Reed */ 1510af2616552738d653d5453915d3236e7154b868cdMike Reed SkFontHost::FilterRec(rec); 15111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 15124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // be sure to call PostMakeRec(rec) before you actually use it! 15134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 15144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/** 15164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * We ensure that the rec is self-consistent and efficient (where possible) 15174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 15184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkScalerContext::PostMakeRec(SkScalerContext::Rec* rec) { 15194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 15204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger /** 15214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * If we're asking for A8, we force the colorlum to be gray, since that 15224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * that limits the number of unique entries, and the scaler will only 15234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * look at the lum of one of them. 15244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 15254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger switch (rec->fMaskFormat) { 15264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kLCD16_Format: 15274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kLCD32_Format: { 15284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // filter down the luminance color to a finite number of bits 15304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkColor c = rec->getLuminanceColor(); 15314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger c = SkColorSetRGB(reduce_lumbits(SkColorGetR(c)), 15324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger reduce_lumbits(SkColorGetG(c)), 15334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger reduce_lumbits(SkColorGetB(c))); 15344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(c); 15354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 15364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 15374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kA8_Format: { 15394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // filter down the luminance to a single component, since A8 can't 15414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // use per-component information 15424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger unsigned lum = computeLuminance(rec->getLuminanceColor()); 15434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // reduce to our finite number of bits 15444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger lum = reduce_lumbits(lum); 15454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(SkColorSetRGB(lum, lum, lum)); 15464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 15474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 15484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 15494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger case SkMask::kBW_Format: 15504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // No need to differentiate gamma if we're BW 15514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceColor(0); 15534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 15544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec->setLuminanceBits(0); 15554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 15564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger break; 15571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 15580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 15590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER 1024 15610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 156235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef SK_DEBUG 156335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger #define TEST_DESC 156435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif 156535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 15671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * ignoreGamma tells us that the caller just wants metrics that are unaffected 15681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * by gamma correction, so we jam the luminance field to 0 (most common value 15691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * for black text) in hopes that we get a cache hit easier. A better solution 15701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * would be for the fontcache lookup to know to ignore the luminance field 15711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * entirely, but not sure how to do that and keep it fast. 15721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 15730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix, 15740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project void (*proc)(const SkDescriptor*, void*), 157540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void* context, bool ignoreGamma) const { 15760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalerContext::Rec rec; 15770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalerContext::MakeRec(*this, deviceMatrix, &rec); 1579fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy if (ignoreGamma) { 15804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE 15814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger rec.setLuminanceColor(0); 15824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else 15831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger rec.setLuminanceBits(0); 15844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif 1585fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy } 15860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project size_t descSize = sizeof(rec); 15880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int entryCount = 1; 15890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPathEffect* pe = this->getPathEffect(); 15900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkMaskFilter* mf = this->getMaskFilter(); 15910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRasterizer* ra = this->getRasterizer(); 15920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 15940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 15950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFlattenableWriteBuffer raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER); 15960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 15970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (pe) { 15980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project peBuffer.writeFlattenable(pe); 15990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += peBuffer.size(); 16000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // seems like we could support kLCD as well at this point... 16030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (mf) { 16050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project mfBuffer.writeFlattenable(mf); 16060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += mfBuffer.size(); 16070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters 16090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ra) { 16110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project raBuffer.writeFlattenable(ra); 16120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += raBuffer.size(); 16130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project entryCount += 1; 16140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger /////////////////////////////////////////////////////////////////////////// 16184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // Now that we're done tweaking the rec, call the PostMakeRec cleanup 16194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkScalerContext::PostMakeRec(&rec); 16204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 16210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project descSize += SkDescriptor::ComputeOverhead(entryCount); 16220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkAutoDescriptor ad(descSize); 16240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkDescriptor* desc = ad.getDesc(); 16250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->init(); 16270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 16280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (pe) { 16300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer); 16310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (mf) { 16330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer); 16340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (ra) { 16360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer); 16370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 16380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(descSize == desc->getLength()); 16400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project desc->computeChecksum(); 16410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 164235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef TEST_DESC 164335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger { 164435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // Check that we completely write the bytes in desc (our key), and that 164535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // there are no uninitialized bytes. If there were, then we would get 164635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // false-misses (or worse, false-hits) in our fontcache. 164735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // 164835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // We do this buy filling 2 others, one with 0s and the other with 1s 164935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger // and create those, and then check that all 3 are identical. 165035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkAutoDescriptor ad1(descSize); 165135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkAutoDescriptor ad2(descSize); 165235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDescriptor* desc1 = ad1.getDesc(); 165335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkDescriptor* desc2 = ad2.getDesc(); 165435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 165535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger memset(desc1, 0x00, descSize); 165635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger memset(desc2, 0xFF, descSize); 165735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 165835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->init(); 165935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->init(); 166035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 166135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 166235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 166335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (pe) { 166435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer); 166535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer); 166635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 166735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (mf) { 166835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer); 166935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer); 167035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 167135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger if (ra) { 167235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer); 167335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer); 167435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 167535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 167635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(descSize == desc1->getLength()); 167735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(descSize == desc2->getLength()); 167835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc1->computeChecksum(); 167935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger desc2->computeChecksum(); 168035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(!memcmp(desc, desc1, descSize)); 168135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger SkASSERT(!memcmp(desc, desc2, descSize)); 168235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger } 168335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif 168435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 16850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project proc(desc, context); 16860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 16870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 168840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const { 16890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache* cache; 16900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project this->descriptorProc(deviceMatrix, DetachDescProc, &cache); 16910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return cache; 16920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 16930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 16950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h" 16970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 16985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uintptr_t asint(const void* p) { 16995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return reinterpret_cast<uintptr_t>(p); 17005f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedunion Scalar32 { 17035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkScalar fScalar; 17045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t f32; 17055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}; 17065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) { 17085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 17095f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed Scalar32 tmp; 17105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp.fScalar = value; 17115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr = tmp.f32; 17125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return ptr + 1; 17135f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic SkScalar read_scalar(const uint32_t*& ptr) { 17165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 17175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed Scalar32 tmp; 17185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp.f32 = *ptr++; 17195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return tmp.fScalar; 17205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { 17235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(a == (uint8_t)a); 17245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(b == (uint8_t)b); 17255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(c == (uint8_t)c); 17265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(d == (uint8_t)d); 17275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed return (a << 24) | (b << 16) | (c << 8) | d; 17285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed} 17295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedenum FlatFlags { 17315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed kHasTypeface_FlatFlag = 0x01, 17325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed kHasEffects_FlatFlag = 0x02 17335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}; 17345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed// The size of a flat paint's POD fields 17365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + 17375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1 * sizeof(SkColor) + 17385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 1 * sizeof(uint16_t) + 17395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 6 * sizeof(uint8_t); 17405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed/* To save space/time, we analyze the paint, and write a truncated version of 17425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed it if there are not tricky elements like shaders, etc. 17435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed */ 17440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const { 17455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint8_t flatFlags = 0; 17465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (this->getTypeface()) { 17475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed flatFlags |= kHasTypeface_FlatFlag; 17485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 17495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (asint(this->getPathEffect()) | 17505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getShader()) | 17515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getXfermode()) | 17525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getMaskFilter()) | 17535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getColorFilter()) | 17545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed asint(this->getRasterizer()) | 17551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger asint(this->getLooper()) | 17561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger asint(this->getImageFilter())) { 17575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed flatFlags |= kHasEffects_FlatFlag; 17585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 175940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 17605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 17615f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t* ptr = buffer.reserve(kPODPaintSize); 17625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextSize()); 17645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextScaleX()); 17655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getTextSkewX()); 17665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getStrokeWidth()); 17675f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed ptr = write_scalar(ptr, this->getStrokeMiter()); 17685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr++ = this->getColor(); 17691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // previously flags:16, textAlign:8, flatFlags:8 17701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // now flags:16, hinting:4, textAlign:4, flatFlags:8 17711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *ptr++ = (this->getFlags() << 16) | 17721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // hinting added later. 0 in this nibble means use the default. 17731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger ((this->getHinting()+1) << 12) | 17741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger (this->getTextAlign() << 8) | 17751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger flatFlags; 17765f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(), 17775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->getStyle(), this->getTextEncoding()); 17785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 17795f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // now we're done with ptr and the (pre)reserved space. If we need to write 17805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // additional fields, use the buffer directly 17815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasTypeface_FlatFlag) { 17825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeTypeface(this->getTypeface()); 17835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 17845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasEffects_FlatFlag) { 17855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getPathEffect()); 17865f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getShader()); 17875f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getXfermode()); 17885f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getMaskFilter()); 17895f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getColorFilter()); 17905f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getRasterizer()); 17915f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed buffer.writeFlattenable(this->getLooper()); 17921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger buffer.writeFlattenable(this->getImageFilter()); 17935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 17940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 17950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 17960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) { 17975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 17985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed const void* podData = buffer.skip(kPODPaintSize); 17995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); 180040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 18015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed // the order we read must match the order we wrote in flatten() 18025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextSize(read_scalar(pod)); 18035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextScaleX(read_scalar(pod)); 18045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextSkewX(read_scalar(pod)); 18055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeWidth(read_scalar(pod)); 180640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger this->setStrokeMiter(read_scalar(pod)); 18075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setColor(*pod++); 18085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // previously flags:16, textAlign:8, flatFlags:8 18101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // now flags:16, hinting:4, textAlign:4, flatFlags:8 18115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint32_t tmp = *pod++; 18125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setFlags(tmp >> 16); 18131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) { 18154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF)); 18164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setHinting(SkPaintDefaults_Hinting); 18174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 18184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger // hinting added later. 0 in this nibble means use the default. 18194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger uint32_t hinting = (tmp >> 12) & 0xF; 18204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setHinting(0 == hinting ? kNormal_Hinting : static_cast<Hinting>(hinting-1)); 18211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xF)); 18234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 18241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 18255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed uint8_t flatFlags = tmp & 0xFF; 18265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed tmp = *pod++; 18285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); 18295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); 18305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); 18315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); 18325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasTypeface_FlatFlag) { 18345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTypeface(buffer.readTypeface()); 18355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } else { 18365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setTypeface(NULL); 18375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed 18395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed if (flatFlags & kHasEffects_FlatFlag) { 184040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setPathEffect((SkPathEffect*) buffer.readFlattenable())); 184140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setShader((SkShader*) buffer.readFlattenable())); 184240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setXfermode((SkXfermode*) buffer.readFlattenable())); 184340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())); 184440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setColorFilter((SkColorFilter*) buffer.readFlattenable())); 184540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setRasterizer((SkRasterizer*) buffer.readFlattenable())); 184640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeUnref(this->setLooper((SkDrawLooper*) buffer.readFlattenable())); 18474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (buffer.getPictureVersion() != PICTURE_VERSION_ICS) 18484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkSafeUnref(this->setImageFilter((SkImageFilter*) buffer.readFlattenable())); 18494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger else 18504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger this->setImageFilter(NULL); 18515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } else { 18525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setPathEffect(NULL); 18535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setShader(NULL); 18545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setXfermode(NULL); 18555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setMaskFilter(NULL); 18565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setColorFilter(NULL); 18575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setRasterizer(NULL); 18585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed this->setLooper(NULL); 18591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->setImageFilter(NULL); 18605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed } 18610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 18630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 18640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 186587b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkShader* SkPaint::setShader(SkShader* shader) { 186687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(shader != fShader); 18670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fShader, shader); 18680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return shader; 18690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 187187b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { 187287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(filter != fColorFilter); 18730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fColorFilter, filter); 18740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return filter; 18750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 187787b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkXfermode* SkPaint::setXfermode(SkXfermode* mode) { 187887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(mode != fXfermode); 18790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fXfermode, mode); 18800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return mode; 18810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 188303f42ddd729377f21719a140c027a1f8cc5c2152Mike ReedSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { 188403f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed SkSafeUnref(fXfermode); 188503f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed fXfermode = SkXfermode::Create(mode); 188687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC; 188703f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed return fXfermode; 188803f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed} 188903f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed 189087b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { 189187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(effect != fPathEffect); 18920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fPathEffect, effect); 18930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return effect; 18940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 18950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 189687b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { 189787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger GEN_ID_INC_EVAL(filter != fMaskFilter); 18980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkRefCnt_SafeAssign(fMaskFilter, filter); 18990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return filter; 19000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 190240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 19030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 190440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const { 19050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPath effectPath, strokePath; 19060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPath* path = &src; 19070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar width = this->getStrokeWidth(); 190940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 19100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project switch (this->getStyle()) { 191140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kFill_Style: 19120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; // mark it as no-stroke 191340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 191440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kStrokeAndFill_Style: 191540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width == 0) { 191640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger width = -1; // mark it as no-stroke 191740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 191840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 191940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger case SkPaint::kStroke_Style: 192040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 192140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger default: 19221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("unknown paint style"); 19230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 192540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getPathEffect()) { 19260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill 192740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getStyle() == SkPaint::kStrokeAndFill_Style) { 19280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; // mark it as no-stroke 192940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 19300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 193140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getPathEffect()->filterPath(&effectPath, src, &width)) { 19320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path = &effectPath; 193340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 193440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 19350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // restore the width if we earlier had to lie, and if we're still set to no-stroke 19360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // note: if we're now stroke (width >= 0), then the pathEffect asked for that change 19370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // and we want to respect that (i.e. don't overwrite their setting for width) 193840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0) { 19390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = this->getStrokeWidth(); 194040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width == 0) { 19410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = -1; 194240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 19430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 194540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 194640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (width > 0 && !path->isEmpty()) { 19470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkStroke stroker(*this, width); 19480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project stroker.strokePath(*path, &strokePath); 19490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project path = &strokePath; 19500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 195240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (path == &src) { 19530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst = src; 195440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 19550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(path == &effectPath || path == &strokePath); 19560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project dst->swap(*(SkPath*)path); 19570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 19580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 19590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return width != 0; // return true if we're filled, or false if we're hairline (width == 0) 19600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1962717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerconst SkRect& SkPaint::doComputeFastBounds(const SkRect& src, 1963717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect* storage) const { 19640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(storage); 1965717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 1966717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getLooper()) { 1967717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkASSERT(this->getLooper()->canComputeFastBounds(*this)); 1968717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->getLooper()->computeFastBounds(*this, src, storage); 1969717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return *storage; 1970717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 1971717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 1972717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getStyle() != SkPaint::kFill_Style) { 1973717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger // since we're stroked, outset the rect by the radius (and join type) 1974717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkScalar radius = SkScalarHalf(this->getStrokeWidth()); 1975717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (0 == radius) { // hairline 1976717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger radius = SK_Scalar1; 1977717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { 1978717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkScalar scale = this->getStrokeMiter(); 1979717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (scale > SK_Scalar1) { 1980717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger radius = SkScalarMul(radius, scale); 1981717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 19820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1983717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger storage->set(src.fLeft - radius, src.fTop - radius, 1984717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger src.fRight + radius, src.fBottom + radius); 1985717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 1986717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger *storage = src; 19870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1988717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 1989717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger // check the mask filter 1990717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->getMaskFilter()) { 1991717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->getMaskFilter()->computeFastBounds(*storage, storage); 1992717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 1993717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 199435d15937afb7f4b3472e43ea784b02485ec910fbMike Reed return *storage; 19950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 19960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 199740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 19980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 199940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool has_thick_frame(const SkPaint& paint) { 200040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return paint.getStrokeWidth() > 0 && 200140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger paint.getStyle() != SkPaint::kFill_Style; 20020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length, 20050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkPaint& paint, 20060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project bool applyStrokeAndPathEffects, 200740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool forceLinearTextOn) : fPaint(paint) { 20080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection, 20090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project true); 20100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 201140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (forceLinearTextOn) { 20120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setLinearText(true); 201340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup 20150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 201640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { 20170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project applyStrokeAndPathEffects = false; 201840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // can't use our canonical size if we need to apply patheffects/strokes 202140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (fPaint.isLinearText() && !applyStrokeAndPathEffects) { 20220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); 20230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; 202440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 20250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fScale = SK_Scalar1; 202640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 202740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 202840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!applyStrokeAndPathEffects) { 20290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setStyle(SkPaint::kFill_Style); 20300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setPathEffect(NULL); 20310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fCache = fPaint.detachCache(NULL); 20340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPaint::Style style = SkPaint::kFill_Style; 20360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkPathEffect* pe = NULL; 20370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 203840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (!applyStrokeAndPathEffects) { 20390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project style = paint.getStyle(); // restore 20400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project pe = paint.getPathEffect(); // restore 20410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setStyle(style); 20430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setPathEffect(pe); 20440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPaint.setMaskFilter(paint.getMaskFilter()); // restore 20450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // now compute fXOffset if needed 20470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkScalar xOffset = 0; 204940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first 20500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int count; 205140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, 205240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger &count, NULL), fScale); 205340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (paint.getTextAlign() == SkPaint::kCenter_Align) { 20540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project width = SkScalarHalf(width); 205540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project xOffset = -width; 20570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXPos = xOffset; 20590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fPrevAdvance = 0; 20600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fText = text; 20620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fStop = text + length; 20631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 20641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fXYIndex = paint.isVerticalText() ? 1 : 0; 20650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 206740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTextToPathIter::~SkTextToPathIter() { 20680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkGlyphCache::AttachCache(fCache); 20690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 20700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 207140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkPath* SkTextToPathIter::next(SkScalar* xpos) { 207240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (fText < fStop) { 20730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 20740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 20750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); 20761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); 20770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 207840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (glyph.fWidth) { 207940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (xpos) { 20800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *xpos = fXPos; 208140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fCache->findPath(glyph); 20830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 20850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return NULL; 20860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2087717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2088717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 2089717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 20901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkPaint::nothingToDraw() const { 20911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (fLooper) { 20921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 20931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 20941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkXfermode::Mode mode; 20951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (SkXfermode::AsMode(fXfermode, &mode)) { 20961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger switch (mode) { 20971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSrcOver_Mode: 20981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kSrcATop_Mode: 20991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDstOut_Mode: 21001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDstOver_Mode: 21011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kPlus_Mode: 21021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return 0 == this->getAlpha(); 21031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger case SkXfermode::kDst_Mode: 21041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 21051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger default: 21061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger break; 21071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 21091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////// Move these to their own file soon. 21141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, 21161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger const SkMatrix& ctm, 21171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap* result, SkIPoint* loc) { 21181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(proxy); 21191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(result); 21201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(loc); 21211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger /* 21221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Give the proxy first shot at the filter. If it returns false, ask 21231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * the filter to do it. 21241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 21251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return proxy->filterImage(this, src, ctm, result, loc) || 21261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->onFilterImage(proxy, src, ctm, result, loc); 21271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, 21301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect* dst) { 21311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(&src); 21321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkASSERT(dst); 21331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return this->onFilterBounds(src, ctm, dst); 21341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&, 21371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap*, SkIPoint*) { 21381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, 21421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkIRect* dst) { 21431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *dst = src; 21441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return true; 21451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::asABlur(SkSize* sigma) const { 21481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return false; 21491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger} 21501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asAnErode(SkISize* radius) const { 21524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 21534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 21544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 21554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asADilate(SkISize* radius) const { 21564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return false; 21574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger} 21584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 21594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger////// 21604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2161717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerbool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) { 2162717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkCanvas canvas; 2163717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2164717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->init(&canvas); 2165717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger for (;;) { 2166717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkPaint p(paint); 2167717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->next(&canvas, &p)) { 2168717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.setLooper(NULL); 2169717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (!p.canComputeFastBounds()) { 2170717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return false; 2171717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2172717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2173717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger break; 2174717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2175717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2176717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger return true; 2177717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 2178717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2179717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergervoid SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src, 2180717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect* dst) { 2181717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkCanvas canvas; 21824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger 2183717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger this->init(&canvas); 2184717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger for (bool firstTime = true;; firstTime = false) { 2185717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkPaint p(paint); 2186717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (this->next(&canvas, &p)) { 2187717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger SkRect r(src); 2188717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2189717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.setLooper(NULL); 2190717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger p.computeFastBounds(r, &r); 2191717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger canvas.getTotalMatrix().mapRect(&r); 2192717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger 2193717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger if (firstTime) { 2194717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger *dst = r; 2195717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2196717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger dst->join(r); 2197717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2198717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } else { 2199717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger break; 2200717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2201717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger } 2202717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger} 22031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 2204