1d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/*
2d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * Copyright 2013 Google Inc.
3d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com *
4d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * Use of this source code is governed by a BSD-style license that can be
5d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com * found in the LICENSE file.
6d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com */
7d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
8d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrDistanceFieldTextContext.h"
9d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrAtlas.h"
102d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#include "SkColorFilter.h"
11d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrDrawTarget.h"
126c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org#include "GrDrawTargetCaps.h"
13d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrFontScaler.h"
148128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org#include "SkGlyphCache.h"
152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#include "GrGpu.h"
16d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrIndexBuffer.h"
17d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "GrStrokeInfo.h"
18d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrTextStrike.h"
19d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "GrTextStrike_impl.h"
2064b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org#include "SkDistanceFieldGen.h"
219f94b9104a02c5918720517de3ffd547f354900acommit-bot@chromium.org#include "SkDraw.h"
22e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org#include "SkGpuDevice.h"
23d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "SkPath.h"
24d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "SkRTConf.h"
25d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "SkStrokeRec.h"
26d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "effects/GrDistanceFieldTextureEffect.h"
27d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
28d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comstatic const int kGlyphCoordsAttributeIndex = 1;
29d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
30dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.orgstatic const int kSmallDFFontSize = 32;
31dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.orgstatic const int kSmallDFFontLimit = 32;
32dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.orgstatic const int kMediumDFFontSize = 64;
33dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.orgstatic const int kMediumDFFontLimit = 64;
34dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.orgstatic const int kLargeDFFontSize = 128;
358128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
36d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comSK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false,
37d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                "Dump the contents of the font cache before every purge.");
38d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
396fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.orgGrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
406fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org                                                       const SkDeviceProperties& properties,
416fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org                                                       bool enable)
426fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org                                                    : GrTextContext(context, properties) {
43ae796120928621e9ac44421b71cb8ba6e8beb85dcommit-bot@chromium.org#if SK_FORCE_DISTANCEFIELD_FONTS
446fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    fEnableDFRendering = true;
45ae796120928621e9ac44421b71cb8ba6e8beb85dcommit-bot@chromium.org#else
466fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    fEnableDFRendering = enable;
47ae796120928621e9ac44421b71cb8ba6e8beb85dcommit-bot@chromium.org#endif
48d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fStrike = NULL;
492d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    fGammaTexture = NULL;
50d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
51d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fCurrTexture = NULL;
52d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fCurrVertex = 0;
53d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
54d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fVertices = NULL;
55d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fMaxVertices = 0;
56d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
57d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
58d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comGrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
59d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    this->flushGlyphs();
602d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    SkSafeSetNull(fGammaTexture);
61d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
62d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
63cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.orgbool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) {
646fcd1ef244f50b382627cdc7cdb50eb9e2dd46ebcommit-bot@chromium.org    if (!fEnableDFRendering && !paint.isDistanceFieldTextTEMP()) {
65eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org        return false;
66eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    }
67eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org
68e1d94437585dad1c195d7cf095f8a5a8219d196askia.committer@gmail.com    // rasterizers and mask filters modify alpha, which doesn't
69eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    // translate well to distance
70eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    if (paint.getRasterizer() || paint.getMaskFilter() ||
71eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org        !fContext->getTextTarget()->caps()->shaderDerivativeSupport()) {
72eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org        return false;
73eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    }
74eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org
75eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    // TODO: add some stroking support
76eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    if (paint.getStyle() != SkPaint::kFill_Style) {
77eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org        return false;
78eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    }
79eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org
80eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    // TODO: choose an appropriate maximum scale for distance fields and
81eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    //       enable perspective
82eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    if (SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix())) {
83eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org        return false;
84eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    }
85eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org
86eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    // distance fields cannot represent color fonts
87eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    SkScalerContext::Rec    rec;
88eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec);
89eefd8a01fc984e15ca108cb2951c52b3ea17d6b8commit-bot@chromium.org    return rec.getFormat() != SkMask::kARGB32_Format;
90cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org}
91cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
92d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comstatic inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
93d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    unsigned r = SkColorGetR(c);
94d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    unsigned g = SkColorGetG(c);
95d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    unsigned b = SkColorGetB(c);
96d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    return GrColorPackRGBA(r, g, b, 0xff);
97d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
98d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
99d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comvoid GrDistanceFieldTextContext::flushGlyphs() {
100d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (NULL == fDrawTarget) {
101d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        return;
102d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
103d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
104d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrDrawState* drawState = fDrawTarget->drawState();
105d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrDrawState::AutoRestoreEffects are(drawState);
106d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
107d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
108d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (fCurrVertex > 0) {
109d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // setup our sampler state for our text texture/atlas
110972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        SkASSERT(SkIsAlign4(fCurrVertex));
111d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkASSERT(fCurrTexture);
112d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
1132d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        GrTextureParams gammaParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode);
114d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
115609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        // Effects could be stored with one of the cache objects (atlas?)
1162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkColor filteredColor;
1172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkColorFilter* colorFilter = fSkPaint.getColorFilter();
1182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        if (NULL != colorFilter) {
1192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            filteredColor = colorFilter->filterColor(fSkPaint.getColor());
1202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        } else {
1212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            filteredColor = fSkPaint.getColor();
1222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        }
123609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org        if (fUseLCDText) {
1242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor);
125609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            bool useBGR = SkDeviceProperties::Geometry::kBGR_Layout ==
126609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                                                            fDeviceProperties.fGeometry.getLayout();
127609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org            drawState->addCoverageEffect(GrDistanceFieldLCDTextureEffect::Create(
128609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                                                            fCurrTexture,
129609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                                                            params,
1302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                            fGammaTexture,
1312d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                            gammaParams,
1322d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                            colorNoPreMul,
133609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                                                            fContext->getMatrix().rectStaysRect() &&
134609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                                                            fContext->getMatrix().isSimilarity(),
135609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                                                            useBGR),
136609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org                                         kGlyphCoordsAttributeIndex)->unref();
137d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
138d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
139d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
140d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                fPaint.numColorStages()) {
141d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                GrPrintf("LCD Text will not draw correctly.\n");
142d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
143d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            // We don't use the GrPaint's color in this case because it's been premultiplied by
144d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
145d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            // the mask texture color. The end result is that we get
146d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            //            mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
1478128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            int a = SkColorGetA(fSkPaint.getColor());
148d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            // paintAlpha
149d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            drawState->setColor(SkColorSetARGB(a, a, a, a));
150d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            // paintColor
1512d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            drawState->setBlendConstant(colorNoPreMul);
152d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
153d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        } else {
1542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_APPLY_TO_A8
1552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.fGamma,
1562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                                filteredColor);
1572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(
1582d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                              fCurrTexture, params,
1592d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                              fGammaTexture, gammaParams,
1602d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                              lum/255.f,
1614d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth                                                              fContext->getMatrix().isSimilarity()),
1624d517fdbb145cb95e5e935470df331e1b6667cfcjvanverth                                         kGlyphCoordsAttributeIndex)->unref();
1632d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#else
1642d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            drawState->addCoverageEffect(GrDistanceFieldTextureEffect::Create(
1652d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                              fCurrTexture, params,
1662d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                              fContext->getMatrix().isSimilarity()),
1672d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                         kGlyphCoordsAttributeIndex)->unref();
1682d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
169d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            // set back to normal in case we took LCD path previously.
170d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
171d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            drawState->setColor(fPaint.getColor());
172d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
173d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
174d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int nGlyphs = fCurrVertex / 4;
175d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
176d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
177d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                          nGlyphs,
178d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                          4, 6);
179d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fDrawTarget->resetVertexSource();
180d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fVertices = NULL;
181d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fMaxVertices = 0;
182d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fCurrVertex = 0;
183d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkSafeSetNull(fCurrTexture);
184d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
185d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
186d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
187d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comnamespace {
188d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
189d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com// position + texture coord
190d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comextern const GrVertexAttrib gTextVertexAttribs[] = {
191d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
192972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
193d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com};
194d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
195d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com};
196d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
197d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comvoid GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
198972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                                                 SkFixed vx, SkFixed vy,
199d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                                 GrFontScaler* scaler) {
200d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (NULL == fDrawTarget) {
201d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        return;
202d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
203d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (NULL == fStrike) {
204d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fStrike = fContext->getFontCache()->getStrike(scaler, true);
205d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
206d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
207d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrGlyph* glyph = fStrike->getGlyph(packed, scaler);
208d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (NULL == glyph || glyph->fBounds.isEmpty()) {
209d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        return;
210d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
211d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
212d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    SkScalar sx = SkFixedToScalar(vx);
213d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    SkScalar sy = SkFixedToScalar(vy);
214d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com/*
215d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    // not valid, need to find a different solution for this
216d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    vx += SkIntToFixed(glyph->fBounds.fLeft);
217d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    vy += SkIntToFixed(glyph->fBounds.fTop);
21811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
219d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    // keep them as ints until we've done the clip-test
220d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrFixed width = glyph->fBounds.width();
221d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrFixed height = glyph->fBounds.height();
222d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
223d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    // check if we clipped out
224d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (true || NULL == glyph->fPlot) {
225d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int x = vx >> 16;
226d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int y = vy >> 16;
227d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (fClipRect.quickReject(x, y, x + width, y + height)) {
228d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com//            SkCLZ(3);    // so we can set a break-point in the debugger
229d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            return;
230d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
231d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
232d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com*/
233d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (NULL == glyph->fPlot) {
234c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        if (fStrike->addGlyphToAtlas(glyph, scaler)) {
235d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            goto HAS_ATLAS;
236d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
237d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
238d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // try to clear out an unused plot before we flush
239c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
240c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org            fStrike->addGlyphToAtlas(glyph, scaler)) {
241d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            goto HAS_ATLAS;
242d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
243d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
244d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (c_DumpFontCache) {
245d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#ifdef SK_DEVELOPER
246d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            fContext->getFontCache()->dump();
247d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
248d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
249d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
250d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // before we purge the cache, we must flush any accumulated draws
251d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        this->flushGlyphs();
252d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fContext->flush();
253d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
254c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        // we should have an unused plot now
255c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        if (fContext->getFontCache()->freeUnusedPlot(fStrike) &&
256c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org            fStrike->addGlyphToAtlas(glyph, scaler)) {
257d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            goto HAS_ATLAS;
258d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
259d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
260d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (NULL == glyph->fPath) {
261d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            SkPath* path = SkNEW(SkPath);
262d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
263d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                // flag the glyph as being dead?
264d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                delete path;
265d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                return;
266d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
267d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            glyph->fPath = path;
268d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
269d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
270d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        GrContext::AutoMatrix am;
271762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org        SkMatrix ctm;
272762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org        ctm.setScale(fTextRatio, fTextRatio);
273762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org        ctm.postTranslate(sx, sy);
274d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        GrPaint tmpPaint(fPaint);
275762cd804375ff8478427dba4fe29379562b8fb60commit-bot@chromium.org        am.setPreConcat(fContext, ctm, &tmpPaint);
276d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
277d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        fContext->drawPath(tmpPaint, *glyph->fPath, strokeInfo);
278d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        return;
279d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
280d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
281d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.comHAS_ATLAS:
282d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    SkASSERT(glyph->fPlot);
283d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
284d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    glyph->fPlot->setDrawToken(drawToken);
285d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
286d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrTexture* texture = glyph->fPlot->texture();
287d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    SkASSERT(texture);
288d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
289d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (fCurrTexture != texture || fCurrVertex + 4 > fMaxVertices) {
290d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        this->flushGlyphs();
291d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fCurrTexture = texture;
292d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fCurrTexture->ref();
293d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
294d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
295d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (NULL == fVertices) {
296d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com       // If we need to reserve vertices allow the draw target to suggest
297d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // a number of verts to reserve and whether to perform a flush.
298d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fMaxVertices = kMinRequestedVerts;
299d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
300d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            SK_ARRAY_COUNT(gTextVertexAttribs));
301d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bool flush = fDrawTarget->geometryHints(&fMaxVertices, NULL);
302d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (flush) {
303d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            this->flushGlyphs();
304d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            fContext->flush();
305d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            fDrawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
306d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                SK_ARRAY_COUNT(gTextVertexAttribs));
307d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
308d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fMaxVertices = kDefaultRequestedVerts;
309d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // ignore return, no point in flushing again.
310d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        fDrawTarget->geometryHints(&fMaxVertices, NULL);
311d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
312d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int maxQuadVertices = 4 * fContext->getQuadIndexBuffer()->maxQuads();
313d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (fMaxVertices < kMinRequestedVerts) {
314d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            fMaxVertices = kDefaultRequestedVerts;
315d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        } else if (fMaxVertices > maxQuadVertices) {
316d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            // don't exceed the limit of the index buffer
317d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            fMaxVertices = maxQuadVertices;
318d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
319d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bool success = fDrawTarget->reserveVertexAndIndexSpace(fMaxVertices,
320d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                                               0,
321d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                                               GrTCast<void**>(&fVertices),
322d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                                               NULL);
323d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        GrAlwaysAssert(success);
324972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        SkASSERT(2*sizeof(SkPoint) == fDrawTarget->getDrawState().getVertexSize());
325d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
326d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
32764b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkScalar dx = SkIntToScalar(glyph->fBounds.fLeft + SK_DistanceFieldInset);
32864b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkScalar dy = SkIntToScalar(glyph->fBounds.fTop + SK_DistanceFieldInset);
32964b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkScalar width = SkIntToScalar(glyph->fBounds.width() - 2*SK_DistanceFieldInset);
33064b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkScalar height = SkIntToScalar(glyph->fBounds.height() - 2*SK_DistanceFieldInset);
331d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
332d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    SkScalar scale = fTextRatio;
333d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    dx *= scale;
334d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    dy *= scale;
335d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    sx += dx;
336d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    sy += dy;
337d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    width *= scale;
338d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    height *= scale;
339a3b532743dbb1d54a4c17a2574083ef93c949d50skia.committer@gmail.com
34064b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset);
34164b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY + SK_DistanceFieldInset);
34264b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkFixed tw = SkIntToFixed(glyph->fBounds.width() - 2*SK_DistanceFieldInset);
34364b08a1026851a84031713f0e12a3e59d55ce808commit-bot@chromium.org    SkFixed th = SkIntToFixed(glyph->fBounds.height() - 2*SK_DistanceFieldInset);
344d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
3456c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org    static const size_t kVertexSize = 2 * sizeof(SkPoint);
346d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fVertices[2*fCurrVertex].setRectFan(sx,
347d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                        sy,
348d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                        sx + width,
349d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                        sy + height,
3506c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org                                        kVertexSize);
351d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)),
352d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                          SkFixedToFloat(texture->normalizeFixedY(ty)),
353d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                          SkFixedToFloat(texture->normalizeFixedX(tx + tw)),
354d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                          SkFixedToFloat(texture->normalizeFixedY(ty + th)),
3556c89c34614573797ce63e429229b6f7848df0bb7commit-bot@chromium.org                                          kVertexSize);
356d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    fCurrVertex += 4;
357d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com}
3588128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
359cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.orginline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint& skPaint) {
360cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    GrTextContext::init(paint, skPaint);
361cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
362cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fStrike = NULL;
363cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
364cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fCurrTexture = NULL;
365cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fCurrVertex = 0;
366cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
367cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fVertices = NULL;
368cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fMaxVertices = 0;
369cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
370dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org    if (fSkPaint.getTextSize() <= kSmallDFFontLimit) {
371dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org        fTextRatio = fSkPaint.getTextSize()/kSmallDFFontSize;
372dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org        fSkPaint.setTextSize(SkIntToScalar(kSmallDFFontSize));
373dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org    } else if (fSkPaint.getTextSize() <= kMediumDFFontLimit) {
374dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org        fTextRatio = fSkPaint.getTextSize()/kMediumDFFontSize;
375dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org        fSkPaint.setTextSize(SkIntToScalar(kMediumDFFontSize));
376dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org    } else {
377dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org        fTextRatio = fSkPaint.getTextSize()/kLargeDFFontSize;
378dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org        fSkPaint.setTextSize(SkIntToScalar(kLargeDFFontSize));
379dc5cd8552e787ac9563e664524332037327ba6d4commit-bot@chromium.org    }
3804c18e9fbb685cccf23342757e786027a032197daskia.committer@gmail.com
381609ced42e7cebef533cf9c1622280f5cdda1faaecommit-bot@chromium.org    fUseLCDText = fSkPaint.isLCDRenderText();
382221b911f38cadfe6636bcc127c663fde548adc9askia.committer@gmail.com
383cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fSkPaint.setLCDRenderText(false);
384cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fSkPaint.setAutohinted(false);
3852d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    fSkPaint.setHinting(SkPaint::kNormal_Hinting);
3860bed43c92623c01288812aae4f5030c56608d572commit-bot@chromium.org    fSkPaint.setSubpixelText(true);
3872d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
388cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org}
389cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
390cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.orginline void GrDistanceFieldTextContext::finish() {
391cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    flushGlyphs();
392cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
393cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    GrTextContext::finish();
394cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org}
395cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
3962d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverthstatic void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache,
3972d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                const SkDeviceProperties& deviceProperties,
3982d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                GrTexture** gammaTexture) {
3992d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    if (NULL == *gammaTexture) {
4002d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        int width, height;
4012d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        size_t size;
4022d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
4032d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#ifdef SK_GAMMA_CONTRAST
4042d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkScalar contrast = SK_GAMMA_CONTRAST;
4052d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#else
4062d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkScalar contrast = 0.5f;
4072d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth#endif
4082d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkScalar paintGamma = deviceProperties.fGamma;
4092d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkScalar deviceGamma = deviceProperties.fGamma;
4102d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
4112d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        size = SkScalerContext::GetGammaLUTSize(contrast, paintGamma, deviceGamma,
4122d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                                &width, &height);
4132d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
4142d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkAutoTArray<uint8_t> data((int)size);
4152d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        SkScalerContext::GetGammaLUTData(contrast, paintGamma, deviceGamma, data.get());
4162d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
4172d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        // TODO: Update this to use the cache rather than directly creating a texture.
4182d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        GrTextureDesc desc;
4192d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        desc.fFlags = kDynamicUpdate_GrTextureFlagBit;
4202d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        desc.fWidth = width;
4212d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        desc.fHeight = height;
4222d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        desc.fConfig = kAlpha_8_GrPixelConfig;
4232d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
4242d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        *gammaTexture = context->getGpu()->createTexture(desc, NULL, 0);
4252d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        if (NULL == *gammaTexture) {
4262d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth            return;
4272d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        }
4282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
4292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth        context->writeTexturePixels(*gammaTexture,
4302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                    0, 0, width, height,
4312d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                    (*gammaTexture)->config(), data.get(), 0,
4322d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth                                    GrContext::kDontFlush_PixelOpsFlag);
4332d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    }
4342d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth}
4352d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
436cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.orgvoid GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
437cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                          const char text[], size_t byteLength,
438e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org                                          SkScalar x, SkScalar y) {
4398128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkASSERT(byteLength == 0 || text != NULL);
4408128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
441e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    // nothing to draw or can't draw
442e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/
443e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        || fSkPaint.getRasterizer()) {
4448128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        return;
4458128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    }
446e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
447cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    this->init(paint, skPaint);
448cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
4498128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkScalar sizeRatio = fTextRatio;
4508128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4518128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
4528128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4532d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    SkAutoGlyphCacheNoGamma    autoCache(fSkPaint, &fDeviceProperties, NULL);
4542d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    SkGlyphCache*              cache = autoCache.getCache();
4552d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    GrFontScaler*              fontScaler = GetGrFontScaler(cache);
4562d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
4572d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
458e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
4598128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    // need to measure first
4608128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    // TODO - generate positions and pre-load cache as well?
4618128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    const char* stop = text + byteLength;
4628128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
4638128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkFixed    stopX = 0;
4648128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkFixed    stopY = 0;
4658128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4668128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        const char* textPtr = text;
4678128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        while (textPtr < stop) {
4688128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            // don't need x, y here, since all subpixel variants will have the
4698128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            // same advance
4708128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0);
4718128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4728128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            stopX += glyph.fAdvanceX;
4738128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            stopY += glyph.fAdvanceY;
4748128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        }
4758128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkASSERT(textPtr == stop);
4768128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4778128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio;
4788128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio;
4798128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4808128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) {
4818128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            alignX = SkScalarHalf(alignX);
4828128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            alignY = SkScalarHalf(alignY);
4838128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        }
4848128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4858128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        x -= alignX;
4868128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        y -= alignY;
4878128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    }
4888128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4895408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org    SkFixed fx = SkScalarToFixed(x);
4905408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org    SkFixed fy = SkScalarToFixed(y);
4918128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkFixed fixedScale = SkScalarToFixed(sizeRatio);
4928128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    while (text < stop) {
493a9dae71210c3d4a689518ee87be6b1930d843315commit-bot@chromium.org        const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
4948128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
4958128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        if (glyph.fWidth) {
4968128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
4978128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                                glyph.getSubXFixed(),
4988128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                                glyph.getSubYFixed()),
4995408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org                                  fx,
5005408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org                                  fy,
5018128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                  fontScaler);
5028128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        }
5038128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5048128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale);
5058128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale);
5068128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    }
507cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
508cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    this->finish();
5098128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org}
5108128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
511cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.orgvoid GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
512cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                             const char text[], size_t byteLength,
5138128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                             const SkScalar pos[], SkScalar constY,
514e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org                                             int scalarsPerPosition) {
5158128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5168128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkASSERT(byteLength == 0 || text != NULL);
5178128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
5188128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5198128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    // nothing to draw
520cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) {
5218128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        return;
5228128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    }
5238128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
524cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    this->init(paint, skPaint);
525cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
5268128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
5278128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5282d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    SkAutoGlyphCacheNoGamma    autoCache(fSkPaint, &fDeviceProperties, NULL);
5292d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    SkGlyphCache*              cache = autoCache.getCache();
5302d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    GrFontScaler*              fontScaler = GetGrFontScaler(cache);
5312d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth
5322d2a68c51b4a71bd60760510bf2b2e58bc9890b2jvanverth    setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture);
533e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
5348128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    const char*        stop = text + byteLength;
5358128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5368128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) {
5378128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        while (text < stop) {
5388128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            // the last 2 parameters are ignored
5398128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
5408128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5418128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            if (glyph.fWidth) {
5428128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                SkScalar x = pos[0];
5438128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
5448128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5458128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
5468128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                                    glyph.getSubXFixed(),
5478128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                                    glyph.getSubYFixed()),
5485408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org                                      SkScalarToFixed(x),
5495408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org                                      SkScalarToFixed(y),
5508128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                      fontScaler);
5518128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            }
5528128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            pos += scalarsPerPosition;
5538128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        }
5548128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    } else {
5558128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 : 0;
5568128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        while (text < stop) {
5578128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            // the last 2 parameters are ignored
5588128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
5598128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org
5608128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            if (glyph.fWidth) {
5618128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                SkScalar x = pos[0];
5628128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                SkScalar y = scalarsPerPosition == 1 ? constY : pos[1];
56322e967228deb773e3509cbc5772963779451c191skia.committer@gmail.com
5648128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(),
5658128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                                    glyph.getSubXFixed(),
5668128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                                    glyph.getSubYFixed()),
5675408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org                                      SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift),
5685408f8ffdbca9efd787304d62dde6b142c3f0f82commit-bot@chromium.org                                      SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift),
5698128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org                                      fontScaler);
5708128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            }
5718128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org            pos += scalarsPerPosition;
5728128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org        }
5738128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org    }
574cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
575cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    this->finish();
5768128d8c119382279918b90ad8d80ccb3aaebb8a0commit-bot@chromium.org}
577