GrTextContext.cpp revision aab626c3670205d02ca42bb34a540f550cb75dc2
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"
10e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org
11e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org#include "SkAutoKern.h"
12e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org#include "SkGlyphCache.h"
13733f5f5dbca10fc6385ec3c77b3e9ff78227dac7jvanverth#include "GrFontScaler.h"
14ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
15cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.orgGrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
168c27a188a0b216021d439eb627622d17b9f78343jvanverth                            fFallbackTextContext(NULL),
17cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                            fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) {
18cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org}
19375ff85e96cf0f8438ea0b11be67e85474e42c29tomhudson@google.com
208c27a188a0b216021d439eb627622d17b9f78343jvanverthGrTextContext::~GrTextContext() {
218c27a188a0b216021d439eb627622d17b9f78343jvanverth    SkDELETE(fFallbackTextContext);
228c27a188a0b216021d439eb627622d17b9f78343jvanverth}
238c27a188a0b216021d439eb627622d17b9f78343jvanverth
24cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.orgvoid GrTextContext::init(const GrPaint& grPaint, const SkPaint& skPaint) {
25cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    const GrClipData* clipData = fContext->getClip();
26beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com
27fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkRect devConservativeBound;
28641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com    clipData->fClipStack->getConservativeBounds(
29641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                     -clipData->fOrigin.fX,
30641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                     -clipData->fOrigin.fY,
31cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                     fContext->getRenderTarget()->width(),
32cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org                                     fContext->getRenderTarget()->height(),
33641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com                                     &devConservativeBound);
34beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com
35641f8b19a6799b6d73ac17b9c2d2f8a5e6f5ad4drobertphillips@google.com    devConservativeBound.roundOut(&fClipRect);
36beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com
37cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fDrawTarget = fContext->getTextTarget();
38cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org
39cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fPaint = grPaint;
40cbbc481e918c0d32454455626235f67106f216a1commit-bot@chromium.org    fSkPaint = skPaint;
41ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
42e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org
438c27a188a0b216021d439eb627622d17b9f78343jvanverthbool GrTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint,
448c27a188a0b216021d439eb627622d17b9f78343jvanverth                             const char text[], size_t byteLength,
458c27a188a0b216021d439eb627622d17b9f78343jvanverth                             SkScalar x, SkScalar y) {
468c27a188a0b216021d439eb627622d17b9f78343jvanverth
47aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth    GrTextContext* textContext = this;
48aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth    do {
49aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth        if (textContext->canDraw(skPaint)) {
50aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth            textContext->onDrawText(paint, skPaint, text, byteLength, x, y);
51aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth            return true;
52aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth        }
53aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth        textContext = textContext->fFallbackTextContext;
54aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth    } while (textContext);
55aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth
56aab626c3670205d02ca42bb34a540f550cb75dc2jvanverth    return false;
578c27a188a0b216021d439eb627622d17b9f78343jvanverth}
588c27a188a0b216021d439eb627622d17b9f78343jvanverth
598c27a188a0b216021d439eb627622d17b9f78343jvanverthbool GrTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint,
608c27a188a0b216021d439eb627622d17b9f78343jvanverth                                const char text[], size_t byteLength,
618c27a188a0b216021d439eb627622d17b9f78343jvanverth                                const SkScalar pos[], int scalarsPerPosition,
628c27a188a0b216021d439eb627622d17b9f78343jvanverth                                const SkPoint& offset) {
638c27a188a0b216021d439eb627622d17b9f78343jvanverth
648c27a188a0b216021d439eb627622d17b9f78343jvanverth    GrTextContext* textContext = this;
658c27a188a0b216021d439eb627622d17b9f78343jvanverth    do {
668c27a188a0b216021d439eb627622d17b9f78343jvanverth        if (textContext->canDraw(skPaint)) {
678c27a188a0b216021d439eb627622d17b9f78343jvanverth            textContext->onDrawPosText(paint, skPaint, text, byteLength, pos, scalarsPerPosition,
688c27a188a0b216021d439eb627622d17b9f78343jvanverth                                     offset);
698c27a188a0b216021d439eb627622d17b9f78343jvanverth            return true;
708c27a188a0b216021d439eb627622d17b9f78343jvanverth        }
718c27a188a0b216021d439eb627622d17b9f78343jvanverth        textContext = textContext->fFallbackTextContext;
728c27a188a0b216021d439eb627622d17b9f78343jvanverth    } while (textContext);
738c27a188a0b216021d439eb627622d17b9f78343jvanverth
748c27a188a0b216021d439eb627622d17b9f78343jvanverth    return false;
758c27a188a0b216021d439eb627622d17b9f78343jvanverth}
768c27a188a0b216021d439eb627622d17b9f78343jvanverth
778c27a188a0b216021d439eb627622d17b9f78343jvanverth
78e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org//*** change to output positions?
79e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.orgvoid GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
80e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org                                const char text[], size_t byteLength, SkVector* stopVector) {
81e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    SkFixed     x = 0, y = 0;
82e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    const char* stop = text + byteLength;
83e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
84e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    SkAutoKern  autokern;
85e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
86e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    while (text < stop) {
87e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        // don't need x, y here, since all subpixel variants will have the
88e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        // same advance
89e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
90e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
91e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        x += autokern.adjust(glyph) + glyph.fAdvanceX;
92e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        y += glyph.fAdvanceY;
93e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    }
94e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    stopVector->set(SkFixedToScalar(x), SkFixedToScalar(y));
95e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
96e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    SkASSERT(text == stop);
97e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org}
98e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org
99e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.orgstatic void GlyphCacheAuxProc(void* data) {
100e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    GrFontScaler* scaler = (GrFontScaler*)data;
101e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    SkSafeUnref(scaler);
102e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org}
103e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org
104e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.orgGrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) {
105e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    void* auxData;
106e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    GrFontScaler* scaler = NULL;
107e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
108e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) {
109e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        scaler = (GrFontScaler*)auxData;
110e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    }
111e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    if (NULL == scaler) {
112733f5f5dbca10fc6385ec3c77b3e9ff78227dac7jvanverth        scaler = SkNEW_ARGS(GrFontScaler, (cache));
113e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org        cache->setAuxProc(GlyphCacheAuxProc, scaler);
114e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    }
115e5d7015cde3b6f2a3929b8e378822e3d7be223d4skia.committer@gmail.com
116e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org    return scaler;
117e8612d9a8d616c2ed0195421a0675e10b0c2d230commit-bot@chromium.org}
118