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" 14791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkFontDescriptor.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFontHost.h" 16791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkGlyphCache.h" 1715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com#include "SkImageFilter.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 1997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com#include "SkMaskGamma.h" 208b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 218b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 22791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkPaintDefaults.h" 2397f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org#include "SkPaintOptionsAndroid.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, 5745d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org kPaintOptionsAndroid_DirtyBit = 1 << 16, 58aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org}; 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 60a3237875f807aed9608cb4a023bc044f32850727reed@google.com// define this to get a printf for out-of-range parameter in setters 61a3237875f807aed9608cb4a023bc044f32850727reed@google.com// e.g. setTextSize(-1) 62a3237875f807aed9608cb4a023bc044f32850727reed@google.com//#define SK_REPORT_API_RANGE_CHECK 63a3237875f807aed9608cb4a023bc044f32850727reed@google.com 6456c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 65f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC fGenerationID++ 66f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; } 67f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#else 68f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC 69f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC_EVAL(expression) 70f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 71f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 72a3122b9b1ec66efef606d8797b7b16b6634e08d2reed@android.comSkPaint::SkPaint() { 73aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fTypeface = NULL; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPathEffect = NULL; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShader = NULL; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode = NULL; 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMaskFilter = NULL; 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColorFilter = NULL; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRasterizer = NULL; 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLooper = NULL; 8115356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com fImageFilter = NULL; 82b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com fAnnotation = NULL; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 84e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fTextSize = SkPaintDefaults_TextSize; 85e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fTextScaleX = SK_Scalar1; 86e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fTextSkewX = 0; 87e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fColor = SK_ColorBLACK; 88e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fWidth = 0; 89e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fMiterLimit = SkPaintDefaults_MiterLimit; 90e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 91e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org // Zero all bitfields, then set some non-zero defaults. 92e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fBitfields = 0; 93e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fFlags = SkPaintDefaults_Flags; 94e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fCapType = kDefault_Cap; 95e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fJoinType = kDefault_Join; 96e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fTextAlign = kLeft_Align; 97e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fStyle = kFill_Style; 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextEncoding = kUTF8_TextEncoding; 99e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fHinting = SkPaintDefaults_Hinting; 100e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 101e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org fDirtyBits = 0; 10256c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 103c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org new (&fPaintOptionsAndroid) SkPaintOptionsAndroid; 104f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com fGenerationID = 0; 105f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint::SkPaint(const SkPaint& src) { 109e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define COPY(field) field = src.field 110e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define REF_COPY(field) field = SkSafeRef(src.field) 111e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 112e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fTypeface); 113e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fPathEffect); 114e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fShader); 115e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fXfermode); 116e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fMaskFilter); 117e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fColorFilter); 118e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fRasterizer); 119e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fLooper); 120e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fImageFilter); 121e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fAnnotation); 122e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 123e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSize); 124e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextScaleX); 125e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSkewX); 126e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fColor); 127e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fWidth); 128e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fMiterLimit); 129e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fBitfields); 130e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fDirtyBits); 13140078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com 13240078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 13340078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com new (&fPaintOptionsAndroid) SkPaintOptionsAndroid(src.fPaintOptionsAndroid); 134e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fGenerationID); 13540078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com#endif 136e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 137e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef COPY 138e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef REF_COPY 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint::~SkPaint() { 14282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fTypeface); 14382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fPathEffect); 14482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fShader); 14582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fXfermode); 14682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fMaskFilter); 14782065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fColorFilter); 14882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fRasterizer); 14982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fLooper); 15015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com SkSafeUnref(fImageFilter); 151b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com SkSafeUnref(fAnnotation); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1546fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint& SkPaint::operator=(const SkPaint& src) { 155f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org if (this == &src) { 156f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org return *this; 157f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org } 158f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org 159e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define COPY(field) field = src.field 160e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define REF_COPY(field) SkSafeUnref(field); field = SkSafeRef(src.field) 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 162e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org SkASSERT(&src); 16382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com 164e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fTypeface); 165e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fPathEffect); 166e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fShader); 167e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fXfermode); 168e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fMaskFilter); 169e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fColorFilter); 170e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fRasterizer); 171e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fLooper); 172e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fImageFilter); 173e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fAnnotation); 174e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 175e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSize); 176e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextScaleX); 177e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSkewX); 178e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fColor); 179e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fWidth); 180e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fMiterLimit); 181e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fBitfields); 182e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fDirtyBits); 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18456c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 185c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org fPaintOptionsAndroid.~SkPaintOptionsAndroid(); 186c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org new (&fPaintOptionsAndroid) SkPaintOptionsAndroid(src.fPaintOptionsAndroid); 187e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org ++fGenerationID; 188f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *this; 191e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 192e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef COPY 193e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef REF_COPY 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 196b265741cc17f897b349caacdb890119e4111a415robertphillips@google.combool operator==(const SkPaint& a, const SkPaint& b) { 197e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define EQUAL(field) (a.field == b.field) 198e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org // Don't check fGenerationID or fDirtyBits, which can be different for logically equal paints. 199e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org return EQUAL(fTypeface) 200e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fPathEffect) 201e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fShader) 202e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fXfermode) 203e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fMaskFilter) 204e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fColorFilter) 205e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fRasterizer) 206e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fLooper) 207e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fImageFilter) 208e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fAnnotation) 209e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextSize) 210e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextScaleX) 211e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextSkewX) 212e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fColor) 213e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fWidth) 214e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fMiterLimit) 215e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fBitfields) 216b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com#ifdef SK_BUILD_FOR_ANDROID 217e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fPaintOptionsAndroid) 218b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com#endif 219e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org ; 220e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef EQUAL 221b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com} 222b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com 2236fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::reset() { 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint init; 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22656c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 227f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com uint32_t oldGenerationID = fGenerationID; 228f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *this = init; 23056c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 231f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com fGenerationID = oldGenerationID + 1; 232f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 233f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com} 234f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 23556c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 236f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.comuint32_t SkPaint::getGenerationID() const { 237f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com return fGenerationID; 238f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com} 2394bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com 2404bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.comvoid SkPaint::setGenerationID(uint32_t generationID) { 2414bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com fGenerationID = generationID; 2424bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com} 243f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 24460abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.comunsigned SkPaint::getBaseGlyphCount(SkUnichar text) const { 245ba3284e7bbb830749206414890f8152e421969f2bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 24660abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com SkGlyphCache* cache = autoCache.getCache(); 24760abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com return cache->getBaseGlyphCount(text); 24860abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com} 249c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org 250c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.orgvoid SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) { 251c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org if (options != fPaintOptionsAndroid) { 252c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org fPaintOptionsAndroid = options; 253c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org GEN_ID_INC; 254aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits |= kPaintOptionsAndroid_DirtyBit; 255c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org } 256c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org} 25760abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com#endif 25860abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com 259c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.comvoid SkPaint::setFilterLevel(FilterLevel level) { 26085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org GEN_ID_INC_EVAL((unsigned) level != fFilterLevel); 26185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org fFilterLevel = level; 262c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.com} 263c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.com 264f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.comvoid SkPaint::setHinting(Hinting hintingLevel) { 265f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); 266f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com fHinting = hintingLevel; 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setFlags(uint32_t flags) { 270f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(fFlags != flags); 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFlags = flags; 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2746fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAntiAlias(bool doAA) { 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag)); 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2786fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setDither(bool doDither) { 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag)); 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2826fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setSubpixelText(bool doSubpixel) { 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag)); 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2866fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setLCDRenderText(bool doLCDRender) { 287309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag)); 288309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org} 289309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org 2906fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) { 291e95c91e6d9201d50d0b84fbc3d2f53f92f753e0bagl@chromium.org this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag)); 292e95c91e6d9201d50d0b84fbc3d2f53f92f753e0bagl@chromium.org} 293e95c91e6d9201d50d0b84fbc3d2f53f92f753e0bagl@chromium.org 2946fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAutohinted(bool useAutohinter) { 295a2c71cbd51da8b7767d43fe8954e7a4c674b2005agl@chromium.org this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag)); 296a2c71cbd51da8b7767d43fe8954e7a4c674b2005agl@chromium.org} 297a2c71cbd51da8b7767d43fe8954e7a4c674b2005agl@chromium.org 2986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setLinearText(bool doLinearText) { 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag)); 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 302830a23e39bb4a126e573940cd6e354732e295b10reed@google.comvoid SkPaint::setVerticalText(bool doVertical) { 303830a23e39bb4a126e573940cd6e354732e295b10reed@google.com this->setFlags(SkSetClearMask(fFlags, doVertical, kVerticalText_Flag)); 304830a23e39bb4a126e573940cd6e354732e295b10reed@google.com} 305830a23e39bb4a126e573940cd6e354732e295b10reed@google.com 3066fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setUnderlineText(bool doUnderline) { 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag)); 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3106fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrikeThruText(bool doStrikeThru) { 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag)); 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3146fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setFakeBoldText(bool doFakeBold) { 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag)); 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setDevKernText(bool doDevKern) { 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 322b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.orgvoid SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) { 323b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.org this->setFlags(SkSetClearMask(fFlags, doDistanceFieldText, kDistanceFieldTextTEMP_Flag)); 324b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.org} 325b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.org 3266fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStyle(Style style) { 3276fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)style < kStyleCount) { 328f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL((unsigned)style != fStyle); 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStyle = style; 330f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 331a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 332a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 333a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3346fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setColor(SkColor color) { 338f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(color != fColor); 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor = color; 340aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits |= kColor_DirtyBit; 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAlpha(U8CPU a) { 344f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), 345f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com SkColorGetG(fColor), SkColorGetB(fColor))); 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3486fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 349f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com this->setColor(SkColorSetARGB(a, r, g, b)); 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3526fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeWidth(SkScalar width) { 3536fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (width >= 0) { 354f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(width != fWidth); 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWidth = width; 356aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits |= kStrokeWidth_DirtyBit; 357f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 358a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 359a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); 360a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3616fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeMiter(SkScalar limit) { 3656fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (limit >= 0) { 366f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(limit != fMiterLimit); 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMiterLimit = limit; 368aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits |= kStrokeMiter_DirtyBit; 369f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 370a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 371a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 372a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3736fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3766fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeCap(Cap ct) { 3776fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)ct < kCapCount) { 378f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL((unsigned)ct != fCapType); 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCapType = SkToU8(ct); 3806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 381a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 382a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 383a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3846fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3876fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeJoin(Join jt) { 3886fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)jt < kJoinCount) { 389f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL((unsigned)jt != fJoinType); 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fJoinType = SkToU8(jt); 3916fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 392a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 393a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 394a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3956fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4006fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextAlign(Align align) { 4016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)align < kAlignCount) { 402f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL((unsigned)align != fTextAlign); 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextAlign = SkToU8(align); 4046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 405a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 406a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 407a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 4086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4116fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextSize(SkScalar ts) { 412c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (ts >= 0) { 413f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(ts != fTextSize); 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextSize = ts; 415aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits |= kTextSize_DirtyBit; 4166fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 417a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 418a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextSize() called with negative value\n"); 419a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 4206fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4236fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextScaleX(SkScalar scaleX) { 424f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(scaleX != fTextScaleX); 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextScaleX = scaleX; 426aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits |= kTextScaleX_DirtyBit; 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4296fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextSkewX(SkScalar skewX) { 430f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(skewX != fTextSkewX); 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextSkewX = skewX; 432aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits |= kTextSkewX_DirtyBit; 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4356fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextEncoding(TextEncoding encoding) { 4366fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)encoding <= kGlyphID_TextEncoding) { 437f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextEncoding = encoding; 4396fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 440a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 441a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 442a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 4436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 448aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org// Returns dst with the given bitmask enabled or disabled, depending on value. 449aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orginline static uint32_t set_mask(uint32_t dst, uint32_t bitmask, bool value) { 450aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org return value ? (dst | bitmask) : (dst & ~bitmask); 451aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 452aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 4536fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkTypeface* SkPaint::setTypeface(SkTypeface* font) { 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fTypeface, font); 455f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 456aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kTypeface_DirtyBit, font != NULL); 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return font; 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4606fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fRasterizer, r); 462f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 463aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kRasterizer_DirtyBit, r != NULL); 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return r; 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4676fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fLooper, looper); 469f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 470aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kLooper_DirtyBit, looper != NULL); 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return looper; 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 47415356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comSkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { 47515356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com SkRefCnt_SafeAssign(fImageFilter, imageFilter); 47615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com GEN_ID_INC; 477aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kImageFilter_DirtyBit, imageFilter != NULL); 47815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com return imageFilter; 47915356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com} 48015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com 481b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.comSkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { 482b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com SkRefCnt_SafeAssign(fAnnotation, annotation); 483b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com GEN_ID_INC; 484aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kAnnotation_DirtyBit, annotation != NULL); 485b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com return annotation; 486b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com} 487b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 490ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comstatic SkScalar mag2(SkScalar x, SkScalar y) { 491ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return x * x + y * y; 492ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 493ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 494ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comstatic bool tooBig(const SkMatrix& m, SkScalar ma2max) { 495ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return mag2(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewY]) > ma2max 496ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com || 497ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com mag2(m[SkMatrix::kMSkewX], m[SkMatrix::kMScaleY]) > ma2max; 498ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 499ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 500ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.combool SkPaint::TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM) { 501ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkASSERT(!ctm.hasPerspective()); 502ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkASSERT(!textM.hasPerspective()); 503ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 504ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkMatrix matrix; 505ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com matrix.setConcat(ctm, textM); 506ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return tooBig(matrix, MaxCacheSize2()); 507ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 508ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 509ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.combool SkPaint::tooBigToUseCache(const SkMatrix& ctm) const { 510ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkMatrix textM; 511ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return TooBigToUseCache(ctm, *this->setTextMatrix(&textM)); 512ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 513ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 514ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.combool SkPaint::tooBigToUseCache() const { 515ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkMatrix textM; 516ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return tooBig(*this->setTextMatrix(&textM), MaxCacheSize2()); 517ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 518ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 519ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com/////////////////////////////////////////////////////////////////////////////// 520ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGlyphCache.h" 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 52490808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.comstatic void DetachDescProc(SkTypeface* typeface, const SkDescriptor* desc, 52590808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void* context) { 52690808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(typeface, desc); 527f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com} 528f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkPaint::textToGlyphs(const void* textData, size_t byteLength, 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t glyphs[]) const { 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (byteLength == 0) { 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 53472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(textData != NULL); 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == glyphs) { 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (this->getTextEncoding()) { 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kUTF8_TextEncoding: 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkUTF8_CountUnichars((const char*)textData, byteLength); 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kUTF16_TextEncoding: 5422cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkUTF16_CountUnichars((const uint16_t*)textData, SkToInt(byteLength >> 1)); 54368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case kUTF32_TextEncoding: 5442cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 2); 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kGlyphID_TextEncoding: 5462cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 1); 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 5480c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 55272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we get here, we have a valid glyphs[] array, so time to fill it in 55472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // handle this encoding before the setup for the glyphcache 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->getTextEncoding() == kGlyphID_TextEncoding) { 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want to ignore the low bit of byteLength 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(glyphs, textData, byteLength >> 1 << 1); 5592cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 1); 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 56172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 562532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = text + byteLength; 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* gptr = glyphs; 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (this->getTextEncoding()) { 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPaint::kUTF8_TextEncoding: 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text)); 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPaint::kUTF16_TextEncoding: { 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* text16 = (const uint16_t*)text; 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* stop16 = (const uint16_t*)stop; 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text16 < stop16) { 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 58368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case kUTF32_TextEncoding: { 58468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* text32 = (const int32_t*)text; 58568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* stop32 = (const int32_t*)stop; 58668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com while (text32 < stop32) { 58768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *gptr++ = cache->unicharToGlyph(*text32++); 58868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 58968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com break; 59068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 5920c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5942cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(gptr - glyphs); 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 597a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.combool SkPaint::containsText(const void* textData, size_t byteLength) const { 598a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == byteLength) { 599a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 600a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 60172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 602a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com SkASSERT(textData != NULL); 60372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 604a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com // handle this encoding before the setup for the glyphcache 605a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (this->getTextEncoding() == kGlyphID_TextEncoding) { 606a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* glyphID = static_cast<const uint16_t*>(textData); 607a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com size_t count = byteLength >> 1; 608a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com for (size_t i = 0; i < count; i++) { 609a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == glyphID[i]) { 610a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 611a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 612a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 613a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 614a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 61572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 616532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 617a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com SkGlyphCache* cache = autoCache.getCache(); 618a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com 619a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com switch (this->getTextEncoding()) { 620a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com case SkPaint::kUTF8_TextEncoding: { 621a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const char* text = static_cast<const char*>(textData); 622a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const char* stop = text + byteLength; 623a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com while (text < stop) { 624a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) { 625a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 626a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 627a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 628a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com break; 629a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 630a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com case SkPaint::kUTF16_TextEncoding: { 631a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* text = static_cast<const uint16_t*>(textData); 632a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* stop = text + (byteLength >> 1); 633a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com while (text < stop) { 634a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) { 635a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 636a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 637a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 638a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com break; 639a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 64068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case SkPaint::kUTF32_TextEncoding: { 64168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* text = static_cast<const int32_t*>(textData); 64268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* stop = text + (byteLength >> 2); 64368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com while (text < stop) { 64468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com if (0 == cache->unicharToGlyph(*text++)) { 64568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return false; 64668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 64768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 64868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com break; 64968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 650a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com default: 6510c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 652a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 653a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 654a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 655a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com} 656a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com 6579d3a985aa3c82605346ed1518375a8c384b925e5reed@android.comvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, 6589d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkUnichar textData[]) const { 6599d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com if (count <= 0) { 6609d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com return; 6619d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com } 6629d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 6639d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkASSERT(glyphs != NULL); 6649d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkASSERT(textData != NULL); 6659d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 666532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 6679d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkGlyphCache* cache = autoCache.getCache(); 6689d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 6699d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com for (int index = 0; index < count; index++) { 6709d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com textData[index] = cache->glyphToUnichar(glyphs[index]); 6719d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com } 6729d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com} 6739d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6766fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, 6776fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 68072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6846fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, 6856fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 68872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text)); 6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6926fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, 6936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 696fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 6978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 6988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7006fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, 7016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 704fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text)); 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 70868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_next(SkGlyphCache* cache, 70968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 71068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 71168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 71268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 71368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 71468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 71568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 71668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 71768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 71868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 71968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_prev(SkGlyphCache* cache, 72068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 72168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 72268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 723fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 72468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 72568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *--ptr; 72668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 72768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 72868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 72968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 7306fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_next(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 const uint16_t* ptr = *(const uint16_t**)text; 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 7408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7426fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, 7436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 74672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr -= 1; 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7546fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, 7556fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 75872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF8_NextUnichar(text)); 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7626fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, 7636fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 76672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text)); 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7706fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, 7716fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 77472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text)); 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7786fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, 7796fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 78272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text)); 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 78668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getAdvance_utf32_next(SkGlyphCache* cache, 78768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 78868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 78968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 790fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 79168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 79268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 79368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 79468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharAdvance(uni); 79568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 79668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 79768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getAdvance_utf32_prev(SkGlyphCache* cache, 79868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 79968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 80068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 801fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 80268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 80368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *--ptr; 80468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 80568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharAdvance(uni); 80668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 80768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 8086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, 8096fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 81272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 8148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 8158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 8168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 8178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDAdvance(glyphID); 8188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8206fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, 8216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 82472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 8268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr -= 1; 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDAdvance(glyphID); 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd, 8336fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com bool needFullMetrics) const { 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const SkMeasureCacheProc gMeasureCacheProcs[] = { 8358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_next, 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_next, 83768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_next, 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_next, 83972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_prev, 8418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_prev, 84268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_prev, 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_prev, 84472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf8_next, 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf16_next, 84768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getAdvance_utf32_next, 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_glyph_next, 84972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf8_prev, 8518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf16_prev, 85268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getAdvance_utf32_prev, 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_glyph_prev 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 85572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned index = this->getTextEncoding(); 8578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8586fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (kBackward_TextBufferDirection == tbd) { 85968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com index += 4; 8606fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 8616fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!needFullMetrics && !this->isDevKernText()) { 86268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com index += 8; 8636fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 8648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs)); 8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gMeasureCacheProcs[index]; 8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache, 8726fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 8738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 87572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache, 8806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 88372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y); 8858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8876fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, 8886fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 8898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 89172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache, 8966fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 8978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 8988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 89972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text), 9018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x, y); 9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 90468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_00(SkGlyphCache* cache, 90568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text, SkFixed, SkFixed) { 90668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 90768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 908fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 90968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 91068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 91168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 91268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 91368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 91468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 91568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_xy(SkGlyphCache* cache, 91668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text, SkFixed x, SkFixed y) { 91768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 91868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 919fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 92068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 921584f337832d585e23037e59517f7bcc420424692commit-bot@chromium.org SkUnichar uni = *ptr++; 92268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 9238d38d516c0f17d8d9f6b170055ac05ac181c0554sugoi@google.com return cache->getUnicharMetrics(uni, x, y); 92468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 92568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 9266fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, 9276fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 9288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 9298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 93072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 9328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 9338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 9348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 9358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 9368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache, 9396fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 94272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 9448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 9458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 9468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 9478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID, x, y); 9488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9506fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkDrawCacheProc SkPaint::getDrawCacheProc() const { 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const SkDrawCacheProc gDrawCacheProcs[] = { 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_00, 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_00, 95468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_00, 9558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_00, 95672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_xy, 9588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_xy, 95968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_xy, 9608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_xy 9618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 96272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned index = this->getTextEncoding(); 9646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (fFlags & kSubpixelText_Flag) { 96568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com index += 4; 9666fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 96772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs)); 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gDrawCacheProcs[index]; 9708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 974ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com#define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \ 975ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kDevKernText_Flag | \ 976ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kLinearText_Flag | \ 977ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kLCDRenderText_Flag | \ 978ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kEmbeddedBitmapText_Flag | \ 979ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kAutoHinting_Flag | \ 980ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kGenA8FromLCD_Flag ) 981ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 982ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkScalar SkPaint::setupForAsPaths() { 983ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com uint32_t flags = this->getFlags(); 984ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // clear the flags we don't care about 985ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com flags &= ~TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE; 986ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // set the flags we do care about 987ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com flags |= SkPaint::kSubpixelText_Flag; 9888f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 989ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setFlags(flags); 990ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setHinting(SkPaint::kNo_Hinting); 9918f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 992ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar textSize = fTextSize; 993ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setTextSize(kCanonicalTextSizeForPaths); 994ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return textSize / kCanonicalTextSizeForPaths; 995ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 996ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 997ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comclass SkCanonicalizePaint { 9988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 999ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint(const SkPaint& paint) : fPaint(&paint), fScale(0) { 1000ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com if (paint.isLinearText() || paint.tooBigToUseCache()) { 1001ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkPaint* p = fLazy.set(paint); 1002ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com fScale = p->setupForAsPaths(); 1003ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com fPaint = p; 1004ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com } 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10066fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com 1007ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& getPaint() const { return *fPaint; } 10088f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 1009ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com /** 1010ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com * Returns 0 if the paint was unmodified, or the scale factor need to 1011ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com * the original textSize 1012ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com */ 1013ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar getScale() const { return fScale; } 101472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 10158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1016ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint* fPaint; 1017ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar fScale; 1018ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkTLazy<SkPaint> fLazy; 10198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 10208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic void set_bounds(const SkGlyph& g, SkRect* bounds) { 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->set(SkIntToScalar(g.fLeft), 10238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop), 10248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fLeft + g.fWidth), 10258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop + g.fHeight)); 10268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1028e88f551b38c2893566b7016d906b1455e43542f5reed@android.com// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so 1029e88f551b38c2893566b7016d906b1455e43542f5reed@android.com// we don't overflow along the way 1030e88f551b38c2893566b7016d906b1455e43542f5reed@android.comtypedef int64_t Sk48Dot16; 1031e88f551b38c2893566b7016d906b1455e43542f5reed@android.com 10328f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.comstatic inline float Sk48Dot16ToScalar(Sk48Dot16 x) { 10338f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com return (float) (x * 1.5258789e-5); // x * (1 / 65536.0f) 10348f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com} 1035e88f551b38c2893566b7016d906b1455e43542f5reed@android.com 103644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { 1037e88f551b38c2893566b7016d906b1455e43542f5reed@android.com SkScalar sx = Sk48Dot16ToScalar(dx); 10388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->join(SkIntToScalar(g.fLeft) + sx, 10398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop), 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fLeft + g.fWidth) + sx, 10418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop + g.fHeight)); 10428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 104444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) { 104544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkScalar sy = Sk48Dot16ToScalar(dy); 104644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com bounds->join(SkIntToScalar(g.fLeft), 104744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fTop) + sy, 104844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fLeft + g.fWidth), 104944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fTop + g.fHeight) + sy); 105044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com} 105144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 105244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comtypedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16); 105344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 105444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY 105544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic SkFixed advance(const SkGlyph& glyph, int xyIndex) { 105644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkASSERT(0 == xyIndex || 1 == xyIndex); 105744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com return (&glyph.fAdvanceX)[xyIndex]; 105844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com} 105944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkScalar SkPaint::measure_text(SkGlyphCache* cache, 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text, size_t byteLength, 10626fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com int* count, SkRect* bounds) const { 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count); 10646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (byteLength == 0) { 10658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *count = 0; 10666fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (bounds) { 10678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->setEmpty(); 10686fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 10708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMeasureCacheProc glyphCacheProc; 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection, 10748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NULL != bounds); 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 107644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com int xyIndex; 107744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com JoinBoundsProc joinBoundsProc; 107844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com if (this->isVerticalText()) { 107944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com xyIndex = 1; 108044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc = join_bounds_y; 108144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com } else { 108244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com xyIndex = 0; 108344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc = join_bounds_x; 108444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com } 108544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 10868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = 1; 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = (const char*)text + byteLength; 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph* g = &glyphCacheProc(cache, &text); 1089e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // our accumulated fixed-point advances might overflow 16.16, so we use 1090e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // a 48.16 (64bit) accumulator, and then convert that to scalar at the 1091e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // very end. 109244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com Sk48Dot16 x = advance(*g, xyIndex); 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10966fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == bounds) { 10976fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb; 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g->fRsbDelta; 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 110244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex); 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 110644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(glyphCacheProc(cache, &text), xyIndex); 11078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11096fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 11108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(*g, bounds); 11116fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 11128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb; 11138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 11148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g->fRsbDelta; 11158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 11168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += SkAutoKern_AdjustF(rsb, g->fLsbDelta); 111744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc(*g, bounds, x); 111844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(*g, xyIndex); 11198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11206fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 11218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 11228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 112344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc(*g, bounds, x); 112444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(*g, xyIndex); 11258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text == stop); 11298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *count = n; 1131e88f551b38c2893566b7016d906b1455e43542f5reed@android.com return Sk48Dot16ToScalar(x); 11328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkScalar SkPaint::measureText(const void* textData, size_t length, 11356fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkRect* bounds, SkScalar zoom) const { 11368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 11378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL || length == 0); 11388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1139ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1140ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1141ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 114272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 11436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkMatrix zoomMatrix, *zoomPtr = NULL; 11446fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (zoom) { 11458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomMatrix.setScale(zoom, zoom); 11468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomPtr = &zoomMatrix; 11478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1149ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkAutoGlyphCache autoCache(paint, NULL, zoomPtr); 11508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 11518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar width = 0; 115372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 11546fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (length > 0) { 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int tempCount; 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1157ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com width = paint.measure_text(cache, text, length, &tempCount, bounds); 11586fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width = SkScalarMul(width, scale); 11606fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (bounds) { 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fLeft = SkScalarMul(bounds->fLeft, scale); 11628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fTop = SkScalarMul(bounds->fTop, scale); 11638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fRight = SkScalarMul(bounds->fRight, scale); 11648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fBottom = SkScalarMul(bounds->fBottom, scale); 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 116746348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com } else if (bounds) { 116846348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com // ensure that even if we don't measure_text we still update the bounds 116946348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com bounds->setEmpty(); 11708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return width; 11728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef bool (*SkTextBufferPred)(const char* text, const char* stop); 11758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11766fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool forward_textBufferPred(const char* text, const char* stop) { 11778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return text < stop; 11788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool backward_textBufferPred(const char* text, const char* stop) { 11818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return text > stop; 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd, 11856fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, size_t length, 11866fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** stop) { 11876fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (SkPaint::kForward_TextBufferDirection == tbd) { 11888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *stop = *text + length; 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return forward_textBufferPred; 11906fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 11918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // text should point to the end of the buffer, and stop to the beginning 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *stop = *text; 11938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text += length; 11948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return backward_textBufferPred; 11958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth, 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar* measuredWidth, 12006fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com TextBufferDirection tbd) const { 12016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (0 == length || 0 >= maxWidth) { 12026fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (measuredWidth) { 12038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *measuredWidth = 0; 12046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 12058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 12068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1208c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (0 == fTextSize) { 1209c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (measuredWidth) { 1210c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com *measuredWidth = 0; 1211c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com } 1212c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com return length; 1213c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com } 1214c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com 12158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(textD != NULL); 12168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textD; 12178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1219ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1220ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 12218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1222ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // adjust max in case we changed the textSize in paint 1223ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com if (scale) { 1224ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com maxWidth /= scale; 12258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 122672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1227ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkAutoGlyphCache autoCache(paint, NULL, NULL); 12288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 12298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1230ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc(tbd, false); 12318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop; 12328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop); 1233ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const int xyIndex = paint.isVerticalText() ? 1 : 0; 1234e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // use 64bits for our accumulator, to avoid overflowing 16.16 1235e88f551b38c2893566b7016d906b1455e43542f5reed@android.com Sk48Dot16 max = SkScalarToFixed(maxWidth); 1236e88f551b38c2893566b7016d906b1455e43542f5reed@android.com Sk48Dot16 width = 0; 12378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 12398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12406fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 12418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb = 0; 12426fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com while (pred(text, stop)) { 12438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* curr = text; 12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 124544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex); 12466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((width += x) > max) { 12478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width -= x; 12488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text = curr; 12498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 12508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g.fRsbDelta; 12528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12536fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 12546fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com while (pred(text, stop)) { 12558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* curr = text; 125644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex); 12576fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((width += x) > max) { 12588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width -= x; 12598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text = curr; 12608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 12618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 126472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 12656fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (measuredWidth) { 1266e88f551b38c2893566b7016d906b1455e43542f5reed@android.com SkScalar scalarWidth = Sk48Dot16ToScalar(width); 12676fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 12688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scalarWidth = SkScalarMul(scalarWidth, scale); 12696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 12708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *measuredWidth = scalarWidth; 12718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 127272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 12738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return the number of bytes measured 12748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (kForward_TextBufferDirection == tbd) ? 12758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text - stop + length : stop - text + length; 12768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 12798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) { 12810a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com *(SkPaint::FontMetrics*)context = cache->getFontMetrics(); 12828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; // don't detach the cache 12838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 128590808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.comstatic void FontMetricsDescProc(SkTypeface* typeface, const SkDescriptor* desc, 128690808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void* context) { 128790808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com SkGlyphCache::VisitCache(typeface, desc, FontMetricsCacheProc, context); 12888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12906fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const { 1291ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1292ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1293ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 12948f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 12956fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkMatrix zoomMatrix, *zoomPtr = NULL; 12966fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (zoom) { 12978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomMatrix.setScale(zoom, zoom); 12988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomPtr = &zoomMatrix; 12998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FontMetrics storage; 13026fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == metrics) { 13038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics = &storage; 13046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 130572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1306ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com paint.descriptorProc(NULL, zoomPtr, FontMetricsDescProc, metrics, true); 13078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 13098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fTop = SkScalarMul(metrics->fTop, scale); 13108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 13118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 13128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 13138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 13140a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale); 13150a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXMin = SkScalarMul(metrics->fXMin, scale); 13160a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXMax = SkScalarMul(metrics->fXMax, scale); 13170a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); 13180bc406df48ac6f358ab8dcff08f71fe9c32b79decommit-bot@chromium.org metrics->fUnderlineThickness = SkScalarMul(metrics->fUnderlineThickness, scale); 13190bc406df48ac6f358ab8dcff08f71fe9c32b79decommit-bot@chromium.org metrics->fUnderlinePosition = SkScalarMul(metrics->fUnderlinePosition, scale); 13208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return metrics->fDescent - metrics->fAscent + metrics->fLeading; 13228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13246fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 13258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13266fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) { 13278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->set(g.fLeft * scale, 13288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g.fTop * scale, 13298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g.fLeft + g.fWidth) * scale, 13308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g.fTop + g.fHeight) * scale); 13318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 13328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13336fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comint SkPaint::getTextWidths(const void* textData, size_t byteLength, 13346fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar widths[], SkRect bounds[]) const { 13356fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (0 == byteLength) { 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 13376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 13388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(NULL != textData); 13408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == widths && NULL == bounds) { 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->countText(textData, byteLength); 13436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 13448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1345ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1346ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1347ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 13488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1349ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkAutoGlyphCache autoCache(paint, NULL, NULL); 13508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 13518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMeasureCacheProc glyphCacheProc; 1352ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com glyphCacheProc = paint.getMeasureCacheProc(kForward_TextBufferDirection, 13538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NULL != bounds); 13548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 13568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = text + byteLength; 13578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 1358ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const int xyIndex = paint.isVerticalText() ? 1 : 0; 13598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13606fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 13618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we adjust the widths returned here through auto-kerning 13628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 13638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed prevWidth = 0; 13648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (scale) { 13668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 13678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 13688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 13698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed adjust = autokern.adjust(g); 13708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 13728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar w = SkFixedToScalar(prevWidth + adjust); 13738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths++ = SkScalarMul(w, scale); 13748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 137544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com prevWidth = advance(g, xyIndex); 13768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 13788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++, scale); 13798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 13818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0 && widths) { 13838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale); 13848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 13868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 13878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 13888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 13898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed adjust = autokern.adjust(g); 13908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 13928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths++ = SkFixedToScalar(prevWidth + adjust); 13938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 139444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com prevWidth = advance(g, xyIndex); 13958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 13978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++); 13988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 14008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0 && widths) { 14028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths = SkFixedToScalar(prevWidth); 14038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no devkern 14068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (scale) { 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 14088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 14098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 141044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)), 14118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scale); 14128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 14148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++, scale); 14158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 14178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 14198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 14208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 14218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 142244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com *widths++ = SkFixedToScalar(advance(g, xyIndex)); 14238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 14258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++); 14268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 14288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text == stop); 14338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 14348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14366fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 14378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 14398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14406fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::getTextPath(const void* textData, size_t length, 14416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar x, SkScalar y, SkPath* path) const { 14426fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkASSERT(length == 0 || textData != NULL); 14436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com 14448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 14456fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (text == NULL || length == 0 || path == NULL) { 14468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 14476fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 14488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1449166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com SkTextToPathIter iter(text, length, *this, false); 14508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 14518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar prevXPos = 0; 14528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setScale(iter.getPathScale(), iter.getPathScale()); 14548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.postTranslate(x, y); 14558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path->reset(); 14568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar xpos; 14588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath* iterPath; 14597b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com while (iter.next(&iterPath, &xpos)) { 14608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.postTranslate(xpos - prevXPos, 0); 14617b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (iterPath) { 14627b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com path->addPath(*iterPath, matrix); 14637b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 14648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prevXPos = xpos; 14658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 14678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1468ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.comvoid SkPaint::getPosTextPath(const void* textData, size_t length, 1469ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const SkPoint pos[], SkPath* path) const { 1470ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkASSERT(length == 0 || textData != NULL); 1471ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1472ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const char* text = (const char*)textData; 1473ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com if (text == NULL || length == 0 || path == NULL) { 1474ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com return; 1475ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com } 1476ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1477ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkTextToPathIter iter(text, length, *this, false); 1478ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkMatrix matrix; 1479ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkPoint prevPos; 1480ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com prevPos.set(0, 0); 1481ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1482ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com matrix.setScale(iter.getPathScale(), iter.getPathScale()); 1483ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com path->reset(); 1484ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1485ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com unsigned int i = 0; 1486ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const SkPath* iterPath; 14877b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com while (iter.next(&iterPath, NULL)) { 1488ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); 14897b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (iterPath) { 14907b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com path->addPath(*iterPath, matrix); 14917b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 1492ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com prevPos = pos[i]; 1493ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com i++; 1494ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com } 1495ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com} 1496ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 14978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void add_flattenable(SkDescriptor* desc, uint32_t tag, 14988b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkWriteBuffer* buffer) { 14998b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), NULL)); 15008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15022739b27d7d13691603d07982ff0d6dd0658bd364reed@google.com// SkFontHost can override this choice in FilterRec() 15036fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic SkMask::Format computeMaskFormat(const SkPaint& paint) { 15048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t flags = paint.getFlags(); 15058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1506b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org // Antialiasing being disabled trumps all other settings. 150765dd8f83106ceb11fbff330bed3037557db974cfreed@google.com if (!(flags & SkPaint::kAntiAlias_Flag)) { 1508b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org return SkMask::kBW_Format; 1509f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com } 1510f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com 151165dd8f83106ceb11fbff330bed3037557db974cfreed@google.com if (flags & SkPaint::kLCDRenderText_Flag) { 1512f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com return SkMask::kLCD16_Format; 151365dd8f83106ceb11fbff330bed3037557db974cfreed@google.com } 1514b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org 1515b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org return SkMask::kA8_Format; 15168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15181cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com// if linear-text is on, then we force hinting to be off (since that's sort of 15191cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com// the point of linear-text. 15201cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.comstatic SkPaint::Hinting computeHinting(const SkPaint& paint) { 15211cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com SkPaint::Hinting h = paint.getHinting(); 15221cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com if (paint.isLinearText()) { 15231cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com h = SkPaint::kNo_Hinting; 15241cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com } 15251cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com return h; 15261cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com} 15271cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com 15281f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com// return true if the paint is just a single color (i.e. not a shader). If its 15291f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com// a shader, then we can't compute a const luminance for it :( 15301f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.comstatic bool justAColor(const SkPaint& paint, SkColor* color) { 15311f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com if (paint.getShader()) { 15321f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com return false; 15331f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 15341f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com SkColor c = paint.getColor(); 15351f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com if (paint.getColorFilter()) { 15361f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com c = paint.getColorFilter()->filterColor(c); 15371f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 15381f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com if (color) { 15391f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com *color = c; 15401f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 15411f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com return true; 15421f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com} 15431f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com 1544ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.comstatic SkColor computeLuminanceColor(const SkPaint& paint) { 1545ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com SkColor c; 1546ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com if (!justAColor(paint, &c)) { 1547ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com c = SkColorSetRGB(0x7F, 0x80, 0x7F); 1548ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com } 1549ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com return c; 1550ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com} 1551813d38b7a07957f2990ccca52ddab55fe0b1c632reed@google.com 1552dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com#define assert_byte(x) SkASSERT(0 == ((x) >> 8)) 1553dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com 15544f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com// Beyond this size, LCD doesn't appreciably improve quality, but it always 15554f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com// cost more RAM and draws slower, so we set a cap. 1556c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com#ifndef SK_MAX_SIZE_FOR_LCDTEXT 1557c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com #define SK_MAX_SIZE_FOR_LCDTEXT 48 1558c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com#endif 15594f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com 15604f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.comstatic bool tooBigForLCD(const SkScalerContext::Rec& rec) { 1561e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org SkScalar area = rec.fPost2x2[0][0] * rec.fPost2x2[1][1] - 1562e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org rec.fPost2x2[1][0] * rec.fPost2x2[0][1]; 1563e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org SkScalar size = SkScalarSqrt(SkScalarAbs(area)) * rec.fTextSize; 1564e78f7cfced5787f741d0e1a4911b2bea2dfa2f02commit-bot@chromium.org return size > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT); 15654f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com} 15664f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com 156772cf4927e503f49c4bd07369e85764ddde57071breed@google.com/* 156872cf4927e503f49c4bd07369e85764ddde57071breed@google.com * Return the scalar with only limited fractional precision. Used to consolidate matrices 156972cf4927e503f49c4bd07369e85764ddde57071breed@google.com * that vary only slightly when we create our key into the font cache, since the font scaler 157072cf4927e503f49c4bd07369e85764ddde57071breed@google.com * typically returns the same looking resuts for tiny changes in the matrix. 157172cf4927e503f49c4bd07369e85764ddde57071breed@google.com */ 1572f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkScalar sk_relax(SkScalar x) { 1573f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com int n = sk_float_round2int(x * 1024); 1574f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return n / 1024.0f; 1575f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 1576f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 157736a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.comvoid SkScalerContext::MakeRec(const SkPaint& paint, 1578532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkDeviceProperties* deviceProperties, 1579532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkMatrix* deviceMatrix, 1580532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com Rec* rec) { 15818d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); 15828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1583cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com SkTypeface* typeface = paint.getTypeface(); 1584cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com if (NULL == typeface) { 1585cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com typeface = SkTypeface::GetDefaultTypeface(); 1586cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com } 1587cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com rec->fOrigFontID = typeface->uniqueID(); 15887d26c590f6bc431a5ecf5c25619b64d058613a4dreed@google.com rec->fFontID = rec->fOrigFontID; 15898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fTextSize = paint.getTextSize(); 15908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPreScaleX = paint.getTextScaleX(); 15918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPreSkewX = paint.getTextSkewX(); 15928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (deviceMatrix) { 1594f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX()); 1595f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX()); 1596f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY()); 1597f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY()); 15986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 15998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 16008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0; 16018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 160272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 16038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::Style style = paint.getStyle(); 16048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar strokeWidth = paint.getStrokeWidth(); 160572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1606ffe49f5380dd5062073efeda70f2f91682c828careed@google.com unsigned flags = 0; 16074526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org 16086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isFakeBoldText()) { 16094526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#ifdef SK_USE_FREETYPE_EMBOLDEN 16104526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org flags |= SkScalerContext::kEmbolden_Flag; 16114526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#else 161228be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(), 161328be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpKeys, 161428be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpValues, 161528be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpLength); 16168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale); 161772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 16186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style == SkPaint::kFill_Style) { 16198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = SkPaint::kStrokeAndFill_Style; 16208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com strokeWidth = extra; // ignore paint's strokeWidth if it was "fill" 16216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 16228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com strokeWidth += extra; 16236fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 16244526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#endif 16258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16276fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isDevKernText()) { 16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkScalerContext::kDevKernText_Flag; 16296fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 163072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 16316fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style != SkPaint::kFill_Style && strokeWidth > 0) { 16328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fFrameWidth = strokeWidth; 16338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fMiterLimit = paint.getStrokeMiter(); 16348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fStrokeJoin = SkToU8(paint.getStrokeJoin()); 16358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16366fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style == SkPaint::kStrokeAndFill_Style) { 16378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkScalerContext::kFrameAndFill_Flag; 16386fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 16396fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 16408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fFrameWidth = 0; 16418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fMiterLimit = 0; 16428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fStrokeJoin = 0; 16438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 164502b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); 164602b5331078861b02b61e9a93f845617a7c900409reed@google.com 1647532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkDeviceProperties::Geometry geometry = deviceProperties 1648532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com ? deviceProperties->fGeometry 1649532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com : SkDeviceProperties::Geometry::MakeDefault(); 1650532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (SkMask::kLCD16_Format == rec->fMaskFormat || SkMask::kLCD32_Format == rec->fMaskFormat) { 1651532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (!geometry.isOrientationKnown() || !geometry.isLayoutKnown() || tooBigForLCD(*rec)) { 165202b5331078861b02b61e9a93f845617a7c900409reed@google.com // eeek, can't support LCD 165302b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fMaskFormat = SkMask::kA8_Format; 165402b5331078861b02b61e9a93f845617a7c900409reed@google.com } else { 1655532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (SkDeviceProperties::Geometry::kVertical_Orientation == geometry.getOrientation()) { 165602b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kLCD_Vertical_Flag; 165702b5331078861b02b61e9a93f845617a7c900409reed@google.com } 1658532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (SkDeviceProperties::Geometry::kBGR_Layout == geometry.getLayout()) { 165902b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kLCD_BGROrder_Flag; 166002b5331078861b02b61e9a93f845617a7c900409reed@google.com } 166102b5331078861b02b61e9a93f845617a7c900409reed@google.com } 166202b5331078861b02b61e9a93f845617a7c900409reed@google.com } 166302b5331078861b02b61e9a93f845617a7c900409reed@google.com 16646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isEmbeddedBitmapText()) { 166502b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kEmbeddedBitmapText_Flag; 16666fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 16676fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isSubpixelText()) { 166802b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kSubpixelPositioning_Flag; 16696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 16706fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isAutohinted()) { 1671f6f56878bc96386882721b15ba610984185d3dc9bungeman@google.com flags |= SkScalerContext::kForceAutohinting_Flag; 16726fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 1673830a23e39bb4a126e573940cd6e354732e295b10reed@google.com if (paint.isVerticalText()) { 1674830a23e39bb4a126e573940cd6e354732e295b10reed@google.com flags |= SkScalerContext::kVertical_Flag; 1675830a23e39bb4a126e573940cd6e354732e295b10reed@google.com } 16768351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { 16778351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com flags |= SkScalerContext::kGenA8FromLCD_Flag; 16788351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com } 167902b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fFlags = SkToU16(flags); 168036a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com 1681ffe49f5380dd5062073efeda70f2f91682c828careed@google.com // these modify fFlags, so do them after assigning fFlags 16829d7576724cf9602ff778b18126e0fef0ab3d3bf2reed@google.com rec->setHinting(computeHinting(paint)); 168397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 1684ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com rec->setLuminanceColor(computeLuminanceColor(paint)); 1685532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1686532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (NULL == deviceProperties) { 1687532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setDeviceGamma(SK_GAMMA_EXPONENT); 1688532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setPaintGamma(SK_GAMMA_EXPONENT); 1689532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com } else { 1690532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setDeviceGamma(deviceProperties->fGamma); 1691532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1692532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //For now always set the paint gamma equal to the device gamma. 1693532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //The math in SkMaskGamma can handle them being different, 1694532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //but it requires superluminous masks when 1695532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large. 1696532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setPaintGamma(deviceProperties->fGamma); 1697532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com } 1698532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1699532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#ifdef SK_GAMMA_CONTRAST 1700532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setContrast(SK_GAMMA_CONTRAST); 1701ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com#else 1702532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com /** 1703532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise. 1704532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * With lower values small text appears washed out (though correctly so). 1705532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * With higher values lcd fringing is worse and the smoothing effect of 1706532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * partial coverage is diminished. 1707532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com */ 17084b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org rec->setContrast(0.5f); 1709ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com#endif 1710532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 17112bf82d843d8896dd10bb86adc1e974c6d52324e6bungeman@google.com rec->fReservedAlign = 0; 1712fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 171336a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com /* Allow the fonthost to modify our rec before we use it as a key into the 171436a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com cache. This way if we're asking for something that they will ignore, 171536a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com they can modify our rec up front, so we don't create duplicate cache 171636a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com entries. 171736a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com */ 1718fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com typeface->onFilterRec(rec); 17193e8ae5b457558435218a864dd0e852f83abfe802reed@google.com 172010d2d4d1062ef56526f187e6716c5e747689b598reed@google.com // be sure to call PostMakeRec(rec) before you actually use it! 172110d2d4d1062ef56526f187e6716c5e747689b598reed@google.com} 172210d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 172310d2d4d1062ef56526f187e6716c5e747689b598reed@google.com/** 172497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * In order to call cachedDeviceLuminance, cachedPaintLuminance, or 172597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * cachedMaskGamma the caller must hold the gMaskGammaCacheMutex and continue 172697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * to hold it until the returned pointer is refed or forgotten. 172710d2d4d1062ef56526f187e6716c5e747689b598reed@google.com */ 172897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.comSK_DECLARE_STATIC_MUTEX(gMaskGammaCacheMutex); 172910d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 1730ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.comstatic SkMaskGamma* gLinearMaskGamma = NULL; 1731b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkMaskGamma* gMaskGamma = NULL; 1732b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gContrast = SK_ScalarMin; 1733b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gPaintGamma = SK_ScalarMin; 1734b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gDeviceGamma = SK_ScalarMin; 173597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 173697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * The caller must hold the gMaskGammaCacheMutex and continue to hold it until 173797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * the returned SkMaskGamma pointer is refed or forgotten. 173897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 1739a76de72a6036da0a6b051b14411b80941971f881bungeman@google.comstatic const SkMaskGamma& cachedMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) { 1740b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein gMaskGammaCacheMutex.assertHeld(); 1741ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com if (0 == contrast && SK_Scalar1 == paintGamma && SK_Scalar1 == deviceGamma) { 1742ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com if (NULL == gLinearMaskGamma) { 1743ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com gLinearMaskGamma = SkNEW(SkMaskGamma); 1744ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com } 1745a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return *gLinearMaskGamma; 1746ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com } 174797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com if (gContrast != contrast || gPaintGamma != paintGamma || gDeviceGamma != deviceGamma) { 174897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkSafeUnref(gMaskGamma); 1749b1a72cb90a9b515978bc9abda1f267f31a544e08bungeman@google.com gMaskGamma = SkNEW_ARGS(SkMaskGamma, (contrast, paintGamma, deviceGamma)); 175097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gContrast = contrast; 175197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gPaintGamma = paintGamma; 175297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gDeviceGamma = deviceGamma; 175397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com } 1754a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return *gMaskGamma; 175597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com} 175697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 1757b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com/*static*/ void SkPaint::Term() { 1758b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 1759b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com 1760ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com SkSafeUnref(gLinearMaskGamma); 17615987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com gLinearMaskGamma = NULL; 1762b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkSafeUnref(gMaskGamma); 17635987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com gMaskGamma = NULL; 1764b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gContrast = SK_ScalarMin;) 1765b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gPaintGamma = SK_ScalarMin;) 1766b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gDeviceGamma = SK_ScalarMin;) 1767b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com} 1768b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com 176997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 177097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * We ensure that the rec is self-consistent and efficient (where possible) 177197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 17728d38d516c0f17d8d9f6b170055ac05ac181c0554sugoi@google.comvoid SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) { 177310d2d4d1062ef56526f187e6716c5e747689b598reed@google.com /** 177410d2d4d1062ef56526f187e6716c5e747689b598reed@google.com * If we're asking for A8, we force the colorlum to be gray, since that 177597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * limits the number of unique entries, and the scaler will only look at 177697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * the lum of one of them. 177710d2d4d1062ef56526f187e6716c5e747689b598reed@google.com */ 1778dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com switch (rec->fMaskFormat) { 1779dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kLCD16_Format: 1780dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kLCD32_Format: { 1781dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // filter down the luminance color to a finite number of bits 178297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkColor color = rec->getLuminanceColor(); 1783b5715a1c8003e4a8af2301ab44aeef043547808ereed@google.com rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color)); 1784dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 1785dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com } 1786dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kA8_Format: { 1787dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // filter down the luminance to a single component, since A8 can't 1788dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // use per-component information 1789fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 179097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkColor color = rec->getLuminanceColor(); 1791b1a72cb90a9b515978bc9abda1f267f31a544e08bungeman@google.com U8CPU lum = SkColorSpaceLuminance::computeLuminance(rec->getPaintGamma(), color); 1792fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.com //If we are asked to look like LCD, look like LCD. 1793fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.com if (!(rec->fFlags & SkScalerContext::kGenA8FromLCD_Flag)) { 1794fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.com // HACK: Prevents green from being pre-blended as white. 1795fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.com lum -= ((255 - lum) * lum) / 255; 1796fd668cfffe3fdcfbf6e0b858343a62818d337590bungeman@google.com } 1797fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1798dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // reduce to our finite number of bits 179997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com color = SkColorSetRGB(lum, lum, lum); 1800b5715a1c8003e4a8af2301ab44aeef043547808ereed@google.com rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color)); 1801dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 1802dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com } 1803dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kBW_Format: 1804dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // No need to differentiate gamma if we're BW 1805532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->ignorePreBlend(); 1806dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 18073e8ae5b457558435218a864dd0e852f83abfe802reed@google.com } 18088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 18098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MIN_SIZE_FOR_EFFECT_BUFFER 1024 18118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 181217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#ifdef SK_DEBUG 181317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com #define TEST_DESC 181417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#endif 181517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com 1816ffe49f5380dd5062073efeda70f2f91682c828careed@google.com/* 1817ffe49f5380dd5062073efeda70f2f91682c828careed@google.com * ignoreGamma tells us that the caller just wants metrics that are unaffected 18182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, 18192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth * contrast = 0, luminanceColor = transparent black. 1820ffe49f5380dd5062073efeda70f2f91682c828careed@google.com */ 1821532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.comvoid SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, 1822532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkMatrix* deviceMatrix, 182390808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void (*proc)(SkTypeface*, const SkDescriptor*, void*), 182457f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com void* context, bool ignoreGamma) const { 18258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalerContext::Rec rec; 18268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1827532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkScalerContext::MakeRec(*this, deviceProperties, deviceMatrix, &rec); 182857f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com if (ignoreGamma) { 18292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth rec.ignorePreBlend(); 183057f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 18318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com size_t descSize = sizeof(rec); 18338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int entryCount = 1; 18348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect* pe = this->getPathEffect(); 18358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMaskFilter* mf = this->getMaskFilter(); 18368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRasterizer* ra = this->getRasterizer(); 18378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18388b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkWriteBuffer peBuffer, mfBuffer, raBuffer; 18398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pe) { 18418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com peBuffer.writeFlattenable(pe); 18428b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org descSize += peBuffer.bytesWritten(); 18438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 18448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 18458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // seems like we could support kLCD as well at this point... 18468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mf) { 18488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mfBuffer.writeFlattenable(mf); 18498b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org descSize += mfBuffer.bytesWritten(); 18508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 18518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters 1852a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com /* Pre-blend is not currently applied to filtered text. 1853a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com The primary filter is blur, for which contrast makes no sense, 1854a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com and for which the destination guess error is more visible. 1855a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com Also, all existing users of blur have calibrated for linear. */ 1856a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.ignorePreBlend(); 18578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ra) { 18598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com raBuffer.writeFlattenable(ra); 18608b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org descSize += raBuffer.bytesWritten(); 18618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 18628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec.fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 18638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 186410d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 1865c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 18668b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkWriteBuffer androidBuffer; 1867c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org fPaintOptionsAndroid.flatten(androidBuffer); 18688b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org descSize += androidBuffer.bytesWritten(); 1869c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org entryCount += 1; 1870c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#endif 1871c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org 187210d2d4d1062ef56526f187e6716c5e747689b598reed@google.com /////////////////////////////////////////////////////////////////////////// 187310d2d4d1062ef56526f187e6716c5e747689b598reed@google.com // Now that we're done tweaking the rec, call the PostMakeRec cleanup 187497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkScalerContext::PostMakeRec(*this, &rec); 1875fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 18768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com descSize += SkDescriptor::ComputeOverhead(entryCount); 18778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoDescriptor ad(descSize); 18798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDescriptor* desc = ad.getDesc(); 18808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->init(); 18828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 18838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1884c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 1885c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org add_flattenable(desc, kAndroidOpts_SkDescriptorTag, &androidBuffer); 1886c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#endif 1887c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org 18888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pe) { 18898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer); 18908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mf) { 18928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer); 18938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ra) { 18958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer); 18968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 18978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(descSize == desc->getLength()); 18998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->computeChecksum(); 19008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 190117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#ifdef TEST_DESC 190217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com { 190317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // Check that we completely write the bytes in desc (our key), and that 190417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // there are no uninitialized bytes. If there were, then we would get 190517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // false-misses (or worse, false-hits) in our fontcache. 190617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // 190717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // We do this buy filling 2 others, one with 0s and the other with 1s 190817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com // and create those, and then check that all 3 are identical. 190917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkAutoDescriptor ad1(descSize); 191017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkAutoDescriptor ad2(descSize); 191117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkDescriptor* desc1 = ad1.getDesc(); 191217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkDescriptor* desc2 = ad2.getDesc(); 1913fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 191417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com memset(desc1, 0x00, descSize); 191517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com memset(desc2, 0xFF, descSize); 1916fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 191717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc1->init(); 191817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc2->init(); 191917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 192017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 1921fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1922c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 1923c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org add_flattenable(desc1, kAndroidOpts_SkDescriptorTag, &androidBuffer); 1924c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org add_flattenable(desc2, kAndroidOpts_SkDescriptorTag, &androidBuffer); 1925c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org#endif 1926c7a20e40938ae031368e3a9e4df33ce90a765abacommit-bot@chromium.org 192717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com if (pe) { 192817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer); 192917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer); 193017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 193117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com if (mf) { 193217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer); 193317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer); 193417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 193517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com if (ra) { 193617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer); 193717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer); 193817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 1939fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 194017fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(descSize == desc1->getLength()); 194117fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(descSize == desc2->getLength()); 194217fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc1->computeChecksum(); 194317fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com desc2->computeChecksum(); 194417fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(!memcmp(desc, desc1, descSize)); 194517fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com SkASSERT(!memcmp(desc, desc2, descSize)); 194617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com } 194717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#endif 1948fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 194990808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com proc(fTypeface, desc, context); 19508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1952532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.comSkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties, 19532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMatrix* deviceMatrix, 19542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth bool ignoreGamma) const { 19558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache; 19562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, ignoreGamma); 19578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache; 19588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 196097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 196197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-blend. 196297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 196397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com//static 196497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.comSkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Rec& rec) { 196597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 1966a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com const SkMaskGamma& maskGamma = cachedMaskGamma(rec.getContrast(), 1967a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.getPaintGamma(), 1968a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.getDeviceGamma()); 1969a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return maskGamma.preBlend(rec.getLuminanceColor()); 197097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com} 197197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 19722d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthsize_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, 19732d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkScalar deviceGamma, int* width, int* height) { 19742d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 19752d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, 19762d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth paintGamma, 19772d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth deviceGamma); 19782d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19792d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth maskGamma.getGammaTableDimensions(width, height); 19802d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth size_t size = (*width)*(*height)*sizeof(uint8_t); 19812d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19822d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth return size; 19832d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth} 19842d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthvoid SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, 19862d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth void* data) { 19872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 19882d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, 19892d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth paintGamma, 19902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth deviceGamma); 19912d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth int width, height; 19922d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth maskGamma.getGammaTableDimensions(&width, &height); 19932d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth size_t size = width*height*sizeof(uint8_t); 19942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const uint8_t* gammaTables = maskGamma.getGammaTables(); 19952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth memcpy(data, gammaTables, size); 19962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth} 19972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19982d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 19998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 20008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 20028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2003aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uintptr_t asint(const void* p) { 2004aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return reinterpret_cast<uintptr_t>(p); 2005aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 2006aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2007aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comunion Scalar32 { 2008aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkScalar fScalar; 2009aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com uint32_t f32; 2010aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com}; 2011aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2012aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) { 2013aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 2014aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com Scalar32 tmp; 2015aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com tmp.fScalar = value; 2016aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com *ptr = tmp.f32; 2017aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return ptr + 1; 2018aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 2019aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2020aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic SkScalar read_scalar(const uint32_t*& ptr) { 2021aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 2022aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com Scalar32 tmp; 2023aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com tmp.f32 = *ptr++; 2024aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return tmp.fScalar; 2025aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 2026aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2027aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { 2028aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(a == (uint8_t)a); 2029aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(b == (uint8_t)b); 2030aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(c == (uint8_t)c); 2031aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(d == (uint8_t)d); 2032aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return (a << 24) | (b << 16) | (c << 8) | d; 2033aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 2034aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 203585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#ifdef SK_DEBUG 203685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org static void ASSERT_FITS_IN(uint32_t value, int bitCount) { 203785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org SkASSERT(bitCount > 0 && bitCount <= 32); 203885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t mask = ~0U; 203985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org mask >>= (32 - bitCount); 204085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org SkASSERT(0 == (value & ~mask)); 204185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 204285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#else 204385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org #define ASSERT_FITS_IN(value, bitcount) 204485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#endif 204585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 2046aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comenum FlatFlags { 204797f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org kHasTypeface_FlatFlag = 0x01, 204897f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org kHasEffects_FlatFlag = 0x02, 204997f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org kHasNonDefaultPaintOptionsAndroid_FlatFlag = 0x04, 2050667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com 205185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlatFlagMask = 0x7, 205285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org}; 205385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 205485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgenum BitsPerField { 205585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlags_BPF = 16, 205685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kHint_BPF = 2, 205785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kAlign_BPF = 2, 205885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFilter_BPF = 2, 205985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlatFlags_BPF = 3, 2060aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com}; 2061aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 206285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic inline int BPF_Mask(int bits) { 206385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (1 << bits) - 1; 206485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 206585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 206685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align, 206785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org unsigned filter, unsigned flatFlags) { 206885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(flags, kFlags_BPF); 206985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(hint, kHint_BPF); 207085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(align, kAlign_BPF); 207185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(filter, kFilter_BPF); 207285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(flatFlags, kFlatFlags_BPF); 207385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 207485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly 207585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // add more bits in the future. 207685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (flags << 16) | (hint << 14) | (align << 12) | (filter << 10) | flatFlags; 207785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 207885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 207985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) { 208085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFlags(packed >> 16); 208185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF))); 208285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF))); 208385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFilterLevel((SkPaint::FilterLevel)((packed >> 10) & BPF_Mask(kFilter_BPF))); 208485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (FlatFlags)(packed & kFlatFlagMask); 208585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 208685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 208785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org// V22_COMPATIBILITY_CODE 208885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic FlatFlags unpack_paint_flags_v22(SkPaint* paint, uint32_t packed) { 208985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org enum { 209085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFilterBitmap_Flag = 0x02, 209185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kHighQualityFilterBitmap_Flag = 0x4000, 2092667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com 209385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kAll_Flags = kFilterBitmap_Flag | kHighQualityFilterBitmap_Flag 209485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org }; 209585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 209685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // previously flags:16, textAlign:8, flatFlags:8 209785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // now flags:16, hinting:4, textAlign:4, flatFlags:8 209885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org unsigned flags = packed >> 16; 209985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org int filter = 0; 210085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org if (flags & kFilterBitmap_Flag) { 210185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org filter |= 1; 210285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 210385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org if (flags & kHighQualityFilterBitmap_Flag) { 210485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org filter |= 2; 210585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 210685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFilterLevel((SkPaint::FilterLevel)filter); 210785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org flags &= ~kAll_Flags; // remove these (now dead) bit flags 210885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 210985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFlags(flags); 2110667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com 211185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // hinting added later. 0 in this nibble means use the default. 211285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t hinting = (packed >> 12) & 0xF; 211385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setHinting(0 == hinting ? SkPaint::kNormal_Hinting : static_cast<SkPaint::Hinting>(hinting-1)); 211485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setTextAlign(static_cast<SkPaint::Align>((packed >> 8) & 0xF)); 211585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (FlatFlags)(packed & kFlatFlagMask); 211685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 211785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 2118aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com// The size of a flat paint's POD fields 2119d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comstatic const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + 21201f1543f012b8834ea760175a023eb127bde2b895reed@google.com 1 * sizeof(SkColor) + 21211f1543f012b8834ea760175a023eb127bde2b895reed@google.com 1 * sizeof(uint16_t) + 21221f1543f012b8834ea760175a023eb127bde2b895reed@google.com 6 * sizeof(uint8_t); 2123aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2124aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com/* To save space/time, we analyze the paint, and write a truncated version of 2125aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com it if there are not tricky elements like shaders, etc. 2126aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com */ 21278b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPaint::flatten(SkWriteBuffer& buffer) const { 2128aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com uint8_t flatFlags = 0; 2129aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (this->getTypeface()) { 2130aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com flatFlags |= kHasTypeface_FlatFlag; 2131aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 2132aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (asint(this->getPathEffect()) | 2133aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getShader()) | 2134aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getXfermode()) | 2135aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getMaskFilter()) | 2136aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getColorFilter()) | 2137aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getRasterizer()) | 213854e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org asint(this->getLooper()) | 2139b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com asint(this->getAnnotation()) | 214054e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org asint(this->getImageFilter())) { 2141aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com flatFlags |= kHasEffects_FlatFlag; 2142aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 214380f3fcd2554c39987323946306ff32273164ea6acommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 214497f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org if (this->getPaintOptionsAndroid() != SkPaintOptionsAndroid()) { 214597f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org flatFlags |= kHasNonDefaultPaintOptionsAndroid_FlatFlag; 214697f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org } 214797f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org#endif 2148c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com 21498b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 21508b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org uint32_t* ptr = buffer.reserve(kPODPaintSize); 21518b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 21528b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextSize()); 21538b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextScaleX()); 21548b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextSkewX()); 21558b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getStrokeWidth()); 21568b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getStrokeMiter()); 21578b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *ptr++ = this->getColor(); 215885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 215985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org *ptr++ = pack_paint_flags(this->getFlags(), this->getHinting(), this->getTextAlign(), 216085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org this->getFilterLevel(), flatFlags); 21618b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(), 21628b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->getStyle(), this->getTextEncoding()); 2163aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2164aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com // now we're done with ptr and the (pre)reserved space. If we need to write 2165aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com // additional fields, use the buffer directly 2166aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasTypeface_FlatFlag) { 2167aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeTypeface(this->getTypeface()); 2168aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 2169aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasEffects_FlatFlag) { 2170aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getPathEffect()); 2171aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getShader()); 2172aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getXfermode()); 2173aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getMaskFilter()); 2174aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getColorFilter()); 2175aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getRasterizer()); 2176aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getLooper()); 217754e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org buffer.writeFlattenable(this->getImageFilter()); 21780cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com 21790cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com if (fAnnotation) { 21800cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com buffer.writeBool(true); 21810cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com fAnnotation->writeToBuffer(buffer); 21820cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } else { 21830cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com buffer.writeBool(false); 21840cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } 2185aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 218680f3fcd2554c39987323946306ff32273164ea6acommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 218797f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org if (flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) { 218897f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org this->getPaintOptionsAndroid().flatten(buffer); 218997f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org } 219097f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org#endif 21918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21938b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPaint::unflatten(SkReadBuffer& buffer) { 21948b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 21958b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org const void* podData = buffer.skip(kPODPaintSize); 21968b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); 21978b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 21988b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org // the order we read must match the order we wrote in flatten() 21998b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextSize(read_scalar(pod)); 22008b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextScaleX(read_scalar(pod)); 22018b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextSkewX(read_scalar(pod)); 22028b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeWidth(read_scalar(pod)); 22038b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeMiter(read_scalar(pod)); 22048b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setColor(*pod++); 22058b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 220685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org unsigned flatFlags = 0; 22077ed173b1ebac84671fb0dc1b9bd323a5e6e63771commit-bot@chromium.org if (buffer.isVersionLT(SkReadBuffer::kFilterLevelIsEnum_Version)) { 220885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org flatFlags = unpack_paint_flags_v22(this, *pod++); 220985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } else { 221085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org flatFlags = unpack_paint_flags(this, *pod++); 221185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 22128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 221385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t tmp = *pod++; 22148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); 22158b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); 22168b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); 22178b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); 2218aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2219aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasTypeface_FlatFlag) { 2220aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setTypeface(buffer.readTypeface()); 2221aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } else { 2222aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setTypeface(NULL); 2223aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 2224aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 2225aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasEffects_FlatFlag) { 2226353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setPathEffect(buffer.readPathEffect())); 2227353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setShader(buffer.readShader())); 2228353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setXfermode(buffer.readXfermode())); 2229353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setMaskFilter(buffer.readMaskFilter())); 2230353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setColorFilter(buffer.readColorFilter())); 2231353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setRasterizer(buffer.readRasterizer())); 2232353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setLooper(buffer.readDrawLooper())); 2233353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setImageFilter(buffer.readImageFilter())); 2234fbc58a305518fe611113a51649bf557c991ac8cfskia.committer@gmail.com 22350cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com if (buffer.readBool()) { 2236d957984c1efbd18f3b2bbeca78d282837c5a2ae1commit-bot@chromium.org this->setAnnotation(SkAnnotation::Create(buffer))->unref(); 22370cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } 2238aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } else { 2239aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setPathEffect(NULL); 2240aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setShader(NULL); 2241aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setXfermode(NULL); 2242aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setMaskFilter(NULL); 2243aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setColorFilter(NULL); 2244aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setRasterizer(NULL); 2245aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setLooper(NULL); 224654e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org this->setImageFilter(NULL); 2247aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 224897f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org 224980f3fcd2554c39987323946306ff32273164ea6acommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 225097f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org this->setPaintOptionsAndroid(SkPaintOptionsAndroid()); 225197f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org#endif 225297f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org if (flatFlags & kHasNonDefaultPaintOptionsAndroid_FlatFlag) { 225397f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org SkPaintOptionsAndroid options; 225497f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org options.unflatten(buffer); 225580f3fcd2554c39987323946306ff32273164ea6acommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 225697f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org this->setPaintOptionsAndroid(options); 225797f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org#endif 225897f8167622473edf2e4262fa619883e616574c19commit-bot@chromium.org } 22598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 22628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 226382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkShader* SkPaint::setShader(SkShader* shader) { 2264f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(shader != fShader); 22658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fShader, shader); 2266aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kShader_DirtyBit, shader != NULL); 22678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return shader; 22688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 227082065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { 2271f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(filter != fColorFilter); 22728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fColorFilter, filter); 2273aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kColorFilter_DirtyBit, filter != NULL); 22748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 22758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 227782065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkXfermode* SkPaint::setXfermode(SkXfermode* mode) { 2278f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(mode != fXfermode); 22798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fXfermode, mode); 2280aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, mode != NULL); 22818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mode; 22828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22840baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.comSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { 2285d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com SkSafeUnref(fXfermode); 2286d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com fXfermode = SkXfermode::Create(mode); 2287f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC; 2288aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, fXfermode != NULL); 2289d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com return fXfermode; 2290d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com} 2291d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com 229282065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { 2293f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(effect != fPathEffect); 22948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fPathEffect, effect); 2295aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kPathEffect_DirtyBit, effect != NULL); 22968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return effect; 22978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 229982065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { 2300f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com GEN_ID_INC_EVAL(filter != fMaskFilter); 23018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMaskFilter, filter); 2302aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fDirtyBits = set_mask(fDirtyBits, kMaskFilter_DirtyBit, filter != NULL); 23038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 23048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 230682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 23078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23084bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.combool SkPaint::getFillPath(const SkPath& src, SkPath* dst, 23094bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com const SkRect* cullRect) const { 2310fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com SkStrokeRec rec(*this); 23118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2312fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com const SkPath* srcPtr = &src; 2313fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com SkPath tmpPath; 231472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 23154bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com if (fPathEffect && fPathEffect->filterPath(&tmpPath, src, &rec, cullRect)) { 2316fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com srcPtr = &tmpPath; 23178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2319fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com if (!rec.applyToPath(dst, *srcPtr)) { 2320fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com if (srcPtr == &tmpPath) { 2321fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // If path's were copy-on-write, this trick would not be needed. 2322fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // As it is, we want to save making a deep-copy from tmpPath -> dst 2323fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // since we know we're just going to delete tmpPath when we return, 2324fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // so the swap saves that copy. 2325fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com dst->swap(tmpPath); 2326fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com } else { 2327fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com *dst = *srcPtr; 2328d3521f1a8dc07fe84d6a8f2151b0c176ff1ec8careed@google.com } 2329d3521f1a8dc07fe84d6a8f2151b0c176ff1ec8careed@google.com } 2330fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com return !rec.isHairlineStyle(); 23318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2333e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.comconst SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc, 2334a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com SkRect* storage, 2335a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com Style style) const { 23368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(storage); 23379efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2338e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com const SkRect* src = &origSrc; 2339e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 23409efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (this->getLooper()) { 23419efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkASSERT(this->getLooper()->canComputeFastBounds(*this)); 2342e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com this->getLooper()->computeFastBounds(*this, *src, storage); 23439efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com return *storage; 23449efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 23459efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2346e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com SkRect tmpSrc; 2347e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com if (this->getPathEffect()) { 2348e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com this->getPathEffect()->computeFastBounds(&tmpSrc, origSrc); 2349e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com src = &tmpSrc; 2350e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com } 2351e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 2352a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (kFill_Style != style) { 23539efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com // since we're stroked, outset the rect by the radius (and join type) 23549efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkScalar radius = SkScalarHalf(this->getStrokeWidth()); 23559efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (0 == radius) { // hairline 23569efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com radius = SK_Scalar1; 23579efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { 23589efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkScalar scale = this->getStrokeMiter(); 23599efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (scale > SK_Scalar1) { 23609efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com radius = SkScalarMul(radius, scale); 23619efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 23628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2363e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com storage->set(src->fLeft - radius, src->fTop - radius, 2364e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com src->fRight + radius, src->fBottom + radius); 23659efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } else { 2366e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com *storage = *src; 23678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23689efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 23699efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (this->getMaskFilter()) { 23709efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com this->getMaskFilter()->computeFastBounds(*storage, storage); 23719efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 23729efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2373336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (this->getImageFilter()) { 2374336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org this->getImageFilter()->computeFastBounds(*storage, storage); 2375336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 2376336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 2377d252db03d9650013b545ef9781fe993c07f8f314reed@android.com return *storage; 23788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23800f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 2381791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.comvoid SkPaint::toString(SkString* str) const { 2382791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dl><dt>SkPaint:</dt><dd><dl>"); 2383791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2384791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkTypeface* typeface = this->getTypeface(); 2385791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != typeface) { 2386791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkDynamicMemoryWStream ostream; 2387791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com typeface->serialize(&ostream); 2388791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAutoTUnref<SkData> data(ostream.copyToData()); 2389791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2390791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkMemoryStream stream(data); 2391791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkFontDescriptor descriptor(&stream); 2392791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2393791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Font Family Name:</dt><dd>"); 2394791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFamilyName()); 2395791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font Full Name:</dt><dd>"); 2396791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFullName()); 2397791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font PS Name:</dt><dd>"); 2398791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getPostscriptName()); 2399791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font File Name:</dt><dd>"); 2400791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFontFileName()); 2401791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2402791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2403791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2404791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextSize:</dt><dd>"); 2405791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextSize()); 2406791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2407791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2408791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextScaleX:</dt><dd>"); 2409791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextScaleX()); 2410791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2411791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2412791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextSkewX:</dt><dd>"); 2413791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextSkewX()); 2414791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2415791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2416791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkPathEffect* pathEffect = this->getPathEffect(); 2417791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != pathEffect) { 2418791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>PathEffect:</dt><dd>"); 2419791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2420791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2421791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2422791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkShader* shader = this->getShader(); 2423791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != shader) { 2424791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Shader:</dt><dd>"); 24251202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com shader->toString(str); 2426791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2427791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2428791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2429791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkXfermode* xfer = this->getXfermode(); 2430791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != xfer) { 2431791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Xfermode:</dt><dd>"); 24321202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com xfer->toString(str); 2433791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2434791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2435791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2436791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkMaskFilter* maskFilter = this->getMaskFilter(); 2437791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != maskFilter) { 2438791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>MaskFilter:</dt><dd>"); 24391202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com maskFilter->toString(str); 2440791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2441791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2442791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2443791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkColorFilter* colorFilter = this->getColorFilter(); 2444791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != colorFilter) { 2445791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>ColorFilter:</dt><dd>"); 24461202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com colorFilter->toString(str); 2447791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2448791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2449791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2450791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkRasterizer* rasterizer = this->getRasterizer(); 2451791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != rasterizer) { 2452791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Rasterizer:</dt><dd>"); 2453791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2454791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2455791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2456791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkDrawLooper* looper = this->getLooper(); 2457791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != looper) { 2458791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>DrawLooper:</dt><dd>"); 24591202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com looper->toString(str); 2460791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2461791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2462791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2463791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkImageFilter* imageFilter = this->getImageFilter(); 2464791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != imageFilter) { 2465791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>ImageFilter:</dt><dd>"); 2466791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2467791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2468791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2469791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAnnotation* annotation = this->getAnnotation(); 2470791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (NULL != annotation) { 2471791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Annotation:</dt><dd>"); 2472791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2473791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2474791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2475791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Color:</dt><dd>0x"); 2476791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkColor color = this->getColor(); 2477791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendHex(color); 2478791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2479791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2480791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Stroke Width:</dt><dd>"); 2481791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getStrokeWidth()); 2482791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2483791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2484791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Stroke Miter:</dt><dd>"); 2485791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getStrokeMiter()); 2486791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2487791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2488791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Flags:</dt><dd>("); 2489791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (this->getFlags()) { 2490791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com bool needSeparator = false; 2491791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isAntiAlias(), "AntiAlias", &needSeparator); 2492791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isDither(), "Dither", &needSeparator); 2493791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isUnderlineText(), "UnderlineText", &needSeparator); 2494791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isStrikeThruText(), "StrikeThruText", &needSeparator); 2495791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isFakeBoldText(), "FakeBoldText", &needSeparator); 2496791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isLinearText(), "LinearText", &needSeparator); 2497791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isSubpixelText(), "SubpixelText", &needSeparator); 2498791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isDevKernText(), "DevKernText", &needSeparator); 2499791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isLCDRenderText(), "LCDRenderText", &needSeparator); 2500791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isEmbeddedBitmapText(), 2501791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com "EmbeddedBitmapText", &needSeparator); 2502791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isAutohinted(), "Autohinted", &needSeparator); 2503791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isVerticalText(), "VerticalText", &needSeparator); 2504791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, SkToBool(this->getFlags() & SkPaint::kGenA8FromLCD_Flag), 2505791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com "GenA8FromLCD", &needSeparator); 2506791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } else { 2507791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("None"); 2508791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2509791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(")</dd>"); 2510791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 25113e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append("<dt>FilterLevel:</dt><dd>"); 25123e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com static const char* gFilterLevelStrings[] = { "None", "Low", "Medium", "High" }; 25133e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append(gFilterLevelStrings[this->getFilterLevel()]); 25143e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append("</dd>"); 25153e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com 2516791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextAlign:</dt><dd>"); 2517791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gTextAlignStrings[SkPaint::kAlignCount] = { "Left", "Center", "Right" }; 2518791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gTextAlignStrings[this->getTextAlign()]); 2519791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2520791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2521791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>CapType:</dt><dd>"); 2522791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gStrokeCapStrings[SkPaint::kCapCount] = { "Butt", "Round", "Square" }; 2523791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gStrokeCapStrings[this->getStrokeCap()]); 2524791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2525791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2526791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>JoinType:</dt><dd>"); 2527791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gJoinStrings[SkPaint::kJoinCount] = { "Miter", "Round", "Bevel" }; 2528791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gJoinStrings[this->getStrokeJoin()]); 2529791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2530791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2531791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Style:</dt><dd>"); 2532791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gStyleStrings[SkPaint::kStyleCount] = { "Fill", "Stroke", "StrokeAndFill" }; 2533791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gStyleStrings[this->getStyle()]); 2534791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2535791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2536791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextEncoding:</dt><dd>"); 2537791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gTextEncodingStrings[] = { "UTF8", "UTF16", "UTF32", "GlyphID" }; 2538791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gTextEncodingStrings[this->getTextEncoding()]); 2539791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2540791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2541791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Hinting:</dt><dd>"); 2542791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gHintingStrings[] = { "None", "Slight", "Normal", "Full" }; 2543791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gHintingStrings[this->getHinting()]); 2544791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2545791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2546791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd></dl></dl>"); 2547791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com} 2548791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#endif 2549791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 25506fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 25518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25526fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool has_thick_frame(const SkPaint& paint) { 25536fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com return paint.getStrokeWidth() > 0 && 25546fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com paint.getStyle() != SkPaint::kFill_Style; 25558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 25568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTextToPathIter::SkTextToPathIter( const char text[], size_t length, 25588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint, 2559166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com bool applyStrokeAndPathEffects) 2560166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com : fPaint(paint) { 25618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection, 25628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com true); 25638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2564166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com fPaint.setLinearText(true); 25658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup 25668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25676fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { 25688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com applyStrokeAndPathEffects = false; 25696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 25708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2571166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com // can't use our canonical size if we need to apply patheffects 2572166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com if (fPaint.getPathEffect() == NULL) { 25738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); 25748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; 2575166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com if (has_thick_frame(fPaint)) { 2576166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale)); 2577166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com } 25786fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 25798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = SK_Scalar1; 25806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 258172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 25826fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!applyStrokeAndPathEffects) { 25838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setStyle(SkPaint::kFill_Style); 25848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setPathEffect(NULL); 25858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = fPaint.detachCache(NULL, NULL, false); 25888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::Style style = SkPaint::kFill_Style; 25908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect* pe = NULL; 25918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25926fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!applyStrokeAndPathEffects) { 25938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = paint.getStyle(); // restore 25948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pe = paint.getPathEffect(); // restore 25958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 25968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setStyle(style); 25978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setPathEffect(pe); 25988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setMaskFilter(paint.getMaskFilter()); // restore 25998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now compute fXOffset if needed 26018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar xOffset = 0; 26036fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first 26048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count; 26056fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, 26066fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com &count, NULL), fScale); 26076fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 26088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width = SkScalarHalf(width); 26096fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 26108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com xOffset = -width; 26118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXPos = xOffset; 26138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPrevAdvance = 0; 26148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fText = text; 26168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = text + length; 26177b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com 261844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com fXYIndex = paint.isVerticalText() ? 1 : 0; 26198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkTextToPathIter::~SkTextToPathIter() { 26228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache::AttachCache(fCache); 26238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 26248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26257b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.combool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { 26267b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (fText < fStop) { 26278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 26288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); 263044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); 26318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 26326fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (glyph.fWidth) { 26337b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (path) { 26347b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *path = fCache->findPath(glyph); 26357b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 26367b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } else { 26377b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (path) { 26387b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *path = NULL; 26396fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 26408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26417b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (xpos) { 26427b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *xpos = fXPos; 26437b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 26447b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com return true; 26458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 26467b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com return false; 26478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2648dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com 2649dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com/////////////////////////////////////////////////////////////////////////////// 2650dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com 2651dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.combool SkPaint::nothingToDraw() const { 2652733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com if (fLooper) { 2653733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com return false; 2654733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com } 2655dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com SkXfermode::Mode mode; 2656dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com if (SkXfermode::AsMode(fXfermode, &mode)) { 2657dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com switch (mode) { 2658dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kSrcOver_Mode: 2659dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kSrcATop_Mode: 2660dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDstOut_Mode: 2661dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDstOver_Mode: 2662dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kPlus_Mode: 2663dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return 0 == this->getAlpha(); 2664dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDst_Mode: 2665dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return true; 2666dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com default: 2667dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com break; 2668dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com } 2669dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com } 2670dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return false; 2671dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com} 2672aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2673aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orgvoid SkPaint::setBitfields(uint32_t bitfields) { 2674aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fBitfields = bitfields; 2675aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 2676aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2677aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orginline static unsigned popcount(uint8_t x) { 2678aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org // As in Hacker's delight, adapted for just 8 bits. 2679aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-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 2680aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-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 2681aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-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 2682aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org return x; 2683aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 2684aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2685aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orgvoid SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& paint) { 2686aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org const uint32_t dirty = paint.fDirtyBits; 2687aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 268845d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org // Each of the low 7 dirty bits corresponds to a 4-byte flat value, 268945d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org // plus one for the dirty bits and one for the bitfields 269045d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org const size_t flatBytes = 4 * (popcount(dirty & kPOD_DirtyBitMask) + 2); 2691aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org SkASSERT(flatBytes <= 32); 2692aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org uint32_t* u32 = buffer.reserve(flatBytes); 2693aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org *u32++ = dirty; 269445d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org *u32++ = paint.getBitfields(); 269545d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org if (0 == dirty) { 2696aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org return; 2697aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org } 2698aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2699aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field() 2700aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(u32, Color); 2701aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org SkScalar* f32 = reinterpret_cast<SkScalar*>(u32); 2702aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, TextSize); 2703aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, TextScaleX); 2704aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, TextSkewX); 2705aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, StrokeWidth); 2706aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(f32, StrokeMiter); 2707aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F 2708aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint.get##field()) 2709aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(PathEffect); 2710aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Shader); 2711aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Xfermode); 2712aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(MaskFilter); 2713aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(ColorFilter); 2714aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Rasterizer); 2715aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Looper); 2716aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(ImageFilter); 2717aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F 2718aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); 2719aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffer); 2720aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 2721aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().flatten(buffer); 2722aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#endif 2723aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 2724aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2725aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.orgvoid SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) { 2726aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org const uint32_t dirty = buffer.readUInt(); 272745d86e7072cda3b3108a84a033fba98072b12f85commit-bot@chromium.org paint->setBitfields(buffer.readUInt()); 2728aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty == 0) { 2729aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org return; 2730aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org } 2731aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buffer.reader()) 2732aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org// Same function, except it unrefs the object newly set on the paint: 2733aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#define F_UNREF(field, reader) \ 2734aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & k##field##_DirtyBit) \ 2735aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org paint->set##field(buffer.reader())->unref() 2736aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2737aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Color, readUInt); 2738aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(TextSize, readScalar); 2739aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(TextScaleX, readScalar); 2740aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(TextSkewX, readScalar); 2741aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(StrokeWidth, readScalar); 2742aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(StrokeMiter, readScalar); 2743aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(PathEffect, readPathEffect); 2744aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Shader, readShader); 2745aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Xfermode, readXfermode); 2746aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(MaskFilter, readMaskFilter); 2747aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(ColorFilter, readColorFilter); 2748aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Rasterizer, readRasterizer); 2749aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(Looper, readDrawLooper); 2750aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F_UNREF(ImageFilter, readImageFilter); 2751aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org F(Typeface, readTypeface); 2752aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F 2753aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#undef F_UNREF 2754aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kAnnotation_DirtyBit) { 2755d957984c1efbd18f3b2bbeca78d282837c5a2ae1commit-bot@chromium.org paint->setAnnotation(SkAnnotation::Create(buffer))->unref(); 2756aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org } 2757aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 2758aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org if (dirty & kPaintOptionsAndroid_DirtyBit) { 2759aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org SkPaintOptionsAndroid options; 2760aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org options.unflatten(buffer); 2761aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org paint->setPaintOptionsAndroid(options); 2762aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org } 2763aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org#endif 2764aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org SkASSERT(dirty == paint->fDirtyBits); 2765aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org} 2766