SkPaint.cpp revision 0910916c0f7b951ee55c4b7c6358295b9bca0565
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
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::SkPaint()
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface   = NULL;
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSize   = SK_DefaultTextSize;
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextScaleX = SK_Scalar1;
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSkewX  = 0;
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect  = NULL;
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader      = NULL;
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode    = NULL;
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter  = NULL;
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter = NULL;
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer  = NULL;
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper      = NULL;
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor      = SK_ColorBLACK;
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fWidth      = 0;
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMiterLimit = SK_DefaultMiterLimit;
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fFlags      = SK_DefaultFlags;
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCapType    = kDefault_Cap;
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fJoinType   = kDefault_Join;
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextAlign  = kLeft_Align;
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStyle      = kFill_Style;
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextEncoding = kUTF8_TextEncoding;
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::SkPaint(const SkPaint& src)
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeRef();
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeRef();
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeRef();
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeRef();
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeRef();
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeRef();
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeRef();
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeRef();
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::~SkPaint()
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint& SkPaint::operator=(const SkPaint& src)
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(&src);
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fTypeface->safeRef();
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fPathEffect->safeRef();
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fShader->safeRef();
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fXfermode->safeRef();
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fMaskFilter->safeRef();
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fColorFilter->safeRef();
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fRasterizer->safeRef();
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fLooper->safeRef();
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return *this;
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint operator==(const SkPaint& a, const SkPaint& b)
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return memcmp(&a, &b, sizeof(a)) == 0;
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::reset()
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint init;
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *this = init;
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFlags(uint32_t flags)
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fFlags = flags;
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAntiAlias(bool doAA)
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDither(bool doDither)
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setSubpixelText(bool doSubpixel)
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setLinearText(bool doLinearText)
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setUnderlineText(bool doUnderline)
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrikeThruText(bool doStrikeThru)
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFakeBoldText(bool doFakeBold)
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDevKernText(bool doDevKern)
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFilterBitmap(bool doFilter)
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag));
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStyle(Style style)
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)style < kStyleCount)
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = style;
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setColor(SkColor color)
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = color;
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAlpha(U8CPU a)
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = SkColorSetARGB(a, SkColorGetR(fColor), SkColorGetG(fColor), SkColorGetB(fColor));
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = SkColorSetARGB(a, r, g, b);
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeWidth(SkScalar width)
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width >= 0)
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fWidth = width;
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeMiter(SkScalar limit)
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (limit >= 0)
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMiterLimit = limit;
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeCap(Cap ct)
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)ct < kCapCount)
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fCapType = SkToU8(ct);
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeJoin(Join jt)
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)jt < kJoinCount)
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fJoinType = SkToU8(jt);
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextAlign(Align align)
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)align < kAlignCount)
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextAlign = SkToU8(align);
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSize(SkScalar ts)
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ts > 0)
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = ts;
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextSize() called with non-positive value\n");
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextScaleX(SkScalar scaleX)
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextScaleX = scaleX;
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSkewX(SkScalar skewX)
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSkewX = skewX;
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextEncoding(TextEncoding encoding)
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)encoding <= kGlyphID_TextEncoding)
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextEncoding = encoding;
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTypeface* SkPaint::setTypeface(SkTypeface* font)
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fTypeface, font);
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return font;
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r)
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fRasterizer, r);
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return r;
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper)
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fLooper, looper);
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return looper;
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h"
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength,
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          uint16_t glyphs[]) const {
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0) {
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textData != NULL);
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == glyphs) {
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        switch (this->getTextEncoding()) {
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF8_TextEncoding:
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF8_CountUnichars((const char*)textData, byteLength);
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF16_TextEncoding:
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF16_CountUnichars((const uint16_t*)textData,
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                         byteLength >> 1);
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kGlyphID_TextEncoding:
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return byteLength >> 1;
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // if we get here, we have a valid glyphs[] array, so time to fill it in
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // handle this encoding before the setup for the glyphcache
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we want to ignore the low bit of byteLength
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(glyphs, textData, byteLength >> 1 << 1);
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return byteLength >> 1;
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache autoCache(*this, NULL);
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*    cache = autoCache.getCache();
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint16_t*   gptr = glyphs;
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getTextEncoding()) {
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF8_TextEncoding:
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text));
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF16_TextEncoding: {
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* text16 = (const uint16_t*)text;
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* stop16 = (const uint16_t*)stop;
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text16 < stop16) {
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16));
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gptr - glyphs;
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, const char** text)
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, const char** text)
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text));
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, const char** text)
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, const char** text)
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text));
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, const char** text)
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, const char** text)
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, const char** text)
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_NextUnichar(text));
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, const char** text)
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text));
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, const char** text)
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text));
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, const char** text)
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text));
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, const char** text)
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, const char** text)
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd,
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                bool needFullMetrics) const
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkMeasureCacheProc gMeasureCacheProcs[] = {
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_next,
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_next,
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_next,
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_prev,
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_prev,
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_prev,
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_next,
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_next,
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_next,
4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_prev,
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_prev,
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_prev
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kBackward_TextBufferDirection == tbd)
5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!needFullMetrics && !this->isDevKernText())
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 6;
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs));
5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gMeasureCacheProcs[index];
5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache,
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed, SkFixed)
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->getUnicharMetrics(SkUTF8_NextUnichar(text));
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache,
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed x, SkFixed y)
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y);
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, const char** text,
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache,
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text),
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    x, y);
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, const char** text,
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache,
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID, x, y);
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawCacheProc SkPaint::getDrawCacheProc() const
5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkDrawCacheProc gDrawCacheProcs[] = {
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_00,
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_00,
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_00,
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_xy,
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_xy,
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_xy
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fFlags & kSubpixelText_Flag)
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs));
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gDrawCacheProcs[index];
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame {
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint) : fPaint((SkPaint*)paint)
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = paint->getTextSize();
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = paint->getStyle();
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(SkPaint::kFill_Style);
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkAutoRestorePaintTextSizeAndFrame()
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(fStyle);
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setTextSize(fTextSize);
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint*        fPaint;
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        fTextSize;
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  fStyle;
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds)
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(SkIntToScalar(g.fLeft),
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop),
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fLeft + g.fWidth),
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop + g.fHeight));
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void join_bounds(const SkGlyph& g, SkRect* bounds, SkFixed dx)
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar sx = SkFixedToScalar(dx);
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->join(SkIntToScalar(g.fLeft) + sx,
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop),
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fLeft + g.fWidth) + sx,
6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop + g.fHeight));
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache,
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const char* text, size_t byteLength,
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               int* count, SkRect* bounds) const
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count);
6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0)
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = 0;
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (bounds)
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            bounds->setEmpty();
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc;
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         n = 1;
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = (const char*)text + byteLength;
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkGlyph* g = &glyphCacheProc(cache, &text);
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed x = g->fAdvanceX;
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == bounds)
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + g->fAdvanceX;
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += glyphCacheProc(cache, &text).fAdvanceX;
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        set_bounds(*g, bounds);
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta);
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *count = n;
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkFixedToScalar(x);
7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length,
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                              SkRect* bounds, SkScalar zoom) const
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL || length == 0);
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = 0;
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length > 0)
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int tempCount;
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = this->measure_text(cache, text, length, &tempCount, bounds);
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarMul(width, scale);
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (bounds)
7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fLeft = SkScalarMul(bounds->fLeft, scale);
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fTop = SkScalarMul(bounds->fTop, scale);
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fRight = SkScalarMul(bounds->fRight, scale);
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fBottom = SkScalarMul(bounds->fBottom, scale);
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop);
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool forward_textBufferPred(const char* text, const char* stop)
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text < stop;
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool backward_textBufferPred(const char* text, const char* stop)
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text > stop;
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd,
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            const char** text, size_t length, const char** stop)
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkPaint::kForward_TextBufferDirection == tbd)
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text + length;
7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return forward_textBufferPred;
7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // text should point to the end of the buffer, and stop to the beginning
7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text;
7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *text += length;
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return backward_textBufferPred;
7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          SkScalar* measuredWidth,
7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          TextBufferDirection tbd) const
7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == length || 0 >= maxWidth)
7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (measuredWidth)
7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *measuredWidth = 0;
7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textD != NULL);
8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textD;
8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false);
8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char*      stop;
8170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop);
8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed          max = SkScalarToFixed(maxWidth);
8190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed          width = 0;
8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int rsb = 0;
8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
8290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const SkGlyph& g = glyphCacheProc(cache, &text);
8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + g.fAdvanceX;
8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            rsb = g.fRsbDelta;
8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
8410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = glyphCacheProc(cache, &text).fAdvanceX;
8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (measuredWidth)
8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar scalarWidth = SkFixedToScalar(width);
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scalarWidth = SkScalarMul(scalarWidth, scale);
8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *measuredWidth = scalarWidth;
8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // return the number of bytes measured
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (kForward_TextBufferDirection == tbd) ?
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text - stop + length : stop - text + length;
8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context)
8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *(SkPaint::FontMetrics*)context = cache->getFontMetricsY();
8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;   // don't detach the cache
8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context)
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context);
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const
8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const FontMetrics&  my = cache->getFontMetricsY();
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    FontMetrics storage;
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == metrics)
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics = &storage;
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics);
9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (scale)
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fTop = SkScalarMul(metrics->fTop, scale);
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return metrics->fDescent - metrics->fAscent + metrics->fLeading;
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale)
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(g.fLeft * scale,
9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g.fTop * scale,
9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fLeft + g.fWidth) * scale,
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fTop + g.fHeight) * scale);
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::getTextWidths(const void* textData, size_t byteLength, SkScalar widths[],
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                           SkRect bounds[]) const
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == byteLength)
9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(NULL != textData);
9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == widths && NULL == bounds)
9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->countText(textData, byteLength);
9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc  glyphCacheProc;
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         count = 0;
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we adjust the widths returned here through auto-kerning
9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoKern  autokern;
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkFixed     prevWidth = 0;
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkScalar w = SkFixedToScalar(prevWidth + adjust);
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkScalarMul(w, scale);
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale);
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
9940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkFixedToScalar(prevWidth + adjust);
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkFixedToScalar(prevWidth);
10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {    // no devkern
10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *widths++ = SkScalarMul(SkFixedToScalar(g.fAdvanceX),
10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            scale);
10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *widths++ = SkFixedToScalar(g.fAdvanceX);
10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return count;
10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h"
10440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::getTextPath(const void* textData, size_t length, SkScalar x, SkScalar y, SkPath* path) const
10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
10480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length == 0 || text != NULL);
10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (text == NULL || length == 0 || path == NULL)
10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextToPathIter    iter(text, length, *this, false, true);
10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix            matrix;
10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar            prevXPos = 0;
10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.setScale(iter.getPathScale(), iter.getPathScale());
10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.postTranslate(x, y);
10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    path->reset();
10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        xpos;
10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   iterPath;
10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while ((iterPath = iter.next(&xpos)) != NULL)
10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        matrix.postTranslate(xpos - prevXPos, 0);
10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path->addPath(*iterPath, matrix);
10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevXPos = xpos;
10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag,
10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            SkFlattenableWriteBuffer* buffer) {
10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
10760910916c0f7b951ee55c4b7c6358295b9bca0565The 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])
10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    inspired by a desire to change the multiplier for thickness in fakebold
10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    therefore, i assumed number of pairs (length) will be small, so a linear search is sufficient
10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    repeated keys are allowed for discontinuous functions (so long as keys is monotonically increasing), and if
10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        key is the value of a repeated scalar in keys, the first one will be used
10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - this may change if a binary search is used
10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - also, this ensures that there is no divide by zero (an assert also checks for that)
10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkScalar interpolate(SkScalar key, const SkScalar keys[], const SkScalar values[], int length)
10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length > 0);
10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(keys != NULL);
10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(values != NULL);
10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 1; i < length; i++)
10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(keys[i] >= keys[i-1]);
10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int right = 0;
10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (right < length && key > keys[right])
10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        right++;
10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //could use sentinal values to eliminate conditionals
10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //i assume i am not in control of input values, so i want to make it simple
10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length == right)
11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[length-1];
11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == right)
11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[0];
11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //otherwise, we interpolate between right-1 and right
11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rVal = values[right];
11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar lVal = values[right-1];
11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rightKey = keys[right];
11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar leftKey = keys[right-1];
11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(rightKey != leftKey);
11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //fractional amount which we will multiply by the difference in the left value and right value
11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar fract = SkScalarDiv(key-leftKey,rightKey-leftKey);
11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return lVal + SkScalarMul(fract, rVal-lVal);
11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//used for interpolating in fakeBold
11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar pointSizes[] = { SkIntToScalar(9), SkIntToScalar(36) };
11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar multipliers[] = { SK_Scalar1/24, SK_Scalar1/32 };
11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkMask::Format computeMaskFormat(const SkPaint& paint)
11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flags = paint.getFlags();
11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (flags & SkPaint::kAntiAlias_Flag) ? SkMask::kA8_Format : SkMask::kBW_Format;
11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkScalerContext::Hints computeScalerHints(const SkPaint& paint)
11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flags = paint.getFlags();
11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (flags & SkPaint::kLinearText_Flag)
11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkScalerContext::kNo_Hints;
11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else if (flags & SkPaint::kSubpixelText_Flag)
11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkScalerContext::kSubpixel_Hints;
11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return SkScalerContext::kNormal_Hints;
11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScalerContext::MakeRec(const SkPaint& paint, const SkMatrix* deviceMatrix, Rec* rec)
11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(deviceMatrix == NULL || (deviceMatrix->getType() & SkMatrix::kPerspective_Mask) == 0);
11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFontID = SkTypeface::UniqueID(paint.getTypeface());
11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fTextSize = paint.getTextSize();
11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreScaleX = paint.getTextScaleX();
11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreSkewX  = paint.getTextSkewX();
11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (deviceMatrix)
11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = deviceMatrix->getScaleX();
11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = deviceMatrix->getSkewX();
11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][0] = deviceMatrix->getSkewY();
11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][1] = deviceMatrix->getScaleY();
11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = paint.getStyle();
11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        strokeWidth = paint.getStrokeWidth();
11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isFakeBoldText())
11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar fakeBoldScale = interpolate(paint.getTextSize(), pointSizes, multipliers, 2);
11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kFill_Style)
11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            style = SkPaint::kStrokeAndFill_Style;
11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth = extra;    // ignore paint's strokeWidth if it was "fill"
11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth += extra;
11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned flags = SkFontHost::ComputeGammaFlag(paint);
11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isDevKernText())
11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        flags |= SkScalerContext::kDevKernText_Flag;
11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (style != SkPaint::kFill_Style && strokeWidth > 0)
11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = strokeWidth;
11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = paint.getStrokeMiter();
11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kStrokeAndFill_Style)
11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            flags |= SkScalerContext::kFrameAndFill_Flag;
11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = 0;
11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = 0;
11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = 0;
11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fHints = SkToU8(computeScalerHints(paint));
11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFlags = SkToU8(flags);
12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER  1024
12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void (*proc)(const SkDescriptor*, void*),
12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void* context) const
12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::Rec    rec;
12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::MakeRec(*this, deviceMatrix, &rec);
12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t          descSize = sizeof(rec);
12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int             entryCount = 1;
12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = this->getPathEffect();
12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMaskFilter*   mf = this->getMaskFilter();
12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRasterizer*   ra = this->getRasterizer();
12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        peBuffer.writeFlattenable(pe);
12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += peBuffer.size();
12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
12260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // seems like we could support kLCD as well at this point...
12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mfBuffer.writeFlattenable(mf);
12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += mfBuffer.size();
12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing with maskfilters
12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        raBuffer.writeFlattenable(ra);
12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += raBuffer.size();
12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    descSize += SkDescriptor::ComputeOverhead(entryCount);
12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoDescriptor    ad(descSize);
12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDescriptor*       desc = ad.getDesc();
12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->init();
12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(descSize == desc->getLength());
12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->computeChecksum();
12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    proc(desc, context);
12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void DetachDescProc(const SkDescriptor* desc, void* context)
12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc);
12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const
12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache* cache;
12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(deviceMatrix, DetachDescProc, &cache);
12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache;
12750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h"
12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeTypeface(this->getTypeface());
12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(this->getTextSize());
12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(this->getTextScaleX());
12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(this->getTextSkewX());
12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(this->getPathEffect());
12870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(this->getShader());
12880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(this->getXfermode());
12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(this->getMaskFilter());
12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(this->getColorFilter());
12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(this->getRasterizer());
12920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeFlattenable(this->getLooper());
12930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write32(this->getColor());
12940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(this->getStrokeWidth());
12950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.writeScalar(this->getStrokeMiter());
12960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write16(this->getFlags());
12970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(this->getTextAlign());
12980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(this->getStrokeCap());
12990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(this->getStrokeJoin());
13000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(this->getStyle());
13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer.write8(this->getTextEncoding());
13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
13050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setTypeface(buffer.readTypeface());
13060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setTextSize(buffer.readScalar());
13070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setTextScaleX(buffer.readScalar());
13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setTextSkewX(buffer.readScalar());
13090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setPathEffect((SkPathEffect*) buffer.readFlattenable())->safeUnref();
13100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setShader((SkShader*) buffer.readFlattenable())->safeUnref();
13110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setXfermode((SkXfermode*) buffer.readFlattenable())->safeUnref();
13120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())->safeUnref();
13130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setColorFilter((SkColorFilter*) buffer.readFlattenable())->safeUnref();
13140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setRasterizer((SkRasterizer*) buffer.readFlattenable())->safeUnref();
13150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setLooper((SkDrawLooper*) buffer.readFlattenable())->safeUnref();
13160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setColor(buffer.readU32());
13170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setStrokeWidth(buffer.readScalar());
13180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setStrokeMiter(buffer.readScalar());
13190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(buffer.readU16());
13200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setTextAlign((SkPaint::Align) buffer.readU8());
13210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setStrokeCap((SkPaint::Cap) buffer.readU8());
13220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setStrokeJoin((SkPaint::Join) buffer.readU8());
13230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setStyle((SkPaint::Style) buffer.readU8());
13240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setTextEncoding((SkPaint::TextEncoding) buffer.readU8());
13250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
13280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader* SkPaint::setShader(SkShader* shader)
13300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fShader, shader);
13320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return shader;
13330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter)
13360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fColorFilter, filter);
13380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
13390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkXfermode* SkPaint::setXfermode(SkXfermode* mode)
13420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fXfermode, mode);
13440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return mode;
13450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkXfermode* SkPaint::setPorterDuffXfermode(SkPorterDuff::Mode mode)
13480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
13500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode = SkPorterDuff::CreateXfermode(mode);
13510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fXfermode;
13520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect)
13550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fPathEffect, effect);
13570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return effect;
13580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter)
13610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fMaskFilter, filter);
13630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
13640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
13670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const
13690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath          effectPath, strokePath;
13710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   path = &src;
13720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = this->getStrokeWidth();
13740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getStyle()) {
13760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kFill_Style:
13770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = -1; // mark it as no-stroke
13780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
13790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStrokeAndFill_Style:
13800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (width == 0)
13810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
13820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
13830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStroke_Style:
13840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
13850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    default:
13860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(!"unknown paint style");
13870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
13880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getPathEffect())
13900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
13910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill
13920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style)
13930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
13940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getPathEffect()->filterPath(&effectPath, src, &width))
13960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            path = &effectPath;
13970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // restore the width if we earlier had to lie, and if we're still set to no-stroke
13990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // note: if we're now stroke (width >= 0), then the pathEffect asked for that change
14000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // and we want to respect that (i.e. don't overwrite their setting for width)
14010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0)
14020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
14030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = this->getStrokeWidth();
14040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (width == 0)
14050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width = -1;
14060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
14070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width > 0 && !path->isEmpty())
14100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
14110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkStroke stroker(*this, width);
14120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        stroker.strokePath(*path, &strokePath);
14130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path = &strokePath;
14140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (path == &src)
14170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst = src;
14180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
14190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
14200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(path == &effectPath || path == &strokePath);
14210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->swap(*(SkPath*)path);
14220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width != 0;  // return true if we're filled, or false if we're hairline (width == 0)
14250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkPaint::canComputeFastBounds() const {
14280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // use bit-or since no need for early exit
14290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (reinterpret_cast<uintptr_t>(this->getMaskFilter()) |
14300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            reinterpret_cast<uintptr_t>(this->getLooper()) |
14310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            reinterpret_cast<uintptr_t>(this->getRasterizer()) |
14320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            reinterpret_cast<uintptr_t>(this->getPathEffect())) == 0;
14330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkRect& SkPaint::computeFastBounds(const SkRect& src,
14360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                         SkRect* storage) const {
14370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storage);
14380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getStyle() != SkPaint::kFill_Style) {
14400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // if we're stroked, outset the rect by the radius (and join type)
14410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar radius = SkScalarHalf(this->getStrokeWidth());
14420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (0 == radius) {  // hairline
14440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            radius = SK_Scalar1;
14450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
14460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkScalar scale = this->getStrokeMiter();
14470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (scale > SK_Scalar1) {
14480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                radius = SkScalarMul(radius, scale);
14490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
14500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
14510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        storage->set(src.fLeft - radius, src.fTop - radius,
14520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                     src.fRight + radius, src.fBottom + radius);
14530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return *storage;
14540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // no adjustments needed, just return the original rect
14560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return src;
14570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
14600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool has_thick_frame(const SkPaint& paint)
14620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return paint.getStrokeWidth() > 0 && paint.getStyle() != SkPaint::kFill_Style;
14640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
14670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    const SkPaint& paint,
14680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool applyStrokeAndPathEffects,
14690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool forceLinearTextOn)
14700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    : fPaint(paint) /* make a copy of the paint */
14710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
14730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                true);
14740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (forceLinearTextOn)
14760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setLinearText(true);
14770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
14780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint))
14800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        applyStrokeAndPathEffects = false;
14810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // can't use our canonical size if we need to apply patheffects/strokes
14830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.isLinearText() && !applyStrokeAndPathEffects)
14840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
14850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
14860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
14870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
14890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = SK_Scalar1;
14900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
14920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
14930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setStyle(SkPaint::kFill_Style);
14940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setPathEffect(NULL);
14950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
14960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCache = fPaint.detachCache(NULL);
14980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = SkPaint::kFill_Style;
15000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = NULL;
15010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
15030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        style = paint.getStyle();   // restore
15050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        pe = paint.getPathEffect();     // restore
15060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setStyle(style);
15080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setPathEffect(pe);
15090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(paint.getMaskFilter());    // restore
15100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // now compute fXOffset if needed
15120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar xOffset = 0;
15140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.getTextAlign() != SkPaint::kLeft_Align)   // need to measure first
15150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int      count;
15170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, &count, NULL), fScale);
15180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (paint.getTextAlign() == SkPaint::kCenter_Align)
15190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarHalf(width);
15200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        xOffset = -width;
15210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXPos = xOffset;
15230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPrevAdvance = 0;
15240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fText = text;
15260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStop = text + length;
15270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::~SkTextToPathIter()
15300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::AttachCache(fCache);
15320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkPath* SkTextToPathIter::next(SkScalar* xpos)
15350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (fText < fStop)
15370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
15390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
15410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPrevAdvance = glyph.fAdvanceX;   // + fPaint.getTextTracking();
15420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (glyph.fWidth)
15440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
15450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (xpos)
15460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *xpos = fXPos;
15470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fCache->findPath(glyph);
15480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
15490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
15510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1552