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