SkPaint.cpp revision 75c8af293816b94cd8fd9a3d9b3a4d6e052dedfe
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;
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::SkPaint(const SkPaint& src)
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeRef();
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeRef();
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeRef();
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeRef();
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeRef();
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeRef();
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeRef();
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeRef();
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::~SkPaint()
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint& SkPaint::operator=(const SkPaint& src)
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(&src);
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fTypeface->safeRef();
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fPathEffect->safeRef();
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fShader->safeRef();
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fXfermode->safeRef();
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fMaskFilter->safeRef();
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fColorFilter->safeRef();
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fRasterizer->safeRef();
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fLooper->safeRef();
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return *this;
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint operator==(const SkPaint& a, const SkPaint& b)
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return memcmp(&a, &b, sizeof(a)) == 0;
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::reset()
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint init;
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *this = init;
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFlags(uint32_t flags)
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fFlags = flags;
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAntiAlias(bool doAA)
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDither(bool doDither)
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setSubpixelText(bool doSubpixel)
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
153af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkPaint::setLCDRenderText(bool doLCDRender)
154af2616552738d653d5453915d3236e7154b868cdMike Reed{
155af2616552738d653d5453915d3236e7154b868cdMike Reed    this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag));
156af2616552738d653d5453915d3236e7154b868cdMike Reed}
157af2616552738d653d5453915d3236e7154b868cdMike Reed
1582cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reedvoid SkPaint::setEmbeddedBitmapText(bool doEmbeddedBitmapText)
1592cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed{
1602cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed    this->setFlags(SkSetClearMask(fFlags, doEmbeddedBitmapText, kEmbeddedBitmapText_Flag));
1612cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed}
1622cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setLinearText(bool doLinearText)
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setUnderlineText(bool doUnderline)
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrikeThruText(bool doStrikeThru)
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFakeBoldText(bool doFakeBold)
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDevKernText(bool doDevKern)
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFilterBitmap(bool doFilter)
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag));
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStyle(Style style)
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)style < kStyleCount)
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = style;
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setColor(SkColor color)
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = color;
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAlpha(U8CPU a)
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = SkColorSetARGB(a, SkColorGetR(fColor), SkColorGetG(fColor), SkColorGetB(fColor));
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = SkColorSetARGB(a, r, g, b);
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeWidth(SkScalar width)
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width >= 0)
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fWidth = width;
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeMiter(SkScalar limit)
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (limit >= 0)
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMiterLimit = limit;
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeCap(Cap ct)
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)ct < kCapCount)
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fCapType = SkToU8(ct);
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeJoin(Join jt)
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)jt < kJoinCount)
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fJoinType = SkToU8(jt);
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextAlign(Align align)
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)align < kAlignCount)
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextAlign = SkToU8(align);
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSize(SkScalar ts)
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ts > 0)
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = ts;
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextSize() called with non-positive value\n");
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextScaleX(SkScalar scaleX)
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextScaleX = scaleX;
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSkewX(SkScalar skewX)
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSkewX = skewX;
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextEncoding(TextEncoding encoding)
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)encoding <= kGlyphID_TextEncoding)
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextEncoding = encoding;
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTypeface* SkPaint::setTypeface(SkTypeface* font)
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fTypeface, font);
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return font;
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r)
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fRasterizer, r);
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return r;
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper)
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fLooper, looper);
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return looper;
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h"
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength,
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          uint16_t glyphs[]) const {
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0) {
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textData != NULL);
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == glyphs) {
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        switch (this->getTextEncoding()) {
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF8_TextEncoding:
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF8_CountUnichars((const char*)textData, byteLength);
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF16_TextEncoding:
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF16_CountUnichars((const uint16_t*)textData,
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                         byteLength >> 1);
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kGlyphID_TextEncoding:
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return byteLength >> 1;
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // if we get here, we have a valid glyphs[] array, so time to fill it in
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // handle this encoding before the setup for the glyphcache
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we want to ignore the low bit of byteLength
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(glyphs, textData, byteLength >> 1 << 1);
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return byteLength >> 1;
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache autoCache(*this, NULL);
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*    cache = autoCache.getCache();
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint16_t*   gptr = glyphs;
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getTextEncoding()) {
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF8_TextEncoding:
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text));
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF16_TextEncoding: {
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* text16 = (const uint16_t*)text;
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* stop16 = (const uint16_t*)stop;
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text16 < stop16) {
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16));
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gptr - glyphs;
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
38475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reedbool SkPaint::containsText(const void* textData, size_t byteLength) const {
38575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    if (0 == byteLength) {
38675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        return true;
38775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
38875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
38975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkASSERT(textData != NULL);
39075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
39175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    // handle this encoding before the setup for the glyphcache
39275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
39375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        const uint16_t* glyphID = static_cast<const uint16_t*>(textData);
39475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        size_t count = byteLength >> 1;
39575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        for (size_t i = 0; i < count; i++) {
39675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            if (0 == glyphID[i]) {
39775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                return false;
39875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
39975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
40075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        return true;
40175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
40275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
40375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkAutoGlyphCache autoCache(*this, NULL);
40475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    SkGlyphCache*    cache = autoCache.getCache();
40575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
40675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    switch (this->getTextEncoding()) {
40775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        case SkPaint::kUTF8_TextEncoding: {
40875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const char* text = static_cast<const char*>(textData);
40975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const char* stop = text + byteLength;
41075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            while (text < stop) {
41175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) {
41275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                    return false;
41375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                }
41475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
41575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            break;
41675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
41775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        case SkPaint::kUTF16_TextEncoding: {
41875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const uint16_t* text = static_cast<const uint16_t*>(textData);
41975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            const uint16_t* stop = text + (byteLength >> 1);
42075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            while (text < stop) {
42175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) {
42275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                    return false;
42375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed                }
42475c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            }
42575c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            break;
42675c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        }
42775c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed        default:
42875c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            SkASSERT(!"unknown text encoding");
42975c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed            return false;
43075c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    }
43175c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed    return true;
43275c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed}
43375c8af293816b94cd8fd9a3d9b3a4d6e052dedfeMike Reed
434091f227385b467090b5a7169a8e2faf19eca7105Mike Reedvoid SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count,
435091f227385b467090b5a7169a8e2faf19eca7105Mike Reed                               SkUnichar textData[]) const {
436091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    if (count <= 0) {
437091f227385b467090b5a7169a8e2faf19eca7105Mike Reed        return;
438091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    }
439091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
440091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkASSERT(glyphs != NULL);
441091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkASSERT(textData != NULL);
442091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
443091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkAutoGlyphCache autoCache(*this, NULL);
444091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    SkGlyphCache*    cache = autoCache.getCache();
445091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
446091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    for (int index = 0; index < count; index++) {
447091f227385b467090b5a7169a8e2faf19eca7105Mike Reed        textData[index] = cache->glyphToUnichar(glyphs[index]);
448091f227385b467090b5a7169a8e2faf19eca7105Mike Reed    }
449091f227385b467090b5a7169a8e2faf19eca7105Mike Reed}
450091f227385b467090b5a7169a8e2faf19eca7105Mike Reed
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, const char** text)
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, const char** text)
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text));
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, const char** text)
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, const char** text)
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text));
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, const char** text)
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, const char** text)
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, const char** text)
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_NextUnichar(text));
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, const char** text)
5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text));
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, const char** text)
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text));
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, const char** text)
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text));
5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, const char** text)
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, const char** text)
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd,
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                bool needFullMetrics) const
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkMeasureCacheProc gMeasureCacheProcs[] = {
5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_next,
5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_next,
5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_next,
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_prev,
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_prev,
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_prev,
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_next,
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_next,
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_next,
5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_prev,
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_prev,
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_prev
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kBackward_TextBufferDirection == tbd)
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!needFullMetrics && !this->isDevKernText())
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 6;
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs));
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gMeasureCacheProcs[index];
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache,
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed, SkFixed)
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache,
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed x, SkFixed y)
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y);
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, const char** text,
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
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    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache,
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text),
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    x, y);
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, const char** text,
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache,
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID, x, y);
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawCacheProc SkPaint::getDrawCacheProc() const
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkDrawCacheProc gDrawCacheProcs[] = {
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_00,
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_00,
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_00,
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_xy,
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_xy,
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_xy
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fFlags & kSubpixelText_Flag)
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs));
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gDrawCacheProcs[index];
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame {
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint) : fPaint((SkPaint*)paint)
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = paint->getTextSize();
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = paint->getStyle();
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(SkPaint::kFill_Style);
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkAutoRestorePaintTextSizeAndFrame()
6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(fStyle);
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setTextSize(fTextSize);
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint*        fPaint;
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        fTextSize;
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  fStyle;
7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds)
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(SkIntToScalar(g.fLeft),
7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop),
7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fLeft + g.fWidth),
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop + g.fHeight));
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void join_bounds(const SkGlyph& g, SkRect* bounds, SkFixed dx)
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar sx = SkFixedToScalar(dx);
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->join(SkIntToScalar(g.fLeft) + sx,
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop),
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fLeft + g.fWidth) + sx,
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop + g.fHeight));
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache,
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const char* text, size_t byteLength,
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               int* count, SkRect* bounds) const
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count);
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0)
7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = 0;
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (bounds)
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            bounds->setEmpty();
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc;
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         n = 1;
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = (const char*)text + byteLength;
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkGlyph* g = &glyphCacheProc(cache, &text);
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed x = g->fAdvanceX;
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == bounds)
7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + g->fAdvanceX;
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += glyphCacheProc(cache, &text).fAdvanceX;
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        set_bounds(*g, bounds);
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta);
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *count = n;
7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkFixedToScalar(x);
7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length,
7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                              SkRect* bounds, SkScalar zoom) const
7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL || length == 0);
7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
8190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = 0;
8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length > 0)
8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int tempCount;
8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = this->measure_text(cache, text, length, &tempCount, bounds);
8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
8290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarMul(width, scale);
8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (bounds)
8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fLeft = SkScalarMul(bounds->fLeft, scale);
8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fTop = SkScalarMul(bounds->fTop, scale);
8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fRight = SkScalarMul(bounds->fRight, scale);
8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fBottom = SkScalarMul(bounds->fBottom, scale);
8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop);
8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool forward_textBufferPred(const char* text, const char* stop)
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text < stop;
8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool backward_textBufferPred(const char* text, const char* stop)
8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text > stop;
8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd,
8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            const char** text, size_t length, const char** stop)
8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkPaint::kForward_TextBufferDirection == tbd)
8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text + length;
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return forward_textBufferPred;
8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // text should point to the end of the buffer, and stop to the beginning
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text;
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *text += length;
8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return backward_textBufferPred;
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          SkScalar* measuredWidth,
8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          TextBufferDirection tbd) const
8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == length || 0 >= maxWidth)
8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (measuredWidth)
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *measuredWidth = 0;
8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textD != NULL);
8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textD;
8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false);
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char*      stop;
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop);
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed          max = SkScalarToFixed(maxWidth);
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed          width = 0;
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int rsb = 0;
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const SkGlyph& g = glyphCacheProc(cache, &text);
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + g.fAdvanceX;
9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            rsb = g.fRsbDelta;
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = glyphCacheProc(cache, &text).fAdvanceX;
9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
9360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (measuredWidth)
9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar scalarWidth = SkFixedToScalar(width);
9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scalarWidth = SkScalarMul(scalarWidth, scale);
9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *measuredWidth = scalarWidth;
9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // return the number of bytes measured
9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (kForward_TextBufferDirection == tbd) ?
9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text - stop + length : stop - text + length;
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context)
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *(SkPaint::FontMetrics*)context = cache->getFontMetricsY();
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;   // don't detach the cache
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context)
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context);
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const FontMetrics&  my = cache->getFontMetricsY();
9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    FontMetrics storage;
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == metrics)
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics = &storage;
9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics);
9940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (scale)
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fTop = SkScalarMul(metrics->fTop, scale);
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return metrics->fDescent - metrics->fAscent + metrics->fLeading;
10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale)
10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(g.fLeft * scale,
10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g.fTop * scale,
10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fLeft + g.fWidth) * scale,
10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fTop + g.fHeight) * scale);
10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::getTextWidths(const void* textData, size_t byteLength, SkScalar widths[],
10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                           SkRect bounds[]) const
10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == byteLength)
10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(NULL != textData);
10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == widths && NULL == bounds)
10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->countText(textData, byteLength);
10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
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    SkMeasureCacheProc  glyphCacheProc;
10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
10440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         count = 0;
10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
10480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we adjust the widths returned here through auto-kerning
10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoKern  autokern;
10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkFixed     prevWidth = 0;
10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkScalar w = SkFixedToScalar(prevWidth + adjust);
10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkScalarMul(w, scale);
10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale);
10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkFixedToScalar(prevWidth + adjust);
10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkFixedToScalar(prevWidth);
10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {    // no devkern
10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *widths++ = SkScalarMul(SkFixedToScalar(g.fAdvanceX),
10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            scale);
11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *widths++ = SkFixedToScalar(g.fAdvanceX);
11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return count;
11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h"
11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::getTextPath(const void* textData, size_t length, SkScalar x, SkScalar y, SkPath* path) const
11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length == 0 || text != NULL);
11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (text == NULL || length == 0 || path == NULL)
11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextToPathIter    iter(text, length, *this, false, true);
11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix            matrix;
11370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar            prevXPos = 0;
11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.setScale(iter.getPathScale(), iter.getPathScale());
11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.postTranslate(x, y);
11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    path->reset();
11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        xpos;
11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   iterPath;
11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while ((iterPath = iter.next(&xpos)) != NULL)
11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        matrix.postTranslate(xpos - prevXPos, 0);
11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path->addPath(*iterPath, matrix);
11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevXPos = xpos;
11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag,
11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            SkFlattenableWriteBuffer* buffer) {
11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
11590910916c0f7b951ee55c4b7c6358295b9bca0565The 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])
11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    inspired by a desire to change the multiplier for thickness in fakebold
11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    therefore, i assumed number of pairs (length) will be small, so a linear search is sufficient
11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    repeated keys are allowed for discontinuous functions (so long as keys is monotonically increasing), and if
11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        key is the value of a repeated scalar in keys, the first one will be used
11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - this may change if a binary search is used
11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - also, this ensures that there is no divide by zero (an assert also checks for that)
11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkScalar interpolate(SkScalar key, const SkScalar keys[], const SkScalar values[], int length)
11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length > 0);
11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(keys != NULL);
11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(values != NULL);
11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 1; i < length; i++)
11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(keys[i] >= keys[i-1]);
11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int right = 0;
11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (right < length && key > keys[right])
11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        right++;
11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //could use sentinal values to eliminate conditionals
11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //i assume i am not in control of input values, so i want to make it simple
11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length == right)
11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[length-1];
11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == right)
11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[0];
11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //otherwise, we interpolate between right-1 and right
11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rVal = values[right];
11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar lVal = values[right-1];
11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rightKey = keys[right];
11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar leftKey = keys[right-1];
11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(rightKey != leftKey);
11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //fractional amount which we will multiply by the difference in the left value and right value
11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar fract = SkScalarDiv(key-leftKey,rightKey-leftKey);
11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return lVal + SkScalarMul(fract, rVal-lVal);
11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//used for interpolating in fakeBold
11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar pointSizes[] = { SkIntToScalar(9), SkIntToScalar(36) };
11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar multipliers[] = { SK_Scalar1/24, SK_Scalar1/32 };
12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkMask::Format computeMaskFormat(const SkPaint& paint)
12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flags = paint.getFlags();
12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1205c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    // Antialiasing being disabled trumps all other settings.
1206c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    if (!(flags & SkPaint::kAntiAlias_Flag))
1207c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed        return SkMask::kBW_Format;
1208c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed
1209af2616552738d653d5453915d3236e7154b868cdMike Reed#if defined(SK_SUPPORT_LCDTEXT)
1210c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    if (flags & SkPaint::kLCDRenderText_Flag)
1211af2616552738d653d5453915d3236e7154b868cdMike Reed        return SkFontHost::GetSubpixelOrientation() == SkFontHost::kHorizontal_LCDOrientation ?
1212af2616552738d653d5453915d3236e7154b868cdMike Reed                   SkMask::kHorizontalLCD_Format : SkMask::kVerticalLCD_Format;
1213af2616552738d653d5453915d3236e7154b868cdMike Reed#endif
1214c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed
1215c49fcf5e8bc1c84bcb0a51fe615caa7e72dd7dccMike Reed    return SkMask::kA8_Format;
12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12184bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// if linear-text is on, then we force hinting to be off (since that's sort of
12194bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// the point of linear-text.
12204bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reedstatic SkPaint::Hinting computeHinting(const SkPaint& paint) {
12214bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    SkPaint::Hinting h = paint.getHinting();
12224bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    if (paint.isLinearText()) {
12234bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed        h = SkPaint::kNo_Hinting;
12244bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    }
12254bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    return h;
12264bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed}
12274bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed
1228af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkScalerContext::MakeRec(const SkPaint& paint,
1229af2616552738d653d5453915d3236e7154b868cdMike Reed                              const SkMatrix* deviceMatrix, Rec* rec)
12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1231af2616552738d653d5453915d3236e7154b868cdMike Reed    SkASSERT(deviceMatrix == NULL ||
1232af2616552738d653d5453915d3236e7154b868cdMike Reed             (deviceMatrix->getType() & SkMatrix::kPerspective_Mask) == 0);
12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFontID = SkTypeface::UniqueID(paint.getTypeface());
12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fTextSize = paint.getTextSize();
12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreScaleX = paint.getTextScaleX();
12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreSkewX  = paint.getTextSkewX();
12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (deviceMatrix)
12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = deviceMatrix->getScaleX();
12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = deviceMatrix->getSkewX();
12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][0] = deviceMatrix->getSkewY();
12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][1] = deviceMatrix->getScaleY();
12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = paint.getStyle();
12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        strokeWidth = paint.getStrokeWidth();
12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isFakeBoldText())
12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar fakeBoldScale = interpolate(paint.getTextSize(), pointSizes, multipliers, 2);
12580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kFill_Style)
12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            style = SkPaint::kStrokeAndFill_Style;
12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth = extra;    // ignore paint's strokeWidth if it was "fill"
12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth += extra;
12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned flags = SkFontHost::ComputeGammaFlag(paint);
12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isDevKernText())
12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        flags |= SkScalerContext::kDevKernText_Flag;
12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (style != SkPaint::kFill_Style && strokeWidth > 0)
12750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = strokeWidth;
12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = paint.getStrokeMiter();
12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kStrokeAndFill_Style)
12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            flags |= SkScalerContext::kFrameAndFill_Flag;
12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = 0;
12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = 0;
12870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = 0;
12880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1290af2616552738d653d5453915d3236e7154b868cdMike Reed    rec->fSubpixelPositioning = paint.isSubpixelText();
12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
12920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFlags = SkToU8(flags);
12934bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    rec->setHinting(computeHinting(paint));
12942cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed    if (paint.isEmbeddedBitmapText())
12952cf237c941bf5964f654d0ccdd639a26468e1d71Mike Reed        rec->fFlags |= SkScalerContext::kEmbeddedBitmapText_Flag;
1296af2616552738d653d5453915d3236e7154b868cdMike Reed
1297af2616552738d653d5453915d3236e7154b868cdMike Reed    /*  Allow the fonthost to modify our rec before we use it as a key into the
1298af2616552738d653d5453915d3236e7154b868cdMike Reed        cache. This way if we're asking for something that they will ignore,
1299af2616552738d653d5453915d3236e7154b868cdMike Reed        they can modify our rec up front, so we don't create duplicate cache
1300af2616552738d653d5453915d3236e7154b868cdMike Reed        entries.
1301af2616552738d653d5453915d3236e7154b868cdMike Reed     */
1302af2616552738d653d5453915d3236e7154b868cdMike Reed    SkFontHost::FilterRec(rec);
13030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER  1024
13060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void (*proc)(const SkDescriptor*, void*),
13090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void* context) const
13100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::Rec    rec;
13120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::MakeRec(*this, deviceMatrix, &rec);
13140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t          descSize = sizeof(rec);
13160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int             entryCount = 1;
13170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = this->getPathEffect();
13180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMaskFilter*   mf = this->getMaskFilter();
13190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRasterizer*   ra = this->getRasterizer();
13200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
13220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
13230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
13240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
13260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        peBuffer.writeFlattenable(pe);
13270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += peBuffer.size();
13280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
13290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
13300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // seems like we could support kLCD as well at this point...
13310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
13330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mfBuffer.writeFlattenable(mf);
13340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += mfBuffer.size();
13350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
13360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing with maskfilters
13370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
13390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        raBuffer.writeFlattenable(ra);
13400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += raBuffer.size();
13410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
13420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
13430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    descSize += SkDescriptor::ComputeOverhead(entryCount);
13450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoDescriptor    ad(descSize);
13470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDescriptor*       desc = ad.getDesc();
13480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->init();
13500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
13510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
13530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
13540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
13560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
13570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
13590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
13600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(descSize == desc->getLength());
13630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->computeChecksum();
13640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    proc(desc, context);
13660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void DetachDescProc(const SkDescriptor* desc, void* context)
13690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc);
13710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const
13740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache* cache;
13760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(deviceMatrix, DetachDescProc, &cache);
13770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache;
13780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
13810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h"
13830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uintptr_t asint(const void* p) {
13855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return reinterpret_cast<uintptr_t>(p);
13865f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
13875f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13885f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedunion Scalar32 {
13895f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkScalar    fScalar;
13905f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t    f32;
13915f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
13925f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) {
13945f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
13955f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
13965f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.fScalar = value;
13975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr = tmp.f32;
13985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return ptr + 1;
13995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
14005f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic SkScalar read_scalar(const uint32_t*& ptr) {
14025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
14035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
14045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.f32 = *ptr++;
14055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return tmp.fScalar;
14065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
14075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
14095f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(a == (uint8_t)a);
14105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(b == (uint8_t)b);
14115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(c == (uint8_t)c);
14125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(d == (uint8_t)d);
14135f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return (a << 24) | (b << 16) | (c << 8) | d;
14145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
14155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedenum FlatFlags {
14175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasTypeface_FlatFlag   = 0x01,
14185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasEffects_FlatFlag    = 0x02
14195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
14205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed// The size of a flat paint's POD fields
14225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic const uint32_t kPODPaintSize =   5 * sizeof(SkScalar) +
14235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(SkColor) +
14245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(uint16_t) +
14255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        6 * sizeof(uint8_t);
14265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed/*  To save space/time, we analyze the paint, and write a truncated version of
14285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    it if there are not tricky elements like shaders, etc.
14295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed */
14300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
14315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = 0;
14325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (this->getTypeface()) {
14335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasTypeface_FlatFlag;
14345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
14355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (asint(this->getPathEffect()) |
14365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getShader()) |
14375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getXfermode()) |
14385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getMaskFilter()) |
14395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getColorFilter()) |
14405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getRasterizer()) |
14415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getLooper())) {
14425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasEffects_FlatFlag;
14435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
14445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
14465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t* ptr = buffer.reserve(kPODPaintSize);
14475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSize());
14495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextScaleX());
14505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSkewX());
14515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeWidth());
14525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeMiter());
14535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = this->getColor();
14545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = (this->getFlags() << 16) | (this->getTextAlign() << 8) | flatFlags;
14555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
14565f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                    this->getStyle(), this->getTextEncoding());
14575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // now we're done with ptr and the (pre)reserved space. If we need to write
14595f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // additional fields, use the buffer directly
14605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
14615f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeTypeface(this->getTypeface());
14625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
14635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
14645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getPathEffect());
14655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getShader());
14665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getXfermode());
14675f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getMaskFilter());
14685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getColorFilter());
14695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getRasterizer());
14705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getLooper());
14715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
14720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
14755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
14765f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const void* podData = buffer.skip(kPODPaintSize);
14775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
14785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14795f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // the order we read must match the order we wrote in flatten()
14805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSize(read_scalar(pod));
14815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextScaleX(read_scalar(pod));
14825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSkewX(read_scalar(pod));
14835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeWidth(read_scalar(pod));
14845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeMiter(read_scalar(pod));
14855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setColor(*pod++);
14865f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14875f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t tmp = *pod++;
14885f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setFlags(tmp >> 16);
14895f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF));
14905f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = tmp & 0xFF;
14915f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14925f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp = *pod++;
14935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
14945f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
14955f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
14965f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
14975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14985f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
14995f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(buffer.readTypeface());
15005f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
15015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(NULL);
15025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
15035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
15045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
15055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setPathEffect((SkPathEffect*) buffer.readFlattenable())->safeUnref();
15065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setShader((SkShader*) buffer.readFlattenable())->safeUnref();
15075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setXfermode((SkXfermode*) buffer.readFlattenable())->safeUnref();
15085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())->safeUnref();
15095f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setColorFilter((SkColorFilter*) buffer.readFlattenable())->safeUnref();
15105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setRasterizer((SkRasterizer*) buffer.readFlattenable())->safeUnref();
15115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setLooper((SkDrawLooper*) buffer.readFlattenable())->safeUnref();
15125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
15135f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setPathEffect(NULL);
15145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setShader(NULL);
15155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setXfermode(NULL);
15165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setMaskFilter(NULL);
15175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setColorFilter(NULL);
15185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setRasterizer(NULL);
15195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setLooper(NULL);
15205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
15210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
15240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader* SkPaint::setShader(SkShader* shader)
15260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fShader, shader);
15280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return shader;
15290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter)
15320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fColorFilter, filter);
15340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
15350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkXfermode* SkPaint::setXfermode(SkXfermode* mode)
15380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fXfermode, mode);
15400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return mode;
15410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
154303f42ddd729377f21719a140c027a1f8cc5c2152Mike ReedSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
154403f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    SkSafeUnref(fXfermode);
154503f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    fXfermode = SkXfermode::Create(mode);
154603f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    return fXfermode;
154703f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed}
154803f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed
15490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect)
15500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fPathEffect, effect);
15520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return effect;
15530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter)
15560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fMaskFilter, filter);
15580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
15590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
15620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const
15640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath          effectPath, strokePath;
15660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   path = &src;
15670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = this->getStrokeWidth();
15690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getStyle()) {
15710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kFill_Style:
15720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = -1; // mark it as no-stroke
15730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
15740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStrokeAndFill_Style:
15750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (width == 0)
15760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
15770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
15780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStroke_Style:
15790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
15800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    default:
15810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(!"unknown paint style");
15820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getPathEffect())
15850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill
15870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style)
15880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
15890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getPathEffect()->filterPath(&effectPath, src, &width))
15910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            path = &effectPath;
15920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // restore the width if we earlier had to lie, and if we're still set to no-stroke
15940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // note: if we're now stroke (width >= 0), then the pathEffect asked for that change
15950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // and we want to respect that (i.e. don't overwrite their setting for width)
15960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0)
15970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
15980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = this->getStrokeWidth();
15990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (width == 0)
16000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width = -1;
16010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
16020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width > 0 && !path->isEmpty())
16050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkStroke stroker(*this, width);
16070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        stroker.strokePath(*path, &strokePath);
16080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path = &strokePath;
16090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (path == &src)
16120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst = src;
16130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
16140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(path == &effectPath || path == &strokePath);
16160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->swap(*(SkPath*)path);
16170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width != 0;  // return true if we're filled, or false if we're hairline (width == 0)
16200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
162235d15937afb7f4b3472e43ea784b02485ec910fbMike Reedconst SkRect& SkPaint::computeStrokeFastBounds(const SkRect& src,
162335d15937afb7f4b3472e43ea784b02485ec910fbMike Reed                                               SkRect* storage) const {
16240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storage);
162535d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    SkASSERT(this->getStyle() != SkPaint::kFill_Style);
162635d15937afb7f4b3472e43ea784b02485ec910fbMike Reed
162735d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    // since we're stroked, outset the rect by the radius (and join type)
162835d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    SkScalar radius = SkScalarHalf(this->getStrokeWidth());
162935d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    if (0 == radius) {  // hairline
163035d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        radius = SK_Scalar1;
163135d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
163235d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        SkScalar scale = this->getStrokeMiter();
163335d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        if (scale > SK_Scalar1) {
163435d15937afb7f4b3472e43ea784b02485ec910fbMike Reed            radius = SkScalarMul(radius, scale);
16350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
16360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
163735d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    storage->set(src.fLeft - radius, src.fTop - radius,
163835d15937afb7f4b3472e43ea784b02485ec910fbMike Reed                 src.fRight + radius, src.fBottom + radius);
163935d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    return *storage;
16400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
16430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool has_thick_frame(const SkPaint& paint)
16450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
16460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return paint.getStrokeWidth() > 0 && paint.getStyle() != SkPaint::kFill_Style;
16470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
16500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    const SkPaint& paint,
16510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool applyStrokeAndPathEffects,
16520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool forceLinearTextOn)
16530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    : fPaint(paint) /* make a copy of the paint */
16540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
16550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
16560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                true);
16570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (forceLinearTextOn)
16590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setLinearText(true);
16600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
16610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint))
16630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        applyStrokeAndPathEffects = false;
16640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // can't use our canonical size if we need to apply patheffects/strokes
16660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.isLinearText() && !applyStrokeAndPathEffects)
16670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
16690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
16700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
16720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = SK_Scalar1;
16730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
16750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setStyle(SkPaint::kFill_Style);
16770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setPathEffect(NULL);
16780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCache = fPaint.detachCache(NULL);
16810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = SkPaint::kFill_Style;
16830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = NULL;
16840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
16860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        style = paint.getStyle();   // restore
16880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        pe = paint.getPathEffect();     // restore
16890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setStyle(style);
16910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setPathEffect(pe);
16920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(paint.getMaskFilter());    // restore
16930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // now compute fXOffset if needed
16950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar xOffset = 0;
16970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.getTextAlign() != SkPaint::kLeft_Align)   // need to measure first
16980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int      count;
17000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, &count, NULL), fScale);
17010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (paint.getTextAlign() == SkPaint::kCenter_Align)
17020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarHalf(width);
17030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        xOffset = -width;
17040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
17050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXPos = xOffset;
17060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPrevAdvance = 0;
17070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fText = text;
17090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStop = text + length;
17100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
17110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::~SkTextToPathIter()
17130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
17140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::AttachCache(fCache);
17150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
17160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkPath* SkTextToPathIter::next(SkScalar* xpos)
17180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
17190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (fText < fStop)
17200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
17210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
17220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
17240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPrevAdvance = glyph.fAdvanceX;   // + fPaint.getTextTracking();
17250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
17260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (glyph.fWidth)
17270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
17280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (xpos)
17290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *xpos = fXPos;
17300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fCache->findPath(glyph);
17310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
17320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
17330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
17340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1735