SkPaint.cpp revision 5c7fc8f96344cc7f780558c714d3e52f0669b0b8
11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
105c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#include <new>
115c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h"
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFontHost.h"
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkImageFilter.h"
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h"
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPathEffect.h"
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRasterizer.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h"
2040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkScalar.h"
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScalerContext.h"
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStroke.h"
2340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkTextFormatParams.h"
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypeface.h"
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h"
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAutoKern.h"
271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include "SkGlyphCache.h"
284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkPaintDefaults.h"
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// define this to get a printf for out-of-range parameter in setters
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// e.g. setTextSize(-1)
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//#define SK_REPORT_API_RANGE_CHECK
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
3587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC                  fGenerationID++
3687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression) if (expression) { fGenerationID++; }
3787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#else
3887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC
3987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#define GEN_ID_INC_EVAL(expression)
4087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
4187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
42c1c43a17e7f2a87951739691056728a80e9aef6bMike ReedSkPaint::SkPaint() {
43c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // since we may have padding, we zero everything so that our memcmp() call
44c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // in operator== will work correctly.
45c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // with this, we can skip 0 and null individual initializations
46c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    sk_bzero(this, sizeof(*this));
47c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed
48c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#if 0   // not needed with the bzero call above
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface   = NULL;
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSkewX  = 0;
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect  = NULL;
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader      = NULL;
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode    = NULL;
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter  = NULL;
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter = NULL;
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer  = NULL;
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper      = NULL;
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fImageFilter = NULL;
59c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fWidth      = 0;
60c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#endif
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fTextSize   = SkPaintDefaults_TextSize;
63c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fTextScaleX = SK_Scalar1;
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor      = SK_ColorBLACK;
654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fMiterLimit = SkPaintDefaults_MiterLimit;
664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fFlags      = SkPaintDefaults_Flags;
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCapType    = kDefault_Cap;
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fJoinType   = kDefault_Join;
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextAlign  = kLeft_Align;
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStyle      = kFill_Style;
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextEncoding = kUTF8_TextEncoding;
724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fHinting    = SkPaintDefaults_Hinting;
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
745c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio    new(&fTextLocale) SkString();
7595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    fGenerationID = 0;
7687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::SkPaint(const SkPaint& src) {
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fTypeface);
8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fPathEffect);
8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fShader);
8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fXfermode);
8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fMaskFilter);
8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fColorFilter);
8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fRasterizer);
8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(fLooper);
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSafeRef(fImageFilter);
915c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#ifdef SK_BUILD_FOR_ANDROID
925c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio    new(&fTextLocale) SkString(src.fTextLocale);
935c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#endif
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint::~SkPaint() {
9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fTypeface);
9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fPathEffect);
9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fShader);
10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fXfermode);
10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fMaskFilter);
10240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fColorFilter);
10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fRasterizer);
10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fLooper);
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSafeUnref(fImageFilter);
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkPaint& SkPaint::operator=(const SkPaint& src) {
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(&src);
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fTypeface);
11240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fPathEffect);
11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fShader);
11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fXfermode);
11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fMaskFilter);
11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fColorFilter);
11740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fRasterizer);
11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeRef(src.fLooper);
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSafeRef(src.fImageFilter);
12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fTypeface);
12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fPathEffect);
12340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fShader);
12440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fXfermode);
12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fMaskFilter);
12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fColorFilter);
12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fRasterizer);
12840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkSafeUnref(fLooper);
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkSafeUnref(fImageFilter);
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
1325c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio    fTextLocale.~SkString();
1339f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    uint32_t oldGenerationID = fGenerationID;
13487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
1375c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio    new(&fTextLocale) SkString(src.fTextLocale);
1389f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    fGenerationID = oldGenerationID + 1;
13987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return *this;
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool operator==(const SkPaint& a, const SkPaint& b) {
1451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
1461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    //assumes that fGenerationID is the last field in the struct
1471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return !memcmp(&a, &b, SK_OFFSETOF(SkPaint, fGenerationID));
1481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
1491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return !memcmp(&a, &b, sizeof(a));
1501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::reset() {
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint init;
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
1579f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    uint32_t oldGenerationID = fGenerationID;
15887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *this = init;
1601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
1619f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    fGenerationID = oldGenerationID + 1;
16287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
16395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase}
16495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase
1651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
16695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haaseuint32_t SkPaint::getGenerationID() const {
16795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    return fGenerationID;
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerunsigned SkPaint::getBaseGlyphCount(SkUnichar text) const {
1731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkAutoGlyphCache autoCache(*this, NULL);
1741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkGlyphCache* cache = autoCache.getCache();
1751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return cache->getBaseGlyphCount(text);
1761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
1781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
17987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setHinting(Hinting hintingLevel) {
18087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting);
18187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fHinting = hintingLevel;
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFlags(uint32_t flags) {
18587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(fFlags != flags);
18687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fFlags = flags;
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAntiAlias(bool doAA) {
19087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doAA != isAntiAlias());
19187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
19487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDither(bool doDither) {
19587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doDither != isDither());
19687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
19987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setSubpixelText(bool doSubpixel) {
20087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doSubpixel != isSubpixelText());
20187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
202af2616552738d653d5453915d3236e7154b868cdMike Reed}
203af2616552738d653d5453915d3236e7154b868cdMike Reed
20487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLCDRenderText(bool doLCDRender) {
20587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doLCDRender != isLCDRenderText());
20687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag));
20787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger}
20887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
20987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText) {
21087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doEmbeddedBitmapText != isEmbeddedBitmapText());
21187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
2122cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed}
2132cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed
21487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAutohinted(bool useAutohinter) {
21587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(useAutohinter != isAutohinted());
21640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, useAutohinter, kAutoHinting_Flag));
21740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
21840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
21987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setLinearText(bool doLinearText) {
22087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doLinearText != isLinearText());
22187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkPaint::setVerticalText(bool doVertical) {
2251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GEN_ID_INC_EVAL(doVertical != isVerticalText());
2261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doVertical, kVerticalText_Flag));
2271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
2281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
22987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setUnderlineText(bool doUnderline) {
23087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doUnderline != isUnderlineText());
23187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrikeThruText(bool doStrikeThru) {
23587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doStrikeThru != isStrikeThruText());
23687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
23987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFakeBoldText(bool doFakeBold) {
24087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doFakeBold != isFakeBoldText());
24187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
24487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setDevKernText(bool doDevKern) {
24587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doDevKern != isDevKernText());
24687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
24987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setFilterBitmap(bool doFilter) {
25087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(doFilter != isFilterBitmap());
25187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag));
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
25487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStyle(Style style) {
25595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)style < kStyleCount) {
25687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL((unsigned)style != fStyle);
25787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fStyle = style;
25887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
2591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
2601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
2611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
26205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
26587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setColor(SkColor color) {
26687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(color != fColor);
26787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fColor = color;
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
27087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setAlpha(U8CPU a) {
27187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setColor(SkColorSetARGB(a, SkColorGetR(fColor),
27287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                                  SkColorGetG(fColor), SkColorGetB(fColor)));
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
27587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
27687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    this->setColor(SkColorSetARGB(a, r, g, b));
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
27987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeWidth(SkScalar width) {
28095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (width >= 0) {
28187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL(width != fWidth);
28287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fWidth = width;
28387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
2841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
2851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
2861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
28705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
29087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeMiter(SkScalar limit) {
29195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (limit >= 0) {
29287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL(limit != fMiterLimit);
29387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fMiterLimit = limit;
29487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
2951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
2961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
2971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
29805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
30187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeCap(Cap ct) {
30295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)ct < kCapCount) {
30387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL((unsigned)ct != fCapType);
30487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fCapType = SkToU8(ct);
30587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
3061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
3071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
3081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
30995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
31287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setStrokeJoin(Join jt) {
31395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)jt < kJoinCount) {
31487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL((unsigned)jt != fJoinType);
31587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fJoinType = SkToU8(jt);
31687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
3171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
3181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
3191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
32095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
32387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
32587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextAlign(Align align) {
32695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)align < kAlignCount) {
32787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL((unsigned)align != fTextAlign);
32887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fTextAlign = SkToU8(align);
32987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
3301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
3311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
3321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
33395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
33687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSize(SkScalar ts) {
3371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (ts >= 0) {
33887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL(ts != fTextSize);
33987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fTextSize = ts;
34087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
3411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
3421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setTextSize() called with negative value\n");
3431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
34495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
34787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextScaleX(SkScalar scaleX) {
34887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(scaleX != fTextScaleX);
34987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fTextScaleX = scaleX;
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
35287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextSkewX(SkScalar skewX) {
35387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(skewX != fTextSkewX);
35487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    fTextSkewX = skewX;
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
35787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergervoid SkPaint::setTextEncoding(TextEncoding encoding) {
35895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)encoding <= kGlyphID_TextEncoding) {
35987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding);
36087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        fTextEncoding = encoding;
36187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else {
3621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_REPORT_API_RANGE_CHECK
3631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
3641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
36595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3685c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#ifdef SK_BUILD_FOR_ANDROID
3695c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Megliovoid SkPaint::setTextLocale(const SkString& locale) {
3705c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio    if(!fTextLocale.equals(locale)) {
3715c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio        fTextLocale.set(locale);
3725c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio        GEN_ID_INC;
3735c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio    }
3745c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio}
3755c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio#endif
3765c7fc8f96344cc7f780558c714d3e52f0669b0b8Fabrice Di Meglio
37787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
37987b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkTypeface* SkPaint::setTypeface(SkTypeface* font) {
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fTypeface, font);
38187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC;
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return font;
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
38540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) {
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fRasterizer, r);
38787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC;
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return r;
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
39140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) {
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fLooper, looper);
39387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC;
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return looper;
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3971cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) {
3981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkRefCnt_SafeAssign(fImageFilter, imageFilter);
3991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    GEN_ID_INC;
4001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return imageFilter;
4011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
4021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h"
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
40840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void DetachDescProc(const SkDescriptor* desc, void* context) {
409fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc);
410fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy}
411fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy
4121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifdef SK_BUILD_FOR_ANDROID
413b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guyconst SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) {
414b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    SkGlyphCache* cache;
415b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    descriptorProc(NULL, DetachDescProc, &cache, true);
416b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy
417b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    const SkGlyph& glyph = cache->getUnicharMetrics(text);
418b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy
419b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    SkGlyphCache::AttachCache(cache);
420b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    return glyph;
421b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy}
422b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy
4231bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guyconst SkGlyph& SkPaint::getGlyphMetrics(uint16_t glyphId) {
4241bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy    SkGlyphCache* cache;
4251bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy    descriptorProc(NULL, DetachDescProc, &cache, true);
4261bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy
4271bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy    const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphId);
4281bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy
4291bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy    SkGlyphCache::AttachCache(cache);
4301bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy    return glyph;
4311bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy}
4321bb7fdb27396cf7069375b10e1f6d763ef4e0511Romain Guy
43390a1efbdde19ee56c33929592277871509c25893Romain Guyconst void* SkPaint::findImage(const SkGlyph& glyph) {
434fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    // See ::detachCache()
435fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    SkGlyphCache* cache;
436fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    descriptorProc(NULL, DetachDescProc, &cache, true);
43790a1efbdde19ee56c33929592277871509c25893Romain Guy
438fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    const void* image = cache->findImage(glyph);
439fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy
440fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    SkGlyphCache::AttachCache(cache);
441fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    return image;
44290a1efbdde19ee56c33929592277871509c25893Romain Guy}
44387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger#endif
44490a1efbdde19ee56c33929592277871509c25893Romain Guy
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength,
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          uint16_t glyphs[]) const {
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0) {
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
45040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textData != NULL);
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == glyphs) {
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        switch (this->getTextEncoding()) {
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF8_TextEncoding:
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF8_CountUnichars((const char*)textData, byteLength);
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF16_TextEncoding:
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF16_CountUnichars((const uint16_t*)textData,
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                         byteLength >> 1);
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kGlyphID_TextEncoding:
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return byteLength >> 1;
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
4631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDEBUGFAIL("unknown text encoding");
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
46740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // if we get here, we have a valid glyphs[] array, so time to fill it in
46940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // handle this encoding before the setup for the glyphcache
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we want to ignore the low bit of byteLength
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(glyphs, textData, byteLength >> 1 << 1);
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return byteLength >> 1;
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
47640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache autoCache(*this, NULL);
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*    cache = autoCache.getCache();
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint16_t*   gptr = glyphs;
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getTextEncoding()) {
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF8_TextEncoding:
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text));
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF16_TextEncoding: {
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* text16 = (const uint16_t*)text;
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* stop16 = (const uint16_t*)stop;
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text16 < stop16) {
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16));
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
4991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDEBUGFAIL("unknown text encoding");
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gptr - glyphs;
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
50475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reedbool SkPaint::containsText(const void* textData, size_t byteLength) const {
50575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    if (0 == byteLength) {
50675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        return true;
50775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
50840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
50975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkASSERT(textData != NULL);
51040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
51175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    // handle this encoding before the setup for the glyphcache
51275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
51375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        const uint16_t* glyphID = static_cast<const uint16_t*>(textData);
51475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        size_t count = byteLength >> 1;
51575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        for (size_t i = 0; i < count; i++) {
51675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            if (0 == glyphID[i]) {
51775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                return false;
51875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
51975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
52075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        return true;
52175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
52240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
52375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkAutoGlyphCache autoCache(*this, NULL);
52475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkGlyphCache*    cache = autoCache.getCache();
52575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
52675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    switch (this->getTextEncoding()) {
52775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        case SkPaint::kUTF8_TextEncoding: {
52875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const char* text = static_cast<const char*>(textData);
52975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const char* stop = text + byteLength;
53075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            while (text < stop) {
53175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) {
53275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                    return false;
53375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                }
53475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
53575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            break;
53675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
53775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        case SkPaint::kUTF16_TextEncoding: {
53875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const uint16_t* text = static_cast<const uint16_t*>(textData);
53975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const uint16_t* stop = text + (byteLength >> 1);
54075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            while (text < stop) {
54175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) {
54275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                    return false;
54375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                }
54475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
54575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            break;
54675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
54775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        default:
5481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDEBUGFAIL("unknown text encoding");
54975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            return false;
55075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
55175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    return true;
55275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed}
55375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
554091f227385b467090b5a7169a8e2faf19eca7105Mike Reedvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count,
555091f227385b467090b5a7169a8e2faf19eca7105Mike Reed                               SkUnichar textData[]) const {
556091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    if (count <= 0) {
557091f227385b467090b5a7169a8e2faf19eca7105Mike Reed        return;
558091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    }
559091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
560091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkASSERT(glyphs != NULL);
561091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkASSERT(textData != NULL);
562091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
563091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkAutoGlyphCache autoCache(*this, NULL);
564091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkGlyphCache*    cache = autoCache.getCache();
565091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
566091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    for (int index = 0; index < count; index++) {
567091f227385b467090b5a7169a8e2faf19eca7105Mike Reed        textData[index] = cache->glyphToUnichar(glyphs[index]);
568091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    }
569091f227385b467090b5a7169a8e2faf19eca7105Mike Reed}
570091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
57340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache,
57440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                              const char** text) {
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
57740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
58140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache,
58240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                              const char** text) {
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
58540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text));
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
58940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache,
59040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
59340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
59740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache,
59840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
60140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text));
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
60540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache,
60640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
60940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
61740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache,
61840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
62140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
62940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache,
63040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                              const char** text) {
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
63340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_NextUnichar(text));
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
63740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache,
63840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                              const char** text) {
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
64140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text));
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
64540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache,
64640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
64940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text));
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
65340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache,
65440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
65740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text));
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
66140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache,
66240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
66540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
67340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache,
67440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                               const char** text) {
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
67740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd,
68640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                                bool needFullMetrics) const {
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkMeasureCacheProc gMeasureCacheProcs[] = {
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_next,
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_next,
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_next,
69140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_prev,
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_prev,
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_prev,
69540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_next,
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_next,
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_next,
69940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_prev,
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_prev,
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_prev
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
70440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
70740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (kBackward_TextBufferDirection == tbd) {
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
70940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
71040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!needFullMetrics && !this->isDevKernText()) {
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 6;
71240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs));
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gMeasureCacheProcs[index];
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache,
72140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                        const char** text, SkFixed, SkFixed) {
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
72440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache,
72940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    const char** text, SkFixed x, SkFixed y) {
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
73240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y);
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
73640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache,
73740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                        const char** text, SkFixed, SkFixed) {
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
74040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache,
74540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                     const char** text, SkFixed x, SkFixed y) {
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
74840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text),
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    x, y);
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
75340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache,
75440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                         const char** text, SkFixed, SkFixed) {
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
75740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache,
76640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                     const char** text, SkFixed x, SkFixed y) {
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
76940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID, x, y);
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
77740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkDrawCacheProc SkPaint::getDrawCacheProc() const {
7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkDrawCacheProc gDrawCacheProcs[] = {
7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_00,
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_00,
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_00,
78240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_xy,
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_xy,
7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_xy
7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
78740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
78940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (fFlags & kSubpixelText_Flag) {
7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
79140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
79240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs));
7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gDrawCacheProcs[index];
7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame {
8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
80140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint)
80240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            : fPaint((SkPaint*)paint) {
8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = paint->getTextSize();
8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = paint->getStyle();
8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(SkPaint::kFill_Style);
8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
80740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
80840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    ~SkAutoRestorePaintTextSizeAndFrame() {
8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(fStyle);
8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setTextSize(fTextSize);
8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
81240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint*        fPaint;
8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        fTextSize;
8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  fStyle;
8170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
81940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds) {
8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(SkIntToScalar(g.fLeft),
8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop),
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fLeft + g.fWidth),
8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop + g.fHeight));
8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
826e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so
827e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// we don't overflow along the way
828e63c5c9f6752244ca0f39075fa148a0281593831Mike Reedtypedef int64_t Sk48Dot16;
829e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed
830e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#ifdef SK_SCALAR_IS_FLOAT
831e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    static inline float Sk48Dot16ToScalar(Sk48Dot16 x) {
83240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        return (float) (x * 1.5258789e-5);   // x * (1 / 65536.0f)
833e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    }
834e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#else
835e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    static inline SkFixed Sk48Dot16ToScalar(Sk48Dot16 x) {
836e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed        // just return the low 32bits
837e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed        return static_cast<SkFixed>(x);
838e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    }
839e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#endif
840e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed
8411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_x(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx) {
842e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    SkScalar sx = Sk48Dot16ToScalar(dx);
8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->join(SkIntToScalar(g.fLeft) + sx,
8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop),
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fLeft + g.fWidth) + sx,
8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop + g.fHeight));
8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic void join_bounds_y(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dy) {
8501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkScalar sy = Sk48Dot16ToScalar(dy);
8511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    bounds->join(SkIntToScalar(g.fLeft),
8521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 SkIntToScalar(g.fTop) + sy,
8531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 SkIntToScalar(g.fLeft + g.fWidth),
8541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                 SkIntToScalar(g.fTop + g.fHeight) + sy);
8551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
8561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergertypedef void (*JoinBoundsProc)(const SkGlyph&, SkRect*, Sk48Dot16);
8581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// xyIndex is 0 for fAdvanceX or 1 for fAdvanceY
8601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic SkFixed advance(const SkGlyph& glyph, int xyIndex) {
8611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(0 == xyIndex || 1 == xyIndex);
8621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return (&glyph.fAdvanceX)[xyIndex];
8631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
8641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache,
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const char* text, size_t byteLength,
86740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                               int* count, SkRect* bounds) const {
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count);
86940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (byteLength == 0) {
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = 0;
87140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (bounds) {
8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            bounds->setEmpty();
87340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc;
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int xyIndex;
8821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    JoinBoundsProc joinBoundsProc;
8831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (this->isVerticalText()) {
8841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        xyIndex = 1;
8851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        joinBoundsProc = join_bounds_y;
8861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    } else {
8871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        xyIndex = 0;
8881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        joinBoundsProc = join_bounds_x;
8891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
8901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         n = 1;
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = (const char*)text + byteLength;
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkGlyph* g = &glyphCacheProc(cache, &text);
894e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // our accumulated fixed-point advances might overflow 16.16, so we use
895e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // a 48.16 (64bit) accumulator, and then convert that to scalar at the
896e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // very end.
8971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    Sk48Dot16 x = advance(*g, xyIndex);
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
90140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (NULL == bounds) {
90240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (this->isDevKernText()) {
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
9071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + advance(*g, xyIndex);
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
90940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
9111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                x += advance(glyphCacheProc(cache, &text), xyIndex);
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
91440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        set_bounds(*g, bounds);
91640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (this->isDevKernText()) {
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta);
9221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                joinBoundsProc(*g, bounds, x);
9231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                x += advance(*g, xyIndex);
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
92540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
9281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                joinBoundsProc(*g, bounds, x);
9291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                x += advance(*g, xyIndex);
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *count = n;
936e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    return Sk48Dot16ToScalar(x);
9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length,
94040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                              SkRect* bounds, SkScalar zoom) const {
9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL || length == 0);
9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
94740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (this->isLinearText()) {
9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
95240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
95340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkMatrix zoomMatrix, *zoomPtr = NULL;
95440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (zoom) {
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = 0;
96340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
96440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (length > 0) {
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int tempCount;
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = this->measure_text(cache, text, length, &tempCount, bounds);
96840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (scale) {
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarMul(width, scale);
97040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (bounds) {
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fLeft = SkScalarMul(bounds->fLeft, scale);
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fTop = SkScalarMul(bounds->fTop, scale);
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fRight = SkScalarMul(bounds->fRight, scale);
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fBottom = SkScalarMul(bounds->fBottom, scale);
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop);
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
98340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool forward_textBufferPred(const char* text, const char* stop) {
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text < stop;
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
98740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool backward_textBufferPred(const char* text, const char* stop) {
9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text > stop;
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd,
99240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                             const char** text, size_t length,
99340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                             const char** stop) {
99440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (SkPaint::kForward_TextBufferDirection == tbd) {
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text + length;
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return forward_textBufferPred;
99740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // text should point to the end of the buffer, and stop to the beginning
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text;
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *text += length;
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return backward_textBufferPred;
10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          SkScalar* measuredWidth,
100740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                          TextBufferDirection tbd) const {
100840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (0 == length || 0 >= maxWidth) {
100940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (measuredWidth) {
10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *measuredWidth = 0;
101140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (0 == fTextSize) {
10161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (measuredWidth) {
10171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            *measuredWidth = 0;
10181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
10191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return length;
10201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
10211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textD != NULL);
10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textD;
10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
102840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (this->isLinearText()) {
10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
10309b1cba8ccd7554cb30905711a426bd86ad8dd38cJean-Baptiste Queru        maxWidth = SkScalarMulDiv(maxWidth, kCanonicalTextSizeForPaths, fTextSize);
10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
103440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false);
10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char*      stop;
10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop);
10411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const int        xyIndex = this->isVerticalText() ? 1 : 0;
1042e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // use 64bits for our accumulator, to avoid overflowing 16.16
1043e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    Sk48Dot16        max = SkScalarToFixed(maxWidth);
1044e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    Sk48Dot16        width = 0;
10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
104840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (this->isDevKernText()) {
10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int rsb = 0;
105040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        while (pred(text, stop)) {
10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const SkGlyph& g = glyphCacheProc(cache, &text);
10531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + advance(g, xyIndex);
105440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if ((width += x) > max) {
10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            rsb = g.fRsbDelta;
10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
106140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
106240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        while (pred(text, stop)) {
10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
10641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkFixed x = advance(glyphCacheProc(cache, &text), xyIndex);
106540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if ((width += x) > max) {
10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
107240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
107340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (measuredWidth) {
1074e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed        SkScalar scalarWidth = Sk48Dot16ToScalar(width);
107540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (scale) {
10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scalarWidth = SkScalarMul(scalarWidth, scale);
107740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *measuredWidth = scalarWidth;
10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
108040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // return the number of bytes measured
10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (kForward_TextBufferDirection == tbd) ?
10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text - stop + length : stop - text + length;
10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
108840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context) {
10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *(SkPaint::FontMetrics*)context = cache->getFontMetricsY();
10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;   // don't detach the cache
10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
109340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context) {
10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context);
10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
109740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const {
10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
110140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (this->isLinearText()) {
11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
110640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
110740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkMatrix zoomMatrix, *zoomPtr = NULL;
110840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (zoom) {
11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const FontMetrics&  my = cache->getFontMetricsY();
11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    FontMetrics storage;
111940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (NULL == metrics) {
11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics = &storage;
112140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
112240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
11231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics, true);
11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
112540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (scale) {
11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fTop = SkScalarMul(metrics->fTop, scale);
11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return metrics->fDescent - metrics->fAscent + metrics->fLeading;
11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
113540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
113740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale) {
11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(g.fLeft * scale,
11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g.fTop * scale,
11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fLeft + g.fWidth) * scale,
11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fTop + g.fHeight) * scale);
11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
114440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerint SkPaint::getTextWidths(const void* textData, size_t byteLength,
114540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                           SkScalar widths[], SkRect bounds[]) const {
114640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (0 == byteLength) {
11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
114840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(NULL != textData);
11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
115240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (NULL == widths && NULL == bounds) {
11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->countText(textData, byteLength);
115440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
115940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (this->isLinearText()) {
11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc  glyphCacheProc;
11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         count = 0;
11741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const int   xyIndex = this->isVerticalText() ? 1 : 0;
11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
117640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (this->isDevKernText()) {
11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we adjust the widths returned here through auto-kerning
11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoKern  autokern;
11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkFixed     prevWidth = 0;
11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkScalar w = SkFixedToScalar(prevWidth + adjust);
11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkScalarMul(w, scale);
11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
11911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    prevWidth = advance(g, xyIndex);
11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale);
12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkFixedToScalar(prevWidth + adjust);
12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
12101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    prevWidth = advance(g, xyIndex);
12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkFixedToScalar(prevWidth);
12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {    // no devkern
12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
12261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    *widths++ = SkScalarMul(SkFixedToScalar(advance(g, xyIndex)),
12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            scale);
12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
12381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    *widths++ = SkFixedToScalar(advance(g, xyIndex));
12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return count;
12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
125240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h"
12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
125640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkPaint::getTextPath(const void* textData, size_t length,
125740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                          SkScalar x, SkScalar y, SkPath* path) const {
125840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    SkASSERT(length == 0 || textData != NULL);
125940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
126140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (text == NULL || length == 0 || path == NULL) {
12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
126340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextToPathIter    iter(text, length, *this, false, true);
12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix            matrix;
12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar            prevXPos = 0;
12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.setScale(iter.getPathScale(), iter.getPathScale());
12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.postTranslate(x, y);
12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    path->reset();
12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        xpos;
12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   iterPath;
127540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while ((iterPath = iter.next(&xpos)) != NULL) {
12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        matrix.postTranslate(xpos - prevXPos, 0);
12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path->addPath(*iterPath, matrix);
12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevXPos = xpos;
12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag,
12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            SkFlattenableWriteBuffer* buffer) {
12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// SkFontHost can override this choice in FilterRec()
128840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkMask::Format computeMaskFormat(const SkPaint& paint) {
12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flags = paint.getFlags();
12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1291c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    // Antialiasing being disabled trumps all other settings.
1292137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    if (!(flags & SkPaint::kAntiAlias_Flag)) {
1293c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed        return SkMask::kBW_Format;
129405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
129505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1296137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    if (flags & SkPaint::kLCDRenderText_Flag) {
1297137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        return SkMask::kLCD16_Format;
1298137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    }
1299c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed
1300c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    return SkMask::kA8_Format;
13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13034bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// if linear-text is on, then we force hinting to be off (since that's sort of
13044bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// the point of linear-text.
13054bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reedstatic SkPaint::Hinting computeHinting(const SkPaint& paint) {
13064bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    SkPaint::Hinting h = paint.getHinting();
13074bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    if (paint.isLinearText()) {
13084bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed        h = SkPaint::kNo_Hinting;
13094bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    }
13104bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    return h;
13114bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed}
13124bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed
13131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// return true if the paint is just a single color (i.e. not a shader). If its
13141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// a shader, then we can't compute a const luminance for it :(
13151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool justAColor(const SkPaint& paint, SkColor* color) {
13161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.getShader()) {
13171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
13181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkColor c = paint.getColor();
13201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.getColorFilter()) {
13211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        c = paint.getColorFilter()->filterColor(c);
13221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (color) {
13241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        *color = c;
13251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
13271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
13281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE
13304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic SkColor computeLuminanceColor(const SkPaint& paint) {
13314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkColor c;
13324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!justAColor(paint, &c)) {
13334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        c = SkColorSetRGB(0x7F, 0x80, 0x7F);
13344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
13354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return c;
13364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
13374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
13384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#define assert_byte(x)  SkASSERT(0 == ((x) >> 8))
13394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
13404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic U8CPU reduce_lumbits(U8CPU x) {
13414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    static const uint8_t gReduceBits[] = {
13424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        0x0, 0x55, 0xAA, 0xFF
13434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    };
13444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    assert_byte(x);
13454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return gReduceBits[x >> 6];
13464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
13474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
13484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic unsigned computeLuminance(SkColor c) {
13494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int r = SkColorGetR(c);
13504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int g = SkColorGetG(c);
13514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int b = SkColorGetB(c);
13524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // compute luminance
13534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // R=0.2126 G=0.7152 B=0.0722
13544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // scaling by 127 yields 27, 92, 9
13554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int luminance = r * 27 + g * 92 + b * 9;
13564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    luminance >>= 7;
13574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    assert_byte(luminance);
13584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return luminance;
13594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
13604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
13614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else
13621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// returns 0..kLuminance_Max
13631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic unsigned computeLuminance(const SkPaint& paint) {
13641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkColor c;
13651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (justAColor(paint, &c)) {
13661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int r = SkColorGetR(c);
13671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int g = SkColorGetG(c);
13681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int b = SkColorGetB(c);
13691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // compute luminance
13701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // R=0.2126 G=0.7152 B=0.0722
13711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        // scaling by 127 yields 27, 92, 9
13721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#if 1
13731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int luminance = r * 27 + g * 92 + b * 9;
13741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        luminance >>= 15 - SkScalerContext::kLuminance_Bits;
13751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#else
13761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        int luminance = r * 2 + g * 5 + b * 1;
13771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        luminance >>= 11 - SkScalerContext::kLuminance_Bits;
13781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
13791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkASSERT(luminance <= SkScalerContext::kLuminance_Max);
13801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return luminance;
13811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
13821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // if we're not a single color, return the middle of the luminance range
13831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return SkScalerContext::kLuminance_Max >> 1;
13841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
13854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif
13861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// Beyond this size, LCD doesn't appreciably improve quality, but it always
13881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger// cost more RAM and draws slower, so we set a cap.
13891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#ifndef SK_MAX_SIZE_FOR_LCDTEXT
13901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    #define SK_MAX_SIZE_FOR_LCDTEXT    48
13911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#endif
13921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
13931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerstatic bool tooBigForLCD(const SkScalerContext::Rec& rec) {
13941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkScalar area = SkScalarMul(rec.fPost2x2[0][0], rec.fPost2x2[1][1]) -
13951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                    SkScalarMul(rec.fPost2x2[1][0], rec.fPost2x2[0][1]);
13961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkScalar size = SkScalarMul(area, rec.fTextSize);
13971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return SkScalarAbs(size) > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT);
13981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
13991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
140040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/*
140140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger *  Return the scalar with only limited fractional precision. Used to consolidate matrices
140240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger *  that vary only slightly when we create our key into the font cache, since the font scaler
140340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger *  typically returns the same looking resuts for tiny changes in the matrix.
140440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */
140540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkScalar sk_relax(SkScalar x) {
140640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#ifdef SK_SCALAR_IS_FLOAT
140740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    int n = sk_float_round2int(x * 1024);
140840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return n / 1024.0f;
140940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#else
141040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    // round to the nearest 10 fractional bits
141140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return (x + (1 << 5)) & ~(1024 - 1);
141240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif
141340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}
141440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
1415af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkScalerContext::MakeRec(const SkPaint& paint,
141640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                              const SkMatrix* deviceMatrix, Rec* rec) {
14170199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    SkASSERT(deviceMatrix == NULL || !deviceMatrix->hasPerspective());
14180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14190199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    rec->fOrigFontID = SkTypeface::UniqueID(paint.getTypeface());
14200199fa7423f89a129da2b22a488f2c18e2e4727fDerek Sollenberger    rec->fFontID = rec->fOrigFontID;
14210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fTextSize = paint.getTextSize();
14220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreScaleX = paint.getTextScaleX();
14230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreSkewX  = paint.getTextSkewX();
14240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
142540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (deviceMatrix) {
142640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec->fPost2x2[0][0] = sk_relax(deviceMatrix->getScaleX());
142740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec->fPost2x2[0][1] = sk_relax(deviceMatrix->getSkewX());
142840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec->fPost2x2[1][0] = sk_relax(deviceMatrix->getSkewY());
142940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        rec->fPost2x2[1][1] = sk_relax(deviceMatrix->getScaleY());
143040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
14310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
14320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
14330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
143440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
14350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = paint.getStyle();
14360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        strokeWidth = paint.getStrokeWidth();
143740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
14381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    unsigned flags = 0;
14391c980e0d7772f05f570ae0227d91635f017c2227Mike Reed
144040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.isFakeBoldText()) {
14411c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#ifdef SK_USE_FREETYPE_EMBOLDEN
14421c980e0d7772f05f570ae0227d91635f017c2227Mike Reed        flags |= SkScalerContext::kEmbolden_Flag;
14431c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#else
144440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkScalar fakeBoldScale = SkScalarInterpFunc(paint.getTextSize(),
144540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                                    kStdFakeBoldInterpKeys,
144640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                                    kStdFakeBoldInterpValues,
144740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                                    kStdFakeBoldInterpLength);
14480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
144940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
145040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (style == SkPaint::kFill_Style) {
14510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            style = SkPaint::kStrokeAndFill_Style;
14520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth = extra;    // ignore paint's strokeWidth if it was "fill"
145340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        } else {
14540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth += extra;
145540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
14561c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#endif
14570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
145940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.isDevKernText()) {
14600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        flags |= SkScalerContext::kDevKernText_Flag;
146140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
146240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
146340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (style != SkPaint::kFill_Style && strokeWidth > 0) {
14640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = strokeWidth;
14650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = paint.getStrokeMiter();
14660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
14670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
146840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (style == SkPaint::kStrokeAndFill_Style) {
14690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            flags |= SkScalerContext::kFrameAndFill_Flag;
147040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
147140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
14720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = 0;
14730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = 0;
14740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = 0;
14750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
14780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
14791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (SkMask::kLCD16_Format == rec->fMaskFormat ||
14801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkMask::kLCD32_Format == rec->fMaskFormat)
14811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    {
14820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkFontHost::LCDOrder order = SkFontHost::GetSubpixelOrder();
14830b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        SkFontHost::LCDOrientation orient = SkFontHost::GetSubpixelOrientation();
14841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (SkFontHost::kNONE_LCDOrder == order || tooBigForLCD(*rec)) {
14850b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            // eeek, can't support LCD
14860b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            rec->fMaskFormat = SkMask::kA8_Format;
14870b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        } else {
14880b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            if (SkFontHost::kVertical_LCDOrientation == orient) {
14890b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                flags |= SkScalerContext::kLCD_Vertical_Flag;
14900b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            }
14910b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            if (SkFontHost::kBGR_LCDOrder == order) {
14920b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger                flags |= SkScalerContext::kLCD_BGROrder_Flag;
14930b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            }
14940b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        }
14950b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    }
14960b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
149740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.isEmbeddedBitmapText()) {
14980b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        flags |= SkScalerContext::kEmbeddedBitmapText_Flag;
149940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
150040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.isSubpixelText()) {
15010b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        flags |= SkScalerContext::kSubpixelPositioning_Flag;
150240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
150340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.isAutohinted()) {
15040b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        flags |= SkScalerContext::kAutohinting_Flag;
150540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
15061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (paint.isVerticalText()) {
15071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        flags |= SkScalerContext::kVertical_Flag;
15081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
15104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        flags |= SkScalerContext::kGenA8FromLCD_Flag;
15114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
15120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    rec->fFlags = SkToU16(flags);
15130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger
15141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // these modify fFlags, so do them after assigning fFlags
15150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    rec->setHinting(computeHinting(paint));
15164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE
15174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    rec->setLuminanceColor(computeLuminanceColor(paint));
15184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else
15191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    rec->setLuminanceBits(computeLuminance(paint));
15204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif
1521af2616552738d653d5453915d3236e7154b868cdMike Reed
1522af2616552738d653d5453915d3236e7154b868cdMike Reed    /*  Allow the fonthost to modify our rec before we use it as a key into the
1523af2616552738d653d5453915d3236e7154b868cdMike Reed        cache. This way if we're asking for something that they will ignore,
1524af2616552738d653d5453915d3236e7154b868cdMike Reed        they can modify our rec up front, so we don't create duplicate cache
1525af2616552738d653d5453915d3236e7154b868cdMike Reed        entries.
1526af2616552738d653d5453915d3236e7154b868cdMike Reed     */
1527af2616552738d653d5453915d3236e7154b868cdMike Reed    SkFontHost::FilterRec(rec);
15281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
15294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // be sure to call PostMakeRec(rec) before you actually use it!
15304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
15314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
15324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/**
15334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *  We ensure that the rec is self-consistent and efficient (where possible)
15344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */
15354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkScalerContext::PostMakeRec(SkScalerContext::Rec* rec) {
15364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
15374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    /**
15384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger     *  If we're asking for A8, we force the colorlum to be gray, since that
15394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger     *  that limits the number of unique entries, and the scaler will only
15404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger     *  look at the lum of one of them.
15414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger     */
15424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    switch (rec->fMaskFormat) {
15434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        case SkMask::kLCD16_Format:
15444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        case SkMask::kLCD32_Format: {
15454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE
15464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            // filter down the luminance color to a finite number of bits
15474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            SkColor c = rec->getLuminanceColor();
15484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            c = SkColorSetRGB(reduce_lumbits(SkColorGetR(c)),
15494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                              reduce_lumbits(SkColorGetG(c)),
15504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                              reduce_lumbits(SkColorGetB(c)));
15514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            rec->setLuminanceColor(c);
15524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif
15534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            break;
15544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        }
15554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        case SkMask::kA8_Format: {
15564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE
15574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            // filter down the luminance to a single component, since A8 can't
15584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            // use per-component information
15594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            unsigned lum = computeLuminance(rec->getLuminanceColor());
15604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            // reduce to our finite number of bits
15614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            lum = reduce_lumbits(lum);
15624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            rec->setLuminanceColor(SkColorSetRGB(lum, lum, lum));
15634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif
15644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            break;
15654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        }
15664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        case SkMask::kBW_Format:
15674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            // No need to differentiate gamma if we're BW
15684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE
15694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            rec->setLuminanceColor(0);
15704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else
15714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            rec->setLuminanceBits(0);
15724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif
15734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            break;
15741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
15750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER  1024
15780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
157935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef SK_DEBUG
158035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    #define TEST_DESC
158135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif
158235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
15831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
15841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *  ignoreGamma tells us that the caller just wants metrics that are unaffected
15851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *  by gamma correction, so we jam the luminance field to 0 (most common value
15861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *  for black text) in hopes that we get a cache hit easier. A better solution
15871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *  would be for the fontcache lookup to know to ignore the luminance field
15881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *  entirely, but not sure how to do that and keep it fast.
15891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
15900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
15910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void (*proc)(const SkDescriptor*, void*),
159240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                             void* context, bool ignoreGamma) const {
15930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::Rec    rec;
15940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::MakeRec(*this, deviceMatrix, &rec);
1596fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    if (ignoreGamma) {
15974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#ifdef SK_USE_COLOR_LUMINANCE
15984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        rec.setLuminanceColor(0);
15994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#else
16001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        rec.setLuminanceBits(0);
16014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#endif
1602fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    }
16030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t          descSize = sizeof(rec);
16050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int             entryCount = 1;
16060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = this->getPathEffect();
16070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMaskFilter*   mf = this->getMaskFilter();
16080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRasterizer*   ra = this->getRasterizer();
16090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
16110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
16120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
16130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
16150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        peBuffer.writeFlattenable(pe);
16160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += peBuffer.size();
16170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
16180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
16190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // seems like we could support kLCD as well at this point...
16200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
16220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mfBuffer.writeFlattenable(mf);
16230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += mfBuffer.size();
16240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
16250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing with maskfilters
16260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
16280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        raBuffer.writeFlattenable(ra);
16290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += raBuffer.size();
16300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
16310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
16320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
16344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    ///////////////////////////////////////////////////////////////////////////
16354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    // Now that we're done tweaking the rec, call the PostMakeRec cleanup
16364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkScalerContext::PostMakeRec(&rec);
16374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
16380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    descSize += SkDescriptor::ComputeOverhead(entryCount);
16390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoDescriptor    ad(descSize);
16410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDescriptor*       desc = ad.getDesc();
16420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->init();
16440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
16450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
16470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
16480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
16500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
16510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
16530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
16540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(descSize == desc->getLength());
16570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->computeChecksum();
16580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
165935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#ifdef TEST_DESC
166035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    {
166135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        // Check that we completely write the bytes in desc (our key), and that
166235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        // there are no uninitialized bytes. If there were, then we would get
166335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        // false-misses (or worse, false-hits) in our fontcache.
166435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        //
166535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        // We do this buy filling 2 others, one with 0s and the other with 1s
166635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        // and create those, and then check that all 3 are identical.
166735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkAutoDescriptor    ad1(descSize);
166835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkAutoDescriptor    ad2(descSize);
166935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkDescriptor*       desc1 = ad1.getDesc();
167035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkDescriptor*       desc2 = ad2.getDesc();
167135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
167235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        memset(desc1, 0x00, descSize);
167335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        memset(desc2, 0xFF, descSize);
167435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
167535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        desc1->init();
167635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        desc2->init();
167735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        desc1->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
167835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        desc2->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
167935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
168035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (pe) {
168135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            add_flattenable(desc1, kPathEffect_SkDescriptorTag, &peBuffer);
168235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            add_flattenable(desc2, kPathEffect_SkDescriptorTag, &peBuffer);
168335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
168435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (mf) {
168535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            add_flattenable(desc1, kMaskFilter_SkDescriptorTag, &mfBuffer);
168635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            add_flattenable(desc2, kMaskFilter_SkDescriptorTag, &mfBuffer);
168735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
168835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        if (ra) {
168935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            add_flattenable(desc1, kRasterizer_SkDescriptorTag, &raBuffer);
169035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger            add_flattenable(desc2, kRasterizer_SkDescriptorTag, &raBuffer);
169135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        }
169235e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
169335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkASSERT(descSize == desc1->getLength());
169435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkASSERT(descSize == desc2->getLength());
169535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        desc1->computeChecksum();
169635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        desc2->computeChecksum();
169735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkASSERT(!memcmp(desc, desc1, descSize));
169835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger        SkASSERT(!memcmp(desc, desc2, descSize));
169935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger    }
170035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger#endif
170135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger
17020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    proc(desc, context);
17030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
17040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
170540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const {
17060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache* cache;
17070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(deviceMatrix, DetachDescProc, &cache);
17080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache;
17090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
17100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
17120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h"
17140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uintptr_t asint(const void* p) {
17165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return reinterpret_cast<uintptr_t>(p);
17175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
17185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedunion Scalar32 {
17205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkScalar    fScalar;
17215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t    f32;
17225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
17235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) {
17255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
17265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
17275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.fScalar = value;
17285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr = tmp.f32;
17295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return ptr + 1;
17305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
17315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic SkScalar read_scalar(const uint32_t*& ptr) {
17335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
17345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
17355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.f32 = *ptr++;
17365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return tmp.fScalar;
17375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
17385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
17405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(a == (uint8_t)a);
17415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(b == (uint8_t)b);
17425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(c == (uint8_t)c);
17435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(d == (uint8_t)d);
17445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return (a << 24) | (b << 16) | (c << 8) | d;
17455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
17465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedenum FlatFlags {
17485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasTypeface_FlatFlag   = 0x01,
17495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasEffects_FlatFlag    = 0x02
17505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
17515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed// The size of a flat paint's POD fields
17535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic const uint32_t kPODPaintSize =   5 * sizeof(SkScalar) +
17545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(SkColor) +
17555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(uint16_t) +
17565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        6 * sizeof(uint8_t);
17575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed/*  To save space/time, we analyze the paint, and write a truncated version of
17595f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    it if there are not tricky elements like shaders, etc.
17605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed */
17610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
17625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = 0;
17635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (this->getTypeface()) {
17645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasTypeface_FlatFlag;
17655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
17665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (asint(this->getPathEffect()) |
17675f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getShader()) |
17685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getXfermode()) |
17695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getMaskFilter()) |
17705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getColorFilter()) |
17715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getRasterizer()) |
17721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        asint(this->getLooper()) |
17731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        asint(this->getImageFilter())) {
17745f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasEffects_FlatFlag;
17755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
177640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
17775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
17785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t* ptr = buffer.reserve(kPODPaintSize);
17795f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSize());
17815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextScaleX());
17825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSkewX());
17835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeWidth());
17845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeMiter());
17855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = this->getColor();
17861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // previously flags:16, textAlign:8, flatFlags:8
17871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // now flags:16, hinting:4, textAlign:4, flatFlags:8
17881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *ptr++ = (this->getFlags() << 16) |
17891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             // hinting added later. 0 in this nibble means use the default.
17901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             ((this->getHinting()+1) << 12) |
17911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             (this->getTextAlign() << 8) |
17921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger             flatFlags;
17935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
17945f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                    this->getStyle(), this->getTextEncoding());
17955f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
17965f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // now we're done with ptr and the (pre)reserved space. If we need to write
17975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // additional fields, use the buffer directly
17985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
17995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeTypeface(this->getTypeface());
18005f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
18015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
18025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getPathEffect());
18035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getShader());
18045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getXfermode());
18055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getMaskFilter());
18065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getColorFilter());
18075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getRasterizer());
18085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getLooper());
18091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        buffer.writeFlattenable(this->getImageFilter());
18105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
18110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
18145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
18155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const void* podData = buffer.skip(kPODPaintSize);
18165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
181740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
18185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // the order we read must match the order we wrote in flatten()
18195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSize(read_scalar(pod));
18205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextScaleX(read_scalar(pod));
18215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSkewX(read_scalar(pod));
18225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeWidth(read_scalar(pod));
182340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    this->setStrokeMiter(read_scalar(pod));
18245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setColor(*pod++);
18255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
18261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // previously flags:16, textAlign:8, flatFlags:8
18271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    // now flags:16, hinting:4, textAlign:4, flatFlags:8
18285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t tmp = *pod++;
18295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setFlags(tmp >> 16);
18301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (buffer.getPictureVersion() == PICTURE_VERSION_ICS) {
18324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF));
18334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        this->setHinting(SkPaintDefaults_Hinting);
18344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else {
18354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        // hinting added later. 0 in this nibble means use the default.
18364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        uint32_t hinting = (tmp >> 12) & 0xF;
18374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        this->setHinting(0 == hinting ? kNormal_Hinting : static_cast<Hinting>(hinting-1));
18381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xF));
18404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
18411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
18425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = tmp & 0xFF;
18435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
18445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp = *pod++;
18455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
18465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
18475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
18485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
18495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
18505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
18515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(buffer.readTypeface());
18525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
18535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(NULL);
18545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
18555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
18565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
185740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(this->setPathEffect((SkPathEffect*) buffer.readFlattenable()));
185840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(this->setShader((SkShader*) buffer.readFlattenable()));
185940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(this->setXfermode((SkXfermode*) buffer.readFlattenable()));
186040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable()));
186140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(this->setColorFilter((SkColorFilter*) buffer.readFlattenable()));
186240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(this->setRasterizer((SkRasterizer*) buffer.readFlattenable()));
186340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkSafeUnref(this->setLooper((SkDrawLooper*) buffer.readFlattenable()));
18644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (buffer.getPictureVersion() != PICTURE_VERSION_ICS)
18654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            SkSafeUnref(this->setImageFilter((SkImageFilter*) buffer.readFlattenable()));
18664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        else
18674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            this->setImageFilter(NULL);
18685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
18695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setPathEffect(NULL);
18705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setShader(NULL);
18715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setXfermode(NULL);
18725f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setMaskFilter(NULL);
18735f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setColorFilter(NULL);
18745f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setRasterizer(NULL);
18755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setLooper(NULL);
18761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->setImageFilter(NULL);
18775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
18780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
18810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
188287b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkShader* SkPaint::setShader(SkShader* shader) {
188387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(shader != fShader);
18840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fShader, shader);
18850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return shader;
18860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
188887b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) {
188987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(filter != fColorFilter);
18900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fColorFilter, filter);
18910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
18920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
189487b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkXfermode* SkPaint::setXfermode(SkXfermode* mode) {
189587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(mode != fXfermode);
18960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fXfermode, mode);
18970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return mode;
18980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
190003f42ddd729377f21719a140c027a1f8cc5c2152Mike ReedSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
190103f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    SkSafeUnref(fXfermode);
190203f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    fXfermode = SkXfermode::Create(mode);
190387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC;
190403f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    return fXfermode;
190503f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed}
190603f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed
190787b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) {
190887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(effect != fPathEffect);
19090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fPathEffect, effect);
19100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return effect;
19110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
19120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
191387b8e645865f9633f410c02252a0fd3feb18f09bDerek SollenbergerSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) {
191487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    GEN_ID_INC_EVAL(filter != fMaskFilter);
19150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fMaskFilter, filter);
19160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
19170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
19180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
191940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
19200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
192140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const {
19220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath          effectPath, strokePath;
19230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   path = &src;
19240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
19250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = this->getStrokeWidth();
192640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
19270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getStyle()) {
192840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkPaint::kFill_Style:
19290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
193040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
193140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkPaint::kStrokeAndFill_Style:
193240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (width == 0) {
193340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                width = -1; // mark it as no-stroke
193440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
193540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
193640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        case SkPaint::kStroke_Style:
193740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            break;
193840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        default:
19391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDEBUGFAIL("unknown paint style");
19400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
19410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
194240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (this->getPathEffect()) {
19430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill
194440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (this->getStyle() == SkPaint::kStrokeAndFill_Style) {
19450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
194640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
19470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
194840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (this->getPathEffect()->filterPath(&effectPath, src, &width)) {
19490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            path = &effectPath;
195040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
195140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
19520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // restore the width if we earlier had to lie, and if we're still set to no-stroke
19530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // note: if we're now stroke (width >= 0), then the pathEffect asked for that change
19540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // and we want to respect that (i.e. don't overwrite their setting for width)
195540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0) {
19560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = this->getStrokeWidth();
195740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (width == 0) {
19580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width = -1;
195940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
19600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
19610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
196240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
196340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (width > 0 && !path->isEmpty()) {
19640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkStroke stroker(*this, width);
19650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        stroker.strokePath(*path, &strokePath);
19660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path = &strokePath;
19670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
19680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
196940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (path == &src) {
19700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst = src;
197140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
19720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(path == &effectPath || path == &strokePath);
19730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->swap(*(SkPath*)path);
19740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
19750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
19760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width != 0;  // return true if we're filled, or false if we're hairline (width == 0)
19770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
19780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1979717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerconst SkRect& SkPaint::doComputeFastBounds(const SkRect& src,
1980717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger                                                 SkRect* storage) const {
19810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storage);
1982717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
1983717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    if (this->getLooper()) {
1984717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        SkASSERT(this->getLooper()->canComputeFastBounds(*this));
1985717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        this->getLooper()->computeFastBounds(*this, src, storage);
1986717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        return *storage;
1987717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    }
1988717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
1989717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    if (this->getStyle() != SkPaint::kFill_Style) {
1990717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        // since we're stroked, outset the rect by the radius (and join type)
1991717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        SkScalar radius = SkScalarHalf(this->getStrokeWidth());
1992717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        if (0 == radius) {  // hairline
1993717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            radius = SK_Scalar1;
1994717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
1995717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            SkScalar scale = this->getStrokeMiter();
1996717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            if (scale > SK_Scalar1) {
1997717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger                radius = SkScalarMul(radius, scale);
1998717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            }
19990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
2000717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        storage->set(src.fLeft - radius, src.fTop - radius,
2001717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger                     src.fRight + radius, src.fBottom + radius);
2002717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    } else {
2003717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        *storage = src;
20040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2005717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
2006717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    // check the mask filter
2007717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    if (this->getMaskFilter()) {
2008717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        this->getMaskFilter()->computeFastBounds(*storage, storage);
2009717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    }
2010717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
201135d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    return *storage;
20120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
20130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
201440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger///////////////////////////////////////////////////////////////////////////////
20150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
201640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool has_thick_frame(const SkPaint& paint) {
201740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    return  paint.getStrokeWidth() > 0 &&
201840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            paint.getStyle() != SkPaint::kFill_Style;
20190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
20200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
20220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    const SkPaint& paint,
20230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool applyStrokeAndPathEffects,
202440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                    bool forceLinearTextOn) : fPaint(paint) {
20250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
20260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                true);
20270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
202840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (forceLinearTextOn) {
20290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setLinearText(true);
203040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
20310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
20320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
203340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint)) {
20340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        applyStrokeAndPathEffects = false;
203540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
20360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // can't use our canonical size if we need to apply patheffects/strokes
2038b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger    if (fPaint.getPathEffect() == NULL) {
20390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
20400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
2041b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger        if (has_thick_frame(fPaint)) {
2042b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger            fPaint.setStrokeWidth(SkScalarDiv(fPaint.getStrokeWidth(), fScale));
2043b9e9dcfa17a61a0cc2c192daae78d0af2927736aDerek Sollenberger        }
204440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    } else {
20450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = SK_Scalar1;
204640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    }
204740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger
204840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!applyStrokeAndPathEffects) {
20490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setStyle(SkPaint::kFill_Style);
20500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setPathEffect(NULL);
20510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
20520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCache = fPaint.detachCache(NULL);
20540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = SkPaint::kFill_Style;
20560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = NULL;
20570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
205840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (!applyStrokeAndPathEffects) {
20590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        style = paint.getStyle();   // restore
20600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        pe = paint.getPathEffect();     // restore
20610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
20620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setStyle(style);
20630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setPathEffect(pe);
20640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(paint.getMaskFilter());    // restore
20650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // now compute fXOffset if needed
20670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar xOffset = 0;
206940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    if (paint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first
20700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int      count;
207140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length,
207240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger                                                         &count, NULL), fScale);
207340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (paint.getTextAlign() == SkPaint::kCenter_Align) {
20740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarHalf(width);
207540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        }
20760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        xOffset = -width;
20770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
20780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXPos = xOffset;
20790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPrevAdvance = 0;
20800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fText = text;
20820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStop = text + length;
20831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
20841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fXYIndex = paint.isVerticalText() ? 1 : 0;
20850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
20860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
208740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTextToPathIter::~SkTextToPathIter() {
20880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::AttachCache(fCache);
20890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
20900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
209140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerconst SkPath* SkTextToPathIter::next(SkScalar* xpos) {
209240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger    while (fText < fStop) {
20930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
20940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
20950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
20961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        fPrevAdvance = advance(glyph, fXYIndex);   // + fPaint.getTextTracking();
20970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
209840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger        if (glyph.fWidth) {
209940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            if (xpos) {
21000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *xpos = fXPos;
210140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger            }
21020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fCache->findPath(glyph);
21030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
21040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
21050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
21060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2107717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
2108717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
2109717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
21101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkPaint::nothingToDraw() const {
21111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fLooper) {
21121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return false;
21131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
21141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkXfermode::Mode mode;
21151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (SkXfermode::AsMode(fXfermode, &mode)) {
21161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        switch (mode) {
21171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkXfermode::kSrcOver_Mode:
21181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkXfermode::kSrcATop_Mode:
21191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkXfermode::kDstOut_Mode:
21201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkXfermode::kDstOver_Mode:
21211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkXfermode::kPlus_Mode:
21221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return 0 == this->getAlpha();
21231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            case SkXfermode::kDst_Mode:
21241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                return true;
21251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            default:
21261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                break;
21271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
21281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
21291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return false;
21301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
21311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger//////////// Move these to their own file soon.
21341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src,
21361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                const SkMatrix& ctm,
21371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                SkBitmap* result, SkIPoint* loc) {
21381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(proxy);
21391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(result);
21401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(loc);
21411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    /*
21421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  Give the proxy first shot at the filter. If it returns false, ask
21431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     *  the filter to do it.
21441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger     */
21451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return proxy->filterImage(this, src, ctm, result, loc) ||
21461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger           this->onFilterImage(proxy, src, ctm, result, loc);
21471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
21481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm,
21501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 SkIRect* dst) {
21511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(&src);
21521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    SkASSERT(dst);
21531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return this->onFilterBounds(src, ctm, dst);
21541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
21551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&,
21571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                  SkBitmap*, SkIPoint*) {
21581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return false;
21591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
21601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
21621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                   SkIRect* dst) {
21631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    *dst = src;
21641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return true;
21651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
21661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool SkImageFilter::asABlur(SkSize* sigma) const {
21681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return false;
21691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
21701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asAnErode(SkISize* radius) const {
21724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return false;
21734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
21744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
21754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkImageFilter::asADilate(SkISize* radius) const {
21764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return false;
21774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
21784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
21794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger//////
21804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
2181717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergerbool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) {
2182717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    SkCanvas canvas;
2183717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
2184717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    this->init(&canvas);
2185717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    for (;;) {
2186717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        SkPaint p(paint);
2187717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        if (this->next(&canvas, &p)) {
2188717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            p.setLooper(NULL);
2189717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            if (!p.canComputeFastBounds()) {
2190717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger                return false;
2191717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            }
2192717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        } else {
2193717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            break;
2194717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        }
2195717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    }
2196717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    return true;
2197717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger}
2198717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
2199717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenbergervoid SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src,
2200717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger                                     SkRect* dst) {
2201717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    SkCanvas canvas;
22024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
2203717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    this->init(&canvas);
2204717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    for (bool firstTime = true;; firstTime = false) {
2205717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        SkPaint p(paint);
2206717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        if (this->next(&canvas, &p)) {
2207717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            SkRect r(src);
2208717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
2209717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            p.setLooper(NULL);
2210717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            p.computeFastBounds(r, &r);
2211717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            canvas.getTotalMatrix().mapRect(&r);
2212717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger
2213717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            if (firstTime) {
2214717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger                *dst = r;
2215717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            } else {
2216717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger                dst->join(r);
2217717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            }
2218717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        } else {
2219717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger            break;
2220717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger        }
2221717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger    }
2222717c009190af219a2f9e248d6fa13ad71cfdb0b1Derek Sollenberger}
22231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
2224