SkPaint.cpp revision 9f523ea27ec892a176817dc3a46179c0a910beb4
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/sgl/SkPaint.cpp
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License.
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h"
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDrawLooper.h"
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFontHost.h"
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h"
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPathEffect.h"
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRasterizer.h"
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h"
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScalerContext.h"
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStroke.h"
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypeface.h"
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h"
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAutoKern.h"
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SK_DefaultTextSize      SkIntToScalar(12)
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SK_DefaultFlags         0   //(kNativeHintsText_Flag)
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
36c1c43a17e7f2a87951739691056728a80e9aef6bMike ReedSkPaint::SkPaint() {
37c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // since we may have padding, we zero everything so that our memcmp() call
38c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // in operator== will work correctly.
39c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // with this, we can skip 0 and null individual initializations
40c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    sk_bzero(this, sizeof(*this));
41c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed
42c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#if 0   // not needed with the bzero call above
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface   = NULL;
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSkewX  = 0;
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect  = NULL;
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader      = NULL;
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode    = NULL;
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter  = NULL;
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter = NULL;
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer  = NULL;
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper      = NULL;
52c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fWidth      = 0;
53c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#endif
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
55c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fTextSize   = SK_DefaultTextSize;
56c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fTextScaleX = SK_Scalar1;
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor      = SK_ColorBLACK;
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMiterLimit = SK_DefaultMiterLimit;
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fFlags      = SK_DefaultFlags;
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCapType    = kDefault_Cap;
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fJoinType   = kDefault_Join;
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextAlign  = kLeft_Align;
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStyle      = kFill_Style;
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextEncoding = kUTF8_TextEncoding;
65af2616552738d653d5453915d3236e7154b868cdMike Reed    fHinting    = kNormal_Hinting;
6695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    fGenerationID = 0;
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::SkPaint(const SkPaint& src)
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeRef();
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeRef();
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeRef();
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeRef();
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeRef();
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeRef();
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeRef();
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeRef();
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::~SkPaint()
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint& SkPaint::operator=(const SkPaint& src)
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(&src);
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fTypeface->safeRef();
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fPathEffect->safeRef();
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fShader->safeRef();
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fXfermode->safeRef();
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fMaskFilter->safeRef();
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fColorFilter->safeRef();
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fRasterizer->safeRef();
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fLooper->safeRef();
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1179f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    uint32_t oldGenerationID = fGenerationID;
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
1199f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    fGenerationID = oldGenerationID + 1;
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return *this;
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint operator==(const SkPaint& a, const SkPaint& b)
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return memcmp(&a, &b, sizeof(a)) == 0;
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::reset()
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint init;
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1339f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    uint32_t oldGenerationID = fGenerationID;
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *this = init;
1359f523ea27ec892a176817dc3a46179c0a910beb4Chet Haase    fGenerationID = oldGenerationID + 1;
13695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase}
13795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase
13895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haaseuint32_t SkPaint::getGenerationID() const {
13995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    return fGenerationID;
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFlags(uint32_t flags)
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (fFlags != flags) {
14595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fFlags = flags;
14695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
14795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAntiAlias(bool doAA)
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doAA != isAntiAlias()) {
15395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
15495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
15595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDither(bool doDither)
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
16095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doDither != isDither()) {
16195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
16295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
16395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setSubpixelText(bool doSubpixel)
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
16895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doSubpixel != isSubpixelText()) {
16995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
17095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
17195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
174af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkPaint::setLCDRenderText(bool doLCDRender)
175af2616552738d653d5453915d3236e7154b868cdMike Reed{
17695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doLCDRender != isLCDRenderText()) {
17795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag));
17895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
17995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
180af2616552738d653d5453915d3236e7154b868cdMike Reed}
181af2616552738d653d5453915d3236e7154b868cdMike Reed
1822cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reedvoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText)
1832cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed{
18495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doEmbeddedBitmapText != isEmbeddedBitmapText()) {
18595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
18695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
18795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
1882cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed}
1892cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setLinearText(bool doLinearText)
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
19295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doLinearText != isLinearText()) {
19395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
19495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
19595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setUnderlineText(bool doUnderline)
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
20095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doUnderline != isUnderlineText()) {
20195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
20295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
20395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrikeThruText(bool doStrikeThru)
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
20895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doStrikeThru != isStrikeThruText()) {
20995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
21095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
21195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFakeBoldText(bool doFakeBold)
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
21695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doFakeBold != isFakeBoldText()) {
21795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
21895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
21995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDevKernText(bool doDevKern)
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
22495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doDevKern != isDevKernText()) {
22595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
22695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
22795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFilterBitmap(bool doFilter)
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
23295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (doFilter != isFilterBitmap()) {
23395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag));
23495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
23595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStyle(Style style)
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
24095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)style < kStyleCount) {
24195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if ((unsigned)style != fStyle) {
24295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fStyle = style;
24395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
24495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
24595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setColor(SkColor color)
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
25495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (color != fColor) {
25595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fColor = color;
25695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
25795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAlpha(U8CPU a)
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
26295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    U8CPU oldA = SkColorGetA(fColor);
26395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (a != oldA) {
26495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fColor = SkColorSetARGB(a, SkColorGetR(fColor), SkColorGetG(fColor), SkColorGetB(fColor));
26595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
26695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
27195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    SkColor oldColor = fColor;
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = SkColorSetARGB(a, r, g, b);
27395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (oldColor != fColor) {
27495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
27595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeWidth(SkScalar width)
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
28095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (width >= 0) {
28195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if (width != fWidth) {
28295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fWidth = width;
28395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
28495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
28595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeMiter(SkScalar limit)
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
29495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (limit >= 0) {
29595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if (limit != fMiterLimit) {
29695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fMiterLimit = limit;
29795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
29895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
29995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeCap(Cap ct)
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
30895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)ct < kCapCount) {
30995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if ((unsigned)ct != fCapType) {
31095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fCapType = SkToU8(ct);
31195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
31295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
31395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeJoin(Join jt)
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
32295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)jt < kJoinCount) {
32395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if ((unsigned)jt != fJoinType) {
32495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fJoinType = SkToU8(jt);
32595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
32695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
32795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextAlign(Align align)
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
33895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)align < kAlignCount) {
33995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if ((unsigned)align != fTextAlign) {
34095662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fTextAlign = SkToU8(align);
34195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
34295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
34395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSize(SkScalar ts)
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
35295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (ts > 0) {
35395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if (ts != fTextSize) {
35495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fTextSize = ts;
35595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
35695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
35795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextSize() called with non-positive value\n");
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextScaleX(SkScalar scaleX)
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
36695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (scaleX != fTextScaleX) {
36795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fTextScaleX = scaleX;
36895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
36995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSkewX(SkScalar skewX)
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
37495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (skewX != fTextSkewX) {
37595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fTextSkewX = skewX;
37695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
37795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextEncoding(TextEncoding encoding)
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
38295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if ((unsigned)encoding <= kGlyphID_TextEncoding) {
38395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        if ((unsigned)encoding != fTextEncoding) {
38495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fTextEncoding = encoding;
38595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase            fGenerationID++;
38695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        }
38795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTypeface* SkPaint::setTypeface(SkTypeface* font)
3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fTypeface, font);
39995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    fGenerationID++;
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return font;
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r)
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fRasterizer, r);
40695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    fGenerationID++;
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return r;
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper)
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fLooper, looper);
41395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    fGenerationID++;
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return looper;
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h"
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
422fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guystatic void DetachDescProc(const SkDescriptor* desc, void* context)
423fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy{
424fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc);
425fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy}
426fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy
427b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guyconst SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text) {
428b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    SkGlyphCache* cache;
429b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    descriptorProc(NULL, DetachDescProc, &cache, true);
430b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy
431b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    const SkGlyph& glyph = cache->getUnicharMetrics(text);
432b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy
433b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    SkGlyphCache::AttachCache(cache);
434b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy    return glyph;
435b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy}
436b0bc5be3bc222f6f6586f727e1260a7e39afd14dRomain Guy
43790a1efbdde19ee56c33929592277871509c25893Romain Guyconst void* SkPaint::findImage(const SkGlyph& glyph) {
438fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    // See ::detachCache()
439fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    SkGlyphCache* cache;
440fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    descriptorProc(NULL, DetachDescProc, &cache, true);
44190a1efbdde19ee56c33929592277871509c25893Romain Guy
442fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    const void* image = cache->findImage(glyph);
443fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy
444fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    SkGlyphCache::AttachCache(cache);
445fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    return image;
44690a1efbdde19ee56c33929592277871509c25893Romain Guy}
44790a1efbdde19ee56c33929592277871509c25893Romain Guy
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength,
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          uint16_t glyphs[]) const {
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0) {
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textData != NULL);
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == glyphs) {
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        switch (this->getTextEncoding()) {
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF8_TextEncoding:
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF8_CountUnichars((const char*)textData, byteLength);
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF16_TextEncoding:
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF16_CountUnichars((const uint16_t*)textData,
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                         byteLength >> 1);
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kGlyphID_TextEncoding:
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return byteLength >> 1;
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // if we get here, we have a valid glyphs[] array, so time to fill it in
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // handle this encoding before the setup for the glyphcache
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we want to ignore the low bit of byteLength
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(glyphs, textData, byteLength >> 1 << 1);
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return byteLength >> 1;
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache autoCache(*this, NULL);
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*    cache = autoCache.getCache();
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint16_t*   gptr = glyphs;
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getTextEncoding()) {
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF8_TextEncoding:
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text));
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF16_TextEncoding: {
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* text16 = (const uint16_t*)text;
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* stop16 = (const uint16_t*)stop;
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text16 < stop16) {
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16));
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gptr - glyphs;
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
50775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reedbool SkPaint::containsText(const void* textData, size_t byteLength) const {
50875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    if (0 == byteLength) {
50975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        return true;
51075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
51175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
51275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkASSERT(textData != NULL);
51375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
51475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    // handle this encoding before the setup for the glyphcache
51575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
51675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        const uint16_t* glyphID = static_cast<const uint16_t*>(textData);
51775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        size_t count = byteLength >> 1;
51875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        for (size_t i = 0; i < count; i++) {
51975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            if (0 == glyphID[i]) {
52075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                return false;
52175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
52275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
52375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        return true;
52475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
52575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
52675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkAutoGlyphCache autoCache(*this, NULL);
52775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkGlyphCache*    cache = autoCache.getCache();
52875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
52975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    switch (this->getTextEncoding()) {
53075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        case SkPaint::kUTF8_TextEncoding: {
53175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const char* text = static_cast<const char*>(textData);
53275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const char* stop = text + byteLength;
53375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            while (text < stop) {
53475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) {
53575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                    return false;
53675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                }
53775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
53875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            break;
53975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
54075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        case SkPaint::kUTF16_TextEncoding: {
54175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const uint16_t* text = static_cast<const uint16_t*>(textData);
54275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const uint16_t* stop = text + (byteLength >> 1);
54375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            while (text < stop) {
54475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) {
54575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                    return false;
54675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                }
54775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
54875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            break;
54975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
55075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        default:
55175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            SkASSERT(!"unknown text encoding");
55275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            return false;
55375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
55475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    return true;
55575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed}
55675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
557091f227385b467090b5a7169a8e2faf19eca7105Mike Reedvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count,
558091f227385b467090b5a7169a8e2faf19eca7105Mike Reed                               SkUnichar textData[]) const {
559091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    if (count <= 0) {
560091f227385b467090b5a7169a8e2faf19eca7105Mike Reed        return;
561091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    }
562091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
563091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkASSERT(glyphs != NULL);
564091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkASSERT(textData != NULL);
565091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
566091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkAutoGlyphCache autoCache(*this, NULL);
567091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkGlyphCache*    cache = autoCache.getCache();
568091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
569091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    for (int index = 0; index < count; index++) {
570091f227385b467090b5a7169a8e2faf19eca7105Mike Reed        textData[index] = cache->glyphToUnichar(glyphs[index]);
571091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    }
572091f227385b467090b5a7169a8e2faf19eca7105Mike Reed}
573091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, const char** text)
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, const char** text)
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text));
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, const char** text)
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, const char** text)
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text));
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, const char** text)
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, const char** text)
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, const char** text)
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_NextUnichar(text));
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, const char** text)
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text));
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, const char** text)
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text));
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, const char** text)
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text));
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, const char** text)
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, const char** text)
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd,
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                bool needFullMetrics) const
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkMeasureCacheProc gMeasureCacheProcs[] = {
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_next,
6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_next,
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_next,
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_prev,
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_prev,
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_prev,
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_next,
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_next,
7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_next,
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_prev,
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_prev,
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_prev
7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kBackward_TextBufferDirection == tbd)
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!needFullMetrics && !this->isDevKernText())
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 6;
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs));
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gMeasureCacheProcs[index];
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache,
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed, SkFixed)
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache,
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed x, SkFixed y)
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y);
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, const char** text,
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache,
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text),
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    x, y);
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, const char** text,
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache,
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID, x, y);
7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawCacheProc SkPaint::getDrawCacheProc() const
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkDrawCacheProc gDrawCacheProcs[] = {
7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_00,
7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_00,
7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_00,
7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_xy,
7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_xy,
7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_xy
7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fFlags & kSubpixelText_Flag)
8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs));
8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gDrawCacheProcs[index];
8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame {
8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint) : fPaint((SkPaint*)paint)
8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = paint->getTextSize();
8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = paint->getStyle();
8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(SkPaint::kFill_Style);
8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkAutoRestorePaintTextSizeAndFrame()
8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(fStyle);
8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setTextSize(fTextSize);
8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint*        fPaint;
8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        fTextSize;
8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  fStyle;
8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds)
8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(SkIntToScalar(g.fLeft),
8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop),
8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fLeft + g.fWidth),
8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop + g.fHeight));
8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
837e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so
838e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed// we don't overflow along the way
839e63c5c9f6752244ca0f39075fa148a0281593831Mike Reedtypedef int64_t Sk48Dot16;
840e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed
841e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#ifdef SK_SCALAR_IS_FLOAT
842e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    static inline float Sk48Dot16ToScalar(Sk48Dot16 x) {
843e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed        return x * 1.5258789e-5f;   // x * (1 / 65536.0f)
844e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    }
845e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#else
846e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    static inline SkFixed Sk48Dot16ToScalar(Sk48Dot16 x) {
847e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed        // just return the low 32bits
848e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed        return static_cast<SkFixed>(x);
849e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    }
850e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed#endif
851e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed
852e63c5c9f6752244ca0f39075fa148a0281593831Mike Reedstatic void join_bounds(const SkGlyph& g, SkRect* bounds, Sk48Dot16 dx)
8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
854e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    SkScalar sx = Sk48Dot16ToScalar(dx);
8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->join(SkIntToScalar(g.fLeft) + sx,
8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop),
8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fLeft + g.fWidth) + sx,
8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop + g.fHeight));
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache,
8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const char* text, size_t byteLength,
8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               int* count, SkRect* bounds) const
8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count);
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0)
8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = 0;
8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (bounds)
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            bounds->setEmpty();
8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc;
8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         n = 1;
8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = (const char*)text + byteLength;
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkGlyph* g = &glyphCacheProc(cache, &text);
881e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // our accumulated fixed-point advances might overflow 16.16, so we use
882e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // a 48.16 (64bit) accumulator, and then convert that to scalar at the
883e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // very end.
884e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    Sk48Dot16 x = g->fAdvanceX;
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == bounds)
8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + g->fAdvanceX;
8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += glyphCacheProc(cache, &text).fAdvanceX;
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        set_bounds(*g, bounds);
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta);
9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *count = n;
932e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    return Sk48Dot16ToScalar(x);
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length,
9360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                              SkRect* bounds, SkScalar zoom) const
9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL || length == 0);
9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = 0;
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length > 0)
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
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);
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarMul(width, scale);
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (bounds)
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fLeft = SkScalarMul(bounds->fLeft, scale);
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fTop = SkScalarMul(bounds->fTop, scale);
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fRight = SkScalarMul(bounds->fRight, scale);
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fBottom = SkScalarMul(bounds->fBottom, scale);
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop);
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool forward_textBufferPred(const char* text, const char* stop)
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text < stop;
9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool backward_textBufferPred(const char* text, const char* stop)
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text > stop;
9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd,
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            const char** text, size_t length, const char** stop)
9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkPaint::kForward_TextBufferDirection == tbd)
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text + length;
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return forward_textBufferPred;
10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // text should point to the end of the buffer, and stop to the beginning
10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text;
10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *text += length;
10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return backward_textBufferPred;
10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          SkScalar* measuredWidth,
10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          TextBufferDirection tbd) const
10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == length || 0 >= maxWidth)
10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (measuredWidth)
10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *measuredWidth = 0;
10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textD != NULL);
10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textD;
10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
10329b1cba8ccd7554cb30905711a426bd86ad8dd38cJean-Baptiste Queru        maxWidth = SkScalarMulDiv(maxWidth, kCanonicalTextSizeForPaths, fTextSize);
10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
10340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false);
10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char*      stop;
10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop);
1043e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    // use 64bits for our accumulator, to avoid overflowing 16.16
1044e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    Sk48Dot16        max = SkScalarToFixed(maxWidth);
1045e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed    Sk48Dot16        width = 0;
10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
10480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int rsb = 0;
10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const SkGlyph& g = glyphCacheProc(cache, &text);
10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + g.fAdvanceX;
10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            rsb = g.fRsbDelta;
10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = glyphCacheProc(cache, &text).fAdvanceX;
10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (measuredWidth)
10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1084e63c5c9f6752244ca0f39075fa148a0281593831Mike Reed        SkScalar scalarWidth = Sk48Dot16ToScalar(width);
10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scalarWidth = SkScalarMul(scalarWidth, scale);
10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *measuredWidth = scalarWidth;
10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // return the number of bytes measured
10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (kForward_TextBufferDirection == tbd) ?
10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text - stop + length : stop - text + length;
10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context)
10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *(SkPaint::FontMetrics*)context = cache->getFontMetricsY();
11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;   // don't detach the cache
11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context)
11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context);
11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const
11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const FontMetrics&  my = cache->getFontMetricsY();
11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    FontMetrics storage;
11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == metrics)
11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics = &storage;
11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics);
11370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (scale)
11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fTop = SkScalarMul(metrics->fTop, scale);
11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return metrics->fDescent - metrics->fAscent + metrics->fLeading;
11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale)
11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(g.fLeft * scale,
11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g.fTop * scale,
11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fLeft + g.fWidth) * scale,
11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fTop + g.fHeight) * scale);
11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::getTextWidths(const void* textData, size_t byteLength, SkScalar widths[],
11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                           SkRect bounds[]) const
11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == byteLength)
11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(NULL != textData);
11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == widths && NULL == bounds)
11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->countText(textData, byteLength);
11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc  glyphCacheProc;
11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         count = 0;
11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we adjust the widths returned here through auto-kerning
11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoKern  autokern;
11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkFixed     prevWidth = 0;
11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkScalar w = SkFixedToScalar(prevWidth + adjust);
12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkScalarMul(w, scale);
12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale);
12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkFixedToScalar(prevWidth + adjust);
12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
12260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkFixedToScalar(prevWidth);
12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {    // no devkern
12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *widths++ = SkScalarMul(SkFixedToScalar(g.fAdvanceX),
12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            scale);
12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *widths++ = SkFixedToScalar(g.fAdvanceX);
12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
12580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return count;
12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h"
12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::getTextPath(const void* textData, size_t length, SkScalar x, SkScalar y, SkPath* path) const
12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length == 0 || text != NULL);
12750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (text == NULL || length == 0 || path == NULL)
12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextToPathIter    iter(text, length, *this, false, true);
12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix            matrix;
12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar            prevXPos = 0;
12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.setScale(iter.getPathScale(), iter.getPathScale());
12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.postTranslate(x, y);
12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    path->reset();
12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        xpos;
12870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   iterPath;
12880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while ((iterPath = iter.next(&xpos)) != NULL)
12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        matrix.postTranslate(xpos - prevXPos, 0);
12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path->addPath(*iterPath, matrix);
12920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevXPos = xpos;
12930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag,
12970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            SkFlattenableWriteBuffer* buffer) {
12980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
12990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *  interpolates to find the right value for key, in the function represented by the 'length' number of pairs: (keys[i], values[i])
13030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    inspired by a desire to change the multiplier for thickness in fakebold
13040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    therefore, i assumed number of pairs (length) will be small, so a linear search is sufficient
13050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    repeated keys are allowed for discontinuous functions (so long as keys is monotonically increasing), and if
13060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        key is the value of a repeated scalar in keys, the first one will be used
13070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - this may change if a binary search is used
13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - also, this ensures that there is no divide by zero (an assert also checks for that)
13090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
13100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkScalar interpolate(SkScalar key, const SkScalar keys[], const SkScalar values[], int length)
13110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length > 0);
13140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(keys != NULL);
13150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(values != NULL);
13160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
13170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 1; i < length; i++)
13180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(keys[i] >= keys[i-1]);
13190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
13200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int right = 0;
13210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (right < length && key > keys[right])
13220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        right++;
13230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //could use sentinal values to eliminate conditionals
13240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //i assume i am not in control of input values, so i want to make it simple
13250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length == right)
13260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[length-1];
13270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == right)
13280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[0];
13290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //otherwise, we interpolate between right-1 and right
13300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rVal = values[right];
13310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar lVal = values[right-1];
13320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rightKey = keys[right];
13330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar leftKey = keys[right-1];
13340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(rightKey != leftKey);
13350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //fractional amount which we will multiply by the difference in the left value and right value
13360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar fract = SkScalarDiv(key-leftKey,rightKey-leftKey);
13370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return lVal + SkScalarMul(fract, rVal-lVal);
13380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//used for interpolating in fakeBold
13410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar pointSizes[] = { SkIntToScalar(9), SkIntToScalar(36) };
13420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar multipliers[] = { SK_Scalar1/24, SK_Scalar1/32 };
13430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkMask::Format computeMaskFormat(const SkPaint& paint)
13450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flags = paint.getFlags();
13470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1348c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    // Antialiasing being disabled trumps all other settings.
1349c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    if (!(flags & SkPaint::kAntiAlias_Flag))
1350c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed        return SkMask::kBW_Format;
1351c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed
1352af2616552738d653d5453915d3236e7154b868cdMike Reed#if defined(SK_SUPPORT_LCDTEXT)
1353c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    if (flags & SkPaint::kLCDRenderText_Flag)
1354af2616552738d653d5453915d3236e7154b868cdMike Reed        return SkFontHost::GetSubpixelOrientation() == SkFontHost::kHorizontal_LCDOrientation ?
1355af2616552738d653d5453915d3236e7154b868cdMike Reed                   SkMask::kHorizontalLCD_Format : SkMask::kVerticalLCD_Format;
1356af2616552738d653d5453915d3236e7154b868cdMike Reed#endif
1357c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed
1358c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    return SkMask::kA8_Format;
13590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13614bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// if linear-text is on, then we force hinting to be off (since that's sort of
13624bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// the point of linear-text.
13634bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reedstatic SkPaint::Hinting computeHinting(const SkPaint& paint) {
13644bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    SkPaint::Hinting h = paint.getHinting();
13654bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    if (paint.isLinearText()) {
13664bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed        h = SkPaint::kNo_Hinting;
13674bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    }
13684bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    return h;
13694bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed}
13704bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed
1371af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkScalerContext::MakeRec(const SkPaint& paint,
1372af2616552738d653d5453915d3236e7154b868cdMike Reed                              const SkMatrix* deviceMatrix, Rec* rec)
13730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1374af2616552738d653d5453915d3236e7154b868cdMike Reed    SkASSERT(deviceMatrix == NULL ||
1375af2616552738d653d5453915d3236e7154b868cdMike Reed             (deviceMatrix->getType() & SkMatrix::kPerspective_Mask) == 0);
13760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFontID = SkTypeface::UniqueID(paint.getTypeface());
13780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fTextSize = paint.getTextSize();
13790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreScaleX = paint.getTextScaleX();
13800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreSkewX  = paint.getTextSkewX();
13810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (deviceMatrix)
13830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
13840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = deviceMatrix->getScaleX();
13850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = deviceMatrix->getSkewX();
13860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][0] = deviceMatrix->getSkewY();
13870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][1] = deviceMatrix->getScaleY();
13880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
13900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
13910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
13920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
13930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = paint.getStyle();
13960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        strokeWidth = paint.getStrokeWidth();
13970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13981c980e0d7772f05f570ae0227d91635f017c2227Mike Reed    unsigned flags = SkFontHost::ComputeGammaFlag(paint);
13991c980e0d7772f05f570ae0227d91635f017c2227Mike Reed
14000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isFakeBoldText())
14010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
14021c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#ifdef SK_USE_FREETYPE_EMBOLDEN
14031c980e0d7772f05f570ae0227d91635f017c2227Mike Reed        flags |= SkScalerContext::kEmbolden_Flag;
14041c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#else
14050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar fakeBoldScale = interpolate(paint.getTextSize(), pointSizes, multipliers, 2);
14060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
14070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kFill_Style)
14090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
14100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            style = SkPaint::kStrokeAndFill_Style;
14110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth = extra;    // ignore paint's strokeWidth if it was "fill"
14120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
14130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
14140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth += extra;
14151c980e0d7772f05f570ae0227d91635f017c2227Mike Reed#endif
14160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isDevKernText())
14190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        flags |= SkScalerContext::kDevKernText_Flag;
14200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (style != SkPaint::kFill_Style && strokeWidth > 0)
14220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
14230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = strokeWidth;
14240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = paint.getStrokeMiter();
14250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
14260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kStrokeAndFill_Style)
14280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            flags |= SkScalerContext::kFrameAndFill_Flag;
14290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
14310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
14320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = 0;
14330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = 0;
14340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = 0;
14350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1437af2616552738d653d5453915d3236e7154b868cdMike Reed    rec->fSubpixelPositioning = paint.isSubpixelText();
14380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
14390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFlags = SkToU8(flags);
14404bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    rec->setHinting(computeHinting(paint));
14412cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed    if (paint.isEmbeddedBitmapText())
14422cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed        rec->fFlags |= SkScalerContext::kEmbeddedBitmapText_Flag;
1443af2616552738d653d5453915d3236e7154b868cdMike Reed
1444af2616552738d653d5453915d3236e7154b868cdMike Reed    /*  Allow the fonthost to modify our rec before we use it as a key into the
1445af2616552738d653d5453915d3236e7154b868cdMike Reed        cache. This way if we're asking for something that they will ignore,
1446af2616552738d653d5453915d3236e7154b868cdMike Reed        they can modify our rec up front, so we don't create duplicate cache
1447af2616552738d653d5453915d3236e7154b868cdMike Reed        entries.
1448af2616552738d653d5453915d3236e7154b868cdMike Reed     */
1449af2616552738d653d5453915d3236e7154b868cdMike Reed    SkFontHost::FilterRec(rec);
14500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER  1024
14530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
14550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void (*proc)(const SkDescriptor*, void*),
1456fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy                             void* context, bool ignoreGamma) const
14570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::Rec    rec;
14590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::MakeRec(*this, deviceMatrix, &rec);
1461fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    if (ignoreGamma) {
1462fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy        rec.fFlags &= ~(SkScalerContext::kGammaForBlack_Flag |
1463fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy                SkScalerContext::kGammaForWhite_Flag);
1464fda149e38309f3ee38b172a9997cfee5dbccc32aRomain Guy    }
14650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t          descSize = sizeof(rec);
14670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int             entryCount = 1;
14680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = this->getPathEffect();
14690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMaskFilter*   mf = this->getMaskFilter();
14700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRasterizer*   ra = this->getRasterizer();
14710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
14730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
14740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
14750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
14770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        peBuffer.writeFlattenable(pe);
14780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += peBuffer.size();
14790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
14800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
14810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // seems like we could support kLCD as well at this point...
14820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
14840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mfBuffer.writeFlattenable(mf);
14850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += mfBuffer.size();
14860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
14870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing with maskfilters
14880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
14900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        raBuffer.writeFlattenable(ra);
14910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += raBuffer.size();
14920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
14930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
14940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    descSize += SkDescriptor::ComputeOverhead(entryCount);
14960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoDescriptor    ad(descSize);
14980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDescriptor*       desc = ad.getDesc();
14990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->init();
15010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
15020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
15040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
15050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
15070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
15080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
15100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
15110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(descSize == desc->getLength());
15140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->computeChecksum();
15150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    proc(desc, context);
15170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const
15200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache* cache;
15220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(deviceMatrix, DetachDescProc, &cache);
15230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache;
15240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
15270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h"
15290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uintptr_t asint(const void* p) {
15315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return reinterpret_cast<uintptr_t>(p);
15325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
15335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedunion Scalar32 {
15355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkScalar    fScalar;
15365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t    f32;
15375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
15385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) {
15405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
15415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
15425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.fScalar = value;
15435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr = tmp.f32;
15445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return ptr + 1;
15455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
15465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic SkScalar read_scalar(const uint32_t*& ptr) {
15485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
15495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
15505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.f32 = *ptr++;
15515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return tmp.fScalar;
15525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
15535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
15555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(a == (uint8_t)a);
15565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(b == (uint8_t)b);
15575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(c == (uint8_t)c);
15585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(d == (uint8_t)d);
15595f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return (a << 24) | (b << 16) | (c << 8) | d;
15605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
15615f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedenum FlatFlags {
15635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasTypeface_FlatFlag   = 0x01,
15645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasEffects_FlatFlag    = 0x02
15655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
15665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15675f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed// The size of a flat paint's POD fields
15685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic const uint32_t kPODPaintSize =   5 * sizeof(SkScalar) +
15695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(SkColor) +
15705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(uint16_t) +
15715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        6 * sizeof(uint8_t);
15725f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15735f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed/*  To save space/time, we analyze the paint, and write a truncated version of
15745f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    it if there are not tricky elements like shaders, etc.
15755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed */
15760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
15775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = 0;
15785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (this->getTypeface()) {
15795f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasTypeface_FlatFlag;
15805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
15815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (asint(this->getPathEffect()) |
15825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getShader()) |
15835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getXfermode()) |
15845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getMaskFilter()) |
15855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getColorFilter()) |
15865f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getRasterizer()) |
15875f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getLooper())) {
15885f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasEffects_FlatFlag;
15895f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
15905f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15915f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
15925f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t* ptr = buffer.reserve(kPODPaintSize);
15935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15945f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSize());
15955f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextScaleX());
15965f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSkewX());
15975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeWidth());
15985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeMiter());
15995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = this->getColor();
16005f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = (this->getFlags() << 16) | (this->getTextAlign() << 8) | flatFlags;
16015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
16025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                    this->getStyle(), this->getTextEncoding());
16035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
16045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // now we're done with ptr and the (pre)reserved space. If we need to write
16055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // additional fields, use the buffer directly
16065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
16075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeTypeface(this->getTypeface());
16085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
16095f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
16105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getPathEffect());
16115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getShader());
16125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getXfermode());
16135f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getMaskFilter());
16145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getColorFilter());
16155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getRasterizer());
16165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getLooper());
16175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
16180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
16215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
16225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const void* podData = buffer.skip(kPODPaintSize);
16235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
16245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
16255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // the order we read must match the order we wrote in flatten()
16265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSize(read_scalar(pod));
16275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextScaleX(read_scalar(pod));
16285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSkewX(read_scalar(pod));
16295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeWidth(read_scalar(pod));
16305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeMiter(read_scalar(pod));
16315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setColor(*pod++);
16325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
16335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t tmp = *pod++;
16345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setFlags(tmp >> 16);
16355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF));
16365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = tmp & 0xFF;
16375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
16385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp = *pod++;
16395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
16405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
16415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
16425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
16435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
16445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
16455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(buffer.readTypeface());
16465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
16475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(NULL);
16485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
16495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
16505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
16515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setPathEffect((SkPathEffect*) buffer.readFlattenable())->safeUnref();
16525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setShader((SkShader*) buffer.readFlattenable())->safeUnref();
16535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setXfermode((SkXfermode*) buffer.readFlattenable())->safeUnref();
16545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())->safeUnref();
16555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setColorFilter((SkColorFilter*) buffer.readFlattenable())->safeUnref();
16565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setRasterizer((SkRasterizer*) buffer.readFlattenable())->safeUnref();
16575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setLooper((SkDrawLooper*) buffer.readFlattenable())->safeUnref();
16585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
16595f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setPathEffect(NULL);
16605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setShader(NULL);
16615f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setXfermode(NULL);
16625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setMaskFilter(NULL);
16635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setColorFilter(NULL);
16645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setRasterizer(NULL);
16655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setLooper(NULL);
16665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
16670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
16700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader* SkPaint::setShader(SkShader* shader)
16720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
167395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (shader != fShader) {
167495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
167595662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
16760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fShader, shader);
16770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return shader;
16780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter)
16810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
168295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (filter != fColorFilter) {
168395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
168495662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
16850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fColorFilter, filter);
16860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
16870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkXfermode* SkPaint::setXfermode(SkXfermode* mode)
16900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
169195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (mode != fXfermode) {
169295662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
169395662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
16940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fXfermode, mode);
16950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return mode;
16960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
169803f42ddd729377f21719a140c027a1f8cc5c2152Mike ReedSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
169903f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    SkSafeUnref(fXfermode);
170003f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    fXfermode = SkXfermode::Create(mode);
170195662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    fGenerationID++;
170203f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    return fXfermode;
170303f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed}
170403f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed
17050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect)
17060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
170795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (effect != fPathEffect) {
170895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
170995662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
17100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fPathEffect, effect);
17110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return effect;
17120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
17130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter)
17150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
171695662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    if (filter != fMaskFilter) {
171795662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase        fGenerationID++;
171895662ea6ee460cc84014c41a8c13e881cd8be8edChet Haase    }
17190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fMaskFilter, filter);
17200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
17210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
17220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
17240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const
17260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
17270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath          effectPath, strokePath;
17280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   path = &src;
17290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = this->getStrokeWidth();
17310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getStyle()) {
17330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kFill_Style:
17340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = -1; // mark it as no-stroke
17350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
17360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStrokeAndFill_Style:
17370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (width == 0)
17380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
17390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
17400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStroke_Style:
17410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
17420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    default:
17430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(!"unknown paint style");
17440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
17450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getPathEffect())
17470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
17480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill
17490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style)
17500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
17510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getPathEffect()->filterPath(&effectPath, src, &width))
17530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            path = &effectPath;
17540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // restore the width if we earlier had to lie, and if we're still set to no-stroke
17560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // note: if we're now stroke (width >= 0), then the pathEffect asked for that change
17570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // and we want to respect that (i.e. don't overwrite their setting for width)
17580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0)
17590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
17600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = this->getStrokeWidth();
17610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (width == 0)
17620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width = -1;
17630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
17640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
17650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width > 0 && !path->isEmpty())
17670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
17680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkStroke stroker(*this, width);
17690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        stroker.strokePath(*path, &strokePath);
17700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path = &strokePath;
17710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
17720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (path == &src)
17740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst = src;
17750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
17760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
17770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(path == &effectPath || path == &strokePath);
17780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->swap(*(SkPath*)path);
17790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
17800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width != 0;  // return true if we're filled, or false if we're hairline (width == 0)
17820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
17830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
178435d15937afb7f4b3472e43ea784b02485ec910fbMike Reedconst SkRect& SkPaint::computeStrokeFastBounds(const SkRect& src,
178535d15937afb7f4b3472e43ea784b02485ec910fbMike Reed                                               SkRect* storage) const {
17860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storage);
178735d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    SkASSERT(this->getStyle() != SkPaint::kFill_Style);
178835d15937afb7f4b3472e43ea784b02485ec910fbMike Reed
178935d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    // since we're stroked, outset the rect by the radius (and join type)
179035d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    SkScalar radius = SkScalarHalf(this->getStrokeWidth());
179135d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    if (0 == radius) {  // hairline
179235d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        radius = SK_Scalar1;
179335d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
179435d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        SkScalar scale = this->getStrokeMiter();
179535d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        if (scale > SK_Scalar1) {
179635d15937afb7f4b3472e43ea784b02485ec910fbMike Reed            radius = SkScalarMul(radius, scale);
17970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
17980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
179935d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    storage->set(src.fLeft - radius, src.fTop - radius,
180035d15937afb7f4b3472e43ea784b02485ec910fbMike Reed                 src.fRight + radius, src.fBottom + radius);
180135d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    return *storage;
18020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
18050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool has_thick_frame(const SkPaint& paint)
18070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
18080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return paint.getStrokeWidth() > 0 && paint.getStyle() != SkPaint::kFill_Style;
18090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
18120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    const SkPaint& paint,
18130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool applyStrokeAndPathEffects,
18140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool forceLinearTextOn)
18150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    : fPaint(paint) /* make a copy of the paint */
18160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
18170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
18180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                true);
18190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (forceLinearTextOn)
18210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setLinearText(true);
18220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
18230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint))
18250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        applyStrokeAndPathEffects = false;
18260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // can't use our canonical size if we need to apply patheffects/strokes
18280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.isLinearText() && !applyStrokeAndPathEffects)
18290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
18300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
18310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
18320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
18340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = SK_Scalar1;
18350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
18370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
18380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setStyle(SkPaint::kFill_Style);
18390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setPathEffect(NULL);
18400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCache = fPaint.detachCache(NULL);
18430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = SkPaint::kFill_Style;
18450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = NULL;
18460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
18480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
18490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        style = paint.getStyle();   // restore
18500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        pe = paint.getPathEffect();     // restore
18510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setStyle(style);
18530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setPathEffect(pe);
18540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(paint.getMaskFilter());    // restore
18550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // now compute fXOffset if needed
18570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar xOffset = 0;
18590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.getTextAlign() != SkPaint::kLeft_Align)   // need to measure first
18600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
18610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int      count;
18620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, &count, NULL), fScale);
18630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (paint.getTextAlign() == SkPaint::kCenter_Align)
18640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarHalf(width);
18650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        xOffset = -width;
18660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXPos = xOffset;
18680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPrevAdvance = 0;
18690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fText = text;
18710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStop = text + length;
18720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::~SkTextToPathIter()
18750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
18760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::AttachCache(fCache);
18770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
18780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkPath* SkTextToPathIter::next(SkScalar* xpos)
18800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
18810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (fText < fStop)
18820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
18830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
18840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
18860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPrevAdvance = glyph.fAdvanceX;   // + fPaint.getTextTracking();
18870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
18880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (glyph.fWidth)
18890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
18900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (xpos)
18910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *xpos = fXPos;
18920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fCache->findPath(glyph);
18930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
18940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
18950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
18960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1897