SkPaint.cpp revision 9b1cba8ccd7554cb30905711a426bd86ad8dd38c
10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/* libs/graphics/sgl/SkPaint.cpp
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Copyright 2006, The Android Open Source Project
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** you may not use this file except in compliance with the License.
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** You may obtain a copy of the License at
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project**
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** See the License for the specific language governing permissions and
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project** limitations under the License.
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPaint.h"
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkColorFilter.h"
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDrawLooper.h"
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFontHost.h"
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMaskFilter.h"
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPathEffect.h"
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkRasterizer.h"
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h"
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScalerContext.h"
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStroke.h"
280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkTypeface.h"
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkXfermode.h"
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkAutoKern.h"
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SK_DefaultTextSize      SkIntToScalar(12)
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SK_DefaultFlags         0   //(kNativeHintsText_Flag)
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
36c1c43a17e7f2a87951739691056728a80e9aef6bMike ReedSkPaint::SkPaint() {
37c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // since we may have padding, we zero everything so that our memcmp() call
38c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // in operator== will work correctly.
39c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    // with this, we can skip 0 and null individual initializations
40c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    sk_bzero(this, sizeof(*this));
41c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed
42c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#if 0   // not needed with the bzero call above
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface   = NULL;
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSkewX  = 0;
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect  = NULL;
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader      = NULL;
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode    = NULL;
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter  = NULL;
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter = NULL;
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer  = NULL;
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper      = NULL;
52c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fWidth      = 0;
53c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed#endif
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
55c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fTextSize   = SK_DefaultTextSize;
56c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed    fTextScaleX = SK_Scalar1;
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor      = SK_ColorBLACK;
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMiterLimit = SK_DefaultMiterLimit;
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fFlags      = SK_DefaultFlags;
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCapType    = kDefault_Cap;
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fJoinType   = kDefault_Join;
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextAlign  = kLeft_Align;
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStyle      = kFill_Style;
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextEncoding = kUTF8_TextEncoding;
65af2616552738d653d5453915d3236e7154b868cdMike Reed    fHinting    = kNormal_Hinting;
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::SkPaint(const SkPaint& src)
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeRef();
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeRef();
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeRef();
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeRef();
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeRef();
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeRef();
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeRef();
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeRef();
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint::~SkPaint()
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPaint& SkPaint::operator=(const SkPaint& src)
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(&src);
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fTypeface->safeRef();
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fPathEffect->safeRef();
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fShader->safeRef();
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fXfermode->safeRef();
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fMaskFilter->safeRef();
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fColorFilter->safeRef();
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fRasterizer->safeRef();
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.fLooper->safeRef();
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTypeface->safeUnref();
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPathEffect->safeUnref();
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fShader->safeUnref();
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXfermode->safeUnref();
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMaskFilter->safeUnref();
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColorFilter->safeUnref();
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fRasterizer->safeUnref();
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fLooper->safeUnref();
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    memcpy(this, &src, sizeof(src));
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return *this;
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint operator==(const SkPaint& a, const SkPaint& b)
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return memcmp(&a, &b, sizeof(a)) == 0;
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::reset()
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint init;
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *this = init;
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFlags(uint32_t flags)
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fFlags = flags;
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAntiAlias(bool doAA)
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doAA, kAntiAlias_Flag));
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDither(bool doDither)
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doDither, kDither_Flag));
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setSubpixelText(bool doSubpixel)
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doSubpixel, kSubpixelText_Flag));
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
153af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkPaint::setLCDRenderText(bool doLCDRender)
154af2616552738d653d5453915d3236e7154b868cdMike Reed{
155af2616552738d653d5453915d3236e7154b868cdMike Reed    this->setFlags(SkSetClearMask(fFlags, doLCDRender, kLCDRenderText_Flag));
156af2616552738d653d5453915d3236e7154b868cdMike Reed}
157af2616552738d653d5453915d3236e7154b868cdMike Reed
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setLinearText(bool doLinearText)
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doLinearText, kLinearText_Flag));
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setUnderlineText(bool doUnderline)
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doUnderline, kUnderlineText_Flag));
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrikeThruText(bool doStrikeThru)
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doStrikeThru, kStrikeThruText_Flag));
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFakeBoldText(bool doFakeBold)
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doFakeBold, kFakeBoldText_Flag));
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setDevKernText(bool doDevKern)
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag));
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setFilterBitmap(bool doFilter)
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->setFlags(SkSetClearMask(fFlags, doFilter, kFilterBitmap_Flag));
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStyle(Style style)
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)style < kStyleCount)
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = style;
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStyle(%d) out of range\n", style);
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setColor(SkColor color)
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = color;
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setAlpha(U8CPU a)
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = SkColorSetARGB(a, SkColorGetR(fColor), SkColorGetG(fColor), SkColorGetB(fColor));
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fColor = SkColorSetARGB(a, r, g, b);
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeWidth(SkScalar width)
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width >= 0)
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fWidth = width;
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeWidth() called with negative value\n");
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeMiter(SkScalar limit)
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (limit >= 0)
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fMiterLimit = limit;
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeMiter() called with negative value\n");
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeCap(Cap ct)
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)ct < kCapCount)
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fCapType = SkToU8(ct);
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct);
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setStrokeJoin(Join jt)
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)jt < kJoinCount)
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fJoinType = SkToU8(jt);
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt);
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//////////////////////////////////////////////////////////////////
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextAlign(Align align)
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)align < kAlignCount)
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextAlign = SkToU8(align);
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align);
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSize(SkScalar ts)
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ts > 0)
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = ts;
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextSize() called with non-positive value\n");
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextScaleX(SkScalar scaleX)
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextScaleX = scaleX;
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextSkewX(SkScalar skewX)
2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTextSkewX = skewX;
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::setTextEncoding(TextEncoding encoding)
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned)encoding <= kGlyphID_TextEncoding)
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextEncoding = encoding;
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding);
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTypeface* SkPaint::setTypeface(SkTypeface* font)
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fTypeface, font);
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return font;
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkRasterizer* SkPaint::setRasterizer(SkRasterizer* r)
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fRasterizer, r);
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return r;
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper)
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fLooper, looper);
3120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return looper;
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkGlyphCache.h"
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkUtils.h"
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::textToGlyphs(const void* textData, size_t byteLength,
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          uint16_t glyphs[]) const {
3220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0) {
3230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textData != NULL);
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == glyphs) {
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        switch (this->getTextEncoding()) {
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF8_TextEncoding:
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF8_CountUnichars((const char*)textData, byteLength);
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kUTF16_TextEncoding:
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return SkUTF16_CountUnichars((const uint16_t*)textData,
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                         byteLength >> 1);
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kGlyphID_TextEncoding:
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return byteLength >> 1;
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // if we get here, we have a valid glyphs[] array, so time to fill it in
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // handle this encoding before the setup for the glyphcache
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getTextEncoding() == kGlyphID_TextEncoding) {
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we want to ignore the low bit of byteLength
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        memcpy(glyphs, textData, byteLength >> 1 << 1);
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return byteLength >> 1;
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache autoCache(*this, NULL);
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*    cache = autoCache.getCache();
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint16_t*   gptr = glyphs;
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getTextEncoding()) {
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF8_TextEncoding:
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF8_NextUnichar(&text));
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkPaint::kUTF16_TextEncoding: {
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* text16 = (const uint16_t*)text;
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const uint16_t* stop16 = (const uint16_t*)stop;
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text16 < stop16) {
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16));
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(!"unknown text encoding");
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gptr - glyphs;
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, const char** text)
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_prev(SkGlyphCache* cache, const char** text)
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_PrevUnichar(text));
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, const char** text)
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_prev(SkGlyphCache* cache, const char** text)
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_PrevUnichar((const uint16_t**)text));
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, const char** text)
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_prev(SkGlyphCache* cache, const char** text)
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, const char** text)
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_NextUnichar(text));
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf8_prev(SkGlyphCache* cache, const char** text)
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF8_PrevUnichar(text));
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, const char** text)
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text));
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_utf16_prev(SkGlyphCache* cache, const char** text)
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharAdvance(SkUTF16_PrevUnichar((const uint16_t**)text));
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, const char** text)
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getAdvance_glyph_prev(SkGlyphCache* cache, const char** text)
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr -= 1;
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDAdvance(glyphID);
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMeasureCacheProc SkPaint::getMeasureCacheProc(TextBufferDirection tbd,
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                bool needFullMetrics) const
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkMeasureCacheProc gMeasureCacheProcs[] = {
4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_next,
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_next,
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_next,
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_prev,
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_prev,
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_prev,
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_next,
5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_next,
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_next,
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf8_prev,
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_utf16_prev,
5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getAdvance_glyph_prev
5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (kBackward_TextBufferDirection == tbd)
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!needFullMetrics && !this->isDevKernText())
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 6;
5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gMeasureCacheProcs));
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gMeasureCacheProcs[index];
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_00(SkGlyphCache* cache,
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed, SkFixed)
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text));
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf8_xy(SkGlyphCache* cache,
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            const char** text, SkFixed x, SkFixed y)
5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF8_NextUnichar(text), x, y);
5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_00(SkGlyphCache* cache, const char** text,
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text));
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_utf16_xy(SkGlyphCache* cache,
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text),
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    x, y);
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_00(SkGlyphCache* cache, const char** text,
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             SkFixed, SkFixed)
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID);
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkGlyph& sk_getMetrics_glyph_xy(SkGlyphCache* cache,
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                             const char** text, SkFixed x, SkFixed y)
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(cache != NULL);
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL);
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const uint16_t* ptr = *(const uint16_t**)text;
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned glyphID = *ptr;
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ptr += 1;
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *text = (const char*)ptr;
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache->getGlyphIDMetrics(glyphID, x, y);
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkDrawCacheProc SkPaint::getDrawCacheProc() const
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    static const SkDrawCacheProc gDrawCacheProcs[] = {
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_00,
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_00,
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_00,
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf8_xy,
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_utf16_xy,
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        sk_getMetrics_glyph_xy
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    };
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned index = this->getTextEncoding();
6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fFlags & kSubpixelText_Flag)
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        index += 3;
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(index < SK_ARRAY_COUNT(gDrawCacheProcs));
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return gDrawCacheProcs[index];
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass SkAutoRestorePaintTextSizeAndFrame {
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame(const SkPaint* paint) : fPaint((SkPaint*)paint)
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTextSize = paint->getTextSize();
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fStyle = paint->getStyle();
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(SkPaint::kFill_Style);
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ~SkAutoRestorePaintTextSizeAndFrame()
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setStyle(fStyle);
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint->setTextSize(fTextSize);
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint*        fPaint;
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        fTextSize;
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  fStyle;
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds)
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(SkIntToScalar(g.fLeft),
6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop),
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fLeft + g.fWidth),
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkIntToScalar(g.fTop + g.fHeight));
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void join_bounds(const SkGlyph& g, SkRect* bounds, SkFixed dx)
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar sx = SkFixedToScalar(dx);
6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->join(SkIntToScalar(g.fLeft) + sx,
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop),
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fLeft + g.fWidth) + sx,
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                 SkIntToScalar(g.fTop + g.fHeight));
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measure_text(SkGlyphCache* cache,
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               const char* text, size_t byteLength,
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                               int* count, SkRect* bounds) const
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(count);
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (byteLength == 0)
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *count = 0;
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (bounds)
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            bounds->setEmpty();
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc;
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         n = 1;
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = (const char*)text + byteLength;
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkGlyph* g = &glyphCacheProc(cache, &text);
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed x = g->fAdvanceX;
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == bounds)
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta) + g->fAdvanceX;
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += glyphCacheProc(cache, &text).fAdvanceX;
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        set_bounds(*g, bounds);
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->isDevKernText())
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int rsb;
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                rsb = g->fRsbDelta;
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += SkAutoKern_AdjustF(rsb, g->fLsbDelta);
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            for (; text < stop; n++) {
7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g = &glyphCacheProc(cache, &text);
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                join_bounds(*g, bounds, x);
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                x += g->fAdvanceX;
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *count = n;
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkFixedToScalar(x);
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::measureText(const void* textData, size_t length,
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                              SkRect* bounds, SkScalar zoom) const
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text != NULL || length == 0);
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = 0;
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length > 0)
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int tempCount;
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = this->measure_text(cache, text, length, &tempCount, bounds);
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarMul(width, scale);
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (bounds)
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fLeft = SkScalarMul(bounds->fLeft, scale);
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fTop = SkScalarMul(bounds->fTop, scale);
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fRight = SkScalarMul(bounds->fRight, scale);
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bounds->fBottom = SkScalarMul(bounds->fBottom, scale);
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width;
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecttypedef bool (*SkTextBufferPred)(const char* text, const char* stop);
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool forward_textBufferPred(const char* text, const char* stop)
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text < stop;
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool backward_textBufferPred(const char* text, const char* stop)
7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return text > stop;
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkTextBufferPred chooseTextBufferPred(SkPaint::TextBufferDirection tbd,
7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            const char** text, size_t length, const char** stop)
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (SkPaint::kForward_TextBufferDirection == tbd)
7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text + length;
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return forward_textBufferPred;
7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // text should point to the end of the buffer, and stop to the beginning
7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *stop = *text;
7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *text += length;
7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return backward_textBufferPred;
7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth,
8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          SkScalar* measuredWidth,
8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                          TextBufferDirection tbd) const
8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == length || 0 >= maxWidth)
8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (measuredWidth)
8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *measuredWidth = 0;
8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(textD != NULL);
8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textD;
8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
8170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
8199b1cba8ccd7554cb30905711a426bd86ad8dd38cJean-Baptiste Queru        maxWidth = SkScalarMulDiv(maxWidth, kCanonicalTextSizeForPaths, fTextSize);
8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc glyphCacheProc = this->getMeasureCacheProc(tbd, false);
8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char*      stop;
8290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextBufferPred pred = chooseTextBufferPred(tbd, &text, length, &stop);
8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed          max = SkScalarToFixed(maxWidth);
8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFixed          width = 0;
8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoKern  autokern;
8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int rsb = 0;
8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
8410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const SkGlyph& g = glyphCacheProc(cache, &text);
8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = SkAutoKern_AdjustF(rsb, g.fLsbDelta) + g.fAdvanceX;
8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            rsb = g.fRsbDelta;
8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (pred(text, stop))
8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* curr = text;
8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkFixed x = glyphCacheProc(cache, &text).fAdvanceX;
8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((width += x) > max)
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            {
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width -= x;
8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text = curr;
8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (measuredWidth)
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar scalarWidth = SkFixedToScalar(width);
8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale)
8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scalarWidth = SkScalarMul(scalarWidth, scale);
8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *measuredWidth = scalarWidth;
8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // return the number of bytes measured
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (kForward_TextBufferDirection == tbd) ?
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                text - stop + length : stop - text + length;
8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool FontMetricsCacheProc(const SkGlyphCache* cache, void* context)
8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *(SkPaint::FontMetrics*)context = cache->getFontMetricsY();
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;   // don't detach the cache
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void FontMetricsDescProc(const SkDescriptor* desc, void* context)
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::VisitCache(desc, FontMetricsCacheProc, context);
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix    zoomMatrix, *zoomPtr = NULL;
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (zoom)
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomMatrix.setScale(zoom, zoom);
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        zoomPtr = &zoomMatrix;
9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0
9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, zoomPtr);
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const FontMetrics&  my = cache->getFontMetricsY();
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    FontMetrics storage;
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == metrics)
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics = &storage;
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(zoomPtr, FontMetricsDescProc, metrics);
9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (scale)
9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fTop = SkScalarMul(metrics->fTop, scale);
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fAscent = SkScalarMul(metrics->fAscent, scale);
9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fDescent = SkScalarMul(metrics->fDescent, scale);
9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fBottom = SkScalarMul(metrics->fBottom, scale);
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        metrics->fLeading = SkScalarMul(metrics->fLeading, scale);
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return metrics->fDescent - metrics->fAscent + metrics->fLeading;
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
9360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void set_bounds(const SkGlyph& g, SkRect* bounds, SkScalar scale)
9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bounds->set(g.fLeft * scale,
9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                g.fTop * scale,
9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fLeft + g.fWidth) * scale,
9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                (g.fTop + g.fHeight) * scale);
9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkPaint::getTextWidths(const void* textData, size_t byteLength, SkScalar widths[],
9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                           SkRect bounds[]) const
9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == byteLength)
9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(NULL != textData);
9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (NULL == widths && NULL == bounds)
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return this->countText(textData, byteLength);
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoRestorePaintTextSizeAndFrame  restore(this);
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar                            scale = 0;
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isLinearText())
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scale = fTextSize / kCanonicalTextSizeForPaths;
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // this gets restored by restore
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ((SkPaint*)this)->setTextSize(SkIntToScalar(kCanonicalTextSizeForPaths));
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoGlyphCache    autoCache(*this, NULL);
9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache*       cache = autoCache.getCache();
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMeasureCacheProc  glyphCacheProc;
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    glyphCacheProc = this->getMeasureCacheProc(kForward_TextBufferDirection,
9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                               NULL != bounds);
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* stop = text + byteLength;
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int         count = 0;
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->isDevKernText())
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // we adjust the widths returned here through auto-kerning
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkAutoKern  autokern;
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkFixed     prevWidth = 0;
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        SkScalar w = SkFixedToScalar(prevWidth + adjust);
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkScalarMul(w, scale);
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
9940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkScalarMul(SkFixedToScalar(prevWidth), scale);
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkFixed  adjust = autokern.adjust(g);
10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (count > 0) {
10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        *widths++ = SkFixedToScalar(prevWidth + adjust);
10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    prevWidth = g.fAdvanceX;
10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (count > 0 && widths) {
10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *widths = SkFixedToScalar(prevWidth);
10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } else {    // no devkern
10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (scale) {
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++ = SkScalarMul(SkFixedToScalar(g.fAdvanceX),
10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                            scale);
10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++, scale);
10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            while (text < stop) {
10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const SkGlyph& g = glyphCacheProc(cache, &text);
10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (widths) {
10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *widths++ = SkFixedToScalar(g.fAdvanceX);
10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (bounds) {
10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    set_bounds(g, bounds++);
10430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++count;
10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(text == stop);
10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return count;
10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////
10540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkDraw.h"
10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::getTextPath(const void* textData, size_t length, SkScalar x, SkScalar y, SkPath* path) const
10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* text = (const char*)textData;
10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length == 0 || text != NULL);
10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (text == NULL || length == 0 || path == NULL)
10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTextToPathIter    iter(text, length, *this, false, true);
10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMatrix            matrix;
10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar            prevXPos = 0;
10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.setScale(iter.getPathScale(), iter.getPathScale());
10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    matrix.postTranslate(x, y);
10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    path->reset();
10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        xpos;
10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   iterPath;
10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while ((iterPath = iter.next(&xpos)) != NULL)
10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        matrix.postTranslate(xpos - prevXPos, 0);
10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path->addPath(*iterPath, matrix);
10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        prevXPos = xpos;
10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void add_flattenable(SkDescriptor* desc, uint32_t tag,
10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            SkFlattenableWriteBuffer* buffer) {
10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    buffer->flatten(desc->addEntry(tag, buffer->size(), NULL));
10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project/*
10880910916c0f7b951ee55c4b7c6358295b9bca0565The 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])
10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    inspired by a desire to change the multiplier for thickness in fakebold
10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    therefore, i assumed number of pairs (length) will be small, so a linear search is sufficient
10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    repeated keys are allowed for discontinuous functions (so long as keys is monotonically increasing), and if
10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        key is the value of a repeated scalar in keys, the first one will be used
10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - this may change if a binary search is used
10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    - also, this ensures that there is no divide by zero (an assert also checks for that)
10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project*/
10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkScalar interpolate(SkScalar key, const SkScalar keys[], const SkScalar values[], int length)
10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(length > 0);
11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(keys != NULL);
11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(values != NULL);
11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int i = 1; i < length; i++)
11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(keys[i] >= keys[i-1]);
11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int right = 0;
11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (right < length && key > keys[right])
11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        right++;
11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //could use sentinal values to eliminate conditionals
11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //i assume i am not in control of input values, so i want to make it simple
11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (length == right)
11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[length-1];
11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (0 == right)
11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return values[0];
11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //otherwise, we interpolate between right-1 and right
11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rVal = values[right];
11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar lVal = values[right-1];
11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar rightKey = keys[right];
11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar leftKey = keys[right-1];
11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(rightKey != leftKey);
11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //fractional amount which we will multiply by the difference in the left value and right value
11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar fract = SkScalarDiv(key-leftKey,rightKey-leftKey);
11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return lVal + SkScalarMul(fract, rVal-lVal);
11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project//used for interpolating in fakeBold
11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar pointSizes[] = { SkIntToScalar(9), SkIntToScalar(36) };
11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScalar multipliers[] = { SK_Scalar1/24, SK_Scalar1/32 };
11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkMask::Format computeMaskFormat(const SkPaint& paint)
11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    uint32_t flags = paint.getFlags();
11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1134af2616552738d653d5453915d3236e7154b868cdMike Reed    if (flags & SkPaint::kLCDRenderText_Flag)
1135af2616552738d653d5453915d3236e7154b868cdMike Reed#if defined(SK_SUPPORT_LCDTEXT)
1136af2616552738d653d5453915d3236e7154b868cdMike Reed        return SkFontHost::GetSubpixelOrientation() == SkFontHost::kHorizontal_LCDOrientation ?
1137af2616552738d653d5453915d3236e7154b868cdMike Reed                   SkMask::kHorizontalLCD_Format : SkMask::kVerticalLCD_Format;
1138af2616552738d653d5453915d3236e7154b868cdMike Reed#else
1139af2616552738d653d5453915d3236e7154b868cdMike Reed        return SkMask::kA8_Format;
1140af2616552738d653d5453915d3236e7154b868cdMike Reed#endif
1141af2616552738d653d5453915d3236e7154b868cdMike Reed    if (flags & SkPaint::kAntiAlias_Flag)
1142af2616552738d653d5453915d3236e7154b868cdMike Reed        return SkMask::kA8_Format;
1143af2616552738d653d5453915d3236e7154b868cdMike Reed    return SkMask::kBW_Format;
11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11464bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// if linear-text is on, then we force hinting to be off (since that's sort of
11474bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed// the point of linear-text.
11484bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reedstatic SkPaint::Hinting computeHinting(const SkPaint& paint) {
11494bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    SkPaint::Hinting h = paint.getHinting();
11504bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    if (paint.isLinearText()) {
11514bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed        h = SkPaint::kNo_Hinting;
11524bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    }
11534bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    return h;
11544bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed}
11554bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed
1156af2616552738d653d5453915d3236e7154b868cdMike Reedvoid SkScalerContext::MakeRec(const SkPaint& paint,
1157af2616552738d653d5453915d3236e7154b868cdMike Reed                              const SkMatrix* deviceMatrix, Rec* rec)
11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1159af2616552738d653d5453915d3236e7154b868cdMike Reed    SkASSERT(deviceMatrix == NULL ||
1160af2616552738d653d5453915d3236e7154b868cdMike Reed             (deviceMatrix->getType() & SkMatrix::kPerspective_Mask) == 0);
11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFontID = SkTypeface::UniqueID(paint.getTypeface());
11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fTextSize = paint.getTextSize();
11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreScaleX = paint.getTextScaleX();
11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fPreSkewX  = paint.getTextSkewX();
11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (deviceMatrix)
11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = deviceMatrix->getScaleX();
11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = deviceMatrix->getSkewX();
11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][0] = deviceMatrix->getSkewY();
11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[1][1] = deviceMatrix->getScaleY();
11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][0] = rec->fPost2x2[1][1] = SK_Scalar1;
11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fPost2x2[0][1] = rec->fPost2x2[1][0] = 0;
11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = paint.getStyle();
11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar        strokeWidth = paint.getStrokeWidth();
11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isFakeBoldText())
11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar fakeBoldScale = interpolate(paint.getTextSize(), pointSizes, multipliers, 2);
11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar extra = SkScalarMul(paint.getTextSize(), fakeBoldScale);
11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kFill_Style)
11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            style = SkPaint::kStrokeAndFill_Style;
11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth = extra;    // ignore paint's strokeWidth if it was "fill"
11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else
11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            strokeWidth += extra;
11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned flags = SkFontHost::ComputeGammaFlag(paint);
11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.isDevKernText())
12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        flags |= SkScalerContext::kDevKernText_Flag;
12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (style != SkPaint::kFill_Style && strokeWidth > 0)
12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = strokeWidth;
12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = paint.getStrokeMiter();
12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = SkToU8(paint.getStrokeJoin());
12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (style == SkPaint::kStrokeAndFill_Style)
12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            flags |= SkScalerContext::kFrameAndFill_Flag;
12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fFrameWidth = 0;
12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fMiterLimit = 0;
12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec->fStrokeJoin = 0;
12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1218af2616552738d653d5453915d3236e7154b868cdMike Reed    rec->fSubpixelPositioning = paint.isSubpixelText();
12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fMaskFormat = SkToU8(computeMaskFormat(paint));
12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    rec->fFlags = SkToU8(flags);
12214bf0086251c4e8ad9ef9067ffac7a3a97a09dd4aMike Reed    rec->setHinting(computeHinting(paint));
1222af2616552738d653d5453915d3236e7154b868cdMike Reed
1223af2616552738d653d5453915d3236e7154b868cdMike Reed    /*  Allow the fonthost to modify our rec before we use it as a key into the
1224af2616552738d653d5453915d3236e7154b868cdMike Reed        cache. This way if we're asking for something that they will ignore,
1225af2616552738d653d5453915d3236e7154b868cdMike Reed        they can modify our rec up front, so we don't create duplicate cache
1226af2616552738d653d5453915d3236e7154b868cdMike Reed        entries.
1227af2616552738d653d5453915d3236e7154b868cdMike Reed     */
1228af2616552738d653d5453915d3236e7154b868cdMike Reed    SkFontHost::FilterRec(rec);
12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MIN_SIZE_FOR_EFFECT_BUFFER  1024
12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::descriptorProc(const SkMatrix* deviceMatrix,
12340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void (*proc)(const SkDescriptor*, void*),
12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                             void* context) const
12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::Rec    rec;
12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalerContext::MakeRec(*this, deviceMatrix, &rec);
12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t          descSize = sizeof(rec);
12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int             entryCount = 1;
12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = this->getPathEffect();
12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkMaskFilter*   mf = this->getMaskFilter();
12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRasterizer*   ra = this->getRasterizer();
12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    peBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    mfBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkFlattenableWriteBuffer    raBuffer(MIN_SIZE_FOR_EFFECT_BUFFER);
12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        peBuffer.writeFlattenable(pe);
12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += peBuffer.size();
12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // seems like we could support kLCD as well at this point...
12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mfBuffer.writeFlattenable(mf);
12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += mfBuffer.size();
12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing with maskfilters
12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
12650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        raBuffer.writeFlattenable(ra);
12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        descSize += raBuffer.size();
12670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        entryCount += 1;
12680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        rec.fMaskFormat = SkMask::kA8_Format;   // force antialiasing when we do the scan conversion
12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    descSize += SkDescriptor::ComputeOverhead(entryCount);
12710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkAutoDescriptor    ad(descSize);
12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDescriptor*       desc = ad.getDesc();
12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->init();
12760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (pe) {
12790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kPathEffect_SkDescriptorTag, &peBuffer);
12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (mf) {
12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kMaskFilter_SkDescriptorTag, &mfBuffer);
12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ra) {
12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        add_flattenable(desc, kRasterizer_SkDescriptorTag, &raBuffer);
12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(descSize == desc->getLength());
12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    desc->computeChecksum();
12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    proc(desc, context);
12920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic void DetachDescProc(const SkDescriptor* desc, void* context)
12950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
12960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(desc);
12970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const
13000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache* cache;
13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    this->descriptorProc(deviceMatrix, DetachDescProc, &cache);
13030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return cache;
13040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
13070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkStream.h"
13090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
13105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uintptr_t asint(const void* p) {
13115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return reinterpret_cast<uintptr_t>(p);
13125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
13135f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedunion Scalar32 {
13155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkScalar    fScalar;
13165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t    f32;
13175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
13185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t* write_scalar(uint32_t* ptr, SkScalar value) {
13205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
13215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
13225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.fScalar = value;
13235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr = tmp.f32;
13245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return ptr + 1;
13255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
13265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic SkScalar read_scalar(const uint32_t*& ptr) {
13285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
13295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    Scalar32 tmp;
13305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp.f32 = *ptr++;
13315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return tmp.fScalar;
13325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
13335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
13355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(a == (uint8_t)a);
13365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(b == (uint8_t)b);
13375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(c == (uint8_t)c);
13385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(d == (uint8_t)d);
13395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    return (a << 24) | (b << 16) | (c << 8) | d;
13405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed}
13415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedenum FlatFlags {
13435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasTypeface_FlatFlag   = 0x01,
13445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    kHasEffects_FlatFlag    = 0x02
13455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed};
13465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13475f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed// The size of a flat paint's POD fields
13485f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reedstatic const uint32_t kPODPaintSize =   5 * sizeof(SkScalar) +
13495f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(SkColor) +
13505f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        1 * sizeof(uint16_t) +
13515f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                                        6 * sizeof(uint8_t);
13525f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13535f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed/*  To save space/time, we analyze the paint, and write a truncated version of
13545f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    it if there are not tricky elements like shaders, etc.
13555f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed */
13560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
13575f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = 0;
13585f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (this->getTypeface()) {
13595f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasTypeface_FlatFlag;
13605f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
13615f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (asint(this->getPathEffect()) |
13625f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getShader()) |
13635f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getXfermode()) |
13645f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getMaskFilter()) |
13655f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getColorFilter()) |
13665f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getRasterizer()) |
13675f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        asint(this->getLooper())) {
13685f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        flatFlags |= kHasEffects_FlatFlag;
13695f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
13705f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13715f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
13725f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t* ptr = buffer.reserve(kPODPaintSize);
13735f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13745f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSize());
13755f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextScaleX());
13765f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getTextSkewX());
13775f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeWidth());
13785f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    ptr = write_scalar(ptr, this->getStrokeMiter());
13795f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = this->getColor();
13805f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = (this->getFlags() << 16) | (this->getTextAlign() << 8) | flatFlags;
13815f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    *ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
13825f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed                    this->getStyle(), this->getTextEncoding());
13835f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
13845f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // now we're done with ptr and the (pre)reserved space. If we need to write
13855f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // additional fields, use the buffer directly
13865f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
13875f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeTypeface(this->getTypeface());
13885f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
13895f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
13905f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getPathEffect());
13915f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getShader());
13925f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getXfermode());
13935f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getMaskFilter());
13945f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getColorFilter());
13955f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getRasterizer());
13965f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        buffer.writeFlattenable(this->getLooper());
13975f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
13980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
13990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
14015f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
14025f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const void* podData = buffer.skip(kPODPaintSize);
14035f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
14045f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14055f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    // the order we read must match the order we wrote in flatten()
14065f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSize(read_scalar(pod));
14075f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextScaleX(read_scalar(pod));
14085f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextSkewX(read_scalar(pod));
14095f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeWidth(read_scalar(pod));
14105f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeMiter(read_scalar(pod));
14115f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setColor(*pod++);
14125f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14135f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint32_t tmp = *pod++;
14145f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setFlags(tmp >> 16);
14155f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF));
14165f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    uint8_t flatFlags = tmp & 0xFF;
14175f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14185f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    tmp = *pod++;
14195f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
14205f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
14215f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
14225f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
14235f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14245f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasTypeface_FlatFlag) {
14255f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(buffer.readTypeface());
14265f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
14275f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setTypeface(NULL);
14285f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
14295f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed
14305f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    if (flatFlags & kHasEffects_FlatFlag) {
14315f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setPathEffect((SkPathEffect*) buffer.readFlattenable())->safeUnref();
14325f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setShader((SkShader*) buffer.readFlattenable())->safeUnref();
14335f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setXfermode((SkXfermode*) buffer.readFlattenable())->safeUnref();
14345f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())->safeUnref();
14355f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setColorFilter((SkColorFilter*) buffer.readFlattenable())->safeUnref();
14365f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setRasterizer((SkRasterizer*) buffer.readFlattenable())->safeUnref();
14375f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setLooper((SkDrawLooper*) buffer.readFlattenable())->safeUnref();
14385f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    } else {
14395f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setPathEffect(NULL);
14405f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setShader(NULL);
14415f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setXfermode(NULL);
14425f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setMaskFilter(NULL);
14435f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setColorFilter(NULL);
14445f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setRasterizer(NULL);
14455f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed        this->setLooper(NULL);
14465f6af4c62d33f128b6617fa4a038f309627a14d0Mike Reed    }
14470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
14500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkShader* SkPaint::setShader(SkShader* shader)
14520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fShader, shader);
14540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return shader;
14550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter)
14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fColorFilter, filter);
14600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
14610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkXfermode* SkPaint::setXfermode(SkXfermode* mode)
14640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fXfermode, mode);
14660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return mode;
14670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
146903f42ddd729377f21719a140c027a1f8cc5c2152Mike ReedSkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) {
147003f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    SkSafeUnref(fXfermode);
147103f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    fXfermode = SkXfermode::Create(mode);
147203f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed    return fXfermode;
147303f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed}
147403f42ddd729377f21719a140c027a1f8cc5c2152Mike Reed
14750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect)
14760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fPathEffect, effect);
14780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return effect;
14790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter)
14820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkRefCnt_SafeAssign(fMaskFilter, filter);
14840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return filter;
14850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
14860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
14880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkPaint::getFillPath(const SkPath& src, SkPath* dst) const
14900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
14910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath          effectPath, strokePath;
14920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkPath*   path = &src;
14930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar width = this->getStrokeWidth();
14950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (this->getStyle()) {
14970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kFill_Style:
14980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        width = -1; // mark it as no-stroke
14990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
15000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStrokeAndFill_Style:
15010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (width == 0)
15020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
15030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
15040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    case SkPaint::kStroke_Style:
15050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        break;
15060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    default:
15070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(!"unknown paint style");
15080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (this->getPathEffect())
15110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // lie to the pathEffect if our style is strokeandfill, so that it treats us as just fill
15130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style)
15140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = -1; // mark it as no-stroke
15150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getPathEffect()->filterPath(&effectPath, src, &width))
15170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            path = &effectPath;
15180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // restore the width if we earlier had to lie, and if we're still set to no-stroke
15200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // note: if we're now stroke (width >= 0), then the pathEffect asked for that change
15210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // and we want to respect that (i.e. don't overwrite their setting for width)
15220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (this->getStyle() == SkPaint::kStrokeAndFill_Style && width < 0)
15230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
15240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = this->getStrokeWidth();
15250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (width == 0)
15260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                width = -1;
15270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
15280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (width > 0 && !path->isEmpty())
15310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkStroke stroker(*this, width);
15330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        stroker.strokePath(*path, &strokePath);
15340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        path = &strokePath;
15350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (path == &src)
15380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *dst = src;
15390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
15400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(path == &effectPath || path == &strokePath);
15420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        dst->swap(*(SkPath*)path);
15430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return width != 0;  // return true if we're filled, or false if we're hairline (width == 0)
15460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
154835d15937afb7f4b3472e43ea784b02485ec910fbMike Reedconst SkRect& SkPaint::computeStrokeFastBounds(const SkRect& src,
154935d15937afb7f4b3472e43ea784b02485ec910fbMike Reed                                               SkRect* storage) const {
15500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(storage);
155135d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    SkASSERT(this->getStyle() != SkPaint::kFill_Style);
155235d15937afb7f4b3472e43ea784b02485ec910fbMike Reed
155335d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    // since we're stroked, outset the rect by the radius (and join type)
155435d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    SkScalar radius = SkScalarHalf(this->getStrokeWidth());
155535d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    if (0 == radius) {  // hairline
155635d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        radius = SK_Scalar1;
155735d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    } else if (this->getStrokeJoin() == SkPaint::kMiter_Join) {
155835d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        SkScalar scale = this->getStrokeMiter();
155935d15937afb7f4b3472e43ea784b02485ec910fbMike Reed        if (scale > SK_Scalar1) {
156035d15937afb7f4b3472e43ea784b02485ec910fbMike Reed            radius = SkScalarMul(radius, scale);
15610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
15620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
156335d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    storage->set(src.fLeft - radius, src.fTop - radius,
156435d15937afb7f4b3472e43ea784b02485ec910fbMike Reed                 src.fRight + radius, src.fBottom + radius);
156535d15937afb7f4b3472e43ea784b02485ec910fbMike Reed    return *storage;
15660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////
15690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic bool has_thick_frame(const SkPaint& paint)
15710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return paint.getStrokeWidth() > 0 && paint.getStyle() != SkPaint::kFill_Style;
15730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::SkTextToPathIter( const char text[], size_t length,
15760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    const SkPaint& paint,
15770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool applyStrokeAndPathEffects,
15780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    bool forceLinearTextOn)
15790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    : fPaint(paint) /* make a copy of the paint */
15800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
15810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fGlyphCacheProc = paint.getMeasureCacheProc(SkPaint::kForward_TextBufferDirection,
15820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                true);
15830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (forceLinearTextOn)
15850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setLinearText(true);
15860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(NULL);   // don't want this affecting our path-cache lookup
15870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.getPathEffect() == NULL && !has_thick_frame(fPaint))
15890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        applyStrokeAndPathEffects = false;
15900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
15910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // can't use our canonical size if we need to apply patheffects/strokes
15920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fPaint.isLinearText() && !applyStrokeAndPathEffects)
15930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
15940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setTextSize(SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths));
15950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = paint.getTextSize() / SkPaint::kCanonicalTextSizeForPaths;
15960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
15980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fScale = SK_Scalar1;
15990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
16010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setStyle(SkPaint::kFill_Style);
16030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPaint.setPathEffect(NULL);
16040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fCache = fPaint.detachCache(NULL);
16070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPaint::Style  style = SkPaint::kFill_Style;
16090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPathEffect*   pe = NULL;
16100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!applyStrokeAndPathEffects)
16120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        style = paint.getStyle();   // restore
16140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        pe = paint.getPathEffect();     // restore
16150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setStyle(style);
16170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setPathEffect(pe);
16180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPaint.setMaskFilter(paint.getMaskFilter());    // restore
16190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // now compute fXOffset if needed
16210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar xOffset = 0;
16230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (paint.getTextAlign() != SkPaint::kLeft_Align)   // need to measure first
16240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int      count;
16260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar width = SkScalarMul(fPaint.measure_text(fCache, text, length, &count, NULL), fScale);
16270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (paint.getTextAlign() == SkPaint::kCenter_Align)
16280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            width = SkScalarHalf(width);
16290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        xOffset = -width;
16300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fXPos = xOffset;
16320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPrevAdvance = 0;
16330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fText = text;
16350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fStop = text + length;
16360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkTextToPathIter::~SkTextToPathIter()
16390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
16400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkGlyphCache::AttachCache(fCache);
16410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
16420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkPath* SkTextToPathIter::next(SkScalar* xpos)
16440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
16450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (fText < fStop)
16460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
16470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const SkGlyph& glyph = fGlyphCacheProc(fCache, &fText);
16480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fXPos += SkScalarMul(SkFixedToScalar(fPrevAdvance + fAutoKern.adjust(glyph)), fScale);
16500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPrevAdvance = glyph.fAdvanceX;   // + fPaint.getTextTracking();
16510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
16520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (glyph.fWidth)
16530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        {
16540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (xpos)
16550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *xpos = fXPos;
16560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return fCache->findPath(glyph);
16570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
16580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
16590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return NULL;
16600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1661