1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 9b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com#include "SkAnnotation.h" 10791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkAutoKern.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 12791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkData.h" 13532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#include "SkDeviceProperties.h" 14c4b84aef1adeb68bc853f35abb85b79fa1fcaac6rmistry#include "SkDraw.h" 15791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkFontDescriptor.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFontHost.h" 17791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkGlyphCache.h" 1815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com#include "SkImageFilter.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 2097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com#include "SkMaskGamma.h" 218b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 228b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 23791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkPaintDefaults.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathEffect.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRasterizer.h" 2628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkScalar.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalerContext.h" 28791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkShader.h" 29791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkStringUtils.h" 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStroke.h" 3128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkTextFormatParams.h" 32e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com#include "SkTextToPathIter.h" 33ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com#include "SkTLazy.h" 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h" 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 36791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 37aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orgenum { 38aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org kColor_DirtyBit = 1 << 0, 3945d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kTextSize_DirtyBit = 1 << 1, 4045d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kTextScaleX_DirtyBit = 1 << 2, 4145d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kTextSkewX_DirtyBit = 1 << 3, 4245d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kStrokeWidth_DirtyBit = 1 << 4, 4345d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kStrokeMiter_DirtyBit = 1 << 5, 4445d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org 4545d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kPOD_DirtyBitMask = 63, 4645d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org 4745d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kPathEffect_DirtyBit = 1 << 6, 4845d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kShader_DirtyBit = 1 << 7, 4945d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kXfermode_DirtyBit = 1 << 8, 5045d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kMaskFilter_DirtyBit = 1 << 9, 5145d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kColorFilter_DirtyBit = 1 << 10, 5245d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kRasterizer_DirtyBit = 1 << 11, 5345d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kLooper_DirtyBit = 1 << 12, 5445d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kImageFilter_DirtyBit = 1 << 13, 5545d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kTypeface_DirtyBit = 1 << 14, 5645d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kAnnotation_DirtyBit = 1 << 15, 57aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org}; 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 59a3237875f807aed9608cb4a023bc044f32850727reed@google.com// define this to get a printf for out-of-range parameter in setters 60a3237875f807aed9608cb4a023bc044f32850727reed@google.com// e.g. setTextSize(-1) 61a3237875f807aed9608cb4a023bc044f32850727reed@google.com//#define SK_REPORT_API_RANGE_CHECK 62a3237875f807aed9608cb4a023bc044f32850727reed@google.com 6356c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 64f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC fGenerationID++ 65f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } 66f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#else 67f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC 68f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC_EVAL(expression) 69f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 70f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 71a3122b9b1ec66efef606d8797b7b16b6634e08d2reed@android.comSkPaint::SkPaint() { 72aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fTypeface = NULL; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPathEffect = NULL; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShader = NULL; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode = NULL; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMaskFilter = NULL; 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColorFilter = NULL; 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRasterizer = NULL; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLooper = NULL; 8015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com fImageFilter = NULL; 81b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com fAnnotation = NULL; 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 83f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fTextSize = SkPaintDefaults_TextSize; 84f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fTextScaleX = SK_Scalar1; 85f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fTextSkewX = 0; 86f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fColor = SK_ColorBLACK; 87f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fWidth = 0; 88f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fMiterLimit = SkPaintDefaults_MiterLimit; 89e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 90e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org // Zero all bitfields, then set some non-zero defaults. 91f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfieldsUInt = 0; 92f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fFlags = SkPaintDefaults_Flags; 93f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fCapType = kDefault_Cap; 94f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fJoinType = kDefault_Join; 95f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextAlign = kLeft_Align; 96f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fStyle = kFill_Style; 97f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextEncoding = kUTF8_TextEncoding; 98f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fHinting = SkPaintDefaults_Hinting; 99e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 100e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fDirtyBits = 0; 10156c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 102f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com fGenerationID = 0; 103f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1066fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint::SkPaint(const SkPaint& src) { 107e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define COPY(field) field = src.field 108e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define REF_COPY(field) field = SkSafeRef(src.field) 109e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 110e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fTypeface); 111e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fPathEffect); 112e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fShader); 113e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fXfermode); 114e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fMaskFilter); 115e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fColorFilter); 116e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fRasterizer); 117e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fLooper); 118e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fImageFilter); 119e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fAnnotation); 120e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 121e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSize); 122e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextScaleX); 123e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSkewX); 124e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fColor); 125e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fWidth); 126e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fMiterLimit); 127e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fBitfields); 128e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fDirtyBits); 12940078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com 13040078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 131e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fGenerationID); 13240078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com#endif 133e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 134e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef COPY 135e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef REF_COPY 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1386fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint::~SkPaint() { 13982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fTypeface); 14082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fPathEffect); 14182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fShader); 14282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fXfermode); 14382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fMaskFilter); 14482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fColorFilter); 14582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fRasterizer); 14682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fLooper); 14715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com SkSafeUnref(fImageFilter); 148b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com SkSafeUnref(fAnnotation); 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1516fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint& SkPaint::operator=(const SkPaint& src) { 152f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org if (this == &src) { 153f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org return *this; 154f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org } 155f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org 156e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define COPY(field) field = src.field 157e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define REF_COPY(field) SkSafeUnref(field); field = SkSafeRef(src.field) 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 159e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org SkASSERT(&src); 16082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 161e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fTypeface); 162e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fPathEffect); 163e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fShader); 164e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fXfermode); 165e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fMaskFilter); 166e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fColorFilter); 167e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fRasterizer); 168e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fLooper); 169e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fImageFilter); 170e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fAnnotation); 171e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 172e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSize); 173e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextScaleX); 174e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSkewX); 175e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fColor); 176e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fWidth); 177e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fMiterLimit); 178e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fBitfields); 179e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fDirtyBits); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18156c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 182e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org ++fGenerationID; 183f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *this; 186e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 187e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef COPY 188e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef REF_COPY 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 191b265741cc17f897b349caacdb890119e4111a415robertphillips@google.combool operator==(const SkPaint& a, const SkPaint& b) { 192e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define EQUAL(field) (a.field == b.field) 193ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein // Don't check fGenerationID, which can be different for logically equal paints. 194ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein // fDirtyBits is a very quick check for non-equality, so check it first. 195ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein return EQUAL(fDirtyBits) 196ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein && EQUAL(fTypeface) 197e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fPathEffect) 198e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fShader) 199e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fXfermode) 200e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fMaskFilter) 201e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fColorFilter) 202e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fRasterizer) 203e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fLooper) 204e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fImageFilter) 205e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fAnnotation) 206e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextSize) 207e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextScaleX) 208e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextSkewX) 209e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fColor) 210e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fWidth) 211e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fMiterLimit) 212f59eab269350f36a0c2bf98d1c2a9757c77fc473reed && EQUAL(fBitfieldsUInt) 213e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org ; 214e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef EQUAL 215b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com} 216b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com 2176fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::reset() { 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint init; 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22056c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 221f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com uint32_t oldGenerationID = fGenerationID; 222f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *this = init; 22456c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 225f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com fGenerationID = oldGenerationID + 1; 226f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 227f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com} 228f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 22956c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 230f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.comuint32_t SkPaint::getGenerationID() const { 231f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com return fGenerationID; 232f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com} 2334bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com 2344bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.comvoid SkPaint::setGenerationID(uint32_t generationID) { 2354bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com fGenerationID = generationID; 2364bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com} 23760abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com#endif 23860abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com 239c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.comvoid SkPaint::setFilterLevel(FilterLevel level) { 240f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL((unsigned) level != fBitfields.fFilterLevel); 241f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fFilterLevel = level; 242c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.com} 243c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.com 244f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.comvoid SkPaint::setHinting(Hinting hintingLevel) { 245f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL((unsigned) hintingLevel != fBitfields.fHinting); 246f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fHinting = hintingLevel; 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2496fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setFlags(uint32_t flags) { 250f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL(flags != fBitfields.fFlags); 251f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fFlags = flags; 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2546fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAntiAlias(bool doAA) { 255f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doAA, kAntiAlias_Flag)); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2586fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setDither(bool doDither) { 259f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doDither, kDither_Flag)); 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2626fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setSubpixelText(bool doSubpixel) { 263f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doSubpixel, kSubpixelText_Flag)); 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2666fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setLCDRenderText(bool doLCDRender) { 267f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doLCDRender, kLCDRenderText_Flag)); 268309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org} 269309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org 2706fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) { 271f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag)); 272e95c91e6d9201d50d0b84fbc3d2f53f92f753e0bagl@chromium.org} 273e95c91e6d9201d50d0b84fbc3d2f53f92f753e0bagl@chromium.org 2746fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAutohinted(bool useAutohinter) { 275f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, useAutohinter, kAutoHinting_Flag)); 276a2c71cbd51da8b7767d43fe8954e7a4c674b2005agl@chromium.org} 277a2c71cbd51da8b7767d43fe8954e7a4c674b2005agl@chromium.org 2786fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setLinearText(bool doLinearText) { 279f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doLinearText, kLinearText_Flag)); 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 282830a23e39bb4a126e573940cd6e354732e295b10reed@google.comvoid SkPaint::setVerticalText(bool doVertical) { 283f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doVertical, kVerticalText_Flag)); 284830a23e39bb4a126e573940cd6e354732e295b10reed@google.com} 285830a23e39bb4a126e573940cd6e354732e295b10reed@google.com 2866fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setUnderlineText(bool doUnderline) { 287f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doUnderline, kUnderlineText_Flag)); 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2906fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrikeThruText(bool doStrikeThru) { 291f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doStrikeThru, kStrikeThruText_Flag)); 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2946fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setFakeBoldText(bool doFakeBold) { 295f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doFakeBold, kFakeBoldText_Flag)); 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setDevKernText(bool doDevKern) { 299f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doDevKern, kDevKernText_Flag)); 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 302b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.orgvoid SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) { 303f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doDistanceFieldText, kDistanceFieldTextTEMP_Flag)); 304b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.org} 305b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.org 3066fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStyle(Style style) { 3076fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)style < kStyleCount) { 308f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL((unsigned)style != fBitfields.fStyle); 309f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fStyle = style; 310f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 311a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 312a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 313a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3146fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3176fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setColor(SkColor color) { 318f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(color != fColor); 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor = color; 320ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, color != SK_ColorBLACK, kColor_DirtyBit); 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3236fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAlpha(U8CPU a) { 324f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), 325f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com SkColorGetG(fColor), SkColorGetB(fColor))); 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3286fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 329f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com this->setColor(SkColorSetARGB(a, r, g, b)); 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3326fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeWidth(SkScalar width) { 3336fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (width >= 0) { 334f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(width != fWidth); 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWidth = width; 336ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, width != 0, kStrokeWidth_DirtyBit); 337f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 338a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 339a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); 340a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3446fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeMiter(SkScalar limit) { 3456fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (limit >= 0) { 346f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(limit != fMiterLimit); 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMiterLimit = limit; 348ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, 349ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein limit != SkPaintDefaults_MiterLimit, 350ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein kStrokeMiter_DirtyBit); 351f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 352a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 353a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 354a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3556fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3586fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeCap(Cap ct) { 3596fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)ct < kCapCount) { 360f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL((unsigned)ct != fBitfields.fCapType); 361f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fCapType = SkToU8(ct); 3626fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 363a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 364a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 365a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3666fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeJoin(Join jt) { 3706fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)jt < kJoinCount) { 371f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL((unsigned)jt != fBitfields.fJoinType); 372f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fJoinType = SkToU8(jt); 3736fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 374a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 375a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 376a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3776fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3826fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextAlign(Align align) { 3836fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)align < kAlignCount) { 384f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL((unsigned)align != fBitfields.fTextAlign); 385f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextAlign = SkToU8(align); 3866fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 387a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 388a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 389a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3906fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextSize(SkScalar ts) { 394c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (ts >= 0) { 395f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(ts != fTextSize); 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextSize = ts; 397ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, ts != SkPaintDefaults_TextSize, kTextSize_DirtyBit); 3986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 399a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 400a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextSize() called with negative value\n"); 401a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 4026fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4056fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextScaleX(SkScalar scaleX) { 406f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(scaleX != fTextScaleX); 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextScaleX = scaleX; 408ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, scaleX != SK_Scalar1, kTextScaleX_DirtyBit); 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4116fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextSkewX(SkScalar skewX) { 412f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(skewX != fTextSkewX); 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextSkewX = skewX; 414ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, skewX != 0, kTextSkewX_DirtyBit); 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4176fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextEncoding(TextEncoding encoding) { 4186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)encoding <= kGlyphID_TextEncoding) { 419f59eab269350f36a0c2bf98d1c2a9757c77fc473reed GEN_ID_INC_EVAL((unsigned)encoding != fBitfields.fTextEncoding); 420f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextEncoding = encoding; 4216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 422a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 423a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 424a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 4256fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4286fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4306fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkTypeface* SkPaint::setTypeface(SkTypeface* font) { 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fTypeface, font); 432f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 433ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, font != NULL, kTypeface_DirtyBit); 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return font; 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fRasterizer, r); 439f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 440ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, r != NULL, kRasterizer_DirtyBit); 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return r; 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4446fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fLooper, looper); 446f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 447ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, looper != NULL, kLooper_DirtyBit); 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return looper; 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comSkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { 45215356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com SkRefCnt_SafeAssign(fImageFilter, imageFilter); 45315356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com GEN_ID_INC; 454ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, imageFilter != NULL, kImageFilter_DirtyBit); 45515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com return imageFilter; 45615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com} 45715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com 458b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.comSkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { 459b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com SkRefCnt_SafeAssign(fAnnotation, annotation); 460b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com GEN_ID_INC; 461ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, annotation != NULL, kAnnotation_DirtyBit); 462b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com return annotation; 463b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com} 464b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 467ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comstatic SkScalar mag2(SkScalar x, SkScalar y) { 468ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return x * x + y * y; 469ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 470ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 471ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comstatic bool tooBig(const SkMatrix& m, SkScalar ma2max) { 472ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return mag2(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewY]) > ma2max 473ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com || 474ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com mag2(m[SkMatrix::kMSkewX], m[SkMatrix::kMScaleY]) > ma2max; 475ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 476ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 477ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.combool SkPaint::TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM) { 478ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkASSERT(!ctm.hasPerspective()); 479ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkASSERT(!textM.hasPerspective()); 480ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 481ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkMatrix matrix; 482ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com matrix.setConcat(ctm, textM); 483ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return tooBig(matrix, MaxCacheSize2()); 484ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 485ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 486ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 487ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com/////////////////////////////////////////////////////////////////////////////// 488ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGlyphCache.h" 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 49290808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.comstatic void DetachDescProc(SkTypeface* typeface, const SkDescriptor* desc, 49390808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void* context) { 49490808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(typeface, desc); 495f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com} 496f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkPaint::textToGlyphs(const void* textData, size_t byteLength, 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t glyphs[]) const { 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (byteLength == 0) { 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 50272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(textData != NULL); 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == glyphs) { 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (this->getTextEncoding()) { 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kUTF8_TextEncoding: 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkUTF8_CountUnichars((const char*)textData, byteLength); 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kUTF16_TextEncoding: 5102cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkUTF16_CountUnichars((const uint16_t*)textData, SkToInt(byteLength >> 1)); 51168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case kUTF32_TextEncoding: 5122cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 2); 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kGlyphID_TextEncoding: 5142cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 1); 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 5160c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 52072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we get here, we have a valid glyphs[] array, so time to fill it in 52272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // handle this encoding before the setup for the glyphcache 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->getTextEncoding() == kGlyphID_TextEncoding) { 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want to ignore the low bit of byteLength 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(glyphs, textData, byteLength >> 1 << 1); 5272cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 1); 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 52972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 530532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = text + byteLength; 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* gptr = glyphs; 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (this->getTextEncoding()) { 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPaint::kUTF8_TextEncoding: 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text)); 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPaint::kUTF16_TextEncoding: { 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* text16 = (const uint16_t*)text; 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* stop16 = (const uint16_t*)stop; 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text16 < stop16) { 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 55168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case kUTF32_TextEncoding: { 55268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* text32 = (const int32_t*)text; 55368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* stop32 = (const int32_t*)stop; 55468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com while (text32 < stop32) { 55568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *gptr++ = cache->unicharToGlyph(*text32++); 55668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 55768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com break; 55868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 5600c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5622cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(gptr - glyphs); 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 565a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.combool SkPaint::containsText(const void* textData, size_t byteLength) const { 566a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == byteLength) { 567a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 568a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 56972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 570a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com SkASSERT(textData != NULL); 57172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 572a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com // handle this encoding before the setup for the glyphcache 573a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (this->getTextEncoding() == kGlyphID_TextEncoding) { 574a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* glyphID = static_cast<const uint16_t*>(textData); 575a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com size_t count = byteLength >> 1; 576a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com for (size_t i = 0; i < count; i++) { 577a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == glyphID[i]) { 578a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 579a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 580a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 581a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 582a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 58372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 584532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 585a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com SkGlyphCache* cache = autoCache.getCache(); 586a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com 587a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com switch (this->getTextEncoding()) { 588a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com case SkPaint::kUTF8_TextEncoding: { 589a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const char* text = static_cast<const char*>(textData); 590a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const char* stop = text + byteLength; 591a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com while (text < stop) { 592a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) { 593a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 594a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 595a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 596a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com break; 597a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 598a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com case SkPaint::kUTF16_TextEncoding: { 599a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* text = static_cast<const uint16_t*>(textData); 600a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* stop = text + (byteLength >> 1); 601a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com while (text < stop) { 602a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) { 603a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 604a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 605a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 606a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com break; 607a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 60868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case SkPaint::kUTF32_TextEncoding: { 60968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* text = static_cast<const int32_t*>(textData); 61068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* stop = text + (byteLength >> 2); 61168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com while (text < stop) { 61268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com if (0 == cache->unicharToGlyph(*text++)) { 61368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return false; 61468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 61568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 61668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com break; 61768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 618a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com default: 6190c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 620a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 621a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 622a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 623a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com} 624a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com 6259d3a985aa3c82605346ed1518375a8c384b925e5reed@android.comvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, 6269d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkUnichar textData[]) const { 6279d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com if (count <= 0) { 6289d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com return; 6299d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com } 6309d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 6319d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkASSERT(glyphs != NULL); 6329d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkASSERT(textData != NULL); 6339d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 634532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 6359d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkGlyphCache* cache = autoCache.getCache(); 6369d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 6379d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com for (int index = 0; index < count; index++) { 6389d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com textData[index] = cache->glyphToUnichar(glyphs[index]); 6399d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com } 6409d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com} 6419d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6446fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, 6456fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 64872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6526fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, 6536fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 65672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text)); 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6606fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, 6616fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 664fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6686fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, 6696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 672fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text)); 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 67668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_next(SkGlyphCache* cache, 67768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 67868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 67968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 68068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 68168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 68268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 68368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 68468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 68568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 68668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 68768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_prev(SkGlyphCache* cache, 68868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 68968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 69068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 691fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 69268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 69368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *--ptr; 69468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 69568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 69668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 69768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 6986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, 6996fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 70272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 7048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7106fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, 7116fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 71472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr -= 1; 7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7226fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, 7236fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 72672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF8_NextUnichar(text)); 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7306fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, 7316fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 73472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text)); 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7386fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, 7396fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 74272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text)); 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, 7476fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 75072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text)); 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 75468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getAdvance_utf32_next(SkGlyphCache* cache, 75568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 75668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 75768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 758fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 75968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 76068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 76168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 76268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharAdvance(uni); 76368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 76468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 76568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getAdvance_utf32_prev(SkGlyphCache* cache, 76668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 76768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 76868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 769fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 77068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 77168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *--ptr; 77268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 77368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharAdvance(uni); 77468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 77568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 7766fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, 7776fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 78072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDAdvance(glyphID); 7868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7886fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, 7896fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 79272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr -= 1; 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDAdvance(glyphID); 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd, 8016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com bool needFullMetrics) const { 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const SkMeasureCacheProc gMeasureCacheProcs[] = { 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_next, 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_next, 80568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_next, 8068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_next, 80772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_prev, 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_prev, 81068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_prev, 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_prev, 81272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf8_next, 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf16_next, 81568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getAdvance_utf32_next, 8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_glyph_next, 81772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf8_prev, 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf16_prev, 82068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getAdvance_utf32_prev, 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_glyph_prev 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 82372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned index = this->getTextEncoding(); 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8266fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (kBackward_TextBufferDirection == tbd) { 82768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com index += 4; 8286fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 8296fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!needFullMetrics && !this->isDevKernText()) { 83068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com index += 8; 8316fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs)); 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gMeasureCacheProcs[index]; 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache, 8406fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 84372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache, 8486fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 8498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 85172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y); 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8556fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, 8566fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 8578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 85972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 8618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache, 8646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 86772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text), 8698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x, y); 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 87268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_00(SkGlyphCache* cache, 87368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text, SkFixed, SkFixed) { 87468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 87568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 876fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 87768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 87868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 87968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 88068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 88168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 88268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 88368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_xy(SkGlyphCache* cache, 88468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text, SkFixed x, SkFixed y) { 88568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 88668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 887fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 88868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 889584f337832d585e23037e59517f7bcc420424692commit-bot@chromium.org SkUnichar uni = *ptr++; 89068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 8918d38d516c0f17d8d9f6b170055ac05ac181c0554sugoi@google.com return cache->getUnicharMetrics(uni, x, y); 89268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 89368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 8946fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, 8956fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 8968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 89872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 9008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 9018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 9038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 9048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache, 9076fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 9088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 9098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 91072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 9138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 9148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 9158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID, x, y); 9168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkDrawCacheProc SkPaint::getDrawCacheProc() const { 9198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const SkDrawCacheProc gDrawCacheProcs[] = { 9208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_00, 9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_00, 92268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_00, 9238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_00, 92472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_xy, 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_xy, 92768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_xy, 9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_xy 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 93072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned index = this->getTextEncoding(); 932f59eab269350f36a0c2bf98d1c2a9757c77fc473reed if (fBitfields.fFlags & kSubpixelText_Flag) { 93368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com index += 4; 9346fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 93572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs)); 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gDrawCacheProcs[index]; 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 942ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com#define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \ 943ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kDevKernText_Flag | \ 944ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kLinearText_Flag | \ 945ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kLCDRenderText_Flag | \ 946ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kEmbeddedBitmapText_Flag | \ 947ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kAutoHinting_Flag | \ 948ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kGenA8FromLCD_Flag ) 949ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 950ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkScalar SkPaint::setupForAsPaths() { 951ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com uint32_t flags = this->getFlags(); 952ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // clear the flags we don't care about 953ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com flags &= ~TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE; 954ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // set the flags we do care about 955ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com flags |= SkPaint::kSubpixelText_Flag; 9568f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 957ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setFlags(flags); 958ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setHinting(SkPaint::kNo_Hinting); 9598f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 960ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar textSize = fTextSize; 961ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setTextSize(kCanonicalTextSizeForPaths); 962ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return textSize / kCanonicalTextSizeForPaths; 963ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 964ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 965ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comclass SkCanonicalizePaint { 9668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 967ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint(const SkPaint& paint) : fPaint(&paint), fScale(0) { 968c4b84aef1adeb68bc853f35abb85b79fa1fcaac6rmistry if (paint.isLinearText() || SkDraw::ShouldDrawTextAsPaths(paint, SkMatrix::I())) { 969ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkPaint* p = fLazy.set(paint); 970ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com fScale = p->setupForAsPaths(); 971ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com fPaint = p; 972ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com } 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9746fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com 975ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& getPaint() const { return *fPaint; } 9768f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 977ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com /** 978ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com * Returns 0 if the paint was unmodified, or the scale factor need to 979ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com * the original textSize 980ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com */ 981ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar getScale() const { return fScale; } 98272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 984ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint* fPaint; 985ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar fScale; 986ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkTLazy<SkPaint> fLazy; 9878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 9888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9896fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic void set_bounds(const SkGlyph& g, SkRect* bounds) { 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->set(SkIntToScalar(g.fLeft), 9918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop), 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fLeft + g.fWidth), 9938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop + g.fHeight)); 9948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 996e88f551b38c2893566b7016d906b1455e43542f5reed@android.com// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so 997e88f551b38c2893566b7016d906b1455e43542f5reed@android.com// we don't overflow along the way 998e88f551b38c2893566b7016d906b1455e43542f5reed@android.comtypedef int64_t Sk48Dot16; 999e88f551b38c2893566b7016d906b1455e43542f5reed@android.com 10008f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.comstatic inline float Sk48Dot16ToScalar(Sk48Dot16 x) { 10018f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com return (float) (x * 1.5258789e-5); // x * (1 / 65536.0f) 10028f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com} 1003e88f551b38c2893566b7016d906b1455e43542f5reed@android.com 100444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { 1005e88f551b38c2893566b7016d906b1455e43542f5reed@android.com SkScalar sx = Sk48Dot16ToScalar(dx); 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->join(SkIntToScalar(g.fLeft) + sx, 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop), 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fLeft + g.fWidth) + sx, 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop + g.fHeight)); 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 101244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) { 101344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkScalar sy = Sk48Dot16ToScalar(dy); 101444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com bounds->join(SkIntToScalar(g.fLeft), 101544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fTop) + sy, 101644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fLeft + g.fWidth), 101744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fTop + g.fHeight) + sy); 101844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com} 101944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 102044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comtypedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16); 102144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 102244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY 102344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic SkFixed advance(const SkGlyph& glyph, int xyIndex) { 102444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkASSERT(0 == xyIndex || 1 == xyIndex); 102544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com return (&glyph.fAdvanceX)[xyIndex]; 102644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com} 102744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 10288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkScalar SkPaint::measure_text(SkGlyphCache* cache, 10298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text, size_t byteLength, 10306fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com int* count, SkRect* bounds) const { 10318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count); 10326fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (byteLength == 0) { 10338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *count = 0; 10346fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (bounds) { 10358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->setEmpty(); 10366fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 10378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 10388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMeasureCacheProc glyphCacheProc; 10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 104249f085dddff10473b6ebf832a974288300224e60bsalomon bounds); 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 104444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com int xyIndex; 104544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com JoinBoundsProc joinBoundsProc; 104644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com if (this->isVerticalText()) { 104744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com xyIndex = 1; 104844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc = join_bounds_y; 104944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com } else { 105044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com xyIndex = 0; 105144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc = join_bounds_x; 105244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com } 105344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 10548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = 1; 10558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = (const char*)text + byteLength; 10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph* g = &glyphCacheProc(cache, &text); 1057e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // our accumulated fixed-point advances might overflow 16.16, so we use 1058e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // a 48.16 (64bit) accumulator, and then convert that to scalar at the 1059e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // very end. 106044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com Sk48Dot16 x = advance(*g, xyIndex); 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == bounds) { 10656fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 10668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb; 10678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 10688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g->fRsbDelta; 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 107044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex); 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10726fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 107444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(glyphCacheProc(cache, &text), xyIndex); 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10776fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 10788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(*g, bounds); 10796fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 10808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb; 10818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 10828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g->fRsbDelta; 10838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 10848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += SkAutoKern_AdjustF(rsb, g->fLsbDelta); 108544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc(*g, bounds, x); 108644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(*g, xyIndex); 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10886fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 10908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 109144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc(*g, bounds, x); 109244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(*g, xyIndex); 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text == stop); 10978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *count = n; 1099e88f551b38c2893566b7016d906b1455e43542f5reed@android.com return Sk48Dot16ToScalar(x); 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 110299ae881a7f55a03c2b16fb5704e6e90ea86d965dreedSkScalar SkPaint::measureText(const void* textData, size_t length, SkRect* bounds) const { 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 11048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL || length == 0); 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1106ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1107ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1108ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 110972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 111099ae881a7f55a03c2b16fb5704e6e90ea86d965dreed SkAutoGlyphCache autoCache(paint, NULL, NULL); 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 11128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar width = 0; 111472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 11156fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (length > 0) { 11168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int tempCount; 11178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1118ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com width = paint.measure_text(cache, text, length, &tempCount, bounds); 11196fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 11208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width = SkScalarMul(width, scale); 11216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (bounds) { 11228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fLeft = SkScalarMul(bounds->fLeft, scale); 11238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fTop = SkScalarMul(bounds->fTop, scale); 11248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fRight = SkScalarMul(bounds->fRight, scale); 11258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fBottom = SkScalarMul(bounds->fBottom, scale); 11268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 112846348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com } else if (bounds) { 112946348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com // ensure that even if we don't measure_text we still update the bounds 113046348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com bounds->setEmpty(); 11318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return width; 11338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef bool (*SkTextBufferPred)(const char* text, const char* stop); 11368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool forward_textBufferPred(const char* text, const char* stop) { 11388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return text < stop; 11398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool backward_textBufferPred(const char* text, const char* stop) { 11428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return text > stop; 11438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd, 11466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, size_t length, 11476fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** stop) { 11486fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (SkPaint::kForward_TextBufferDirection == tbd) { 11498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *stop = *text + length; 11508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return forward_textBufferPred; 11516fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 11528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // text should point to the end of the buffer, and stop to the beginning 11538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *stop = *text; 11548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text += length; 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return backward_textBufferPred; 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth, 11608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar* measuredWidth, 11616fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com TextBufferDirection tbd) const { 11626fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (0 == length || 0 >= maxWidth) { 11636fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (measuredWidth) { 11648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *measuredWidth = 0; 11656fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 11668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 11678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1169c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (0 == fTextSize) { 1170c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (measuredWidth) { 1171c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com *measuredWidth = 0; 1172c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com } 1173c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com return length; 1174c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com } 1175c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com 11768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(textD != NULL); 11778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textD; 11788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1179ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1180ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1181ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1183ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // adjust max in case we changed the textSize in paint 1184ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com if (scale) { 1185ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com maxWidth /= scale; 11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 118772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1188ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkAutoGlyphCache autoCache(paint, NULL, NULL); 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1191ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc(tbd, false); 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop; 11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop); 1194ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const int xyIndex = paint.isVerticalText() ? 1 : 0; 1195e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // use 64bits for our accumulator, to avoid overflowing 16.16 1196e88f551b38c2893566b7016d906b1455e43542f5reed@android.com Sk48Dot16 max = SkScalarToFixed(maxWidth); 1197e88f551b38c2893566b7016d906b1455e43542f5reed@android.com Sk48Dot16 width = 0; 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 12008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 12028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb = 0; 12036fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com while (pred(text, stop)) { 12048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* curr = text; 12058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 120644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex); 12076fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((width += x) > max) { 12088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width -= x; 12098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text = curr; 12108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 12118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g.fRsbDelta; 12138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12146fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 12156fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com while (pred(text, stop)) { 12168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* curr = text; 121744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex); 12186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((width += x) > max) { 12198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width -= x; 12208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text = curr; 12218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 12228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 122572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 12266fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (measuredWidth) { 1227e88f551b38c2893566b7016d906b1455e43542f5reed@android.com SkScalar scalarWidth = Sk48Dot16ToScalar(width); 12286fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 12298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scalarWidth = SkScalarMul(scalarWidth, scale); 12306fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 12318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *measuredWidth = scalarWidth; 12328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 123372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 12348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return the number of bytes measured 12358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (kForward_TextBufferDirection == tbd) ? 12368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text - stop + length : stop - text + length; 12378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 12408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) { 12420a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com *(SkPaint::FontMetrics*)context = cache->getFontMetrics(); 12438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; // don't detach the cache 12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 124690808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.comstatic void FontMetricsDescProc(SkTypeface* typeface, const SkDescriptor* desc, 124790808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void* context) { 124890808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com SkGlyphCache::VisitCache(typeface, desc, FontMetricsCacheProc, context); 12498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12516fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const { 1252ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1253ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1254ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 12558f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 12566fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkMatrix zoomMatrix, *zoomPtr = NULL; 12576fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (zoom) { 12588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomMatrix.setScale(zoom, zoom); 12598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomPtr = &zoomMatrix; 12608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FontMetrics storage; 12636fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == metrics) { 12648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics = &storage; 12656fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 126672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1267ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com paint.descriptorProc(NULL, zoomPtr, FontMetricsDescProc, metrics, true); 12688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 12708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fTop = SkScalarMul(metrics->fTop, scale); 12718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 12728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 12738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 12748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 12750a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale); 12760a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXMin = SkScalarMul(metrics->fXMin, scale); 12770a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXMax = SkScalarMul(metrics->fXMax, scale); 12780a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); 12790bc406df48ac6f358ab8dcff08f71fe9c32b79decommit-bot@chromium.org metrics->fUnderlineThickness = SkScalarMul(metrics->fUnderlineThickness, scale); 12800bc406df48ac6f358ab8dcff08f71fe9c32b79decommit-bot@chromium.org metrics->fUnderlinePosition = SkScalarMul(metrics->fUnderlinePosition, scale); 12818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return metrics->fDescent - metrics->fAscent + metrics->fLeading; 12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12856fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 12868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12876fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) { 12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->set(g.fLeft * scale, 12898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g.fTop * scale, 12908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g.fLeft + g.fWidth) * scale, 12918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g.fTop + g.fHeight) * scale); 12928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12946fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comint SkPaint::getTextWidths(const void* textData, size_t byteLength, 12956fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar widths[], SkRect bounds[]) const { 12966fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (0 == byteLength) { 12978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 12986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 130049f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(textData); 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13026fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == widths && NULL == bounds) { 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->countText(textData, byteLength); 13046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 13058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1306ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1307ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1308ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1310ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkAutoGlyphCache autoCache(paint, NULL, NULL); 13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMeasureCacheProc glyphCacheProc; 1313ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com glyphCacheProc = paint.getMeasureCacheProc(kForward_TextBufferDirection, 131449f085dddff10473b6ebf832a974288300224e60bsalomon bounds); 13158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 13178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = text + byteLength; 13188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 1319ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const int xyIndex = paint.isVerticalText() ? 1 : 0; 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we adjust the widths returned here through auto-kerning 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 13248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed prevWidth = 0; 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (scale) { 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed adjust = autokern.adjust(g); 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 13338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar w = SkFixedToScalar(prevWidth + adjust); 13348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths++ = SkScalarMul(w, scale); 13358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 133644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com prevWidth = advance(g, xyIndex); 13378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 13398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++, scale); 13408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0 && widths) { 13448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale); 13458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 13478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 13498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 13508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed adjust = autokern.adjust(g); 13518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 13538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths++ = SkFixedToScalar(prevWidth + adjust); 13548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 135544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com prevWidth = advance(g, xyIndex); 13568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 13588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++); 13598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 13618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0 && widths) { 13638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths = SkFixedToScalar(prevWidth); 13648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no devkern 13678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (scale) { 13688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 13698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 13708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 137144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)), 13728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scale); 13738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 13758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++, scale); 13768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 13788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 13808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 13818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 13828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 138344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com *widths++ = SkFixedToScalar(advance(g, xyIndex)); 13848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 13868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++); 13878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 13898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text == stop); 13948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 13958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13976fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 13988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 14008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::getTextPath(const void* textData, size_t length, 14026fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar x, SkScalar y, SkPath* path) const { 14036fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkASSERT(length == 0 || textData != NULL); 14046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com 14058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 14066fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (text == NULL || length == 0 || path == NULL) { 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 14086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 14098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1410166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com SkTextToPathIter iter(text, length, *this, false); 14118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 14128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar prevXPos = 0; 14138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setScale(iter.getPathScale(), iter.getPathScale()); 14158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.postTranslate(x, y); 14168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path->reset(); 14178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar xpos; 14198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath* iterPath; 14207b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com while (iter.next(&iterPath, &xpos)) { 14218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.postTranslate(xpos - prevXPos, 0); 14227b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (iterPath) { 14237b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com path->addPath(*iterPath, matrix); 14247b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 14258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prevXPos = xpos; 14268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1429ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.comvoid SkPaint::getPosTextPath(const void* textData, size_t length, 1430ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const SkPoint pos[], SkPath* path) const { 1431ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkASSERT(length == 0 || textData != NULL); 1432ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1433ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const char* text = (const char*)textData; 1434ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com if (text == NULL || length == 0 || path == NULL) { 1435ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com return; 1436ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com } 1437ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1438ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkTextToPathIter iter(text, length, *this, false); 1439ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkMatrix matrix; 1440ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkPoint prevPos; 1441ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com prevPos.set(0, 0); 1442ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1443ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com matrix.setScale(iter.getPathScale(), iter.getPathScale()); 1444ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com path->reset(); 1445ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1446ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com unsigned int i = 0; 1447ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const SkPath* iterPath; 14487b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com while (iter.next(&iterPath, NULL)) { 1449ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); 14507b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (iterPath) { 14517b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com path->addPath(*iterPath, matrix); 14527b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 1453ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com prevPos = pos[i]; 1454ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com i++; 1455ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com } 1456ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com} 1457ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 14588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void add_flattenable(SkDescriptor* desc, uint32_t tag, 14598b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkWriteBuffer* buffer) { 14608b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), NULL)); 14618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14632739b27d7d13691603d07982ff0d6dd0658bd364reed@google.com// SkFontHost can override this choice in FilterRec() 14646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic SkMask::Format computeMaskFormat(const SkPaint& paint) { 14658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t flags = paint.getFlags(); 14668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1467b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org // Antialiasing being disabled trumps all other settings. 146865dd8f83106ceb11fbff330bed3037557db974cfreed@google.com if (!(flags & SkPaint::kAntiAlias_Flag)) { 1469b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org return SkMask::kBW_Format; 1470f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com } 1471f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com 147265dd8f83106ceb11fbff330bed3037557db974cfreed@google.com if (flags & SkPaint::kLCDRenderText_Flag) { 1473f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com return SkMask::kLCD16_Format; 147465dd8f83106ceb11fbff330bed3037557db974cfreed@google.com } 1475b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org 1476b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org return SkMask::kA8_Format; 14778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14791cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com// if linear-text is on, then we force hinting to be off (since that's sort of 14801cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com// the point of linear-text. 14811cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.comstatic SkPaint::Hinting computeHinting(const SkPaint& paint) { 14821cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com SkPaint::Hinting h = paint.getHinting(); 14831cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com if (paint.isLinearText()) { 14841cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com h = SkPaint::kNo_Hinting; 14851cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com } 14861cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com return h; 14871cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com} 14881cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com 14891f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com// return true if the paint is just a single color (i.e. not a shader). If its 14901f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com// a shader, then we can't compute a const luminance for it :( 14911f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.comstatic bool justAColor(const SkPaint& paint, SkColor* color) { 14928367b8cb7a6b2f163ee41365323cb219b7049b15reed SkColor c = paint.getColor(); 14938367b8cb7a6b2f163ee41365323cb219b7049b15reed 14948367b8cb7a6b2f163ee41365323cb219b7049b15reed SkShader* shader = paint.getShader(); 14958367b8cb7a6b2f163ee41365323cb219b7049b15reed if (shader && !shader->asLuminanceColor(&c)) { 14961f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com return false; 14971f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 14981f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com if (paint.getColorFilter()) { 14991f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com c = paint.getColorFilter()->filterColor(c); 15001f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 15011f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com if (color) { 15021f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com *color = c; 15031f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 15041f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com return true; 15051f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com} 15061f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com 1507ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.comstatic SkColor computeLuminanceColor(const SkPaint& paint) { 1508ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com SkColor c; 1509ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com if (!justAColor(paint, &c)) { 1510ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com c = SkColorSetRGB(0x7F, 0x80, 0x7F); 1511ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com } 1512ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com return c; 1513ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com} 1514813d38b7a07957f2990ccca52ddab55fe0b1c632reed@google.com 1515dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com#define assert_byte(x) SkASSERT(0 == ((x) >> 8)) 1516dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com 15174f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com// Beyond this size, LCD doesn't appreciably improve quality, but it always 15184f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com// cost more RAM and draws slower, so we set a cap. 1519c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com#ifndef SK_MAX_SIZE_FOR_LCDTEXT 1520c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com #define SK_MAX_SIZE_FOR_LCDTEXT 48 1521c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com#endif 15224f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com 15234f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.comstatic bool tooBigForLCD(const SkScalerContext::Rec& rec) { 1524e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org SkScalar area = rec.fPost2x2[0][0] * rec.fPost2x2[1][1] - 1525e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org rec.fPost2x2[1][0] * rec.fPost2x2[0][1]; 1526e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org SkScalar size = SkScalarSqrt(SkScalarAbs(area)) * rec.fTextSize; 1527e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org return size > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT); 15284f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com} 15294f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com 153072cf4927e503f49c4bd07369e85764ddde57071breed@google.com/* 153172cf4927e503f49c4bd07369e85764ddde57071breed@google.com * Return the scalar with only limited fractional precision. Used to consolidate matrices 153272cf4927e503f49c4bd07369e85764ddde57071breed@google.com * that vary only slightly when we create our key into the font cache, since the font scaler 153372cf4927e503f49c4bd07369e85764ddde57071breed@google.com * typically returns the same looking resuts for tiny changes in the matrix. 153472cf4927e503f49c4bd07369e85764ddde57071breed@google.com */ 1535f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkScalar sk_relax(SkScalar x) { 1536f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com int n = sk_float_round2int(x * 1024); 1537f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return n / 1024.0f; 1538f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 1539f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 154036a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.comvoid SkScalerContext::MakeRec(const SkPaint& paint, 1541532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkDeviceProperties* deviceProperties, 1542532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkMatrix* deviceMatrix, 1543532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com Rec* rec) { 15448d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); 15458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1546cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com SkTypeface* typeface = paint.getTypeface(); 1547cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com if (NULL == typeface) { 1548cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com typeface = SkTypeface::GetDefaultTypeface(); 1549cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com } 1550ec730b9cafaa3b2a4df7e7ceb3ab50601796fbe5bungeman rec->fFontID = typeface->uniqueID(); 15518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fTextSize = paint.getTextSize(); 15528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPreScaleX = paint.getTextScaleX(); 15538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPreSkewX = paint.getTextSkewX(); 15548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15556fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (deviceMatrix) { 1556f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX()); 1557f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX()); 1558f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY()); 1559f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY()); 15606fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 15618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 15628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0; 15638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 156472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 15658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::Style style = paint.getStyle(); 15668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar strokeWidth = paint.getStrokeWidth(); 156772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1568ffe49f5380dd5062073efeda70f2f91682c828careed@google.com unsigned flags = 0; 15694526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org 15706fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isFakeBoldText()) { 15714526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#ifdef SK_USE_FREETYPE_EMBOLDEN 15724526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org flags |= SkScalerContext::kEmbolden_Flag; 15734526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#else 157428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(), 157528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpKeys, 157628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpValues, 157728be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpLength); 15788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale); 157972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 15806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style == SkPaint::kFill_Style) { 15818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = SkPaint::kStrokeAndFill_Style; 15828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com strokeWidth = extra; // ignore paint's strokeWidth if it was "fill" 15836fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 15848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com strokeWidth += extra; 15856fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 15864526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#endif 15878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 15888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15896fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isDevKernText()) { 15908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkScalerContext::kDevKernText_Flag; 15916fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 159272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 15936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style != SkPaint::kFill_Style && strokeWidth > 0) { 15948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fFrameWidth = strokeWidth; 15958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fMiterLimit = paint.getStrokeMiter(); 15968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fStrokeJoin = SkToU8(paint.getStrokeJoin()); 15978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style == SkPaint::kStrokeAndFill_Style) { 15998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkScalerContext::kFrameAndFill_Flag; 16006fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 16016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 16028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fFrameWidth = 0; 16038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fMiterLimit = 0; 16048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fStrokeJoin = 0; 16058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 160702b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); 160802b5331078861b02b61e9a93f845617a7c900409reed@google.com 1609532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (SkMask::kLCD16_Format == rec->fMaskFormat || SkMask::kLCD32_Format == rec->fMaskFormat) { 16104a8126e7f81384526629b1e21bf89b632ea13cd9reed if (tooBigForLCD(*rec)) { 161102b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fMaskFormat = SkMask::kA8_Format; 16124a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kGenA8FromLCD_Flag; 161302b5331078861b02b61e9a93f845617a7c900409reed@google.com } else { 16144a8126e7f81384526629b1e21bf89b632ea13cd9reed SkPixelGeometry geometry = deviceProperties 16154a8126e7f81384526629b1e21bf89b632ea13cd9reed ? deviceProperties->fPixelGeometry 16164a8126e7f81384526629b1e21bf89b632ea13cd9reed : SkSurfacePropsDefaultPixelGeometry(); 16174a8126e7f81384526629b1e21bf89b632ea13cd9reed switch (geometry) { 16184a8126e7f81384526629b1e21bf89b632ea13cd9reed case kUnknown_SkPixelGeometry: 16194a8126e7f81384526629b1e21bf89b632ea13cd9reed // eeek, can't support LCD 16204a8126e7f81384526629b1e21bf89b632ea13cd9reed rec->fMaskFormat = SkMask::kA8_Format; 16214a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kGenA8FromLCD_Flag; 16224a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 16234a8126e7f81384526629b1e21bf89b632ea13cd9reed case kRGB_H_SkPixelGeometry: 16244a8126e7f81384526629b1e21bf89b632ea13cd9reed // our default, do nothing. 16254a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 16264a8126e7f81384526629b1e21bf89b632ea13cd9reed case kBGR_H_SkPixelGeometry: 16274a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_BGROrder_Flag; 16284a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 16294a8126e7f81384526629b1e21bf89b632ea13cd9reed case kRGB_V_SkPixelGeometry: 16304a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_Vertical_Flag; 16314a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 16324a8126e7f81384526629b1e21bf89b632ea13cd9reed case kBGR_V_SkPixelGeometry: 16334a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_Vertical_Flag; 16344a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_BGROrder_Flag; 16354a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 163602b5331078861b02b61e9a93f845617a7c900409reed@google.com } 163702b5331078861b02b61e9a93f845617a7c900409reed@google.com } 163802b5331078861b02b61e9a93f845617a7c900409reed@google.com } 163902b5331078861b02b61e9a93f845617a7c900409reed@google.com 16406fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isEmbeddedBitmapText()) { 164102b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kEmbeddedBitmapText_Flag; 16426fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 16436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isSubpixelText()) { 164402b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kSubpixelPositioning_Flag; 16456fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 16466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isAutohinted()) { 1647f6f56878bc96386882721b15ba610984185d3dc9bungeman@google.com flags |= SkScalerContext::kForceAutohinting_Flag; 16486fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 1649830a23e39bb4a126e573940cd6e354732e295b10reed@google.com if (paint.isVerticalText()) { 1650830a23e39bb4a126e573940cd6e354732e295b10reed@google.com flags |= SkScalerContext::kVertical_Flag; 1651830a23e39bb4a126e573940cd6e354732e295b10reed@google.com } 16528351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { 16538351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com flags |= SkScalerContext::kGenA8FromLCD_Flag; 16548351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com } 165502b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fFlags = SkToU16(flags); 165636a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com 1657ffe49f5380dd5062073efeda70f2f91682c828careed@google.com // these modify fFlags, so do them after assigning fFlags 16589d7576724cf9602ff778b18126e0fef0ab3d3bf2reed@google.com rec->setHinting(computeHinting(paint)); 165997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 1660ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com rec->setLuminanceColor(computeLuminanceColor(paint)); 1661532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1662532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (NULL == deviceProperties) { 1663532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setDeviceGamma(SK_GAMMA_EXPONENT); 1664532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setPaintGamma(SK_GAMMA_EXPONENT); 1665532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com } else { 16664a8126e7f81384526629b1e21bf89b632ea13cd9reed rec->setDeviceGamma(deviceProperties->getGamma()); 1667532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1668532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //For now always set the paint gamma equal to the device gamma. 1669532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //The math in SkMaskGamma can handle them being different, 1670532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //but it requires superluminous masks when 1671532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large. 16724a8126e7f81384526629b1e21bf89b632ea13cd9reed rec->setPaintGamma(deviceProperties->getGamma()); 1673532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com } 1674532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1675532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#ifdef SK_GAMMA_CONTRAST 1676532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setContrast(SK_GAMMA_CONTRAST); 1677ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com#else 1678532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com /** 1679532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise. 1680532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * With lower values small text appears washed out (though correctly so). 1681532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * With higher values lcd fringing is worse and the smoothing effect of 1682532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * partial coverage is diminished. 1683532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com */ 16844b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org rec->setContrast(0.5f); 1685ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com#endif 1686532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 16872bf82d843d8896dd10bb86adc1e974c6d52324e6bungeman@google.com rec->fReservedAlign = 0; 1688fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 168936a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com /* Allow the fonthost to modify our rec before we use it as a key into the 169036a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com cache. This way if we're asking for something that they will ignore, 169136a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com they can modify our rec up front, so we don't create duplicate cache 169236a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com entries. 169336a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com */ 1694fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com typeface->onFilterRec(rec); 16953e8ae5b457558435218a864dd0e852f83abfe802reed@google.com 169610d2d4d1062ef56526f187e6716c5e747689b598reed@google.com // be sure to call PostMakeRec(rec) before you actually use it! 169710d2d4d1062ef56526f187e6716c5e747689b598reed@google.com} 169810d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 169910d2d4d1062ef56526f187e6716c5e747689b598reed@google.com/** 170097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * In order to call cachedDeviceLuminance, cachedPaintLuminance, or 170197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * cachedMaskGamma the caller must hold the gMaskGammaCacheMutex and continue 170297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * to hold it until the returned pointer is refed or forgotten. 170310d2d4d1062ef56526f187e6716c5e747689b598reed@google.com */ 170497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.comSK_DECLARE_STATIC_MUTEX(gMaskGammaCacheMutex); 170510d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 1706ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.comstatic SkMaskGamma* gLinearMaskGamma = NULL; 1707b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkMaskGamma* gMaskGamma = NULL; 1708b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gContrast = SK_ScalarMin; 1709b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gPaintGamma = SK_ScalarMin; 1710b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gDeviceGamma = SK_ScalarMin; 171197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 171297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * The caller must hold the gMaskGammaCacheMutex and continue to hold it until 171397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * the returned SkMaskGamma pointer is refed or forgotten. 171497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 1715a76de72a6036da0a6b051b14411b80941971f881bungeman@google.comstatic const SkMaskGamma& cachedMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) { 1716b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein gMaskGammaCacheMutex.assertHeld(); 1717ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com if (0 == contrast && SK_Scalar1 == paintGamma && SK_Scalar1 == deviceGamma) { 1718ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com if (NULL == gLinearMaskGamma) { 1719ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com gLinearMaskGamma = SkNEW(SkMaskGamma); 1720ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com } 1721a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return *gLinearMaskGamma; 1722ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com } 172397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com if (gContrast != contrast || gPaintGamma != paintGamma || gDeviceGamma != deviceGamma) { 172497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkSafeUnref(gMaskGamma); 1725b1a72cb90a9b515978bc9abda1f267f31a544e08bungeman@google.com gMaskGamma = SkNEW_ARGS(SkMaskGamma, (contrast, paintGamma, deviceGamma)); 172697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gContrast = contrast; 172797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gPaintGamma = paintGamma; 172897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gDeviceGamma = deviceGamma; 172997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com } 1730a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return *gMaskGamma; 173197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com} 173297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 1733b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com/*static*/ void SkPaint::Term() { 1734b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 1735b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com 1736ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com SkSafeUnref(gLinearMaskGamma); 17375987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com gLinearMaskGamma = NULL; 1738b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkSafeUnref(gMaskGamma); 17395987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com gMaskGamma = NULL; 1740b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gContrast = SK_ScalarMin;) 1741b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gPaintGamma = SK_ScalarMin;) 1742b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gDeviceGamma = SK_ScalarMin;) 1743b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com} 1744b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com 174597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 174697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * We ensure that the rec is self-consistent and efficient (where possible) 174797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 17488d38d516c0f17d8d9f6b170055ac05ac181c0554sugoi@google.comvoid SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) { 174910d2d4d1062ef56526f187e6716c5e747689b598reed@google.com /** 175010d2d4d1062ef56526f187e6716c5e747689b598reed@google.com * If we're asking for A8, we force the colorlum to be gray, since that 175197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * limits the number of unique entries, and the scaler will only look at 175297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * the lum of one of them. 175310d2d4d1062ef56526f187e6716c5e747689b598reed@google.com */ 1754dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com switch (rec->fMaskFormat) { 1755dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kLCD16_Format: 1756dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kLCD32_Format: { 1757dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // filter down the luminance color to a finite number of bits 175897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkColor color = rec->getLuminanceColor(); 1759b5715a1c8003e4a8af2301ab44aeef043547808ereed@google.com rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color)); 1760dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 1761dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com } 1762dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kA8_Format: { 1763dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // filter down the luminance to a single component, since A8 can't 1764dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // use per-component information 176597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkColor color = rec->getLuminanceColor(); 1766dc1cf66483e93c2d12d938bc1ce3b8c60cc68da5jvanverth U8CPU lum = SkComputeLuminance(SkColorGetR(color), 1767dc1cf66483e93c2d12d938bc1ce3b8c60cc68da5jvanverth SkColorGetG(color), 1768dc1cf66483e93c2d12d938bc1ce3b8c60cc68da5jvanverth SkColorGetB(color)); 1769dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // reduce to our finite number of bits 177097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com color = SkColorSetRGB(lum, lum, lum); 1771b5715a1c8003e4a8af2301ab44aeef043547808ereed@google.com rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color)); 1772dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 1773dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com } 1774dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kBW_Format: 1775dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // No need to differentiate gamma if we're BW 1776532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->ignorePreBlend(); 1777dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 17783e8ae5b457558435218a864dd0e852f83abfe802reed@google.com } 17798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 17818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MIN_SIZE_FOR_EFFECT_BUFFER 1024 17828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#ifdef SK_DEBUG 178417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com #define TEST_DESC 178517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#endif 178617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com 1787ffe49f5380dd5062073efeda70f2f91682c828careed@google.com/* 1788ffe49f5380dd5062073efeda70f2f91682c828careed@google.com * ignoreGamma tells us that the caller just wants metrics that are unaffected 17892d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, 17902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth * contrast = 0, luminanceColor = transparent black. 1791ffe49f5380dd5062073efeda70f2f91682c828careed@google.com */ 1792532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.comvoid SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, 1793532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkMatrix* deviceMatrix, 179490808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void (*proc)(SkTypeface*, const SkDescriptor*, void*), 179557f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com void* context, bool ignoreGamma) const { 17968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalerContext::Rec rec; 17978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1798532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec); 179957f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com if (ignoreGamma) { 18002d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth rec.ignorePreBlend(); 180157f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 18028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t descSize = sizeof(rec); 18048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int entryCount = 1; 18058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect* pe = this->getPathEffect(); 18068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMaskFilter* mf = this->getMaskFilter(); 18078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRasterizer* ra = this->getRasterizer(); 18088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18098b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkWriteBuffer peBuffer, mfBuffer, raBuffer; 18108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pe) { 18128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com peBuffer.writeFlattenable(pe); 18138b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org descSize += peBuffer.bytesWritten(); 18148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 18158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 18168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // seems like we could support kLCD as well at this point... 18178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mf) { 18198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mfBuffer.writeFlattenable(mf); 18208b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org descSize += mfBuffer.bytesWritten(); 18218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 18228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters 1823a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com /* Pre-blend is not currently applied to filtered text. 1824a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com The primary filter is blur, for which contrast makes no sense, 1825a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com and for which the destination guess error is more visible. 1826a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com Also, all existing users of blur have calibrated for linear. */ 1827a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.ignorePreBlend(); 18288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ra) { 18308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com raBuffer.writeFlattenable(ra); 18318b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org descSize += raBuffer.bytesWritten(); 18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 18338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 183510d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 183610d2d4d1062ef56526f187e6716c5e747689b598reed@google.com /////////////////////////////////////////////////////////////////////////// 183710d2d4d1062ef56526f187e6716c5e747689b598reed@google.com // Now that we're done tweaking the rec, call the PostMakeRec cleanup 183897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkScalerContext::PostMakeRec(*this, &rec); 1839fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com descSize += SkDescriptor::ComputeOverhead(entryCount); 18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoDescriptor ad(descSize); 18438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDescriptor* desc = ad.getDesc(); 18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->init(); 18468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 18478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pe) { 18498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer); 18508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mf) { 18528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer); 18538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ra) { 18558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer); 18568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(descSize == desc->getLength()); 18598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->computeChecksum(); 18608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 186117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#ifdef TEST_DESC 186217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com { 186317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // Check that we completely write the bytes in desc (our key), and that 186417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // there are no uninitialized bytes. If there were, then we would get 186517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // false-misses (or worse, false-hits) in our fontcache. 186617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // 186717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // We do this buy filling 2 others, one with 0s and the other with 1s 186817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // and create those, and then check that all 3 are identical. 186917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkAutoDescriptor ad1(descSize); 187017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkAutoDescriptor ad2(descSize); 187117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkDescriptor* desc1 = ad1.getDesc(); 187217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkDescriptor* desc2 = ad2.getDesc(); 1873fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 187417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com memset(desc1, 0x00, descSize); 187517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com memset(desc2, 0xFF, descSize); 1876fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 187717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc1->init(); 187817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc2->init(); 187917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 188017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 1881fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 188217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com if (pe) { 188317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer); 188417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer); 188517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 188617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com if (mf) { 188717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer); 188817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer); 188917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 189017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com if (ra) { 189117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer); 189217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer); 189317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 1894fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 189517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(descSize == desc1->getLength()); 189617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(descSize == desc2->getLength()); 189717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc1->computeChecksum(); 189817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc2->computeChecksum(); 189917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(!memcmp(desc, desc1, descSize)); 190017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(!memcmp(desc, desc2, descSize)); 190117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 190217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#endif 1903fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 190490808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com proc(fTypeface, desc, context); 19058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1907532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.comSkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties, 19082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMatrix* deviceMatrix, 19092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth bool ignoreGamma) const { 19108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache; 19112d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, ignoreGamma); 19128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache; 19138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 191597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 191697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-blend. 191797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 191897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com//static 191997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.comSkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Rec& rec) { 192097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 1921a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com const SkMaskGamma& maskGamma = cachedMaskGamma(rec.getContrast(), 1922a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.getPaintGamma(), 1923a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.getDeviceGamma()); 1924a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return maskGamma.preBlend(rec.getLuminanceColor()); 192597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com} 192697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 19272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthsize_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, 19282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkScalar deviceGamma, int* width, int* height) { 19292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 19302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, 19312d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth paintGamma, 19322d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth deviceGamma); 19332d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth maskGamma.getGammaTableDimensions(width, height); 19352d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth size_t size = (*width)*(*height)*sizeof(uint8_t); 19362d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19372d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth return size; 19382d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth} 19392d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19402d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthvoid SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, 19412d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth void* data) { 19422d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 19432d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, 19442d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth paintGamma, 19452d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth deviceGamma); 19462d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth int width, height; 19472d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth maskGamma.getGammaTableDimensions(&width, &height); 19482d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth size_t size = width*height*sizeof(uint8_t); 19492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const uint8_t* gammaTables = maskGamma.getGammaTables(); 19502d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth memcpy(data, gammaTables, size); 19512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth} 19522d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 19558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 19578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1958aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uintptr_t asint(const void* p) { 1959aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return reinterpret_cast<uintptr_t>(p); 1960aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1961aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1962aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comunion Scalar32 { 1963aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkScalar fScalar; 1964aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com uint32_t f32; 1965aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com}; 1966aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1967aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) { 1968aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 1969aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com Scalar32 tmp; 1970aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com tmp.fScalar = value; 1971aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com *ptr = tmp.f32; 1972aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return ptr + 1; 1973aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1974aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1975aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic SkScalar read_scalar(const uint32_t*& ptr) { 1976aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 1977aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com Scalar32 tmp; 1978aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com tmp.f32 = *ptr++; 1979aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return tmp.fScalar; 1980aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1981aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1982aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { 1983aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(a == (uint8_t)a); 1984aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(b == (uint8_t)b); 1985aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(c == (uint8_t)c); 1986aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(d == (uint8_t)d); 1987aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return (a << 24) | (b << 16) | (c << 8) | d; 1988aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1989aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 199085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#ifdef SK_DEBUG 199185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org static void ASSERT_FITS_IN(uint32_t value, int bitCount) { 199285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org SkASSERT(bitCount > 0 && bitCount <= 32); 199385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t mask = ~0U; 199485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org mask >>= (32 - bitCount); 199585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org SkASSERT(0 == (value & ~mask)); 199685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 199785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#else 199885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org #define ASSERT_FITS_IN(value, bitcount) 199985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#endif 200085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 2001aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comenum FlatFlags { 200297f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org kHasTypeface_FlatFlag = 0x01, 200397f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org kHasEffects_FlatFlag = 0x02, 200497f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org kHasNonDefaultPaintOptionsAndroid_FlatFlag = 0x04, 2005667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com 200685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlatFlagMask = 0x7, 200785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org}; 200885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 200985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgenum BitsPerField { 201085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlags_BPF = 16, 201185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kHint_BPF = 2, 201285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kAlign_BPF = 2, 201385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFilter_BPF = 2, 201485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlatFlags_BPF = 3, 2015aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com}; 2016aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 201785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic inline int BPF_Mask(int bits) { 201885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (1 << bits) - 1; 201985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 202085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 202185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align, 202285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org unsigned filter, unsigned flatFlags) { 202385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(flags, kFlags_BPF); 202485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(hint, kHint_BPF); 202585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(align, kAlign_BPF); 202685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(filter, kFilter_BPF); 202785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(flatFlags, kFlatFlags_BPF); 202885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 202985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly 203085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // add more bits in the future. 203185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (flags << 16) | (hint << 14) | (align << 12) | (filter << 10) | flatFlags; 203285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 203385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 203485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) { 203585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFlags(packed >> 16); 203685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF))); 203785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF))); 203885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFilterLevel((SkPaint::FilterLevel)((packed >> 10) & BPF_Mask(kFilter_BPF))); 203985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (FlatFlags)(packed & kFlatFlagMask); 204085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 204185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 204285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org// V22_COMPATIBILITY_CODE 204385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic FlatFlags unpack_paint_flags_v22(SkPaint* paint, uint32_t packed) { 204485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org enum { 204585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFilterBitmap_Flag = 0x02, 204685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kHighQualityFilterBitmap_Flag = 0x4000, 2047667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com 204885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kAll_Flags = kFilterBitmap_Flag | kHighQualityFilterBitmap_Flag 204985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org }; 205085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 205185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // previously flags:16, textAlign:8, flatFlags:8 205285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // now flags:16, hinting:4, textAlign:4, flatFlags:8 205385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org unsigned flags = packed >> 16; 205485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org int filter = 0; 205585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org if (flags & kFilterBitmap_Flag) { 205685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org filter |= 1; 205785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 205885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org if (flags & kHighQualityFilterBitmap_Flag) { 205985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org filter |= 2; 206085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 206185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFilterLevel((SkPaint::FilterLevel)filter); 206285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org flags &= ~kAll_Flags; // remove these (now dead) bit flags 206385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 206485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFlags(flags); 2065667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com 206685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // hinting added later. 0 in this nibble means use the default. 206785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t hinting = (packed >> 12) & 0xF; 206885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setHinting(0 == hinting ? SkPaint::kNormal_Hinting : static_cast<SkPaint::Hinting>(hinting-1)); 206985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setTextAlign(static_cast<SkPaint::Align>((packed >> 8) & 0xF)); 207085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (FlatFlags)(packed & kFlatFlagMask); 207185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 207285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 2073aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com// The size of a flat paint's POD fields 2074d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comstatic const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + 20751f1543f012b8834ea760175a023eb127bde2b895reed@google.com 1 * sizeof(SkColor) + 20761f1543f012b8834ea760175a023eb127bde2b895reed@google.com 1 * sizeof(uint16_t) + 20771f1543f012b8834ea760175a023eb127bde2b895reed@google.com 6 * sizeof(uint8_t); 2078aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2079aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com/* To save space/time, we analyze the paint, and write a truncated version of 2080aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com it if there are not tricky elements like shaders, etc. 2081aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com */ 20828b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPaint::flatten(SkWriteBuffer& buffer) const { 2083aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com uint8_t flatFlags = 0; 2084aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (this->getTypeface()) { 2085aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com flatFlags |= kHasTypeface_FlatFlag; 2086aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 2087aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (asint(this->getPathEffect()) | 2088aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getShader()) | 2089aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getXfermode()) | 2090aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getMaskFilter()) | 2091aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getColorFilter()) | 2092aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getRasterizer()) | 209354e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org asint(this->getLooper()) | 2094b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com asint(this->getAnnotation()) | 209554e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org asint(this->getImageFilter())) { 2096aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com flatFlags |= kHasEffects_FlatFlag; 2097aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 2098c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com 20998b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 21008b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org uint32_t* ptr = buffer.reserve(kPODPaintSize); 21018b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 21028b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextSize()); 21038b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextScaleX()); 21048b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextSkewX()); 21058b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getStrokeWidth()); 21068b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getStrokeMiter()); 21078b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *ptr++ = this->getColor(); 210885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 210985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org *ptr++ = pack_paint_flags(this->getFlags(), this->getHinting(), this->getTextAlign(), 211085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org this->getFilterLevel(), flatFlags); 21118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(), 21128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->getStyle(), this->getTextEncoding()); 2113aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2114aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com // now we're done with ptr and the (pre)reserved space. If we need to write 2115aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com // additional fields, use the buffer directly 2116aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasTypeface_FlatFlag) { 2117aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeTypeface(this->getTypeface()); 2118aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 2119aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasEffects_FlatFlag) { 2120aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getPathEffect()); 2121aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getShader()); 2122aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getXfermode()); 2123aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getMaskFilter()); 2124aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getColorFilter()); 2125aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getRasterizer()); 2126aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getLooper()); 212754e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org buffer.writeFlattenable(this->getImageFilter()); 21280cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com 21290cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com if (fAnnotation) { 21300cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com buffer.writeBool(true); 21310cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com fAnnotation->writeToBuffer(buffer); 21320cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } else { 21330cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com buffer.writeBool(false); 21340cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } 2135aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 21368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21388b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPaint::unflatten(SkReadBuffer& buffer) { 21398b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 21408b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org const void* podData = buffer.skip(kPODPaintSize); 21418b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); 21428b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 21438b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org // the order we read must match the order we wrote in flatten() 21448b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextSize(read_scalar(pod)); 21458b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextScaleX(read_scalar(pod)); 21468b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextSkewX(read_scalar(pod)); 21478b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeWidth(read_scalar(pod)); 21488b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeMiter(read_scalar(pod)); 21498b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setColor(*pod++); 21508b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 215185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org unsigned flatFlags = 0; 21527ed173b1ebac84671fb0dc1b9bd323a5e6e63771commit-bot@chromium.org if (buffer.isVersionLT(SkReadBuffer::kFilterLevelIsEnum_Version)) { 215385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org flatFlags = unpack_paint_flags_v22(this, *pod++); 215485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } else { 215585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org flatFlags = unpack_paint_flags(this, *pod++); 215685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 21578b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 215885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t tmp = *pod++; 21598b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); 21608b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); 21618b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); 21628b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); 2163aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2164aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasTypeface_FlatFlag) { 2165aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setTypeface(buffer.readTypeface()); 2166aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } else { 2167aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setTypeface(NULL); 2168aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 2169aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2170aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasEffects_FlatFlag) { 2171353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setPathEffect(buffer.readPathEffect())); 2172353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setShader(buffer.readShader())); 2173353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setXfermode(buffer.readXfermode())); 2174353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setMaskFilter(buffer.readMaskFilter())); 2175353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setColorFilter(buffer.readColorFilter())); 2176353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setRasterizer(buffer.readRasterizer())); 2177353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setLooper(buffer.readDrawLooper())); 2178353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setImageFilter(buffer.readImageFilter())); 2179fbc58a305518fe611113a51649bf557c991ac8cfskia.committer@gmail.com 21800cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com if (buffer.readBool()) { 2181d957984c1efbd18f3b2bbeca78d282837c5a2ae1commit-bot@chromium.org this->setAnnotation(SkAnnotation::Create(buffer))->unref(); 21820cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } 2183aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } else { 2184aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setPathEffect(NULL); 2185aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setShader(NULL); 2186aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setXfermode(NULL); 2187aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setMaskFilter(NULL); 2188aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setColorFilter(NULL); 2189aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setRasterizer(NULL); 2190aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setLooper(NULL); 219154e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org this->setImageFilter(NULL); 2192aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 219397f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org 21943b6255493e458c6b2c1412af908581f0bf3f6b70djsollen if (buffer.isVersionLT(SkReadBuffer::kRemoveAndroidPaintOpts_Version) && 21953b6255493e458c6b2c1412af908581f0bf3f6b70djsollen flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) { 21963b6255493e458c6b2c1412af908581f0bf3f6b70djsollen SkString tag; 21973b6255493e458c6b2c1412af908581f0bf3f6b70djsollen buffer.readUInt(); 21983b6255493e458c6b2c1412af908581f0bf3f6b70djsollen buffer.readString(&tag); 21993b6255493e458c6b2c1412af908581f0bf3f6b70djsollen buffer.readBool(); 220097f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org } 22018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 22048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 220582065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkShader* SkPaint::setShader(SkShader* shader) { 2206f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(shader != fShader); 22078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fShader, shader); 2208ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, shader != NULL, kShader_DirtyBit); 22098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return shader; 22108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 221282065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { 2213f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(filter != fColorFilter); 22148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fColorFilter, filter); 2215ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, filter != NULL, kColorFilter_DirtyBit); 22168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 22178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 221982065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkXfermode* SkPaint::setXfermode(SkXfermode* mode) { 2220f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(mode != fXfermode); 22218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fXfermode, mode); 2222ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, mode != NULL, kXfermode_DirtyBit); 22238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mode; 22248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22260baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.comSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { 2227d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com SkSafeUnref(fXfermode); 2228d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com fXfermode = SkXfermode::Create(mode); 2229f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 2230ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, fXfermode != NULL, kXfermode_DirtyBit); 2231d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com return fXfermode; 2232d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com} 2233d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com 223482065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { 2235f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(effect != fPathEffect); 22368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fPathEffect, effect); 2237ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, effect != NULL, kPathEffect_DirtyBit); 22388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return effect; 22398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 224182065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { 2242f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(filter != fMaskFilter); 22438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMaskFilter, filter); 2244ee902cd4f4b3c8f355c0f4de35152a14904ec54amtklein fDirtyBits = SkSetClearMask(fDirtyBits, filter != NULL, kMaskFilter_DirtyBit); 22458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 22468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 224882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 22498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22504bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.combool SkPaint::getFillPath(const SkPath& src, SkPath* dst, 22514bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com const SkRect* cullRect) const { 2252fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com SkStrokeRec rec(*this); 22538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2254fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com const SkPath* srcPtr = &src; 2255fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com SkPath tmpPath; 225672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 22574bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com if (fPathEffect && fPathEffect->filterPath(&tmpPath, src, &rec, cullRect)) { 2258fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com srcPtr = &tmpPath; 22598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2261fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com if (!rec.applyToPath(dst, *srcPtr)) { 2262fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com if (srcPtr == &tmpPath) { 2263fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // If path's were copy-on-write, this trick would not be needed. 2264fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // As it is, we want to save making a deep-copy from tmpPath -> dst 2265fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // since we know we're just going to delete tmpPath when we return, 2266fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // so the swap saves that copy. 2267fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com dst->swap(tmpPath); 2268fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com } else { 2269fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com *dst = *srcPtr; 2270d3521f1a8dc07fe84d6a8f2151b0c176ff1ec8careed@google.com } 2271d3521f1a8dc07fe84d6a8f2151b0c176ff1ec8careed@google.com } 2272fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com return !rec.isHairlineStyle(); 22738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2275e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.comconst SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc, 2276a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com SkRect* storage, 2277a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com Style style) const { 22788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(storage); 22799efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2280e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com const SkRect* src = &origSrc; 2281e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 22829efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (this->getLooper()) { 22839efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkASSERT(this->getLooper()->canComputeFastBounds(*this)); 2284e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com this->getLooper()->computeFastBounds(*this, *src, storage); 22859efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com return *storage; 22869efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 22879efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2288e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com SkRect tmpSrc; 2289e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com if (this->getPathEffect()) { 2290e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com this->getPathEffect()->computeFastBounds(&tmpSrc, origSrc); 2291e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com src = &tmpSrc; 2292e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com } 2293e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 2294a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (kFill_Style != style) { 22959efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com // since we're stroked, outset the rect by the radius (and join type) 22969efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkScalar radius = SkScalarHalf(this->getStrokeWidth()); 22979efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (0 == radius) { // hairline 22989efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com radius = SK_Scalar1; 22999efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { 23009efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkScalar scale = this->getStrokeMiter(); 23019efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (scale > SK_Scalar1) { 23029efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com radius = SkScalarMul(radius, scale); 23039efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 23048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2305e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com storage->set(src->fLeft - radius, src->fTop - radius, 2306e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com src->fRight + radius, src->fBottom + radius); 23079efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } else { 2308e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com *storage = *src; 23098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23109efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 23119efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (this->getMaskFilter()) { 23129efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com this->getMaskFilter()->computeFastBounds(*storage, storage); 23139efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 23149efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2315336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (this->getImageFilter()) { 2316336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org this->getImageFilter()->computeFastBounds(*storage, storage); 2317336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 2318336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 2319d252db03d9650013b545ef9781fe993c07f8f314reed@android.com return *storage; 23208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23220f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 232383658305a1bda2d862f50145ecf5cb697b575e86reed 2324791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.comvoid SkPaint::toString(SkString* str) const { 2325791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dl><dt>SkPaint:</dt><dd><dl>"); 2326791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2327791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkTypeface* typeface = this->getTypeface(); 232849f085dddff10473b6ebf832a974288300224e60bsalomon if (typeface) { 2329d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman SkDynamicMemoryWStream ostream; 2330d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman typeface->serialize(&ostream); 2331d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman SkAutoTUnref<SkStreamAsset> istream(ostream.detachAsStream()); 2332d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman SkFontDescriptor descriptor(istream); 2333791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2334791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Font Family Name:</dt><dd>"); 2335791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFamilyName()); 2336791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font Full Name:</dt><dd>"); 2337791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFullName()); 2338791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font PS Name:</dt><dd>"); 2339791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getPostscriptName()); 2340791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font File Name:</dt><dd>"); 2341791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFontFileName()); 2342791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2343791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2344791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2345791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextSize:</dt><dd>"); 2346791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextSize()); 2347791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2348791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2349791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextScaleX:</dt><dd>"); 2350791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextScaleX()); 2351791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2352791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2353791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextSkewX:</dt><dd>"); 2354791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextSkewX()); 2355791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2356791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2357791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkPathEffect* pathEffect = this->getPathEffect(); 235849f085dddff10473b6ebf832a974288300224e60bsalomon if (pathEffect) { 2359791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>PathEffect:</dt><dd>"); 2360791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2361791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2362791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2363791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkShader* shader = this->getShader(); 236449f085dddff10473b6ebf832a974288300224e60bsalomon if (shader) { 2365791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Shader:</dt><dd>"); 23661202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com shader->toString(str); 2367791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2368791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2369791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2370791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkXfermode* xfer = this->getXfermode(); 237149f085dddff10473b6ebf832a974288300224e60bsalomon if (xfer) { 2372791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Xfermode:</dt><dd>"); 23731202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com xfer->toString(str); 2374791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2375791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2376791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2377791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkMaskFilter* maskFilter = this->getMaskFilter(); 237849f085dddff10473b6ebf832a974288300224e60bsalomon if (maskFilter) { 2379791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>MaskFilter:</dt><dd>"); 23801202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com maskFilter->toString(str); 2381791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2382791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2383791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2384791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkColorFilter* colorFilter = this->getColorFilter(); 238549f085dddff10473b6ebf832a974288300224e60bsalomon if (colorFilter) { 2386791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>ColorFilter:</dt><dd>"); 23871202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com colorFilter->toString(str); 2388791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2389791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2390791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2391791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkRasterizer* rasterizer = this->getRasterizer(); 239249f085dddff10473b6ebf832a974288300224e60bsalomon if (rasterizer) { 2393791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Rasterizer:</dt><dd>"); 2394791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2395791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2396791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2397791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkDrawLooper* looper = this->getLooper(); 239849f085dddff10473b6ebf832a974288300224e60bsalomon if (looper) { 2399791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>DrawLooper:</dt><dd>"); 24001202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com looper->toString(str); 2401791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2402791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2403791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2404791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkImageFilter* imageFilter = this->getImageFilter(); 240549f085dddff10473b6ebf832a974288300224e60bsalomon if (imageFilter) { 2406791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>ImageFilter:</dt><dd>"); 2407791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2408791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2409791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2410791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAnnotation* annotation = this->getAnnotation(); 241149f085dddff10473b6ebf832a974288300224e60bsalomon if (annotation) { 2412791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Annotation:</dt><dd>"); 2413791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2414791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2415791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2416791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Color:</dt><dd>0x"); 2417791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkColor color = this->getColor(); 2418791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendHex(color); 2419791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2420791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2421791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Stroke Width:</dt><dd>"); 2422791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getStrokeWidth()); 2423791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2424791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2425791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Stroke Miter:</dt><dd>"); 2426791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getStrokeMiter()); 2427791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2428791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2429791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Flags:</dt><dd>("); 2430791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (this->getFlags()) { 2431791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com bool needSeparator = false; 2432791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isAntiAlias(), "AntiAlias", &needSeparator); 2433791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isDither(), "Dither", &needSeparator); 2434791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isUnderlineText(), "UnderlineText", &needSeparator); 2435791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isStrikeThruText(), "StrikeThruText", &needSeparator); 2436791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isFakeBoldText(), "FakeBoldText", &needSeparator); 2437791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isLinearText(), "LinearText", &needSeparator); 2438791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isSubpixelText(), "SubpixelText", &needSeparator); 2439791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isDevKernText(), "DevKernText", &needSeparator); 2440791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isLCDRenderText(), "LCDRenderText", &needSeparator); 2441791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isEmbeddedBitmapText(), 2442791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com "EmbeddedBitmapText", &needSeparator); 2443791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isAutohinted(), "Autohinted", &needSeparator); 2444791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isVerticalText(), "VerticalText", &needSeparator); 2445791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, SkToBool(this->getFlags() & SkPaint::kGenA8FromLCD_Flag), 2446791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com "GenA8FromLCD", &needSeparator); 2447791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } else { 2448791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("None"); 2449791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2450791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(")</dd>"); 2451791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 24523e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append("<dt>FilterLevel:</dt><dd>"); 24533e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com static const char* gFilterLevelStrings[] = { "None", "Low", "Medium", "High" }; 24543e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append(gFilterLevelStrings[this->getFilterLevel()]); 24553e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append("</dd>"); 24563e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com 2457791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextAlign:</dt><dd>"); 2458791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gTextAlignStrings[SkPaint::kAlignCount] = { "Left", "Center", "Right" }; 2459791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gTextAlignStrings[this->getTextAlign()]); 2460791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2461791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2462791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>CapType:</dt><dd>"); 2463791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gStrokeCapStrings[SkPaint::kCapCount] = { "Butt", "Round", "Square" }; 2464791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gStrokeCapStrings[this->getStrokeCap()]); 2465791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2466791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2467791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>JoinType:</dt><dd>"); 2468791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gJoinStrings[SkPaint::kJoinCount] = { "Miter", "Round", "Bevel" }; 2469791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gJoinStrings[this->getStrokeJoin()]); 2470791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2471791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2472791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Style:</dt><dd>"); 2473791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gStyleStrings[SkPaint::kStyleCount] = { "Fill", "Stroke", "StrokeAndFill" }; 2474791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gStyleStrings[this->getStyle()]); 2475791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2476791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2477791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextEncoding:</dt><dd>"); 2478791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gTextEncodingStrings[] = { "UTF8", "UTF16", "UTF32", "GlyphID" }; 2479791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gTextEncodingStrings[this->getTextEncoding()]); 2480791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2481791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2482791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Hinting:</dt><dd>"); 2483791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gHintingStrings[] = { "None", "Slight", "Normal", "Full" }; 2484791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gHintingStrings[this->getHinting()]); 2485791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2486791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2487791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd></dl></dl>"); 2488791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com} 2489791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#endif 2490791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 24916fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 24928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool has_thick_frame(const SkPaint& paint) { 24946fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com return paint.getStrokeWidth() > 0 && 24956fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com paint.getStyle() != SkPaint::kFill_Style; 24968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 24978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTextToPathIter::SkTextToPathIter( const char text[], size_t length, 24998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint, 2500166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com bool applyStrokeAndPathEffects) 2501166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com : fPaint(paint) { 25028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection, 25038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com true); 25048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2505166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com fPaint.setLinearText(true); 25068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup 25078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { 25098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com applyStrokeAndPathEffects = false; 25106fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 25118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2512166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com // can't use our canonical size if we need to apply patheffects 2513166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com if (fPaint.getPathEffect() == NULL) { 25148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); 25158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; 2516166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com if (has_thick_frame(fPaint)) { 2517166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale)); 2518166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com } 25196fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 25208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = SK_Scalar1; 25216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 252272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 25236fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!applyStrokeAndPathEffects) { 25248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setStyle(SkPaint::kFill_Style); 25258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setPathEffect(NULL); 25268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = fPaint.detachCache(NULL, NULL, false); 25298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::Style style = SkPaint::kFill_Style; 25318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect* pe = NULL; 25328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25336fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!applyStrokeAndPathEffects) { 25348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = paint.getStyle(); // restore 25358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pe = paint.getPathEffect(); // restore 25368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setStyle(style); 25388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setPathEffect(pe); 25398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setMaskFilter(paint.getMaskFilter()); // restore 25408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now compute fXOffset if needed 25428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar xOffset = 0; 25446fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first 25458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count; 25466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, 25476fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com &count, NULL), fScale); 25486fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 25498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width = SkScalarHalf(width); 25506fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 25518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com xOffset = -width; 25528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXPos = xOffset; 25548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPrevAdvance = 0; 25558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fText = text; 25578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = text + length; 25587b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com 255944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com fXYIndex = paint.isVerticalText() ? 1 : 0; 25608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25626fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkTextToPathIter::~SkTextToPathIter() { 25638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache::AttachCache(fCache); 25648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25667b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.combool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { 25677b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (fText < fStop) { 25688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 25698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); 257144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); 25728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25736fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (glyph.fWidth) { 25747b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (path) { 25757b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *path = fCache->findPath(glyph); 25767b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 25777b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } else { 25787b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (path) { 25797b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *path = NULL; 25806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 25818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25827b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (xpos) { 25837b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *xpos = fXPos; 25847b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 25857b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com return true; 25868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25877b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com return false; 25888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2589dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com 2590dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com/////////////////////////////////////////////////////////////////////////////// 2591dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com 2592dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.combool SkPaint::nothingToDraw() const { 2593733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com if (fLooper) { 2594733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com return false; 2595733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com } 2596dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com SkXfermode::Mode mode; 2597dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com if (SkXfermode::AsMode(fXfermode, &mode)) { 2598dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com switch (mode) { 2599dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kSrcOver_Mode: 2600dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kSrcATop_Mode: 2601dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDstOut_Mode: 2602dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDstOver_Mode: 2603dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kPlus_Mode: 2604dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return 0 == this->getAlpha(); 2605dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDst_Mode: 2606dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return true; 2607dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com default: 2608dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com break; 2609dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com } 2610dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com } 2611dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return false; 2612dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com} 2613aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2614aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orginline static unsigned popcount(uint8_t x) { 2615aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org // As in Hacker's delight, adapted for just 8 bits. 2616aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z 2617aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z 2618aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z 2619aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org return x; 2620aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 2621aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2622aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orgvoid SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& paint) { 2623aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org const uint32_t dirty = paint.fDirtyBits; 2624aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 262545d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org // Each of the low 7 dirty bits corresponds to a 4-byte flat value, 262645d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org // plus one for the dirty bits and one for the bitfields 262745d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org const size_t flatBytes = 4 * (popcount(dirty & kPOD_DirtyBitMask) + 2); 2628aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org SkASSERT(flatBytes <= 32); 2629aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org uint32_t* u32 = buffer.reserve(flatBytes); 2630aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org *u32++ = dirty; 2631f59eab269350f36a0c2bf98d1c2a9757c77fc473reed *u32++ = paint.fBitfieldsUInt; 263245d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org if (0 == dirty) { 2633aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org return; 2634aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org } 2635aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2636aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field() 2637aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(u32, Color); 2638aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org SkScalar* f32 = reinterpret_cast<SkScalar*>(u32); 2639aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, TextSize); 2640aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, TextScaleX); 2641aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, TextSkewX); 2642aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, StrokeWidth); 2643aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, StrokeMiter); 2644aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F 2645aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint.get##field()) 2646aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(PathEffect); 2647aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Shader); 2648aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Xfermode); 2649aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(MaskFilter); 2650aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(ColorFilter); 2651aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Rasterizer); 2652aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Looper); 2653aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(ImageFilter); 2654aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F 2655aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); 2656aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffer); 2657aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 2658aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2659aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orgvoid SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) { 2660aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org const uint32_t dirty = buffer.readUInt(); 2661f59eab269350f36a0c2bf98d1c2a9757c77fc473reed paint->fBitfieldsUInt = buffer.readUInt(); 2662aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty == 0) { 2663aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org return; 2664aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org } 2665aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buffer.reader()) 2666aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org// Same function, except it unrefs the object newly set on the paint: 2667aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F_UNREF(field, reader) \ 2668aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & k##field##_DirtyBit) \ 2669aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org paint->set##field(buffer.reader())->unref() 2670aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2671aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Color, readUInt); 2672aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(TextSize, readScalar); 2673aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(TextScaleX, readScalar); 2674aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(TextSkewX, readScalar); 2675aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(StrokeWidth, readScalar); 2676aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(StrokeMiter, readScalar); 2677aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(PathEffect, readPathEffect); 2678aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Shader, readShader); 2679aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Xfermode, readXfermode); 2680aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(MaskFilter, readMaskFilter); 2681aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(ColorFilter, readColorFilter); 2682aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Rasterizer, readRasterizer); 2683aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Looper, readDrawLooper); 2684aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(ImageFilter, readImageFilter); 2685aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Typeface, readTypeface); 2686aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F 2687aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F_UNREF 2688aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kAnnotation_DirtyBit) { 2689d957984c1efbd18f3b2bbeca78d282837c5a2ae1commit-bot@chromium.org paint->setAnnotation(SkAnnotation::Create(buffer))->unref(); 2690aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org } 2691aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org SkASSERT(dirty == paint->fDirtyBits); 2692aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 2693