1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 8375ff85e96cf0f8438ea0b11be67e85474e42c29tomhudson@google.com#include "GrTextContext.h" 9e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org#include "GrContext.h" 10570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt#include "GrDrawTarget.h" 11570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt#include "GrFontScaler.h" 12e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org 13e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org#include "SkAutoKern.h" 149c328187d9dee33736b77dc14dfb59529d948bb1joshualitt#include "SkDrawFilter.h" 156e8cd9671958c69babde9338c5c18a4c3d895575joshualitt#include "SkDrawProcs.h" 16e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org#include "SkGlyphCache.h" 176e8cd9671958c69babde9338c5c18a4c3d895575joshualitt#include "SkGpuDevice.h" 189c328187d9dee33736b77dc14dfb59529d948bb1joshualitt#include "SkTextBlob.h" 196e8cd9671958c69babde9338c5c18a4c3d895575joshualitt#include "SkTextMapStateProc.h" 206e8cd9671958c69babde9338c5c18a4c3d895575joshualitt#include "SkTextToPathIter.h" 216e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 226e8cd9671958c69babde9338c5c18a4c3d895575joshualittGrTextContext::GrTextContext(GrContext* context, SkGpuDevice* gpuDevice, 236e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkDeviceProperties& properties) 246e8cd9671958c69babde9338c5c18a4c3d895575joshualitt : fFallbackTextContext(NULL) 256e8cd9671958c69babde9338c5c18a4c3d895575joshualitt , fContext(context) 266e8cd9671958c69babde9338c5c18a4c3d895575joshualitt , fGpuDevice(gpuDevice) 276e8cd9671958c69babde9338c5c18a4c3d895575joshualitt , fDeviceProperties(properties) 286e8cd9671958c69babde9338c5c18a4c3d895575joshualitt , fDrawTarget(NULL) { 29cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org} 30375ff85e96cf0f8438ea0b11be67e85474e42c29tomhudson@google.com 318c27a188a0b216021d439eb627622d17b9f78343jvanverthGrTextContext::~GrTextContext() { 328c27a188a0b216021d439eb627622d17b9f78343jvanverth SkDELETE(fFallbackTextContext); 338c27a188a0b216021d439eb627622d17b9f78343jvanverth} 348c27a188a0b216021d439eb627622d17b9f78343jvanverth 35570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualittvoid GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint, 366e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkPaint& skPaint, const SkIRect& regionClipBounds) { 37570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt fClip = clip; 38beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com 3925d9c154087d2132a51d1ca74a104726f60ef380joshualitt fRenderTarget.reset(SkRef(rt)); 4025d9c154087d2132a51d1ca74a104726f60ef380joshualitt 416e8cd9671958c69babde9338c5c18a4c3d895575joshualitt fRegionClipBounds = regionClipBounds; 42570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect); 43beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com 44cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org fDrawTarget = fContext->getTextTarget(); 45cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org 46cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org fPaint = grPaint; 47cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org fSkPaint = skPaint; 48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 49e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org 506e8cd9671958c69babde9338c5c18a4c3d895575joshualittvoid GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, 51570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const SkPaint& skPaint, const SkMatrix& viewMatrix, 528c27a188a0b216021d439eb627622d17b9f78343jvanverth const char text[], size_t byteLength, 536e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkScalar x, SkScalar y, const SkIRect& clipBounds) { 545f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt if (!fContext->getTextTarget()) { 556e8cd9671958c69babde9338c5c18a4c3d895575joshualitt return; 565f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt } 578c27a188a0b216021d439eb627622d17b9f78343jvanverth 58aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth GrTextContext* textContext = this; 59aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth do { 60e68f7362b1e00e88688906de6384e4e5a83076d0cdalton if (textContext->canDraw(rt, clip, paint, skPaint, viewMatrix)) { 616e8cd9671958c69babde9338c5c18a4c3d895575joshualitt textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, x, y, 626e8cd9671958c69babde9338c5c18a4c3d895575joshualitt clipBounds); 636e8cd9671958c69babde9338c5c18a4c3d895575joshualitt return; 64aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth } 65aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth textContext = textContext->fFallbackTextContext; 66aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth } while (textContext); 67aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth 686e8cd9671958c69babde9338c5c18a4c3d895575joshualitt // fall back to drawing as a path 6979dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt SkASSERT(fGpuDevice); 706e8cd9671958c69babde9338c5c18a4c3d895575joshualitt this->drawTextAsPath(skPaint, viewMatrix, text, byteLength, x, y, clipBounds); 718c27a188a0b216021d439eb627622d17b9f78343jvanverth} 728c27a188a0b216021d439eb627622d17b9f78343jvanverth 736e8cd9671958c69babde9338c5c18a4c3d895575joshualittvoid GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint, 74570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt const SkPaint& skPaint, const SkMatrix& viewMatrix, 758c27a188a0b216021d439eb627622d17b9f78343jvanverth const char text[], size_t byteLength, 768c27a188a0b216021d439eb627622d17b9f78343jvanverth const SkScalar pos[], int scalarsPerPosition, 776e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkPoint& offset, const SkIRect& clipBounds) { 785f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt if (!fContext->getTextTarget()) { 796e8cd9671958c69babde9338c5c18a4c3d895575joshualitt return; 805f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt } 818c27a188a0b216021d439eb627622d17b9f78343jvanverth 828c27a188a0b216021d439eb627622d17b9f78343jvanverth GrTextContext* textContext = this; 838c27a188a0b216021d439eb627622d17b9f78343jvanverth do { 84e68f7362b1e00e88688906de6384e4e5a83076d0cdalton if (textContext->canDraw(rt, clip, paint, skPaint, viewMatrix)) { 85570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, pos, 866e8cd9671958c69babde9338c5c18a4c3d895575joshualitt scalarsPerPosition, offset, clipBounds); 876e8cd9671958c69babde9338c5c18a4c3d895575joshualitt return; 888c27a188a0b216021d439eb627622d17b9f78343jvanverth } 898c27a188a0b216021d439eb627622d17b9f78343jvanverth textContext = textContext->fFallbackTextContext; 908c27a188a0b216021d439eb627622d17b9f78343jvanverth } while (textContext); 918c27a188a0b216021d439eb627622d17b9f78343jvanverth 926e8cd9671958c69babde9338c5c18a4c3d895575joshualitt // fall back to drawing as a path 9379dfb2b6b6db7b2e703810d26dbdc90cf3ea40f9joshualitt SkASSERT(fGpuDevice); 946e8cd9671958c69babde9338c5c18a4c3d895575joshualitt this->drawPosTextAsPath(skPaint, viewMatrix, text, byteLength, pos, scalarsPerPosition, offset, 956e8cd9671958c69babde9338c5c18a4c3d895575joshualitt clipBounds); 968c27a188a0b216021d439eb627622d17b9f78343jvanverth} 978c27a188a0b216021d439eb627622d17b9f78343jvanverth 989c328187d9dee33736b77dc14dfb59529d948bb1joshualittvoid GrTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, const SkPaint& skPaint, 999c328187d9dee33736b77dc14dfb59529d948bb1joshualitt const SkMatrix& viewMatrix, const SkTextBlob* blob, 1009c328187d9dee33736b77dc14dfb59529d948bb1joshualitt SkScalar x, SkScalar y, 1019c328187d9dee33736b77dc14dfb59529d948bb1joshualitt SkDrawFilter* drawFilter, const SkIRect& clipBounds) { 102e68f7362b1e00e88688906de6384e4e5a83076d0cdalton SkPaint runPaint = skPaint; 1039c328187d9dee33736b77dc14dfb59529d948bb1joshualitt 104e68f7362b1e00e88688906de6384e4e5a83076d0cdalton SkTextBlob::RunIterator it(blob); 105e68f7362b1e00e88688906de6384e4e5a83076d0cdalton for (;!it.done(); it.next()) { 106e68f7362b1e00e88688906de6384e4e5a83076d0cdalton size_t textLen = it.glyphCount() * sizeof(uint16_t); 107e68f7362b1e00e88688906de6384e4e5a83076d0cdalton const SkPoint& offset = it.offset(); 108e68f7362b1e00e88688906de6384e4e5a83076d0cdalton // applyFontToPaint() always overwrites the exact same attributes, 109e68f7362b1e00e88688906de6384e4e5a83076d0cdalton // so it is safe to not re-seed the paint for this reason. 110e68f7362b1e00e88688906de6384e4e5a83076d0cdalton it.applyFontToPaint(&runPaint); 111e68f7362b1e00e88688906de6384e4e5a83076d0cdalton 112e68f7362b1e00e88688906de6384e4e5a83076d0cdalton if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Type)) { 113e68f7362b1e00e88688906de6384e4e5a83076d0cdalton // A false return from filter() means we should abort the current draw. 114e68f7362b1e00e88688906de6384e4e5a83076d0cdalton runPaint = skPaint; 115e68f7362b1e00e88688906de6384e4e5a83076d0cdalton continue; 1169c328187d9dee33736b77dc14dfb59529d948bb1joshualitt } 117e68f7362b1e00e88688906de6384e4e5a83076d0cdalton 118e68f7362b1e00e88688906de6384e4e5a83076d0cdalton runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); 119e68f7362b1e00e88688906de6384e4e5a83076d0cdalton 120e68f7362b1e00e88688906de6384e4e5a83076d0cdalton GrPaint grPaint; 121bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon if (!SkPaint2GrPaint(fContext, fRenderTarget, runPaint, viewMatrix, true, &grPaint)) { 122bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon return; 123bed83a66f5fa5821a3a08da32157a6155960b15ebsalomon } 124e68f7362b1e00e88688906de6384e4e5a83076d0cdalton 125e68f7362b1e00e88688906de6384e4e5a83076d0cdalton switch (it.positioning()) { 126e68f7362b1e00e88688906de6384e4e5a83076d0cdalton case SkTextBlob::kDefault_Positioning: 127e68f7362b1e00e88688906de6384e4e5a83076d0cdalton this->drawText(rt, clip, grPaint, runPaint, viewMatrix, (const char *)it.glyphs(), 128e68f7362b1e00e88688906de6384e4e5a83076d0cdalton textLen, x + offset.x(), y + offset.y(), clipBounds); 129e68f7362b1e00e88688906de6384e4e5a83076d0cdalton break; 130e68f7362b1e00e88688906de6384e4e5a83076d0cdalton case SkTextBlob::kHorizontal_Positioning: 131e68f7362b1e00e88688906de6384e4e5a83076d0cdalton this->drawPosText(rt, clip, grPaint, runPaint, viewMatrix, (const char*)it.glyphs(), 132e68f7362b1e00e88688906de6384e4e5a83076d0cdalton textLen, it.pos(), 1, SkPoint::Make(x, y + offset.y()), clipBounds); 133e68f7362b1e00e88688906de6384e4e5a83076d0cdalton break; 134e68f7362b1e00e88688906de6384e4e5a83076d0cdalton case SkTextBlob::kFull_Positioning: 135e68f7362b1e00e88688906de6384e4e5a83076d0cdalton this->drawPosText(rt, clip, grPaint, runPaint, viewMatrix, (const char*)it.glyphs(), 136e68f7362b1e00e88688906de6384e4e5a83076d0cdalton textLen, it.pos(), 2, SkPoint::Make(x, y), clipBounds); 137e68f7362b1e00e88688906de6384e4e5a83076d0cdalton break; 138e68f7362b1e00e88688906de6384e4e5a83076d0cdalton default: 139e68f7362b1e00e88688906de6384e4e5a83076d0cdalton SkFAIL("unhandled positioning mode"); 140e68f7362b1e00e88688906de6384e4e5a83076d0cdalton } 141e68f7362b1e00e88688906de6384e4e5a83076d0cdalton 142e68f7362b1e00e88688906de6384e4e5a83076d0cdalton if (drawFilter) { 143e68f7362b1e00e88688906de6384e4e5a83076d0cdalton // A draw filter may change the paint arbitrarily, so we must re-seed in this case. 144e68f7362b1e00e88688906de6384e4e5a83076d0cdalton runPaint = skPaint; 145e68f7362b1e00e88688906de6384e4e5a83076d0cdalton } 146e68f7362b1e00e88688906de6384e4e5a83076d0cdalton } 1479c328187d9dee33736b77dc14dfb59529d948bb1joshualitt} 1489c328187d9dee33736b77dc14dfb59529d948bb1joshualitt 1496e8cd9671958c69babde9338c5c18a4c3d895575joshualittvoid GrTextContext::drawTextAsPath(const SkPaint& skPaint, const SkMatrix& viewMatrix, 1506e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const char text[], size_t byteLength, SkScalar x, SkScalar y, 1516e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkIRect& clipBounds) { 1526e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkTextToPathIter iter(text, byteLength, skPaint, true); 1536e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1546e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkMatrix matrix; 1556e8cd9671958c69babde9338c5c18a4c3d895575joshualitt matrix.setScale(iter.getPathScale(), iter.getPathScale()); 1566e8cd9671958c69babde9338c5c18a4c3d895575joshualitt matrix.postTranslate(x, y); 1576e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1586e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkPath* iterPath; 1596e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkScalar xpos, prevXPos = 0; 1606e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1616e8cd9671958c69babde9338c5c18a4c3d895575joshualitt while (iter.next(&iterPath, &xpos)) { 1626e8cd9671958c69babde9338c5c18a4c3d895575joshualitt matrix.postTranslate(xpos - prevXPos, 0); 1636e8cd9671958c69babde9338c5c18a4c3d895575joshualitt if (iterPath) { 1646e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkPaint& pnt = iter.getPaint(); 1656e8cd9671958c69babde9338c5c18a4c3d895575joshualitt fGpuDevice->internalDrawPath(*iterPath, pnt, viewMatrix, &matrix, clipBounds, false); 1666e8cd9671958c69babde9338c5c18a4c3d895575joshualitt } 1676e8cd9671958c69babde9338c5c18a4c3d895575joshualitt prevXPos = xpos; 1686e8cd9671958c69babde9338c5c18a4c3d895575joshualitt } 1696e8cd9671958c69babde9338c5c18a4c3d895575joshualitt} 1706e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1716e8cd9671958c69babde9338c5c18a4c3d895575joshualittvoid GrTextContext::drawPosTextAsPath(const SkPaint& origPaint, const SkMatrix& viewMatrix, 1726e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const char text[], size_t byteLength, 1736e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkScalar pos[], int scalarsPerPosition, 1746e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkPoint& offset, const SkIRect& clipBounds) { 1756e8cd9671958c69babde9338c5c18a4c3d895575joshualitt // setup our std paint, in hopes of getting hits in the cache 1766e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkPaint paint(origPaint); 1776e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkScalar matrixScale = paint.setupForAsPaths(); 1786e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1796e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkMatrix matrix; 1806e8cd9671958c69babde9338c5c18a4c3d895575joshualitt matrix.setScale(matrixScale, matrixScale); 1816e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1826e8cd9671958c69babde9338c5c18a4c3d895575joshualitt // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache. 1836e8cd9671958c69babde9338c5c18a4c3d895575joshualitt paint.setStyle(SkPaint::kFill_Style); 1846e8cd9671958c69babde9338c5c18a4c3d895575joshualitt paint.setPathEffect(NULL); 1856e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1866e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); 1876e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkAutoGlyphCache autoCache(paint, NULL, NULL); 1886e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkGlyphCache* cache = autoCache.getCache(); 1896e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1906e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const char* stop = text + byteLength; 1916e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkTextAlignProc alignProc(paint.getTextAlign()); 1926e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); 1936e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1946e8cd9671958c69babde9338c5c18a4c3d895575joshualitt // Now restore the original settings, so we "draw" with whatever style/stroking. 1956e8cd9671958c69babde9338c5c18a4c3d895575joshualitt paint.setStyle(origPaint.getStyle()); 1966e8cd9671958c69babde9338c5c18a4c3d895575joshualitt paint.setPathEffect(origPaint.getPathEffect()); 1976e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 1986e8cd9671958c69babde9338c5c18a4c3d895575joshualitt while (text < stop) { 1996e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 2006e8cd9671958c69babde9338c5c18a4c3d895575joshualitt if (glyph.fWidth) { 2016e8cd9671958c69babde9338c5c18a4c3d895575joshualitt const SkPath* path = cache->findPath(glyph); 2026e8cd9671958c69babde9338c5c18a4c3d895575joshualitt if (path) { 2036e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkPoint tmsLoc; 2046e8cd9671958c69babde9338c5c18a4c3d895575joshualitt tmsProc(pos, &tmsLoc); 2056e8cd9671958c69babde9338c5c18a4c3d895575joshualitt SkPoint loc; 2066e8cd9671958c69babde9338c5c18a4c3d895575joshualitt alignProc(tmsLoc, glyph, &loc); 2076e8cd9671958c69babde9338c5c18a4c3d895575joshualitt 2086e8cd9671958c69babde9338c5c18a4c3d895575joshualitt matrix[SkMatrix::kMTransX] = loc.fX; 2096e8cd9671958c69babde9338c5c18a4c3d895575joshualitt matrix[SkMatrix::kMTransY] = loc.fY; 2106e8cd9671958c69babde9338c5c18a4c3d895575joshualitt fGpuDevice->internalDrawPath(*path, paint, viewMatrix, &matrix, clipBounds, false); 2116e8cd9671958c69babde9338c5c18a4c3d895575joshualitt } 2126e8cd9671958c69babde9338c5c18a4c3d895575joshualitt } 2136e8cd9671958c69babde9338c5c18a4c3d895575joshualitt pos += scalarsPerPosition; 2146e8cd9671958c69babde9338c5c18a4c3d895575joshualitt } 2156e8cd9671958c69babde9338c5c18a4c3d895575joshualitt} 2168c27a188a0b216021d439eb627622d17b9f78343jvanverth 217e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org//*** change to output positions? 21873f105345066b1f22f15ba6575cb3800dd9313b8jvanverthint GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, 219e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org const char text[], size_t byteLength, SkVector* stopVector) { 220e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org SkFixed x = 0, y = 0; 221e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org const char* stop = text + byteLength; 222e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com 223e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org SkAutoKern autokern; 224e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com 22573f105345066b1f22f15ba6575cb3800dd9313b8jvanverth int numGlyphs = 0; 226e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org while (text < stop) { 227e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org // don't need x, y here, since all subpixel variants will have the 228e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org // same advance 229e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); 230e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com 231e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org x += autokern.adjust(glyph) + glyph.fAdvanceX; 232e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org y += glyph.fAdvanceY; 23373f105345066b1f22f15ba6575cb3800dd9313b8jvanverth ++numGlyphs; 234e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org } 235e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y)); 236e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com 237e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org SkASSERT(text == stop); 23873f105345066b1f22f15ba6575cb3800dd9313b8jvanverth 23973f105345066b1f22f15ba6575cb3800dd9313b8jvanverth return numGlyphs; 240e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org} 241e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org 242e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.orgstatic void GlyphCacheAuxProc(void* data) { 243e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org GrFontScaler* scaler = (GrFontScaler*)data; 244e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org SkSafeUnref(scaler); 245e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org} 246e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org 247e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.orgGrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { 248e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org void* auxData; 249e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org GrFontScaler* scaler = NULL; 250e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com 251e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { 252e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org scaler = (GrFontScaler*)auxData; 253e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org } 254e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org if (NULL == scaler) { 255733f5f5dbca10fc6385ec3c77b3e9ff78227dac7jvanverth scaler = SkNEW_ARGS(GrFontScaler, (cache)); 256e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org cache->setAuxProc(GlyphCacheAuxProc, scaler); 257e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org } 258e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com 259e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org return scaler; 260e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org} 261