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" 11fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein#include "SkChecksum.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 13791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkData.h" 14532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#include "SkDeviceProperties.h" 15c4b84aef1adeb68bc853f35abb85b79fa1fcaac6rmistry#include "SkDraw.h" 16791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkFontDescriptor.h" 17791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkGlyphCache.h" 1815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com#include "SkImageFilter.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMaskFilter.h" 2097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com#include "SkMaskGamma.h" 218b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 228b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 23791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkPaintDefaults.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathEffect.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRasterizer.h" 2628be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkScalar.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalerContext.h" 28791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkShader.h" 29791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#include "SkStringUtils.h" 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStroke.h" 3128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org#include "SkTextFormatParams.h" 32e69137620ab0b5b40d230318c8e11b822f63cb9dreed@google.com#include "SkTextToPathIter.h" 33ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com#include "SkTLazy.h" 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h" 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 36791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 37a3237875f807aed9608cb4a023bc044f32850727reed@google.com// define this to get a printf for out-of-range parameter in setters 38a3237875f807aed9608cb4a023bc044f32850727reed@google.com// e.g. setTextSize(-1) 39a3237875f807aed9608cb4a023bc044f32850727reed@google.com//#define SK_REPORT_API_RANGE_CHECK 40a3237875f807aed9608cb4a023bc044f32850727reed@google.com 41a3122b9b1ec66efef606d8797b7b16b6634e08d2reed@android.comSkPaint::SkPaint() { 42aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org fTypeface = NULL; 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPathEffect = NULL; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShader = NULL; 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXfermode = NULL; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMaskFilter = NULL; 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColorFilter = NULL; 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRasterizer = NULL; 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLooper = NULL; 5015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com fImageFilter = NULL; 51b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com fAnnotation = NULL; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 53f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fTextSize = SkPaintDefaults_TextSize; 54f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fTextScaleX = SK_Scalar1; 55f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fTextSkewX = 0; 56f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fColor = SK_ColorBLACK; 57f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fWidth = 0; 58f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fMiterLimit = SkPaintDefaults_MiterLimit; 59e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 60e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org // Zero all bitfields, then set some non-zero defaults. 61f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfieldsUInt = 0; 62f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fFlags = SkPaintDefaults_Flags; 63f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fCapType = kDefault_Cap; 64f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fJoinType = kDefault_Join; 65f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextAlign = kLeft_Align; 66f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fStyle = kFill_Style; 67f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextEncoding = kUTF8_TextEncoding; 68f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fHinting = SkPaintDefaults_Hinting; 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 716fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint::SkPaint(const SkPaint& src) { 72e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define COPY(field) field = src.field 73e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define REF_COPY(field) field = SkSafeRef(src.field) 74e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 75e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fTypeface); 76e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fPathEffect); 77e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fShader); 78e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fXfermode); 79e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fMaskFilter); 80e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fColorFilter); 81e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fRasterizer); 82e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fLooper); 83e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fImageFilter); 84e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fAnnotation); 85e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 86e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSize); 87e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextScaleX); 88e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSkewX); 89e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fColor); 90e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fWidth); 91e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fMiterLimit); 92e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fBitfields); 9340078cb49e290e7fa6da1515c9d32a1d98e304a6djsollen@google.com 94e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef COPY 95e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef REF_COPY 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint::~SkPaint() { 9982065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fTypeface); 10082065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fPathEffect); 10182065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fShader); 10282065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fXfermode); 10382065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fMaskFilter); 10482065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fColorFilter); 10582065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fRasterizer); 10682065d667f64e232bcde2ad849756a6096fcbe6freed@google.com SkSafeUnref(fLooper); 10715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com SkSafeUnref(fImageFilter); 108b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com SkSafeUnref(fAnnotation); 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1116fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkPaint& SkPaint::operator=(const SkPaint& src) { 112f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org if (this == &src) { 113f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org return *this; 114f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org } 115f239d918d8b40a079693fe5b1f172ddf25abd8c1commit-bot@chromium.org 116e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define COPY(field) field = src.field 117e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define REF_COPY(field) SkSafeUnref(field); field = SkSafeRef(src.field) 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 119e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fTypeface); 120e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fPathEffect); 121e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fShader); 122e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fXfermode); 123e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fMaskFilter); 124e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fColorFilter); 125e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fRasterizer); 126e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fLooper); 127e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fImageFilter); 128e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org REF_COPY(fAnnotation); 129e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 130e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSize); 131e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextScaleX); 132e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fTextSkewX); 133e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fColor); 134e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fWidth); 135e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fMiterLimit); 136e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org COPY(fBitfields); 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return *this; 139e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org 140e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef COPY 141e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef REF_COPY 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 144b265741cc17f897b349caacdb890119e4111a415robertphillips@google.combool operator==(const SkPaint& a, const SkPaint& b) { 145e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#define EQUAL(field) (a.field == b.field) 146610a015fda84cd5d1e3f3f826bab393f1193bc0emtklein return EQUAL(fTypeface) 147e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fPathEffect) 148e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fShader) 149e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fXfermode) 150e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fMaskFilter) 151e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fColorFilter) 152e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fRasterizer) 153e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fLooper) 154e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fImageFilter) 155e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fAnnotation) 156e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextSize) 157e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextScaleX) 158e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fTextSkewX) 159e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fColor) 160e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fWidth) 161e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org && EQUAL(fMiterLimit) 162f59eab269350f36a0c2bf98d1c2a9757c77fc473reed && EQUAL(fBitfieldsUInt) 163e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org ; 164e8807f49ed24be3933acf84c9ffa840a03fa43dccommit-bot@chromium.org#undef EQUAL 165b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com} 166b265741cc17f897b349caacdb890119e4111a415robertphillips@google.com 1676fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::reset() { 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint init; 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *this = init; 1704bd2bdbf04f21237337616aa931e34d7c8991edcdjsollen@google.com} 17160abb078e5597c9c6ceaba1ef495c4916ff4df0ddjsollen@google.com 172f803da12cff1d9b6148fea319220351efebfd1e0reedvoid SkPaint::setFilterQuality(SkFilterQuality quality) { 173f803da12cff1d9b6148fea319220351efebfd1e0reed fBitfields.fFilterQuality = quality; 174c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.com} 175c9683151367b2033a26b1e2ebe6b3902d2064bdbreed@google.com 176f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.comvoid SkPaint::setHinting(Hinting hintingLevel) { 177f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fHinting = hintingLevel; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setFlags(uint32_t flags) { 181f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fFlags = flags; 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1846fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAntiAlias(bool doAA) { 185f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doAA, kAntiAlias_Flag)); 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1886fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setDither(bool doDither) { 189f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doDither, kDither_Flag)); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1926fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setSubpixelText(bool doSubpixel) { 193f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doSubpixel, kSubpixelText_Flag)); 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1966fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setLCDRenderText(bool doLCDRender) { 197f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doLCDRender, kLCDRenderText_Flag)); 198309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org} 199309485b7b51f4cae4c0361ab4da00fe9cc89515cagl@chromium.org 2006fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) { 201f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag)); 202e95c91e6d9201d50d0b84fbc3d2f53f92f753e0bagl@chromium.org} 203e95c91e6d9201d50d0b84fbc3d2f53f92f753e0bagl@chromium.org 2046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAutohinted(bool useAutohinter) { 205f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, useAutohinter, kAutoHinting_Flag)); 206a2c71cbd51da8b7767d43fe8954e7a4c674b2005agl@chromium.org} 207a2c71cbd51da8b7767d43fe8954e7a4c674b2005agl@chromium.org 2086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setLinearText(bool doLinearText) { 209f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doLinearText, kLinearText_Flag)); 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 212830a23e39bb4a126e573940cd6e354732e295b10reed@google.comvoid SkPaint::setVerticalText(bool doVertical) { 213f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doVertical, kVerticalText_Flag)); 214830a23e39bb4a126e573940cd6e354732e295b10reed@google.com} 215830a23e39bb4a126e573940cd6e354732e295b10reed@google.com 2166fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setUnderlineText(bool doUnderline) { 217f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doUnderline, kUnderlineText_Flag)); 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2206fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrikeThruText(bool doStrikeThru) { 221f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doStrikeThru, kStrikeThruText_Flag)); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2246fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setFakeBoldText(bool doFakeBold) { 225f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doFakeBold, kFakeBoldText_Flag)); 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2286fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setDevKernText(bool doDevKern) { 229f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doDevKern, kDevKernText_Flag)); 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 232b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.orgvoid SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) { 233f59eab269350f36a0c2bf98d1c2a9757c77fc473reed this->setFlags(SkSetClearMask(fBitfields.fFlags, doDistanceFieldText, kDistanceFieldTextTEMP_Flag)); 234b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.org} 235b97c3ffddf15ac65a0aae6823eb408b3b2772751commit-bot@chromium.org 2366fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStyle(Style style) { 2376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)style < kStyleCount) { 238f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fStyle = style; 239f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 240a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 241a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStyle(%d) out of range\n", style); 242a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 2436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setColor(SkColor color) { 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fColor = color; 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2506fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setAlpha(U8CPU a) { 251f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com this->setColor(SkColorSetARGB(a, SkColorGetR(fColor), 252f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com SkColorGetG(fColor), SkColorGetB(fColor))); 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2556fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 256f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com this->setColor(SkColorSetARGB(a, r, g, b)); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2596fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeWidth(SkScalar width) { 2606fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (width >= 0) { 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWidth = width; 262f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 263a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 264a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); 265a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 2666fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2696fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeMiter(SkScalar limit) { 2706fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (limit >= 0) { 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMiterLimit = limit; 272f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } else { 273a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 274a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); 275a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 2766fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2796fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeCap(Cap ct) { 2806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)ct < kCapCount) { 281f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fCapType = SkToU8(ct); 2826fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 283a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 284a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); 285a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 2866fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2896fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setStrokeJoin(Join jt) { 2906fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)jt < kJoinCount) { 291f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fJoinType = SkToU8(jt); 2926fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 293a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 294a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); 295a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 2966fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2996fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextAlign(Align align) { 3026fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)align < kAlignCount) { 303f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextAlign = SkToU8(align); 3046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 305a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 306a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); 307a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3086fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3116fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextSize(SkScalar ts) { 312c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (ts >= 0) { 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextSize = ts; 3146fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 315a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 316a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextSize() called with negative value\n"); 317a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3216fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextScaleX(SkScalar scaleX) { 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextScaleX = scaleX; 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3256fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextSkewX(SkScalar skewX) { 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fTextSkewX = skewX; 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3296fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::setTextEncoding(TextEncoding encoding) { 3306fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((unsigned)encoding <= kGlyphID_TextEncoding) { 331f59eab269350f36a0c2bf98d1c2a9757c77fc473reed fBitfields.fTextEncoding = encoding; 3326fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 333a3237875f807aed9608cb4a023bc044f32850727reed@google.com#ifdef SK_REPORT_API_RANGE_CHECK 334a3237875f807aed9608cb4a023bc044f32850727reed@google.com SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); 335a3237875f807aed9608cb4a023bc044f32850727reed@google.com#endif 3366fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3396fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkTypeface* SkPaint::setTypeface(SkTypeface* font) { 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fTypeface, font); 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return font; 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fRasterizer, r); 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return r; 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3516fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fLooper, looper); 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return looper; 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 35615356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.comSkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { 35715356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com SkRefCnt_SafeAssign(fImageFilter, imageFilter); 35815356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com return imageFilter; 35915356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com} 36015356a68b2a87e3ab9fc49392d085a4201ffeb62reed@google.com 361b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.comSkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { 362b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com SkRefCnt_SafeAssign(fAnnotation, annotation); 363b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com return annotation; 364b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com} 365b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 368ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comstatic SkScalar mag2(SkScalar x, SkScalar y) { 369ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return x * x + y * y; 370ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 371ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 372ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comstatic bool tooBig(const SkMatrix& m, SkScalar ma2max) { 373ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return mag2(m[SkMatrix::kMScaleX], m[SkMatrix::kMSkewY]) > ma2max 374ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com || 375ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com mag2(m[SkMatrix::kMSkewX], m[SkMatrix::kMScaleY]) > ma2max; 376ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 377ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 378ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.combool SkPaint::TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM) { 379ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkASSERT(!ctm.hasPerspective()); 380ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkASSERT(!textM.hasPerspective()); 381ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 382ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkMatrix matrix; 383ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com matrix.setConcat(ctm, textM); 384ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return tooBig(matrix, MaxCacheSize2()); 385ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 386ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 387ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 388ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com/////////////////////////////////////////////////////////////////////////////// 389ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGlyphCache.h" 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 39390808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.comstatic void DetachDescProc(SkTypeface* typeface, const SkDescriptor* desc, 39490808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void* context) { 39590808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(typeface, desc); 396f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com} 397f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkPaint::textToGlyphs(const void* textData, size_t byteLength, 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t glyphs[]) const { 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (byteLength == 0) { 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 40372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(textData != NULL); 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == glyphs) { 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (this->getTextEncoding()) { 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kUTF8_TextEncoding: 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkUTF8_CountUnichars((const char*)textData, byteLength); 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kUTF16_TextEncoding: 4112cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkUTF16_CountUnichars((const uint16_t*)textData, SkToInt(byteLength >> 1)); 41268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case kUTF32_TextEncoding: 4132cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 2); 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case kGlyphID_TextEncoding: 4152cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 1); 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 4170c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 42172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if we get here, we have a valid glyphs[] array, so time to fill it in 42372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // handle this encoding before the setup for the glyphcache 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (this->getTextEncoding() == kGlyphID_TextEncoding) { 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we want to ignore the low bit of byteLength 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(glyphs, textData, byteLength >> 1 << 1); 4282cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(byteLength >> 1); 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 43072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 431532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = text + byteLength; 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint16_t* gptr = glyphs; 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (this->getTextEncoding()) { 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPaint::kUTF8_TextEncoding: 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text)); 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPaint::kUTF16_TextEncoding: { 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* text16 = (const uint16_t*)text; 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* stop16 = (const uint16_t*)stop; 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text16 < stop16) { 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 45268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case kUTF32_TextEncoding: { 45368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* text32 = (const int32_t*)text; 45468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* stop32 = (const int32_t*)stop; 45568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com while (text32 < stop32) { 45668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *gptr++ = cache->unicharToGlyph(*text32++); 45768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 45868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com break; 45968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 4610c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4632cfa3200fda29279eba1240170c7e873d12f9d48commit-bot@chromium.org return SkToInt(gptr - glyphs); 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 466a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.combool SkPaint::containsText(const void* textData, size_t byteLength) const { 467a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == byteLength) { 468a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 469a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 47072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 471a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com SkASSERT(textData != NULL); 47272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 473a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com // handle this encoding before the setup for the glyphcache 474a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (this->getTextEncoding() == kGlyphID_TextEncoding) { 475a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* glyphID = static_cast<const uint16_t*>(textData); 476a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com size_t count = byteLength >> 1; 477a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com for (size_t i = 0; i < count; i++) { 478a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == glyphID[i]) { 479a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 480a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 481a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 482a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 483a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 48472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 485532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 486a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com SkGlyphCache* cache = autoCache.getCache(); 487a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com 488a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com switch (this->getTextEncoding()) { 489a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com case SkPaint::kUTF8_TextEncoding: { 490a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const char* text = static_cast<const char*>(textData); 491a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const char* stop = text + byteLength; 492a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com while (text < stop) { 493a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) { 494a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 495a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 496a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 497a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com break; 498a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 499a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com case SkPaint::kUTF16_TextEncoding: { 500a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* text = static_cast<const uint16_t*>(textData); 501a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com const uint16_t* stop = text + (byteLength >> 1); 502a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com while (text < stop) { 503a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) { 504a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 505a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 506a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 507a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com break; 508a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 50968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com case SkPaint::kUTF32_TextEncoding: { 51068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* text = static_cast<const int32_t*>(textData); 51168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* stop = text + (byteLength >> 2); 51268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com while (text < stop) { 51368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com if (0 == cache->unicharToGlyph(*text++)) { 51468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return false; 51568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 51668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 51768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com break; 51868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com } 519a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com default: 5200c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("unknown text encoding"); 521a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return false; 522a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com } 523a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com return true; 524a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com} 525a5dcaf6fd8115fb9c6028ca4e9848b968375abcdreed@android.com 5269d3a985aa3c82605346ed1518375a8c384b925e5reed@android.comvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, 5279d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkUnichar textData[]) const { 5289d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com if (count <= 0) { 5299d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com return; 5309d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com } 5319d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 5329d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkASSERT(glyphs != NULL); 5339d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkASSERT(textData != NULL); 5349d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 535532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com SkAutoGlyphCache autoCache(*this, NULL, NULL); 5369d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com SkGlyphCache* cache = autoCache.getCache(); 5379d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 5389d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com for (int index = 0; index < count; index++) { 5399d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com textData[index] = cache->glyphToUnichar(glyphs[index]); 5409d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com } 5419d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com} 5429d3a985aa3c82605346ed1518375a8c384b925e5reed@android.com 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5456fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, 5466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 54972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5536fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, 5546fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 557fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_next(SkGlyphCache* cache, 56268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 56368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 56468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 56568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 56668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 56768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 56868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 56968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 57068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 57168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 5726fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, 5736fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 57672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5846fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, 5856fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 58872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF8_NextUnichar(text)); 5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5926fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, 5936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 59672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text)); 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 60068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getAdvance_utf32_next(SkGlyphCache* cache, 60168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text) { 60268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 60368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 604fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 60568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 60668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 60768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 60868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharAdvance(uni); 60968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 61068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 6116fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, 6126fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text) { 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 61572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDAdvance(glyphID); 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6239e96aa07dbf1210fd35ae8e0c54d4d9822544e89reedSkMeasureCacheProc SkPaint::getMeasureCacheProc(bool needFullMetrics) const { 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const SkMeasureCacheProc gMeasureCacheProcs[] = { 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_next, 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_next, 62768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_next, 6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_next, 62972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf8_next, 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_utf16_next, 63268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getAdvance_utf32_next, 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getAdvance_glyph_next, 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 63572cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned index = this->getTextEncoding(); 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6386fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!needFullMetrics && !this->isDevKernText()) { 6399e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed index += 4; 6406fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs)); 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gMeasureCacheProcs[index]; 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache, 6496fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 65272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache, 6576fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 66072cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y); 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, 6656fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 66872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); 6708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache, 6736fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 6748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 67672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text), 6788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x, y); 6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 68168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_00(SkGlyphCache* cache, 68268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text, SkFixed, SkFixed) { 68368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 68468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 685fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 68668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 68768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkUnichar uni = *ptr++; 68868bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 68968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com return cache->getUnicharMetrics(uni); 69068bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 69168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 69268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.comstatic const SkGlyph& sk_getMetrics_utf32_xy(SkGlyphCache* cache, 69368bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const char** text, SkFixed x, SkFixed y) { 69468bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(cache != NULL); 69568bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com SkASSERT(text != NULL); 696fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 69768bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com const int32_t* ptr = *(const int32_t**)text; 698584f337832d585e23037e59517f7bcc420424692commit-bot@chromium.org SkUnichar uni = *ptr++; 69968bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com *text = (const char*)ptr; 7008d38d516c0f17d8d9f6b170055ac05ac181c0554sugoi@google.com return cache->getUnicharMetrics(uni, x, y); 70168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com} 70268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com 7036fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, 7046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed, SkFixed) { 7058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 70772cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 7118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID); 7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache, 7166fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com const char** text, SkFixed x, SkFixed y) { 7178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(cache != NULL); 7188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL); 71972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint16_t* ptr = *(const uint16_t**)text; 7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned glyphID = *ptr; 7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr += 1; 7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *text = (const char*)ptr; 7248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache->getGlyphIDMetrics(glyphID, x, y); 7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7276fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkDrawCacheProc SkPaint::getDrawCacheProc() const { 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const SkDrawCacheProc gDrawCacheProcs[] = { 7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_00, 7308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_00, 73168bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_00, 7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_00, 73372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf8_xy, 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_utf16_xy, 73668bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com sk_getMetrics_utf32_xy, 7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_getMetrics_glyph_xy 7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 73972cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned index = this->getTextEncoding(); 741f59eab269350f36a0c2bf98d1c2a9757c77fc473reed if (fBitfields.fFlags & kSubpixelText_Flag) { 74268bc6f7b4510813c1af886d0cdeea2f0f7a2a510reed@google.com index += 4; 7436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 74472cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs)); 7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return gDrawCacheProcs[index]; 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 7508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 751ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com#define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \ 752ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kDevKernText_Flag | \ 753ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kLinearText_Flag | \ 754ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kLCDRenderText_Flag | \ 755ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kEmbeddedBitmapText_Flag | \ 756ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kAutoHinting_Flag | \ 757ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkPaint::kGenA8FromLCD_Flag ) 758ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 759ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comSkScalar SkPaint::setupForAsPaths() { 760ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com uint32_t flags = this->getFlags(); 761ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // clear the flags we don't care about 762ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com flags &= ~TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE; 763ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // set the flags we do care about 764ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com flags |= SkPaint::kSubpixelText_Flag; 7658f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 766ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setFlags(flags); 767ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setHinting(SkPaint::kNo_Hinting); 7688f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 769ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar textSize = fTextSize; 770ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com this->setTextSize(kCanonicalTextSizeForPaths); 771ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com return textSize / kCanonicalTextSizeForPaths; 772ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com} 773ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com 774ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.comclass SkCanonicalizePaint { 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 776ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint(const SkPaint& paint) : fPaint(&paint), fScale(0) { 777c4b84aef1adeb68bc853f35abb85b79fa1fcaac6rmistry if (paint.isLinearText() || SkDraw::ShouldDrawTextAsPaths(paint, SkMatrix::I())) { 778ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkPaint* p = fLazy.set(paint); 779ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com fScale = p->setupForAsPaths(); 780ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com fPaint = p; 781ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com } 7828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7836fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com 784ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& getPaint() const { return *fPaint; } 7858f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 786ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com /** 787ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com * Returns 0 if the paint was unmodified, or the scale factor need to 788ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com * the original textSize 789ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com */ 790ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar getScale() const { return fScale; } 79172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 793ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint* fPaint; 794ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar fScale; 795ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkTLazy<SkPaint> fLazy; 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7986fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic void set_bounds(const SkGlyph& g, SkRect* bounds) { 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->set(SkIntToScalar(g.fLeft), 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop), 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fLeft + g.fWidth), 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop + g.fHeight)); 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 80544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) { 806e88f551b38c2893566b7016d906b1455e43542f5reed@android.com SkScalar sx = Sk48Dot16ToScalar(dx); 8078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->join(SkIntToScalar(g.fLeft) + sx, 8088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop), 8098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fLeft + g.fWidth) + sx, 8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIntToScalar(g.fTop + g.fHeight)); 8118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 81344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) { 81444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkScalar sy = Sk48Dot16ToScalar(dy); 81544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com bounds->join(SkIntToScalar(g.fLeft), 81644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fTop) + sy, 81744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fLeft + g.fWidth), 81844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkIntToScalar(g.fTop + g.fHeight) + sy); 81944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com} 82044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 82144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comtypedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16); 82244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 82344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY 82444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.comstatic SkFixed advance(const SkGlyph& glyph, int xyIndex) { 82544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkASSERT(0 == xyIndex || 1 == xyIndex); 82644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com return (&glyph.fAdvanceX)[xyIndex]; 82744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com} 82844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkScalar SkPaint::measure_text(SkGlyphCache* cache, 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text, size_t byteLength, 8316fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com int* count, SkRect* bounds) const { 8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count); 8336fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (byteLength == 0) { 8348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *count = 0; 8356fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (bounds) { 8368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->setEmpty(); 8376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 8388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8419e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(NULL != bounds); 8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 84344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com int xyIndex; 84444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com JoinBoundsProc joinBoundsProc; 84544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com if (this->isVerticalText()) { 84644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com xyIndex = 1; 84744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc = join_bounds_y; 84844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com } else { 84944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com xyIndex = 0; 85044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc = join_bounds_x; 85144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com } 85244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com 8538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = 1; 8548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = (const char*)text + byteLength; 8558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph* g = &glyphCacheProc(cache, &text); 856e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // our accumulated fixed-point advances might overflow 16.16, so we use 857e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // a 48.16 (64bit) accumulator, and then convert that to scalar at the 858e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // very end. 85944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com Sk48Dot16 x = advance(*g, xyIndex); 8608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 8628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8636fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == bounds) { 8646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 8658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb; 8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g->fRsbDelta; 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 86944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex); 8708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8716fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 87344da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(glyphCacheProc(cache, &text), xyIndex); 8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8766fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(*g, bounds); 8786fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 8798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb; 8808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g->fRsbDelta; 8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 8838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += SkAutoKern_AdjustF(rsb, g->fLsbDelta); 88444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc(*g, bounds, x); 88544da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(*g, xyIndex); 8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8876fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 8888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (; text < stop; n++) { 8898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = &glyphCacheProc(cache, &text); 89044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com joinBoundsProc(*g, bounds, x); 89144da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com x += advance(*g, xyIndex); 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text == stop); 8968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *count = n; 898e88f551b38c2893566b7016d906b1455e43542f5reed@android.com return Sk48Dot16ToScalar(x); 8998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 90199ae881a7f55a03c2b16fb5704e6e90ea86d965dreedSkScalar SkPaint::measureText(const void* textData, size_t length, SkRect* bounds) const { 9028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 9038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text != NULL || length == 0); 9048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 905ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 906ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 907ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 90872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 90999ae881a7f55a03c2b16fb5704e6e90ea86d965dreed SkAutoGlyphCache autoCache(paint, NULL, NULL); 9108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar width = 0; 91372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9146fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (length > 0) { 9158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int tempCount; 9168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 917ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com width = paint.measure_text(cache, text, length, &tempCount, bounds); 9186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 9198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width = SkScalarMul(width, scale); 9206fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (bounds) { 9218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fLeft = SkScalarMul(bounds->fLeft, scale); 9228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fTop = SkScalarMul(bounds->fTop, scale); 9238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fRight = SkScalarMul(bounds->fRight, scale); 9248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->fBottom = SkScalarMul(bounds->fBottom, scale); 9258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 92746348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com } else if (bounds) { 92846348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com // ensure that even if we don't measure_text we still update the bounds 92946348e21732e64e1a4dcfb5d859e6edafba471ffdjsollen@google.com bounds->setEmpty(); 9308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return width; 9328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 9338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth, 9359e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed SkScalar* measuredWidth) const { 9366fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (0 == length || 0 >= maxWidth) { 9376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (measuredWidth) { 9388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *measuredWidth = 0; 9396fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 9408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 9418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 943c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (0 == fTextSize) { 944c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com if (measuredWidth) { 945c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com *measuredWidth = 0; 946c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com } 947c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com return length; 948c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com } 949c6f2e7da31d60e48a420b6de520361d966ea278ddjsollen@google.com 9508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(textD != NULL); 9518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textD; 9529e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed const char* stop = text + length; 9538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 954ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 955ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 956ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 9578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 958ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com // adjust max in case we changed the textSize in paint 959ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com if (scale) { 960ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com maxWidth /= scale; 9618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 96272cf4927e503f49c4bd07369e85764ddde57071breed@google.com 963ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkAutoGlyphCache autoCache(paint, NULL, NULL); 9648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 9658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9669e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc(false); 967ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const int xyIndex = paint.isVerticalText() ? 1 : 0; 968e88f551b38c2893566b7016d906b1455e43542f5reed@android.com // use 64bits for our accumulator, to avoid overflowing 16.16 969e88f551b38c2893566b7016d906b1455e43542f5reed@android.com Sk48Dot16 max = SkScalarToFixed(maxWidth); 970e88f551b38c2893566b7016d906b1455e43542f5reed@android.com Sk48Dot16 width = 0; 9718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 9738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9746fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 9758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int rsb = 0; 9769e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed while (text < stop) { 9778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* curr = text; 9788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 97944da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex); 9806fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((width += x) > max) { 9818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width -= x; 9828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text = curr; 9838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rsb = g.fRsbDelta; 9868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9876fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 9889e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed while (text < stop) { 9898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* curr = text; 99044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex); 9916fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if ((width += x) > max) { 9928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width -= x; 9938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com text = curr; 9948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 9958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 9978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 99872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 9996fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (measuredWidth) { 1000e88f551b38c2893566b7016d906b1455e43542f5reed@android.com SkScalar scalarWidth = Sk48Dot16ToScalar(width); 10016fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 10028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scalarWidth = SkScalarMul(scalarWidth, scale); 10036fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *measuredWidth = scalarWidth; 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 100672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // return the number of bytes measured 10089e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed return text - stop + length; 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10136fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) { 10140a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com *(SkPaint::FontMetrics*)context = cache->getFontMetrics(); 10158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; // don't detach the cache 10168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 101890808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.comstatic void FontMetricsDescProc(SkTypeface* typeface, const SkDescriptor* desc, 101990808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com void* context) { 102090808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com SkGlyphCache::VisitCache(typeface, desc, FontMetricsCacheProc, context); 10218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10236fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const { 1024ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1025ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1026ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 10278f6ef4010f6835c5ce9ede180e50a6a58512a81eskia.committer@gmail.com 10286fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkMatrix zoomMatrix, *zoomPtr = NULL; 10296fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (zoom) { 10308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomMatrix.setScale(zoom, zoom); 10318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com zoomPtr = &zoomMatrix; 10328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FontMetrics storage; 10356fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == metrics) { 10368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics = &storage; 10376fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 103872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1039ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com paint.descriptorProc(NULL, zoomPtr, FontMetricsDescProc, metrics, true); 10408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10416fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (scale) { 10428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fTop = SkScalarMul(metrics->fTop, scale); 10438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fAscent = SkScalarMul(metrics->fAscent, scale); 10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fDescent = SkScalarMul(metrics->fDescent, scale); 10458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fBottom = SkScalarMul(metrics->fBottom, scale); 10468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com metrics->fLeading = SkScalarMul(metrics->fLeading, scale); 10470a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fAvgCharWidth = SkScalarMul(metrics->fAvgCharWidth, scale); 10480a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXMin = SkScalarMul(metrics->fXMin, scale); 10490a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXMax = SkScalarMul(metrics->fXMax, scale); 10500a01f5a2c44f3d6a7fa2d3c837f46894d9b29e5dreed@google.com metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); 10510bc406df48ac6f358ab8dcff08f71fe9c32b79decommit-bot@chromium.org metrics->fUnderlineThickness = SkScalarMul(metrics->fUnderlineThickness, scale); 10520bc406df48ac6f358ab8dcff08f71fe9c32b79decommit-bot@chromium.org metrics->fUnderlinePosition = SkScalarMul(metrics->fUnderlinePosition, scale); 10538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 10548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return metrics->fDescent - metrics->fAscent + metrics->fLeading; 10558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10576fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 10588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10596fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) { 10608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bounds->set(g.fLeft * scale, 10618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g.fTop * scale, 10628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g.fLeft + g.fWidth) * scale, 10638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g.fTop + g.fHeight) * scale); 10648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 10658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10666fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comint SkPaint::getTextWidths(const void* textData, size_t byteLength, 10676fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar widths[], SkRect bounds[]) const { 10686fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (0 == byteLength) { 10698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 10706fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 10718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 107249f085dddff10473b6ebf832a974288300224e60bsalomon SkASSERT(textData); 10738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10746fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (NULL == widths && NULL == bounds) { 10758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->countText(textData, byteLength); 10766fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 10778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1078ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkCanonicalizePaint canon(*this); 1079ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const SkPaint& paint = canon.getPaint(); 1080ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkScalar scale = canon.getScale(); 10818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1082ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com SkAutoGlyphCache autoCache(paint, NULL, NULL); 10838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache = autoCache.getCache(); 10848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMeasureCacheProc glyphCacheProc; 10859e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed glyphCacheProc = paint.getMeasureCacheProc(NULL != bounds); 10868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 10888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* stop = text + byteLength; 10898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = 0; 1090ed43dffbf140cebc0575bed7b4dff1b32430ad21reed@google.com const int xyIndex = paint.isVerticalText() ? 1 : 0; 10918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10926fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (this->isDevKernText()) { 10938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we adjust the widths returned here through auto-kerning 10948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoKern autokern; 10958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed prevWidth = 0; 10968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (scale) { 10988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 10998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 11008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 11018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed adjust = autokern.adjust(g); 11028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 11048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar w = SkFixedToScalar(prevWidth + adjust); 11058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths++ = SkScalarMul(w, scale); 11068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 110744da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com prevWidth = advance(g, xyIndex); 11088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 11108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++, scale); 11118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 11138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0 && widths) { 11158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale); 11168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 11188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 11198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 11208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 11218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed adjust = autokern.adjust(g); 11228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0) { 11248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths++ = SkFixedToScalar(prevWidth + adjust); 11258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 112644da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com prevWidth = advance(g, xyIndex); 11278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 11298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++); 11308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 11328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (count > 0 && widths) { 11348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *widths = SkFixedToScalar(prevWidth); 11358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { // no devkern 11388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (scale) { 11398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 11408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 11418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 114244da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)), 11438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com scale); 11448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 11468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++, scale); 11478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 11498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 11518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (text < stop) { 11528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& g = glyphCacheProc(cache, &text); 11538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (widths) { 115444da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com *widths++ = SkFixedToScalar(advance(g, xyIndex)); 11558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (bounds) { 11578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set_bounds(g, bounds++); 11588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ++count; 11608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(text == stop); 11658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return count; 11668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11686fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 11698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDraw.h" 11718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11726fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comvoid SkPaint::getTextPath(const void* textData, size_t length, 11736fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar x, SkScalar y, SkPath* path) const { 11746fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkASSERT(length == 0 || textData != NULL); 11756fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com 11768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* text = (const char*)textData; 11776fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (text == NULL || length == 0 || path == NULL) { 11788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 11796fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 11808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1181166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com SkTextToPathIter iter(text, length, *this, false); 11828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix matrix; 11838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar prevXPos = 0; 11848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.setScale(iter.getPathScale(), iter.getPathScale()); 11868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.postTranslate(x, y); 11878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path->reset(); 11888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar xpos; 11908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath* iterPath; 11917b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com while (iter.next(&iterPath, &xpos)) { 11928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com matrix.postTranslate(xpos - prevXPos, 0); 11937b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (iterPath) { 11947b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com path->addPath(*iterPath, matrix); 11957b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 11968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prevXPos = xpos; 11978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 11988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 11998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1200ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.comvoid SkPaint::getPosTextPath(const void* textData, size_t length, 1201ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const SkPoint pos[], SkPath* path) const { 1202ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkASSERT(length == 0 || textData != NULL); 1203ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1204ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const char* text = (const char*)textData; 1205ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com if (text == NULL || length == 0 || path == NULL) { 1206ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com return; 1207ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com } 1208ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1209ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkTextToPathIter iter(text, length, *this, false); 1210ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkMatrix matrix; 1211ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com SkPoint prevPos; 1212ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com prevPos.set(0, 0); 1213ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1214ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com matrix.setScale(iter.getPathScale(), iter.getPathScale()); 1215ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com path->reset(); 1216ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 1217ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com unsigned int i = 0; 1218ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com const SkPath* iterPath; 12197b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com while (iter.next(&iterPath, NULL)) { 1220ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com matrix.postTranslate(pos[i].fX - prevPos.fX, pos[i].fY - prevPos.fY); 12217b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (iterPath) { 12227b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com path->addPath(*iterPath, matrix); 12237b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 1224ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com prevPos = pos[i]; 1225ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com i++; 1226ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com } 1227ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com} 1228ca0062ee5e74eddff886ada2a200d25946ea52cfreed@google.com 12298893e5f030cb2f6c3bdf698c1767a244ae098a5creedSkRect SkPaint::getFontBounds() const { 12308893e5f030cb2f6c3bdf698c1767a244ae098a5creed SkMatrix m; 12318893e5f030cb2f6c3bdf698c1767a244ae098a5creed m.setScale(fTextSize * fTextScaleX, fTextSize); 12328893e5f030cb2f6c3bdf698c1767a244ae098a5creed m.postSkew(fTextSkewX, 0); 12338893e5f030cb2f6c3bdf698c1767a244ae098a5creed 12348893e5f030cb2f6c3bdf698c1767a244ae098a5creed SkTypeface* typeface = this->getTypeface(); 12358893e5f030cb2f6c3bdf698c1767a244ae098a5creed if (NULL == typeface) { 12368893e5f030cb2f6c3bdf698c1767a244ae098a5creed typeface = SkTypeface::GetDefaultTypeface(); 12378893e5f030cb2f6c3bdf698c1767a244ae098a5creed } 12388893e5f030cb2f6c3bdf698c1767a244ae098a5creed 12398893e5f030cb2f6c3bdf698c1767a244ae098a5creed SkRect bounds; 12408893e5f030cb2f6c3bdf698c1767a244ae098a5creed m.mapRect(&bounds, typeface->getBounds()); 12418893e5f030cb2f6c3bdf698c1767a244ae098a5creed return bounds; 12428893e5f030cb2f6c3bdf698c1767a244ae098a5creed} 12438893e5f030cb2f6c3bdf698c1767a244ae098a5creed 12448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void add_flattenable(SkDescriptor* desc, uint32_t tag, 12458b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkWriteBuffer* buffer) { 12468b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org buffer->writeToMemory(desc->addEntry(tag, buffer->bytesWritten(), NULL)); 12478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12496fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic SkMask::Format computeMaskFormat(const SkPaint& paint) { 12508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t flags = paint.getFlags(); 12518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1252b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org // Antialiasing being disabled trumps all other settings. 125365dd8f83106ceb11fbff330bed3037557db974cfreed@google.com if (!(flags & SkPaint::kAntiAlias_Flag)) { 1254b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org return SkMask::kBW_Format; 1255f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com } 1256f88d6765a594cf9fb0825b74779f74394a7ccc7areed@google.com 125765dd8f83106ceb11fbff330bed3037557db974cfreed@google.com if (flags & SkPaint::kLCDRenderText_Flag) { 1258f67e4cf4c18cd228738a11372859ee0280bce1d7reed@google.com return SkMask::kLCD16_Format; 125965dd8f83106ceb11fbff330bed3037557db974cfreed@google.com } 1260b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org 1261b4234a226612cf7f99a47d9c633233c1a488d6edagl@chromium.org return SkMask::kA8_Format; 12628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 12638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12641cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com// if linear-text is on, then we force hinting to be off (since that's sort of 12651cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com// the point of linear-text. 12661cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.comstatic SkPaint::Hinting computeHinting(const SkPaint& paint) { 12671cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com SkPaint::Hinting h = paint.getHinting(); 12681cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com if (paint.isLinearText()) { 12691cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com h = SkPaint::kNo_Hinting; 12701cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com } 12711cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com return h; 12721cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com} 12731cdcb5138f9b70aff547ea1c3af96f0c90b12f8freed@android.com 12741f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com// return true if the paint is just a single color (i.e. not a shader). If its 12751f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com// a shader, then we can't compute a const luminance for it :( 12761f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.comstatic bool justAColor(const SkPaint& paint, SkColor* color) { 12778367b8cb7a6b2f163ee41365323cb219b7049b15reed SkColor c = paint.getColor(); 12788367b8cb7a6b2f163ee41365323cb219b7049b15reed 12798367b8cb7a6b2f163ee41365323cb219b7049b15reed SkShader* shader = paint.getShader(); 12808367b8cb7a6b2f163ee41365323cb219b7049b15reed if (shader && !shader->asLuminanceColor(&c)) { 12811f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com return false; 12821f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 12831f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com if (paint.getColorFilter()) { 12841f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com c = paint.getColorFilter()->filterColor(c); 12851f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 12861f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com if (color) { 12871f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com *color = c; 12881f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com } 12891f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com return true; 12901f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com} 12911f6b4ae0f723317d01b158ce1498dabf4d93a67breed@google.com 12929e36c1a9306f052331550dab4728b9875127bfb5joshualittSkColor SkPaint::computeLuminanceColor() const { 1293ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com SkColor c; 12949e36c1a9306f052331550dab4728b9875127bfb5joshualitt if (!justAColor(*this, &c)) { 1295ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com c = SkColorSetRGB(0x7F, 0x80, 0x7F); 1296ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com } 1297ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com return c; 1298ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com} 1299813d38b7a07957f2990ccca52ddab55fe0b1c632reed@google.com 1300dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com#define assert_byte(x) SkASSERT(0 == ((x) >> 8)) 1301dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com 13024f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com// Beyond this size, LCD doesn't appreciably improve quality, but it always 13034f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com// cost more RAM and draws slower, so we set a cap. 1304c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com#ifndef SK_MAX_SIZE_FOR_LCDTEXT 1305c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com #define SK_MAX_SIZE_FOR_LCDTEXT 48 1306c27b74174e6a734db3cf1b5a5354eab8f3d27c1creed@google.com#endif 13074f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com 1308b3da83a07fd6081fd703a370ce135837f55de010reedconst SkScalar gMaxSize2ForLCDText = SK_MAX_SIZE_FOR_LCDTEXT * SK_MAX_SIZE_FOR_LCDTEXT; 1309b3da83a07fd6081fd703a370ce135837f55de010reed 13104942e7550ec80796132ab1ce2cc935a5dd1b464creedstatic bool too_big_for_lcd(const SkScalerContext::Rec& rec, bool checkPost2x2) { 1311b3da83a07fd6081fd703a370ce135837f55de010reed if (checkPost2x2) { 1312b3da83a07fd6081fd703a370ce135837f55de010reed SkScalar area = rec.fPost2x2[0][0] * rec.fPost2x2[1][1] - 1313b3da83a07fd6081fd703a370ce135837f55de010reed rec.fPost2x2[1][0] * rec.fPost2x2[0][1]; 13144942e7550ec80796132ab1ce2cc935a5dd1b464creed area *= rec.fTextSize * rec.fTextSize; 13154942e7550ec80796132ab1ce2cc935a5dd1b464creed return area > gMaxSize2ForLCDText; 13164942e7550ec80796132ab1ce2cc935a5dd1b464creed } else { 13174942e7550ec80796132ab1ce2cc935a5dd1b464creed return rec.fTextSize > SK_MAX_SIZE_FOR_LCDTEXT; 1318b3da83a07fd6081fd703a370ce135837f55de010reed } 13194f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com} 13204f79b9be9ea5e8998b3692c1030ae2c90a796e9dreed@google.com 132172cf4927e503f49c4bd07369e85764ddde57071breed@google.com/* 132272cf4927e503f49c4bd07369e85764ddde57071breed@google.com * Return the scalar with only limited fractional precision. Used to consolidate matrices 132372cf4927e503f49c4bd07369e85764ddde57071breed@google.com * that vary only slightly when we create our key into the font cache, since the font scaler 132472cf4927e503f49c4bd07369e85764ddde57071breed@google.com * typically returns the same looking resuts for tiny changes in the matrix. 132572cf4927e503f49c4bd07369e85764ddde57071breed@google.com */ 1326f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comstatic SkScalar sk_relax(SkScalar x) { 1327f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com int n = sk_float_round2int(x * 1024); 1328f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return n / 1024.0f; 1329f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 1330f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 133136a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.comvoid SkScalerContext::MakeRec(const SkPaint& paint, 1332532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkDeviceProperties* deviceProperties, 1333532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com const SkMatrix* deviceMatrix, 1334532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com Rec* rec) { 13358d430185e08d2067584837a76b7193b803fee7a0tomhudson@google.com SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective()); 13368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1337cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com SkTypeface* typeface = paint.getTypeface(); 1338cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com if (NULL == typeface) { 1339cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com typeface = SkTypeface::GetDefaultTypeface(); 1340cb1bbb375aa4fdd099dc60302ca1712f04607782bungeman@google.com } 1341ec730b9cafaa3b2a4df7e7ceb3ab50601796fbe5bungeman rec->fFontID = typeface->uniqueID(); 13428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fTextSize = paint.getTextSize(); 13438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPreScaleX = paint.getTextScaleX(); 13448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPreSkewX = paint.getTextSkewX(); 13458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1346b3da83a07fd6081fd703a370ce135837f55de010reed bool checkPost2x2 = false; 1347b3da83a07fd6081fd703a370ce135837f55de010reed 13486fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (deviceMatrix) { 1349b3da83a07fd6081fd703a370ce135837f55de010reed const SkMatrix::TypeMask mask = deviceMatrix->getType(); 1350b3da83a07fd6081fd703a370ce135837f55de010reed if (mask & SkMatrix::kScale_Mask) { 1351b3da83a07fd6081fd703a370ce135837f55de010reed rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX()); 1352b3da83a07fd6081fd703a370ce135837f55de010reed rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY()); 1353b3da83a07fd6081fd703a370ce135837f55de010reed checkPost2x2 = true; 1354b3da83a07fd6081fd703a370ce135837f55de010reed } else { 1355b3da83a07fd6081fd703a370ce135837f55de010reed rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 1356b3da83a07fd6081fd703a370ce135837f55de010reed } 1357b3da83a07fd6081fd703a370ce135837f55de010reed if (mask & SkMatrix::kAffine_Mask) { 1358b3da83a07fd6081fd703a370ce135837f55de010reed rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX()); 1359b3da83a07fd6081fd703a370ce135837f55de010reed rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY()); 1360b3da83a07fd6081fd703a370ce135837f55de010reed checkPost2x2 = true; 1361b3da83a07fd6081fd703a370ce135837f55de010reed } else { 1362b3da83a07fd6081fd703a370ce135837f55de010reed rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0; 1363b3da83a07fd6081fd703a370ce135837f55de010reed } 13646fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 13658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1; 13668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0; 13678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 136872cf4927e503f49c4bd07369e85764ddde57071breed@google.com 13698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::Style style = paint.getStyle(); 13708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar strokeWidth = paint.getStrokeWidth(); 137172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 1372ffe49f5380dd5062073efeda70f2f91682c828careed@google.com unsigned flags = 0; 13734526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org 13746fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isFakeBoldText()) { 13754526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#ifdef SK_USE_FREETYPE_EMBOLDEN 13764526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org flags |= SkScalerContext::kEmbolden_Flag; 13774526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#else 137828be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(), 137928be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpKeys, 138028be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpValues, 138128be72b63e457c680c192a34fb9f58e1c693363fvandebo@chromium.org kStdFakeBoldInterpLength); 13828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale); 138372cf4927e503f49c4bd07369e85764ddde57071breed@google.com 13846fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style == SkPaint::kFill_Style) { 13858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = SkPaint::kStrokeAndFill_Style; 13868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com strokeWidth = extra; // ignore paint's strokeWidth if it was "fill" 13876fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 13888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com strokeWidth += extra; 13896fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 13904526a847da6dc738dc73103ec4d47cc0dbdec478senorblanco@chromium.org#endif 13918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 13928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 13936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isDevKernText()) { 13948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkScalerContext::kDevKernText_Flag; 13956fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 139672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 13976fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style != SkPaint::kFill_Style && strokeWidth > 0) { 13988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fFrameWidth = strokeWidth; 13998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fMiterLimit = paint.getStrokeMiter(); 14008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fStrokeJoin = SkToU8(paint.getStrokeJoin()); 14018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14026fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (style == SkPaint::kStrokeAndFill_Style) { 14038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com flags |= SkScalerContext::kFrameAndFill_Flag; 14046fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 14056fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 14068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fFrameWidth = 0; 14078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fMiterLimit = 0; 14088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rec->fStrokeJoin = 0; 14098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 14108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 141102b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); 141202b5331078861b02b61e9a93f845617a7c900409reed@google.com 1413d54d3fc82456f8789b3e4dff40faeb7b670bcf4breed if (SkMask::kLCD16_Format == rec->fMaskFormat) { 14144942e7550ec80796132ab1ce2cc935a5dd1b464creed if (too_big_for_lcd(*rec, checkPost2x2)) { 141502b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fMaskFormat = SkMask::kA8_Format; 14164a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kGenA8FromLCD_Flag; 141702b5331078861b02b61e9a93f845617a7c900409reed@google.com } else { 14184a8126e7f81384526629b1e21bf89b632ea13cd9reed SkPixelGeometry geometry = deviceProperties 1419b2d77e4d7458145ef4825c28323d9fbbb6b003acreed ? deviceProperties->pixelGeometry() 14204a8126e7f81384526629b1e21bf89b632ea13cd9reed : SkSurfacePropsDefaultPixelGeometry(); 14214a8126e7f81384526629b1e21bf89b632ea13cd9reed switch (geometry) { 14224a8126e7f81384526629b1e21bf89b632ea13cd9reed case kUnknown_SkPixelGeometry: 14234a8126e7f81384526629b1e21bf89b632ea13cd9reed // eeek, can't support LCD 14244a8126e7f81384526629b1e21bf89b632ea13cd9reed rec->fMaskFormat = SkMask::kA8_Format; 14254a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kGenA8FromLCD_Flag; 14264a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 14274a8126e7f81384526629b1e21bf89b632ea13cd9reed case kRGB_H_SkPixelGeometry: 14284a8126e7f81384526629b1e21bf89b632ea13cd9reed // our default, do nothing. 14294a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 14304a8126e7f81384526629b1e21bf89b632ea13cd9reed case kBGR_H_SkPixelGeometry: 14314a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_BGROrder_Flag; 14324a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 14334a8126e7f81384526629b1e21bf89b632ea13cd9reed case kRGB_V_SkPixelGeometry: 14344a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_Vertical_Flag; 14354a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 14364a8126e7f81384526629b1e21bf89b632ea13cd9reed case kBGR_V_SkPixelGeometry: 14374a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_Vertical_Flag; 14384a8126e7f81384526629b1e21bf89b632ea13cd9reed flags |= SkScalerContext::kLCD_BGROrder_Flag; 14394a8126e7f81384526629b1e21bf89b632ea13cd9reed break; 144002b5331078861b02b61e9a93f845617a7c900409reed@google.com } 144102b5331078861b02b61e9a93f845617a7c900409reed@google.com } 144202b5331078861b02b61e9a93f845617a7c900409reed@google.com } 144302b5331078861b02b61e9a93f845617a7c900409reed@google.com 14446fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isEmbeddedBitmapText()) { 144502b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kEmbeddedBitmapText_Flag; 14466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 14476fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isSubpixelText()) { 144802b5331078861b02b61e9a93f845617a7c900409reed@google.com flags |= SkScalerContext::kSubpixelPositioning_Flag; 14496fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 14506fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.isAutohinted()) { 1451f6f56878bc96386882721b15ba610984185d3dc9bungeman@google.com flags |= SkScalerContext::kForceAutohinting_Flag; 14526fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 1453830a23e39bb4a126e573940cd6e354732e295b10reed@google.com if (paint.isVerticalText()) { 1454830a23e39bb4a126e573940cd6e354732e295b10reed@google.com flags |= SkScalerContext::kVertical_Flag; 1455830a23e39bb4a126e573940cd6e354732e295b10reed@google.com } 14568351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { 14578351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com flags |= SkScalerContext::kGenA8FromLCD_Flag; 14588351aabbfe82a76a698fa2bde00d33c1174518cdreed@google.com } 145902b5331078861b02b61e9a93f845617a7c900409reed@google.com rec->fFlags = SkToU16(flags); 146036a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com 1461ffe49f5380dd5062073efeda70f2f91682c828careed@google.com // these modify fFlags, so do them after assigning fFlags 14629d7576724cf9602ff778b18126e0fef0ab3d3bf2reed@google.com rec->setHinting(computeHinting(paint)); 146397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 14649e36c1a9306f052331550dab4728b9875127bfb5joshualitt rec->setLuminanceColor(paint.computeLuminanceColor()); 1465532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1466532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com if (NULL == deviceProperties) { 1467532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setDeviceGamma(SK_GAMMA_EXPONENT); 1468532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setPaintGamma(SK_GAMMA_EXPONENT); 1469532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com } else { 1470b2d77e4d7458145ef4825c28323d9fbbb6b003acreed rec->setDeviceGamma(deviceProperties->gamma()); 1471532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1472532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //For now always set the paint gamma equal to the device gamma. 1473532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //The math in SkMaskGamma can handle them being different, 1474532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //but it requires superluminous masks when 1475532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com //Ex : deviceGamma(x) < paintGamma(x) and x is sufficiently large. 1476b2d77e4d7458145ef4825c28323d9fbbb6b003acreed rec->setPaintGamma(deviceProperties->gamma()); 1477532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com } 1478532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 1479532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com#ifdef SK_GAMMA_CONTRAST 1480532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->setContrast(SK_GAMMA_CONTRAST); 1481ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com#else 1482532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com /** 1483532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * A value of 0.5 for SK_GAMMA_CONTRAST appears to be a good compromise. 1484532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * With lower values small text appears washed out (though correctly so). 1485532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * With higher values lcd fringing is worse and the smoothing effect of 1486532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com * partial coverage is diminished. 1487532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com */ 14884b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org rec->setContrast(0.5f); 1489ce6dbb6b4ce3f36e0a2245b215dc48b68df35c41reed@google.com#endif 1490532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com 14912bf82d843d8896dd10bb86adc1e974c6d52324e6bungeman@google.com rec->fReservedAlign = 0; 1492fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 149336a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com /* Allow the fonthost to modify our rec before we use it as a key into the 149436a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com cache. This way if we're asking for something that they will ignore, 149536a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com they can modify our rec up front, so we don't create duplicate cache 149636a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com entries. 149736a4c2aa2dc2363dc093089b732346459ddc3b65reed@android.com */ 1498fed86bdb8b9f037439bbfa7cdbd53a581dbc5985reed@google.com typeface->onFilterRec(rec); 14993e8ae5b457558435218a864dd0e852f83abfe802reed@google.com 150010d2d4d1062ef56526f187e6716c5e747689b598reed@google.com // be sure to call PostMakeRec(rec) before you actually use it! 150110d2d4d1062ef56526f187e6716c5e747689b598reed@google.com} 150210d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 150310d2d4d1062ef56526f187e6716c5e747689b598reed@google.com/** 150497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * In order to call cachedDeviceLuminance, cachedPaintLuminance, or 150597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * cachedMaskGamma the caller must hold the gMaskGammaCacheMutex and continue 150697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * to hold it until the returned pointer is refed or forgotten. 150710d2d4d1062ef56526f187e6716c5e747689b598reed@google.com */ 150897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.comSK_DECLARE_STATIC_MUTEX(gMaskGammaCacheMutex); 150910d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 1510ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.comstatic SkMaskGamma* gLinearMaskGamma = NULL; 1511b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkMaskGamma* gMaskGamma = NULL; 1512b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gContrast = SK_ScalarMin; 1513b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gPaintGamma = SK_ScalarMin; 1514b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.comstatic SkScalar gDeviceGamma = SK_ScalarMin; 151597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 151697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * The caller must hold the gMaskGammaCacheMutex and continue to hold it until 151797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * the returned SkMaskGamma pointer is refed or forgotten. 151897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 1519a76de72a6036da0a6b051b14411b80941971f881bungeman@google.comstatic const SkMaskGamma& cachedMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) { 1520b83f6c3cbdabc14d8290b00d9f38ba59bf6719a1mtklein gMaskGammaCacheMutex.assertHeld(); 1521ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com if (0 == contrast && SK_Scalar1 == paintGamma && SK_Scalar1 == deviceGamma) { 1522ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com if (NULL == gLinearMaskGamma) { 1523ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com gLinearMaskGamma = SkNEW(SkMaskGamma); 1524ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com } 1525a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return *gLinearMaskGamma; 1526ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com } 152797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com if (gContrast != contrast || gPaintGamma != paintGamma || gDeviceGamma != deviceGamma) { 152897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkSafeUnref(gMaskGamma); 1529b1a72cb90a9b515978bc9abda1f267f31a544e08bungeman@google.com gMaskGamma = SkNEW_ARGS(SkMaskGamma, (contrast, paintGamma, deviceGamma)); 153097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gContrast = contrast; 153197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gPaintGamma = paintGamma; 153297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com gDeviceGamma = deviceGamma; 153397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com } 1534a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return *gMaskGamma; 153597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com} 153697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 1537b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com/*static*/ void SkPaint::Term() { 1538b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 1539b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com 1540ae30f5601940c78f4537ee48a6316cfac6740712bungeman@google.com SkSafeUnref(gLinearMaskGamma); 15415987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com gLinearMaskGamma = NULL; 1542b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkSafeUnref(gMaskGamma); 15435987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com gMaskGamma = NULL; 1544b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gContrast = SK_ScalarMin;) 1545b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gPaintGamma = SK_ScalarMin;) 1546b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com SkDEBUGCODE(gDeviceGamma = SK_ScalarMin;) 1547b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com} 1548b24b4fa12be03807a0c3c710ec5ad102f3a8e145bungeman@google.com 154997efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 155097efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * We ensure that the rec is self-consistent and efficient (where possible) 155197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 15528d38d516c0f17d8d9f6b170055ac05ac181c0554sugoi@google.comvoid SkScalerContext::PostMakeRec(const SkPaint&, SkScalerContext::Rec* rec) { 155310d2d4d1062ef56526f187e6716c5e747689b598reed@google.com /** 155410d2d4d1062ef56526f187e6716c5e747689b598reed@google.com * If we're asking for A8, we force the colorlum to be gray, since that 155597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * limits the number of unique entries, and the scaler will only look at 155697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * the lum of one of them. 155710d2d4d1062ef56526f187e6716c5e747689b598reed@google.com */ 1558dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com switch (rec->fMaskFormat) { 1559d54d3fc82456f8789b3e4dff40faeb7b670bcf4breed case SkMask::kLCD16_Format: { 1560dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // filter down the luminance color to a finite number of bits 156197efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkColor color = rec->getLuminanceColor(); 1562b5715a1c8003e4a8af2301ab44aeef043547808ereed@google.com rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color)); 1563dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 1564dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com } 1565dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kA8_Format: { 1566dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // filter down the luminance to a single component, since A8 can't 1567dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // use per-component information 156897efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkColor color = rec->getLuminanceColor(); 1569dc1cf66483e93c2d12d938bc1ce3b8c60cc68da5jvanverth U8CPU lum = SkComputeLuminance(SkColorGetR(color), 1570dc1cf66483e93c2d12d938bc1ce3b8c60cc68da5jvanverth SkColorGetG(color), 1571dc1cf66483e93c2d12d938bc1ce3b8c60cc68da5jvanverth SkColorGetB(color)); 1572dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // reduce to our finite number of bits 157397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com color = SkColorSetRGB(lum, lum, lum); 1574b5715a1c8003e4a8af2301ab44aeef043547808ereed@google.com rec->setLuminanceColor(SkMaskGamma::CanonicalColor(color)); 1575dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 1576dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com } 1577dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com case SkMask::kBW_Format: 1578dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com // No need to differentiate gamma if we're BW 1579532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.com rec->ignorePreBlend(); 1580dd43df99b16b67f7b00457b7fff4b2539da40702reed@google.com break; 15813e8ae5b457558435218a864dd0e852f83abfe802reed@google.com } 15828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 15838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 15848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MIN_SIZE_FOR_EFFECT_BUFFER 1024 15858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#ifdef SK_DEBUG 158717fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com #define TEST_DESC 158817fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#endif 158917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com 1590fd45079314b739979492601fc7a242aff24c58a3joshualittstatic void write_out_descriptor(SkDescriptor* desc, const SkScalerContext::Rec& rec, 1591fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkPathEffect* pe, SkWriteBuffer* peBuffer, 1592fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkMaskFilter* mf, SkWriteBuffer* mfBuffer, 1593fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkRasterizer* ra, SkWriteBuffer* raBuffer, 1594fd45079314b739979492601fc7a242aff24c58a3joshualitt size_t descSize) { 1595fd45079314b739979492601fc7a242aff24c58a3joshualitt desc->init(); 1596fd45079314b739979492601fc7a242aff24c58a3joshualitt desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 15978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1598fd45079314b739979492601fc7a242aff24c58a3joshualitt if (pe) { 1599fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc, kPathEffect_SkDescriptorTag, peBuffer); 1600fd45079314b739979492601fc7a242aff24c58a3joshualitt } 1601fd45079314b739979492601fc7a242aff24c58a3joshualitt if (mf) { 1602fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc, kMaskFilter_SkDescriptorTag, mfBuffer); 1603fd45079314b739979492601fc7a242aff24c58a3joshualitt } 1604fd45079314b739979492601fc7a242aff24c58a3joshualitt if (ra) { 1605fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc, kRasterizer_SkDescriptorTag, raBuffer); 160657f4969724a1dd88c8d9ae35a863e6cf621181d5djsollen@google.com } 16078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1608fd45079314b739979492601fc7a242aff24c58a3joshualitt desc->computeChecksum(); 1609fd45079314b739979492601fc7a242aff24c58a3joshualitt} 1610fd45079314b739979492601fc7a242aff24c58a3joshualitt 1611fd45079314b739979492601fc7a242aff24c58a3joshualittstatic size_t fill_out_rec(const SkPaint& paint, SkScalerContext::Rec* rec, 1612fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkDeviceProperties* deviceProperties, 1613fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkMatrix* deviceMatrix, bool ignoreGamma, 1614fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkPathEffect* pe, SkWriteBuffer* peBuffer, 1615fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkMaskFilter* mf, SkWriteBuffer* mfBuffer, 1616fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkRasterizer* ra, SkWriteBuffer* raBuffer) { 1617fd45079314b739979492601fc7a242aff24c58a3joshualitt SkScalerContext::MakeRec(paint, deviceProperties, deviceMatrix, rec); 1618fd45079314b739979492601fc7a242aff24c58a3joshualitt if (ignoreGamma) { 1619fd45079314b739979492601fc7a242aff24c58a3joshualitt rec->ignorePreBlend(); 1620fd45079314b739979492601fc7a242aff24c58a3joshualitt } 16218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1622fd45079314b739979492601fc7a242aff24c58a3joshualitt int entryCount = 1; 1623fd45079314b739979492601fc7a242aff24c58a3joshualitt size_t descSize = sizeof(*rec); 16248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pe) { 1626fd45079314b739979492601fc7a242aff24c58a3joshualitt peBuffer->writeFlattenable(pe); 1627fd45079314b739979492601fc7a242aff24c58a3joshualitt descSize += peBuffer->bytesWritten(); 16288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 1629fd45079314b739979492601fc7a242aff24c58a3joshualitt rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // seems like we could support kLCD as well at this point... 16318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mf) { 1633fd45079314b739979492601fc7a242aff24c58a3joshualitt mfBuffer->writeFlattenable(mf); 1634fd45079314b739979492601fc7a242aff24c58a3joshualitt descSize += mfBuffer->bytesWritten(); 16358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 1636fd45079314b739979492601fc7a242aff24c58a3joshualitt rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing with maskfilters 1637a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com /* Pre-blend is not currently applied to filtered text. 1638a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com The primary filter is blur, for which contrast makes no sense, 1639a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com and for which the destination guess error is more visible. 1640a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com Also, all existing users of blur have calibrated for linear. */ 1641fd45079314b739979492601fc7a242aff24c58a3joshualitt rec->ignorePreBlend(); 16428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ra) { 1644fd45079314b739979492601fc7a242aff24c58a3joshualitt raBuffer->writeFlattenable(ra); 1645fd45079314b739979492601fc7a242aff24c58a3joshualitt descSize += raBuffer->bytesWritten(); 16468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com entryCount += 1; 1647fd45079314b739979492601fc7a242aff24c58a3joshualitt rec->fMaskFormat = SkMask::kA8_Format; // force antialiasing when we do the scan conversion 16488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 164910d2d4d1062ef56526f187e6716c5e747689b598reed@google.com 165010d2d4d1062ef56526f187e6716c5e747689b598reed@google.com /////////////////////////////////////////////////////////////////////////// 165110d2d4d1062ef56526f187e6716c5e747689b598reed@google.com // Now that we're done tweaking the rec, call the PostMakeRec cleanup 1652fd45079314b739979492601fc7a242aff24c58a3joshualitt SkScalerContext::PostMakeRec(paint, rec); 1653fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 16548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com descSize += SkDescriptor::ComputeOverhead(entryCount); 1655fd45079314b739979492601fc7a242aff24c58a3joshualitt return descSize; 1656fd45079314b739979492601fc7a242aff24c58a3joshualitt} 16578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1658fd45079314b739979492601fc7a242aff24c58a3joshualitt#ifdef TEST_DESC 1659fd45079314b739979492601fc7a242aff24c58a3joshualittstatic void test_desc(const SkScalerContext::Rec& rec, 1660fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkPathEffect* pe, SkWriteBuffer* peBuffer, 1661fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkMaskFilter* mf, SkWriteBuffer* mfBuffer, 1662fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkRasterizer* ra, SkWriteBuffer* raBuffer, 1663fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkDescriptor* desc, size_t descSize) { 1664fd45079314b739979492601fc7a242aff24c58a3joshualitt // Check that we completely write the bytes in desc (our key), and that 1665fd45079314b739979492601fc7a242aff24c58a3joshualitt // there are no uninitialized bytes. If there were, then we would get 1666fd45079314b739979492601fc7a242aff24c58a3joshualitt // false-misses (or worse, false-hits) in our fontcache. 1667fd45079314b739979492601fc7a242aff24c58a3joshualitt // 1668fd45079314b739979492601fc7a242aff24c58a3joshualitt // We do this buy filling 2 others, one with 0s and the other with 1s 1669fd45079314b739979492601fc7a242aff24c58a3joshualitt // and create those, and then check that all 3 are identical. 1670fd45079314b739979492601fc7a242aff24c58a3joshualitt SkAutoDescriptor ad1(descSize); 1671fd45079314b739979492601fc7a242aff24c58a3joshualitt SkAutoDescriptor ad2(descSize); 1672fd45079314b739979492601fc7a242aff24c58a3joshualitt SkDescriptor* desc1 = ad1.getDesc(); 1673fd45079314b739979492601fc7a242aff24c58a3joshualitt SkDescriptor* desc2 = ad2.getDesc(); 1674fd45079314b739979492601fc7a242aff24c58a3joshualitt 1675fd45079314b739979492601fc7a242aff24c58a3joshualitt memset(desc1, 0x00, descSize); 1676fd45079314b739979492601fc7a242aff24c58a3joshualitt memset(desc2, 0xFF, descSize); 1677fd45079314b739979492601fc7a242aff24c58a3joshualitt 1678fd45079314b739979492601fc7a242aff24c58a3joshualitt desc1->init(); 1679fd45079314b739979492601fc7a242aff24c58a3joshualitt desc2->init(); 1680fd45079314b739979492601fc7a242aff24c58a3joshualitt desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 1681fd45079314b739979492601fc7a242aff24c58a3joshualitt desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); 16828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pe) { 1684fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc1, kPathEffect_SkDescriptorTag, peBuffer); 1685fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc2, kPathEffect_SkDescriptorTag, peBuffer); 16868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (mf) { 1688fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc1, kMaskFilter_SkDescriptorTag, mfBuffer); 1689fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc2, kMaskFilter_SkDescriptorTag, mfBuffer); 16908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (ra) { 1692fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc1, kRasterizer_SkDescriptorTag, raBuffer); 1693fd45079314b739979492601fc7a242aff24c58a3joshualitt add_flattenable(desc2, kRasterizer_SkDescriptorTag, raBuffer); 16948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 16958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1696fd45079314b739979492601fc7a242aff24c58a3joshualitt SkASSERT(descSize == desc1->getLength()); 1697fd45079314b739979492601fc7a242aff24c58a3joshualitt SkASSERT(descSize == desc2->getLength()); 1698fd45079314b739979492601fc7a242aff24c58a3joshualitt desc1->computeChecksum(); 1699fd45079314b739979492601fc7a242aff24c58a3joshualitt desc2->computeChecksum(); 1700fd45079314b739979492601fc7a242aff24c58a3joshualitt SkASSERT(!memcmp(desc, desc1, descSize)); 1701fd45079314b739979492601fc7a242aff24c58a3joshualitt SkASSERT(!memcmp(desc, desc2, descSize)); 1702fd45079314b739979492601fc7a242aff24c58a3joshualitt} 1703fd45079314b739979492601fc7a242aff24c58a3joshualitt#endif 1704fd45079314b739979492601fc7a242aff24c58a3joshualitt 1705fd45079314b739979492601fc7a242aff24c58a3joshualitt/* see the note on ignoreGamma on descriptorProc */ 17062b6acb4ed52483bc2a89dbbaa6f0db4fdb217cd3joshualittvoid SkPaint::getScalerContextDescriptor(SkAutoDescriptor* ad, 17072b6acb4ed52483bc2a89dbbaa6f0db4fdb217cd3joshualitt const SkDeviceProperties* deviceProperties, 17082b6acb4ed52483bc2a89dbbaa6f0db4fdb217cd3joshualitt const SkMatrix* deviceMatrix, bool ignoreGamma) const { 1709fd45079314b739979492601fc7a242aff24c58a3joshualitt SkScalerContext::Rec rec; 1710fd45079314b739979492601fc7a242aff24c58a3joshualitt 1711fd45079314b739979492601fc7a242aff24c58a3joshualitt SkPathEffect* pe = this->getPathEffect(); 1712fd45079314b739979492601fc7a242aff24c58a3joshualitt SkMaskFilter* mf = this->getMaskFilter(); 1713fd45079314b739979492601fc7a242aff24c58a3joshualitt SkRasterizer* ra = this->getRasterizer(); 1714fd45079314b739979492601fc7a242aff24c58a3joshualitt 1715fd45079314b739979492601fc7a242aff24c58a3joshualitt SkWriteBuffer peBuffer, mfBuffer, raBuffer; 1716fd45079314b739979492601fc7a242aff24c58a3joshualitt size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix, ignoreGamma, 1717fd45079314b739979492601fc7a242aff24c58a3joshualitt pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); 1718fd45079314b739979492601fc7a242aff24c58a3joshualitt 17192b6acb4ed52483bc2a89dbbaa6f0db4fdb217cd3joshualitt ad->reset(descSize); 17202b6acb4ed52483bc2a89dbbaa6f0db4fdb217cd3joshualitt SkDescriptor* desc = ad->getDesc(); 1721fd45079314b739979492601fc7a242aff24c58a3joshualitt 1722fd45079314b739979492601fc7a242aff24c58a3joshualitt write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, descSize); 1723fd45079314b739979492601fc7a242aff24c58a3joshualitt 17248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(descSize == desc->getLength()); 17258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 172617fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#ifdef TEST_DESC 1727fd45079314b739979492601fc7a242aff24c58a3joshualitt test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); 1728fd45079314b739979492601fc7a242aff24c58a3joshualitt#endif 1729fd45079314b739979492601fc7a242aff24c58a3joshualitt} 1730fd45079314b739979492601fc7a242aff24c58a3joshualitt 1731fd45079314b739979492601fc7a242aff24c58a3joshualitt/* 1732fd45079314b739979492601fc7a242aff24c58a3joshualitt * ignoreGamma tells us that the caller just wants metrics that are unaffected 1733fd45079314b739979492601fc7a242aff24c58a3joshualitt * by gamma correction, so we set the rec to ignore preblend: i.e. gamma = 1, 1734fd45079314b739979492601fc7a242aff24c58a3joshualitt * contrast = 0, luminanceColor = transparent black. 1735fd45079314b739979492601fc7a242aff24c58a3joshualitt */ 1736fd45079314b739979492601fc7a242aff24c58a3joshualittvoid SkPaint::descriptorProc(const SkDeviceProperties* deviceProperties, 1737fd45079314b739979492601fc7a242aff24c58a3joshualitt const SkMatrix* deviceMatrix, 1738fd45079314b739979492601fc7a242aff24c58a3joshualitt void (*proc)(SkTypeface*, const SkDescriptor*, void*), 1739fd45079314b739979492601fc7a242aff24c58a3joshualitt void* context, bool ignoreGamma) const { 1740fd45079314b739979492601fc7a242aff24c58a3joshualitt SkScalerContext::Rec rec; 1741fd45079314b739979492601fc7a242aff24c58a3joshualitt 1742fd45079314b739979492601fc7a242aff24c58a3joshualitt SkPathEffect* pe = this->getPathEffect(); 1743fd45079314b739979492601fc7a242aff24c58a3joshualitt SkMaskFilter* mf = this->getMaskFilter(); 1744fd45079314b739979492601fc7a242aff24c58a3joshualitt SkRasterizer* ra = this->getRasterizer(); 1745fd45079314b739979492601fc7a242aff24c58a3joshualitt 1746fd45079314b739979492601fc7a242aff24c58a3joshualitt SkWriteBuffer peBuffer, mfBuffer, raBuffer; 1747fd45079314b739979492601fc7a242aff24c58a3joshualitt size_t descSize = fill_out_rec(*this, &rec, deviceProperties, deviceMatrix, ignoreGamma, 1748fd45079314b739979492601fc7a242aff24c58a3joshualitt pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer); 1749fd45079314b739979492601fc7a242aff24c58a3joshualitt 1750fd45079314b739979492601fc7a242aff24c58a3joshualitt SkAutoDescriptor ad(descSize); 1751fd45079314b739979492601fc7a242aff24c58a3joshualitt SkDescriptor* desc = ad.getDesc(); 1752fd45079314b739979492601fc7a242aff24c58a3joshualitt 1753fd45079314b739979492601fc7a242aff24c58a3joshualitt write_out_descriptor(desc, rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, descSize); 1754fd45079314b739979492601fc7a242aff24c58a3joshualitt 1755fd45079314b739979492601fc7a242aff24c58a3joshualitt SkASSERT(descSize == desc->getLength()); 1756fd45079314b739979492601fc7a242aff24c58a3joshualitt 1757fd45079314b739979492601fc7a242aff24c58a3joshualitt#ifdef TEST_DESC 1758fd45079314b739979492601fc7a242aff24c58a3joshualitt test_desc(rec, pe, &peBuffer, mf, &mfBuffer, ra, &raBuffer, desc, descSize); 175917fb387a56f8fcfcb9ccf585e2c53ee8e709028dreed@google.com#endif 1760fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 176190808e87c21e93b8e670360655e0b0eb12cb2f87reed@google.com proc(fTypeface, desc, context); 17628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1764532470f34dbe9fc0b8b71e3917eca8894feaf336bungeman@google.comSkGlyphCache* SkPaint::detachCache(const SkDeviceProperties* deviceProperties, 17652d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMatrix* deviceMatrix, 17662d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth bool ignoreGamma) const { 17678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache* cache; 17682d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth this->descriptorProc(deviceProperties, deviceMatrix, DetachDescProc, &cache, ignoreGamma); 17698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return cache; 17708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 17718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 177297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com/** 177397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com * Expands fDeviceGamma, fPaintGamma, fContrast, and fLumBits into a mask pre-blend. 177497efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com */ 177597efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com//static 177697efada074e4806479f1350ab1508939c2fdcb53bungeman@google.comSkMaskGamma::PreBlend SkScalerContext::GetMaskPreBlend(const SkScalerContext::Rec& rec) { 177797efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 1778a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com const SkMaskGamma& maskGamma = cachedMaskGamma(rec.getContrast(), 1779a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.getPaintGamma(), 1780a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com rec.getDeviceGamma()); 1781a76de72a6036da0a6b051b14411b80941971f881bungeman@google.com return maskGamma.preBlend(rec.getLuminanceColor()); 178297efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com} 178397efada074e4806479f1350ab1508939c2fdcb53bungeman@google.com 17842d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthsize_t SkScalerContext::GetGammaLUTSize(SkScalar contrast, SkScalar paintGamma, 17852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkScalar deviceGamma, int* width, int* height) { 17862d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 17872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, 17882d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth paintGamma, 17892d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth deviceGamma); 17902d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 17912d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth maskGamma.getGammaTableDimensions(width, height); 17922d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth size_t size = (*width)*(*height)*sizeof(uint8_t); 17932d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 17942d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth return size; 17952d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth} 17962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 17972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthvoid SkScalerContext::GetGammaLUTData(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma, 17982d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth void* data) { 17992d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth SkAutoMutexAcquire ama(gMaskGammaCacheMutex); 18002d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const SkMaskGamma& maskGamma = cachedMaskGamma(contrast, 18012d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth paintGamma, 18022d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth deviceGamma); 18032d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth int width, height; 18042d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth maskGamma.getGammaTableDimensions(&width, &height); 18052d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth size_t size = width*height*sizeof(uint8_t); 18062d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth const uint8_t* gammaTables = maskGamma.getGammaTables(); 18072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth memcpy(data, gammaTables, size); 18082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth} 18092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 18102d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth 18118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 18128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 18148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1815aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uintptr_t asint(const void* p) { 1816aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return reinterpret_cast<uintptr_t>(p); 1817aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1818aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1819aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comunion Scalar32 { 1820aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkScalar fScalar; 1821aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com uint32_t f32; 1822aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com}; 1823aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1824aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) { 1825aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 1826aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com Scalar32 tmp; 1827aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com tmp.fScalar = value; 1828aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com *ptr = tmp.f32; 1829aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return ptr + 1; 1830aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1831aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1832aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic SkScalar read_scalar(const uint32_t*& ptr) { 1833aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(sizeof(SkScalar) == sizeof(uint32_t)); 1834aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com Scalar32 tmp; 1835aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com tmp.f32 = *ptr++; 1836aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return tmp.fScalar; 1837aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1838aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1839aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) { 1840aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(a == (uint8_t)a); 1841aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(b == (uint8_t)b); 1842aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(c == (uint8_t)c); 1843aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com SkASSERT(d == (uint8_t)d); 1844aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com return (a << 24) | (b << 16) | (c << 8) | d; 1845aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com} 1846aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 184785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#ifdef SK_DEBUG 184885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org static void ASSERT_FITS_IN(uint32_t value, int bitCount) { 184985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org SkASSERT(bitCount > 0 && bitCount <= 32); 185085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t mask = ~0U; 185185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org mask >>= (32 - bitCount); 185285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org SkASSERT(0 == (value & ~mask)); 185385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org } 185485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#else 185585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org #define ASSERT_FITS_IN(value, bitcount) 185685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org#endif 185785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 1858aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.comenum FlatFlags { 185988fd0fbcccea615f2d2cd61a121ac9e3185adfe4mtklein kHasTypeface_FlatFlag = 0x1, 186088fd0fbcccea615f2d2cd61a121ac9e3185adfe4mtklein kHasEffects_FlatFlag = 0x2, 1861667b98d947892cec939669bccf204ab9ed565c4eskia.committer@gmail.com 186288fd0fbcccea615f2d2cd61a121ac9e3185adfe4mtklein kFlatFlagMask = 0x3, 186385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org}; 186485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 186585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgenum BitsPerField { 186685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlags_BPF = 16, 186785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kHint_BPF = 2, 186885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kAlign_BPF = 2, 186985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFilter_BPF = 2, 187085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org kFlatFlags_BPF = 3, 1871aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com}; 1872aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 187385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic inline int BPF_Mask(int bits) { 187485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (1 << bits) - 1; 187585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 187685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 187785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic uint32_t pack_paint_flags(unsigned flags, unsigned hint, unsigned align, 187885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org unsigned filter, unsigned flatFlags) { 187985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(flags, kFlags_BPF); 188085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(hint, kHint_BPF); 188185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(align, kAlign_BPF); 188285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(filter, kFilter_BPF); 188385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org ASSERT_FITS_IN(flatFlags, kFlatFlags_BPF); 188485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 188585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // left-align the fields of "known" size, and right-align the last (flatFlags) so it can easly 188685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org // add more bits in the future. 188785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (flags << 16) | (hint << 14) | (align << 12) | (filter << 10) | flatFlags; 188885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 188985faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 189085faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.orgstatic FlatFlags unpack_paint_flags(SkPaint* paint, uint32_t packed) { 189185faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setFlags(packed >> 16); 189285faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setHinting((SkPaint::Hinting)((packed >> 14) & BPF_Mask(kHint_BPF))); 189385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org paint->setTextAlign((SkPaint::Align)((packed >> 12) & BPF_Mask(kAlign_BPF))); 189493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed paint->setFilterQuality((SkFilterQuality)((packed >> 10) & BPF_Mask(kFilter_BPF))); 189585faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org return (FlatFlags)(packed & kFlatFlagMask); 189685faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org} 189785faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 1898aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com// The size of a flat paint's POD fields 1899d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comstatic const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) + 19001f1543f012b8834ea760175a023eb127bde2b895reed@google.com 1 * sizeof(SkColor) + 19011f1543f012b8834ea760175a023eb127bde2b895reed@google.com 1 * sizeof(uint16_t) + 19021f1543f012b8834ea760175a023eb127bde2b895reed@google.com 6 * sizeof(uint8_t); 1903aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1904aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com/* To save space/time, we analyze the paint, and write a truncated version of 1905aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com it if there are not tricky elements like shaders, etc. 1906aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com */ 19078b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPaint::flatten(SkWriteBuffer& buffer) const { 1908aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com uint8_t flatFlags = 0; 1909aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (this->getTypeface()) { 1910aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com flatFlags |= kHasTypeface_FlatFlag; 1911aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 1912aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (asint(this->getPathEffect()) | 1913aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getShader()) | 1914aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getXfermode()) | 1915aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getMaskFilter()) | 1916aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getColorFilter()) | 1917aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com asint(this->getRasterizer()) | 191854e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org asint(this->getLooper()) | 1919b0a34d80c5c7b06db8083a547f8e499781a9c169reed@google.com asint(this->getAnnotation()) | 192054e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org asint(this->getImageFilter())) { 1921aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com flatFlags |= kHasEffects_FlatFlag; 1922aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 1923c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com 19248b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 19258b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org uint32_t* ptr = buffer.reserve(kPODPaintSize); 19268b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 19278b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextSize()); 19288b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextScaleX()); 19298b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getTextSkewX()); 19308b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getStrokeWidth()); 19318b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org ptr = write_scalar(ptr, this->getStrokeMiter()); 19328b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *ptr++ = this->getColor(); 193385faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org 193485faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org *ptr++ = pack_paint_flags(this->getFlags(), this->getHinting(), this->getTextAlign(), 193593a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed this->getFilterQuality(), flatFlags); 19368b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(), 19378b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->getStyle(), this->getTextEncoding()); 1938aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1939aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com // now we're done with ptr and the (pre)reserved space. If we need to write 1940aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com // additional fields, use the buffer directly 1941aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasTypeface_FlatFlag) { 1942aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeTypeface(this->getTypeface()); 1943aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 1944aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasEffects_FlatFlag) { 1945aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getPathEffect()); 1946aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getShader()); 1947aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getXfermode()); 1948aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getMaskFilter()); 1949aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getColorFilter()); 1950aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getRasterizer()); 1951aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com buffer.writeFlattenable(this->getLooper()); 195254e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org buffer.writeFlattenable(this->getImageFilter()); 19530cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com 19540cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com if (fAnnotation) { 19550cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com buffer.writeBool(true); 19560cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com fAnnotation->writeToBuffer(buffer); 19570cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } else { 19580cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com buffer.writeBool(false); 19590cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } 1960aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 19618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 19628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19638b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPaint::unflatten(SkReadBuffer& buffer) { 19648b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize); 19658b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org const void* podData = buffer.skip(kPODPaintSize); 19668b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData); 19678b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 19688b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org // the order we read must match the order we wrote in flatten() 19698b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextSize(read_scalar(pod)); 19708b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextScaleX(read_scalar(pod)); 19718b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextSkewX(read_scalar(pod)); 19728b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeWidth(read_scalar(pod)); 19738b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeMiter(read_scalar(pod)); 19748b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setColor(*pod++); 19758b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 197688fd0fbcccea615f2d2cd61a121ac9e3185adfe4mtklein unsigned flatFlags = unpack_paint_flags(this, *pod++); 19778b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org 197885faf50875fcf6008880a98aaa05d12ae8dad343commit-bot@chromium.org uint32_t tmp = *pod++; 19798b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF)); 19808b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF)); 19818b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF)); 19828b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF)); 1983aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1984aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasTypeface_FlatFlag) { 1985aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setTypeface(buffer.readTypeface()); 1986aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } else { 1987aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setTypeface(NULL); 1988aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 1989aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com 1990aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com if (flatFlags & kHasEffects_FlatFlag) { 1991353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setPathEffect(buffer.readPathEffect())); 1992353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setShader(buffer.readShader())); 1993353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setXfermode(buffer.readXfermode())); 1994353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setMaskFilter(buffer.readMaskFilter())); 1995353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setColorFilter(buffer.readColorFilter())); 1996353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setRasterizer(buffer.readRasterizer())); 1997353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setLooper(buffer.readDrawLooper())); 1998353482251e61971a8cf3a60bbb6910f482be634freed@google.com SkSafeUnref(this->setImageFilter(buffer.readImageFilter())); 1999fbc58a305518fe611113a51649bf557c991ac8cfskia.committer@gmail.com 20000cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com if (buffer.readBool()) { 2001d957984c1efbd18f3b2bbeca78d282837c5a2ae1commit-bot@chromium.org this->setAnnotation(SkAnnotation::Create(buffer))->unref(); 20020cd2ac6c721120a2628524dad91798aa3e7ec41dreed@google.com } 2003aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } else { 2004aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setPathEffect(NULL); 2005aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setShader(NULL); 2006aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setXfermode(NULL); 2007aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setMaskFilter(NULL); 2008aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setColorFilter(NULL); 2009aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setRasterizer(NULL); 2010aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com this->setLooper(NULL); 201154e01b2ab985e7a7d38109812069d056d128bfa1senorblanco@chromium.org this->setImageFilter(NULL); 2012aefd2bc75738963b9b6579897be32bfbc8fb00afreed@android.com } 20138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 20168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 201782065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkShader* SkPaint::setShader(SkShader* shader) { 20188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fShader, shader); 20198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return shader; 20208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 202282065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { 20238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fColorFilter, filter); 20248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 20258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 202782065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkXfermode* SkPaint::setXfermode(SkXfermode* mode) { 20288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fXfermode, mode); 20298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mode; 20308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20320baf19375466cfc24c96532df406e7c5b1d1aae8reed@android.comSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { 2033d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com SkSafeUnref(fXfermode); 2034d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com fXfermode = SkXfermode::Create(mode); 2035d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com return fXfermode; 2036d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com} 2037d66eef71012bdbc14834c12c8af1c946fe0d8499reed@android.com 203882065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { 20398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fPathEffect, effect); 20408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return effect; 20418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 204382065d667f64e232bcde2ad849756a6096fcbe6freed@google.comSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { 20448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRefCnt_SafeAssign(fMaskFilter, filter); 20458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return filter; 20468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 204882065d667f64e232bcde2ad849756a6096fcbe6freed@google.com/////////////////////////////////////////////////////////////////////////////// 20498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205005d9044de4f1c6e791df66a425638752daac4c6breedbool SkPaint::getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect, 205105d9044de4f1c6e791df66a425638752daac4c6breed SkScalar resScale) const { 205205d9044de4f1c6e791df66a425638752daac4c6breed SkStrokeRec rec(*this, resScale); 20538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2054fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com const SkPath* srcPtr = &src; 2055fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com SkPath tmpPath; 205672cf4927e503f49c4bd07369e85764ddde57071breed@google.com 20574bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com if (fPathEffect && fPathEffect->filterPath(&tmpPath, src, &rec, cullRect)) { 2058fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com srcPtr = &tmpPath; 20598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 20608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2061fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com if (!rec.applyToPath(dst, *srcPtr)) { 2062fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com if (srcPtr == &tmpPath) { 2063fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // If path's were copy-on-write, this trick would not be needed. 2064fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // As it is, we want to save making a deep-copy from tmpPath -> dst 2065fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // since we know we're just going to delete tmpPath when we return, 2066fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com // so the swap saves that copy. 2067fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com dst->swap(tmpPath); 2068fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com } else { 2069fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com *dst = *srcPtr; 2070d3521f1a8dc07fe84d6a8f2151b0c176ff1ec8careed@google.com } 2071d3521f1a8dc07fe84d6a8f2151b0c176ff1ec8careed@google.com } 2072fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com return !rec.isHairlineStyle(); 20738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 20748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2075e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.comconst SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc, 2076a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com SkRect* storage, 2077a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com Style style) const { 20788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(storage); 20799efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2080e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com const SkRect* src = &origSrc; 2081e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 20829efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (this->getLooper()) { 20839efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkASSERT(this->getLooper()->canComputeFastBounds(*this)); 2084e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com this->getLooper()->computeFastBounds(*this, *src, storage); 20859efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com return *storage; 20869efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 20879efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2088e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com SkRect tmpSrc; 2089e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com if (this->getPathEffect()) { 2090e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com this->getPathEffect()->computeFastBounds(&tmpSrc, origSrc); 2091e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com src = &tmpSrc; 2092e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com } 2093e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 2094a584aed5f709ff9655fd3326e23cd6f602ac7ae4reed@google.com if (kFill_Style != style) { 20959efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com // since we're stroked, outset the rect by the radius (and join type) 20969efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkScalar radius = SkScalarHalf(this->getStrokeWidth()); 20979efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (0 == radius) { // hairline 20989efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com radius = SK_Scalar1; 20999efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) { 21009efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com SkScalar scale = this->getStrokeMiter(); 21019efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (scale > SK_Scalar1) { 21029efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com radius = SkScalarMul(radius, scale); 21039efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 21048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2105e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com storage->set(src->fLeft - radius, src->fTop - radius, 2106e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com src->fRight + radius, src->fBottom + radius); 21079efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } else { 2108e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com *storage = *src; 21098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 21109efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 21119efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com if (this->getMaskFilter()) { 21129efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com this->getMaskFilter()->computeFastBounds(*storage, storage); 21139efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com } 21149efd9a048aebaa6681afb76b18e1a7dd642078d3reed@google.com 2115336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org if (this->getImageFilter()) { 2116336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org this->getImageFilter()->computeFastBounds(*storage, storage); 2117336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org } 2118336d1d759590d9bedcbc5a96d0fff79861cf8f7asenorblanco@chromium.org 2119d252db03d9650013b545ef9781fe993c07f8f314reed@android.com return *storage; 21208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 21218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21220f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 212383658305a1bda2d862f50145ecf5cb697b575e86reed 2124791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.comvoid SkPaint::toString(SkString* str) const { 2125791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dl><dt>SkPaint:</dt><dd><dl>"); 2126791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2127791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkTypeface* typeface = this->getTypeface(); 212849f085dddff10473b6ebf832a974288300224e60bsalomon if (typeface) { 2129d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman SkDynamicMemoryWStream ostream; 2130d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman typeface->serialize(&ostream); 2131a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkAutoTDelete<SkStreamAsset> istream(ostream.detachAsStream()); 2132d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman SkFontDescriptor descriptor(istream); 2133791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2134791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Font Family Name:</dt><dd>"); 2135791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFamilyName()); 2136791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font Full Name:</dt><dd>"); 2137791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getFullName()); 2138791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd><dt>Font PS Name:</dt><dd>"); 2139791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(descriptor.getPostscriptName()); 2140791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2141791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2142791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2143791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextSize:</dt><dd>"); 2144791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextSize()); 2145791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2146791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2147791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextScaleX:</dt><dd>"); 2148791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextScaleX()); 2149791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2150791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2151791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextSkewX:</dt><dd>"); 2152791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getTextSkewX()); 2153791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2154791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2155791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkPathEffect* pathEffect = this->getPathEffect(); 215649f085dddff10473b6ebf832a974288300224e60bsalomon if (pathEffect) { 2157791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>PathEffect:</dt><dd>"); 215842dbfa8651861f2f686879c996aab9f9f82277ddrobertphillips pathEffect->toString(str); 2159791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2160791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2161791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2162791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkShader* shader = this->getShader(); 216349f085dddff10473b6ebf832a974288300224e60bsalomon if (shader) { 2164791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Shader:</dt><dd>"); 21651202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com shader->toString(str); 2166791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2167791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2168791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2169791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkXfermode* xfer = this->getXfermode(); 217049f085dddff10473b6ebf832a974288300224e60bsalomon if (xfer) { 2171791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Xfermode:</dt><dd>"); 21721202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com xfer->toString(str); 2173791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2174791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2175791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2176791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkMaskFilter* maskFilter = this->getMaskFilter(); 217749f085dddff10473b6ebf832a974288300224e60bsalomon if (maskFilter) { 2178791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>MaskFilter:</dt><dd>"); 21791202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com maskFilter->toString(str); 2180791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2181791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2182791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2183791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkColorFilter* colorFilter = this->getColorFilter(); 218449f085dddff10473b6ebf832a974288300224e60bsalomon if (colorFilter) { 2185791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>ColorFilter:</dt><dd>"); 21861202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com colorFilter->toString(str); 2187791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2188791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2189791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2190791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkRasterizer* rasterizer = this->getRasterizer(); 219149f085dddff10473b6ebf832a974288300224e60bsalomon if (rasterizer) { 2192791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Rasterizer:</dt><dd>"); 2193791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2194791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2195791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2196791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkDrawLooper* looper = this->getLooper(); 219749f085dddff10473b6ebf832a974288300224e60bsalomon if (looper) { 2198791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>DrawLooper:</dt><dd>"); 21991202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com looper->toString(str); 2200791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2201791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2202791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2203791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkImageFilter* imageFilter = this->getImageFilter(); 220449f085dddff10473b6ebf832a974288300224e60bsalomon if (imageFilter) { 2205791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>ImageFilter:</dt><dd>"); 2206f3f5bad7ded35265c0b5d042cc4174386b197a33robertphillips imageFilter->toString(str); 2207791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2208791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2209791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2210791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAnnotation* annotation = this->getAnnotation(); 221149f085dddff10473b6ebf832a974288300224e60bsalomon if (annotation) { 2212791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Annotation:</dt><dd>"); 2213791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2214791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2215791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2216791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Color:</dt><dd>0x"); 2217791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkColor color = this->getColor(); 2218791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendHex(color); 2219791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2220791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2221791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Stroke Width:</dt><dd>"); 2222791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getStrokeWidth()); 2223791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2224791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2225791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Stroke Miter:</dt><dd>"); 2226791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->appendScalar(this->getStrokeMiter()); 2227791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2228791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2229791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Flags:</dt><dd>("); 2230791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com if (this->getFlags()) { 2231791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com bool needSeparator = false; 2232791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isAntiAlias(), "AntiAlias", &needSeparator); 2233791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isDither(), "Dither", &needSeparator); 2234791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isUnderlineText(), "UnderlineText", &needSeparator); 2235791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isStrikeThruText(), "StrikeThruText", &needSeparator); 2236791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isFakeBoldText(), "FakeBoldText", &needSeparator); 2237791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isLinearText(), "LinearText", &needSeparator); 2238791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isSubpixelText(), "SubpixelText", &needSeparator); 2239791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isDevKernText(), "DevKernText", &needSeparator); 2240791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isLCDRenderText(), "LCDRenderText", &needSeparator); 2241791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isEmbeddedBitmapText(), 2242791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com "EmbeddedBitmapText", &needSeparator); 2243791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isAutohinted(), "Autohinted", &needSeparator); 2244791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, this->isVerticalText(), "VerticalText", &needSeparator); 2245791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com SkAddFlagToString(str, SkToBool(this->getFlags() & SkPaint::kGenA8FromLCD_Flag), 2246791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com "GenA8FromLCD", &needSeparator); 2247791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } else { 2248791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("None"); 2249791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com } 2250791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(")</dd>"); 2251791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 22523e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append("<dt>FilterLevel:</dt><dd>"); 225393a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed static const char* gFilterQualityStrings[] = { "None", "Low", "Medium", "High" }; 225493a1215fe0ab007ce941c721f1fd3e9dcb5d4754reed str->append(gFilterQualityStrings[this->getFilterQuality()]); 22553e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com str->append("</dd>"); 22563e7e992a8aa564e75bede2a1dc787142d2c2bab0robertphillips@google.com 2257791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextAlign:</dt><dd>"); 2258791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gTextAlignStrings[SkPaint::kAlignCount] = { "Left", "Center", "Right" }; 2259791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gTextAlignStrings[this->getTextAlign()]); 2260791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2261791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2262791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>CapType:</dt><dd>"); 2263791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gStrokeCapStrings[SkPaint::kCapCount] = { "Butt", "Round", "Square" }; 2264791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gStrokeCapStrings[this->getStrokeCap()]); 2265791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2266791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2267791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>JoinType:</dt><dd>"); 2268791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gJoinStrings[SkPaint::kJoinCount] = { "Miter", "Round", "Bevel" }; 2269791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gJoinStrings[this->getStrokeJoin()]); 2270791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2271791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2272791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Style:</dt><dd>"); 2273791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gStyleStrings[SkPaint::kStyleCount] = { "Fill", "Stroke", "StrokeAndFill" }; 2274791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gStyleStrings[this->getStyle()]); 2275791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2276791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2277791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>TextEncoding:</dt><dd>"); 2278791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gTextEncodingStrings[] = { "UTF8", "UTF16", "UTF32", "GlyphID" }; 2279791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gTextEncodingStrings[this->getTextEncoding()]); 2280791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2281791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2282791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("<dt>Hinting:</dt><dd>"); 2283791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com static const char* gHintingStrings[] = { "None", "Slight", "Normal", "Full" }; 2284791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append(gHintingStrings[this->getHinting()]); 2285791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd>"); 2286791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 2287791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com str->append("</dd></dl></dl>"); 2288791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com} 2289791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com#endif 2290791f12e6cf558e0dd1689fbb0a6b5eddac9f42adrobertphillips@google.com 22916fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com/////////////////////////////////////////////////////////////////////////////// 22928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22936fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comstatic bool has_thick_frame(const SkPaint& paint) { 22946fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com return paint.getStrokeWidth() > 0 && 22956fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com paint.getStyle() != SkPaint::kFill_Style; 22968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 22978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTextToPathIter::SkTextToPathIter( const char text[], size_t length, 22998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPaint& paint, 2300166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com bool applyStrokeAndPathEffects) 2301166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com : fPaint(paint) { 23029e96aa07dbf1210fd35ae8e0c54d4d9822544e89reed fGlyphCacheProc = paint.getMeasureCacheProc(true); 23038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2304166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com fPaint.setLinearText(true); 23058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup 23068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23076fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) { 23088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com applyStrokeAndPathEffects = false; 23096fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 23108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2311166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com // can't use our canonical size if we need to apply patheffects 2312166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com if (fPaint.getPathEffect() == NULL) { 23138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths)); 23148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths; 2315166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com if (has_thick_frame(fPaint)) { 231680ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed fPaint.setStrokeWidth(fPaint.getStrokeWidth() / fScale); 2317166e653f67f3fffc3846184a25ce45ab083f07a2djsollen@google.com } 23186fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } else { 23198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fScale = SK_Scalar1; 23206fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 232172cf4927e503f49c4bd07369e85764ddde57071breed@google.com 23226fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!applyStrokeAndPathEffects) { 23238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setStyle(SkPaint::kFill_Style); 23248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setPathEffect(NULL); 23258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth fCache = fPaint.detachCache(NULL, NULL, false); 23288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::Style style = SkPaint::kFill_Style; 23308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect* pe = NULL; 23318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23326fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (!applyStrokeAndPathEffects) { 23338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = paint.getStyle(); // restore 23348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pe = paint.getPathEffect(); // restore 23358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setStyle(style); 23378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setPathEffect(pe); 23388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPaint.setMaskFilter(paint.getMaskFilter()); // restore 23398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // now compute fXOffset if needed 23418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar xOffset = 0; 23436fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first 23448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count; 23456fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, 23466fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com &count, NULL), fScale); 23476fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (paint.getTextAlign() == SkPaint::kCenter_Align) { 23488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com width = SkScalarHalf(width); 23496fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 23508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com xOffset = -width; 23518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXPos = xOffset; 23538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPrevAdvance = 0; 23548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fText = text; 23568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStop = text + length; 23577b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com 235844da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com fXYIndex = paint.isVerticalText() ? 1 : 0; 23598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23616fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.comSkTextToPathIter::~SkTextToPathIter() { 23628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGlyphCache::AttachCache(fCache); 23638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 23648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23657b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.combool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { 23667b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (fText < fStop) { 23678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText); 23688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale); 237044da42e92f46cae9e96003999f02db04b8b5ff2dreed@google.com fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); 23718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23726fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com if (glyph.fWidth) { 23737b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (path) { 23747b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *path = fCache->findPath(glyph); 23757b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 23767b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } else { 23777b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (path) { 23787b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *path = NULL; 23796fb7e2e153717b69831c34663cbb7bc26ac8eef9reed@google.com } 23808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23817b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com if (xpos) { 23827b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com *xpos = fXPos; 23837b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com } 23847b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com return true; 23858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23867b4531f64cbd85d32a77ceab1bdec8335c5a7864reed@google.com return false; 23878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2388dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com 2389dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com/////////////////////////////////////////////////////////////////////////////// 2390dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com 2391f539b8cdee0204985edca028eec826ee94a0c472reed// return true if the filter exists, and may affect alpha 2392f539b8cdee0204985edca028eec826ee94a0c472reedstatic bool affects_alpha(const SkColorFilter* cf) { 2393f539b8cdee0204985edca028eec826ee94a0c472reed return cf && !(cf->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); 2394f539b8cdee0204985edca028eec826ee94a0c472reed} 2395f539b8cdee0204985edca028eec826ee94a0c472reed 2396f539b8cdee0204985edca028eec826ee94a0c472reed// return true if the filter exists, and may affect alpha 2397f539b8cdee0204985edca028eec826ee94a0c472reedstatic bool affects_alpha(const SkImageFilter* imf) { 2398f539b8cdee0204985edca028eec826ee94a0c472reed // TODO: check if we should allow imagefilters to broadcast that they don't affect alpha 2399f539b8cdee0204985edca028eec826ee94a0c472reed // ala colorfilters 2400f539b8cdee0204985edca028eec826ee94a0c472reed return imf != NULL; 2401f539b8cdee0204985edca028eec826ee94a0c472reed} 2402f539b8cdee0204985edca028eec826ee94a0c472reed 2403dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.combool SkPaint::nothingToDraw() const { 2404733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com if (fLooper) { 2405733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com return false; 2406733e302b1c36a4310d91ea61ea127379f16d1318reed@google.com } 2407dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com SkXfermode::Mode mode; 2408dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com if (SkXfermode::AsMode(fXfermode, &mode)) { 2409dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com switch (mode) { 2410dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kSrcOver_Mode: 2411dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kSrcATop_Mode: 2412dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDstOut_Mode: 2413dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDstOver_Mode: 2414dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kPlus_Mode: 2415f539b8cdee0204985edca028eec826ee94a0c472reed if (0 == this->getAlpha()) { 2416f539b8cdee0204985edca028eec826ee94a0c472reed return !affects_alpha(fColorFilter) && !affects_alpha(fImageFilter); 2417f539b8cdee0204985edca028eec826ee94a0c472reed } 2418f539b8cdee0204985edca028eec826ee94a0c472reed break; 2419dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com case SkXfermode::kDst_Mode: 2420dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return true; 2421dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com default: 2422dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com break; 2423dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com } 2424dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com } 2425dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com return false; 2426dcd0f3a980095b77ebe605b49777a4bd37ca7b0areed@google.com} 2427aca1c01f3b39a8159a0ca10ba740d9995027317bcommit-bot@chromium.org 2428fb1fe4f51820731f557e765f8c71cba9a0d28048mtkleinuint32_t SkPaint::getHash() const { 2429fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein // We're going to hash 10 pointers and 7 32-bit values, finishing up with fBitfields, 2430fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein // so fBitfields should be 10 pointers and 6 32-bit values from the start. 2431fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein SK_COMPILE_ASSERT(offsetof(SkPaint, fBitfields) == 10 * sizeof(void*) + 6 * sizeof(uint32_t), 2432fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein SkPaint_notPackedTightly); 2433fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(this), 2434fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein offsetof(SkPaint, fBitfields) + sizeof(fBitfields)); 2435fb1fe4f51820731f557e765f8c71cba9a0d28048mtklein} 2436