GrTextStrike.cpp revision c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0
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
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrAtlas.h"
9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrGpu.h"
10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrRectanizer.h"
11ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTextStrike.h"
12ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrTextStrike_impl.h"
1303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#include "SkString.h"
14ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
15d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
16d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#include "edtaa3.h"
17d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
18d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
19fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com///////////////////////////////////////////////////////////////////////////////
20fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
2167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#define FONT_CACHE_STATS 0
2267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
2367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic int g_PurgeCount = 0;
2467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
2567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
27ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gpu->ref();
28f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    for (int i = 0; i < kAtlasCount; ++i) {
293fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        fAtlasMgr[i] = NULL;
303fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    }
31ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
32ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fHead = fTail = NULL;
33ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::~GrFontCache() {
36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.deleteAll();
37f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    for (int i = 0; i < kAtlasCount; ++i) {
383fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        delete fAtlasMgr[i];
393fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    }
40ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGpu->unref();
4167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
4267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org      GrPrintf("Num purges: %d\n", g_PurgeCount);
4367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
44ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
45ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
46952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.orgstatic GrPixelConfig mask_format_to_pixel_config(GrMaskFormat format) {
476e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com    static const GrPixelConfig sPixelConfigs[] = {
486e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com        kAlpha_8_GrPixelConfig,
496e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com        kRGB_565_GrPixelConfig,
50f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org        kSkia8888_GrPixelConfig,
51f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org        kSkia8888_GrPixelConfig
52f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    };
53f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sPixelConfigs) == kMaskFormatCount, array_size_mismatch);
54f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org
55f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    return sPixelConfigs[format];
56f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org}
57f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org
58f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.orgstatic int mask_format_to_atlas_index(GrMaskFormat format) {
596e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com    static const int sAtlasIndices[] = {
606e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com        GrFontCache::kA8_AtlasType,
616e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com        GrFontCache::k565_AtlasType,
626e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com        GrFontCache::k8888_AtlasType,
636e515d67d2365ecd05fb80762eeb76c55e81368cskia.committer@gmail.com        GrFontCache::k8888_AtlasType
64f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    };
65f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    SK_COMPILE_ASSERT(SK_ARRAY_COUNT(sAtlasIndices) == kMaskFormatCount, array_size_mismatch);
66f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org
67f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    SkASSERT(sAtlasIndices[format] < GrFontCache::kAtlasCount);
68f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    return sAtlasIndices[format];
69952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org}
70952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org
71ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                          const Key& key) {
733fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    GrMaskFormat format = scaler->getMaskFormat();
74952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org    GrPixelConfig config = mask_format_to_pixel_config(format);
75f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    int atlasIndex = mask_format_to_atlas_index(format);
76f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    if (NULL == fAtlasMgr[atlasIndex]) {
77f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org        fAtlasMgr[atlasIndex] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config));
78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
79c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com    GrTextStrike* strike = SkNEW_ARGS(GrTextStrike,
80f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org                                      (this, scaler->getKey(), format, fAtlasMgr[atlasIndex]));
81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.insert(key, strike);
82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
83ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (fHead) {
84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fHead->fPrev = strike;
85ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
86f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(NULL == fTail);
87ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fTail = strike;
88ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
89ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike->fPrev = NULL;
90ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike->fNext = fHead;
91ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fHead = strike;
92ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return strike;
94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
96ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::freeAll() {
97ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.deleteAll();
98f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    for (int i = 0; i < kAtlasCount; ++i) {
993fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        delete fAtlasMgr[i];
1003fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        fAtlasMgr[i] = NULL;
1013fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    }
1028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fHead = NULL;
1038fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fTail = NULL;
104ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
105ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
106b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.orgvoid GrFontCache::purgeStrike(GrTextStrike* strike) {
107b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    const GrFontCache::Key key(strike->fFontScalerKey);
108b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    fCache.remove(key, strike);
109b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    this->detachStrikeFromList(strike);
110b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    delete strike;
111b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org}
112b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org
113c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.orgbool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) {
114bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com    SkASSERT(NULL != preserveStrike);
115c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org
116c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    GrAtlasMgr* atlasMgr = preserveStrike->fAtlasMgr;
117c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    GrPlot* plot = atlasMgr->getUnusedPlot();
118c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    if (NULL == plot) {
119c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        return false;
120c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    }
121c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    plot->resetRects();
122c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org
123c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    GrTextStrike* strike = fHead;
124bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com    GrMaskFormat maskFormat = preserveStrike->fMaskFormat;
12567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    while (strike) {
126c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        if (maskFormat != strike->fMaskFormat) {
127c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org            strike = strike->fNext;
12867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            continue;
12967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
130c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org
13167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        GrTextStrike* strikeToPurge = strike;
132c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        strike = strikeToPurge->fNext;
133c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        strikeToPurge->removePlot(plot);
134c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org
135c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        // clear out any empty strikes (except this one)
136c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        if (strikeToPurge != preserveStrike && strikeToPurge->fAtlas.isEmpty()) {
137b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org            this->purgeStrike(strikeToPurge);
13867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
13967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    }
140c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org
14167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
14267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    ++g_PurgeCount;
14367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
14467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
145c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    return true;
146ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
147ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
148515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
149ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::validate() const {
150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count = fCache.count();
151ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (0 == count) {
152f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!fHead);
153f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!fTail);
154ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else if (1 == count) {
155f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fHead == fTail);
156ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
157f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fHead != fTail);
158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count2 = 0;
161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const GrTextStrike* strike = fHead;
162ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fNext;
165ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
166f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(count == count2);
167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    count2 = 0;
169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike = fTail;
170ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
171ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
172ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fPrev;
173ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
174f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(count == count2);
175ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
177ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
17803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#ifdef SK_DEVELOPER
17903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.orgvoid GrFontCache::dump() const {
18003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org    static int gDumpCount = 0;
181f8cb184095946ebf8f183d253e27bd544a19f23ccommit-bot@chromium.org    for (int i = 0; i < kAtlasCount; ++i) {
18203e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org        if (NULL != fAtlasMgr[i]) {
18303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org            GrTexture* texture = fAtlasMgr[i]->getTexture();
18403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org            if (NULL != texture) {
18503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org                SkString filename;
18603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org                filename.printf("fontcache_%d%d.png", gDumpCount, i);
18703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org                texture->savePixels(filename.c_str());
18803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org            }
18903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org        }
19003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org    }
19103e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org    ++gDumpCount;
19203e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org}
19303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#endif
19403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org
195ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com///////////////////////////////////////////////////////////////////////////////
196ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
197515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
198ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    static int gCounter;
199ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
200ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
201d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
202d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#define DISTANCE_FIELD_PAD   4
203d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#define DISTANCE_FIELD_RANGE (4.0)
204d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
205d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
206ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/*
207ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    The text strike is specific to a given font/style/matrix setup, which is
208ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    represented by the GrHostFontScaler object we are given in getGlyph().
209ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    We map a 32bit glyphID to a GrGlyph record, which in turn points to a
211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    atlas and a position within that texture.
212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
213ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
214ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
21598539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                           GrMaskFormat format,
216c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org                           GrAtlasMgr* atlasMgr) : fPool(64) {
217ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey = key;
218ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->ref();
219ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
220ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontCache = cache;     // no need to ref, it won't go away before we do
221ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
222ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
22398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    fMaskFormat = format;
22498539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
225515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
2263ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
227ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter += 1;
228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
229ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
230ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
231c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org// this signature is needed because it's used with
232c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org// SkTDArray::visitAll() (see destructor)
23367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void free_glyph(GrGlyph*& glyph) { glyph->free(); }
23467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
235ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::~GrTextStrike() {
236ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->unref();
23767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    fCache.getArray().visitAll(free_glyph);
238ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
239515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
240ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter -= 1;
2413ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf("~GrTextStrike %p %d\n", this, gCounter);
242ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
244ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
245ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
246ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                     GrFontScaler* scaler) {
247fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkIRect bounds;
248ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
249ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return NULL;
250ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
252ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrGlyph* glyph = fPool.alloc();
253d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
254d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    // expand bounds to hold full distance field data
255d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (fUseDistanceField) {
256d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fLeft   -= DISTANCE_FIELD_PAD;
257d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fRight  += DISTANCE_FIELD_PAD;
258d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fTop    -= DISTANCE_FIELD_PAD;
259d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fBottom += DISTANCE_FIELD_PAD;
260d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
261d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
262ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    glyph->init(packed, bounds);
263ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.insert(packed, glyph);
264ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return glyph;
265ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
266ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
267c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.orgvoid GrTextStrike::removePlot(const GrPlot* plot) {
268c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    SkTDArray<GrGlyph*>& glyphArray = fCache.getArray();
269c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    for (int i = 0; i < glyphArray.count(); ++i) {
270c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        if (plot == glyphArray[i]->fPlot) {
271c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org            glyphArray[i]->fPlot = NULL;
272c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org        }
273c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    }
274c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org
275c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.org    fAtlasMgr->removePlot(&fAtlas, plot);
27667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
27767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
278d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
279c9b2c885be8d2bb39f1d75cc316278fa8d0fa9f0commit-bot@chromium.orgbool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
2800ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#if 0   // testing hack to force us to flush our cache often
2810ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    static int gCounter;
2820ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    if ((++gCounter % 10) == 0) return false;
2830ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#endif
2840ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com
285f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(glyph);
286f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(scaler);
287f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fCache.contains(glyph));
28849e80830e9c633dcb8e7596bda17ea004ae48bd4commit-bot@chromium.org    SkASSERT(NULL == glyph->fPlot);
289ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
290a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkAutoRef ar(scaler);
29198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
29298539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
293d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
294d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrPlot* plot;
295d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
296d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (fUseDistanceField) {
297d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkASSERT(1 == bytesPerPixel);
298d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
299d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // we've already expanded the glyph dimensions to match the final size
300d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // but must shrink back down to get the packed glyph data
301d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int dfWidth = glyph->width();
302d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int dfHeight = glyph->height();
303d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int width = dfWidth - 2*DISTANCE_FIELD_PAD;
304d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int height = dfHeight - 2*DISTANCE_FIELD_PAD;
305d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t stride = width*bytesPerPixel;
306d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
307d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t size = width * height * bytesPerPixel;
308d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> storage(size);
309d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride, storage.get())) {
310d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            return false;
311d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
312d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
313d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // alloc storage for distance field glyph
314d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t dfSize = dfWidth * dfHeight * bytesPerPixel;
315d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> dfStorage(dfSize);
316d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
317d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // copy glyph into distance field storage
318d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        sk_bzero(dfStorage.get(), dfSize);
319d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
320d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        unsigned char* ptr = (unsigned char*) storage.get();
321d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        unsigned char* dfPtr = (unsigned char*) dfStorage.get();
322d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t dfStride = dfWidth*bytesPerPixel;
323d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr += DISTANCE_FIELD_PAD*dfStride;
324d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr += DISTANCE_FIELD_PAD*bytesPerPixel;
325d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
326d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        for (int i = 0; i < height; ++i) {
327d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            memcpy(dfPtr, ptr, stride);
328d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
329d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            dfPtr += dfStride;
330d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            ptr += stride;
331d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
332d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
333d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // generate distance field data
334d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> distXStorage(dfWidth*dfHeight*sizeof(short));
335d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> distYStorage(dfWidth*dfHeight*sizeof(short));
336d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> outerDistStorage(dfWidth*dfHeight*sizeof(double));
337d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> innerDistStorage(dfWidth*dfHeight*sizeof(double));
338d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> gxStorage(dfWidth*dfHeight*sizeof(double));
339d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> gyStorage(dfWidth*dfHeight*sizeof(double));
340d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
341d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        short* distX = (short*) distXStorage.get();
342d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        short* distY = (short*) distYStorage.get();
343d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* outerDist = (double*) outerDistStorage.get();
344d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* innerDist = (double*) innerDistStorage.get();
345d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* gx = (double*) gxStorage.get();
346d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* gy = (double*) gyStorage.get();
347d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
348d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr = (unsigned char*) dfStorage.get();
349d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
350d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, outerDist);
351d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
352d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        for (int i = 0; i < dfWidth*dfHeight; ++i) {
353d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            *dfPtr = 255 - *dfPtr;
354d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            dfPtr++;
355d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
356d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr = (unsigned char*) dfStorage.get();
357d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        sk_bzero(gx, sizeof(double)*dfWidth*dfHeight);
358d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        sk_bzero(gy, sizeof(double)*dfWidth*dfHeight);
359d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
360d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, innerDist);
361d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
362d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        for (int i = 0; i < dfWidth*dfHeight; ++i) {
363d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            unsigned char val;
364d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            double outerval = outerDist[i];
36511a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (outerval < 0.0) {
36611a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                outerval = 0.0;
367d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
368d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            double innerval = innerDist[i];
36911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com            if (innerval < 0.0) {
37011a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                innerval = 0.0;
371d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
372d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            double dist = outerval - innerval;
373d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            if (dist <= -DISTANCE_FIELD_RANGE) {
374d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                val = 255;
375d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            } else if (dist > DISTANCE_FIELD_RANGE) {
376d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                val = 0;
377d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            } else {
378d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                val = (unsigned char)((DISTANCE_FIELD_RANGE-dist)*128.0/DISTANCE_FIELD_RANGE);
379d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
380d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            *dfPtr++ = val;
381d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
38211a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com
383d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // copy to atlas
38411a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get(),
385d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                     &glyph->fAtlasLocation);
386d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
387d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    } else {
388d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
389d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t size = glyph->fBounds.area() * bytesPerPixel;
390d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> storage(size);
391d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
392d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                         glyph->height(),
393d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                         glyph->width() * bytesPerPixel,
394d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                         storage.get())) {
395d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            return false;
396d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
397d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
39811a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com        plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
39911a253b686d2f6e9def2de8a4507591fcadfe987skia.committer@gmail.com                                     glyph->height(), storage.get(),
400d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                     &glyph->fAtlasLocation);
401d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
402ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
403d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
404ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4057d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org    if (NULL == plot) {
406ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return false;
407ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
408ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4097d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org    glyph->fPlot = plot;
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return true;
411ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
412