GrTextStrike.cpp revision d830d13c27437b4677a4a1abfa866d98dc2d2ab9
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.comSK_DEFINE_INST_COUNT(GrFontScaler)
20fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.comSK_DEFINE_INST_COUNT(GrKey)
21fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
22fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com///////////////////////////////////////////////////////////////////////////////
23fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
2467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#define FONT_CACHE_STATS 0
2567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
2667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic int g_PurgeCount = 0;
2767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
2867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
29ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
30ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gpu->ref();
313fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    for (int i = 0; i < kMaskFormatCount; ++i) {
323fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        fAtlasMgr[i] = NULL;
333fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    }
34ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
35ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fHead = fTail = NULL;
36ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
37ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
38ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrFontCache::~GrFontCache() {
39ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.deleteAll();
403fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    for (int i = 0; i < kMaskFormatCount; ++i) {
413fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        delete fAtlasMgr[i];
423fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    }
43ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fGpu->unref();
4467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
4567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org      GrPrintf("Num purges: %d\n", g_PurgeCount);
4667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
47ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
49952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.orgstatic GrPixelConfig mask_format_to_pixel_config(GrMaskFormat format) {
50952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org    switch (format) {
51952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org        case kA8_GrMaskFormat:
52952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org            return kAlpha_8_GrPixelConfig;
53952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org        case kA565_GrMaskFormat:
54952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org            return kRGB_565_GrPixelConfig;
55952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org        case kA888_GrMaskFormat:
56952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org            return kSkia8888_GrPixelConfig;
57952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org        default:
58952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org            SkDEBUGFAIL("unknown maskformat");
59952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org    }
60952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org    return kUnknown_GrPixelConfig;
61952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org}
62952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org
63ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike* GrFontCache::generateStrike(GrFontScaler* scaler,
64ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                          const Key& key) {
653fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    GrMaskFormat format = scaler->getMaskFormat();
66952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org    GrPixelConfig config = mask_format_to_pixel_config(format);
673fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    if (NULL == fAtlasMgr[format]) {
68952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org        fAtlasMgr[format] = SkNEW_ARGS(GrAtlasMgr, (fGpu, config));
69ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
70c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com    GrTextStrike* strike = SkNEW_ARGS(GrTextStrike,
71952944144758dd3f9a8a010ec1d99cb4bd035ae4commit-bot@chromium.org                                      (this, scaler->getKey(), format, fAtlasMgr[format]));
72ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.insert(key, strike);
73ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
74ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (fHead) {
75ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fHead->fPrev = strike;
76ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
77f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(NULL == fTail);
78ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fTail = strike;
79ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
80ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike->fPrev = NULL;
81ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike->fNext = fHead;
82ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fHead = strike;
83ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
84ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return strike;
85ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
86ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
87ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::freeAll() {
88ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.deleteAll();
893fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    for (int i = 0; i < kMaskFormatCount; ++i) {
903fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        delete fAtlasMgr[i];
913fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org        fAtlasMgr[i] = NULL;
923fddf0eed6dc2873bcc8e584f435c6cd34964518commit-bot@chromium.org    }
938fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fHead = NULL;
948fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fTail = NULL;
95ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
96ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
97b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.orgvoid GrFontCache::purgeStrike(GrTextStrike* strike) {
98b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    const GrFontCache::Key key(strike->fFontScalerKey);
99b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    fCache.remove(key, strike);
100b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    this->detachStrikeFromList(strike);
101b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org    delete strike;
102b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org}
103b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org
104ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) {
105bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com    SkASSERT(NULL != preserveStrike);
106ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrTextStrike* strike = fTail;
10767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    bool purge = true;
108bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com    GrMaskFormat maskFormat = preserveStrike->fMaskFormat;
10967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    while (strike) {
110bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com        if (strike == preserveStrike || maskFormat != strike->fMaskFormat) {
11167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            strike = strike->fPrev;
11267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            continue;
11367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
11467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        GrTextStrike* strikeToPurge = strike;
11567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        strike = strikeToPurge->fPrev;
11667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        if (purge) {
11767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            // keep purging if we won't free up any atlases with this strike.
1187d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org            purge = strikeToPurge->fAtlas.isEmpty();
119b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org            this->purgeStrike(strikeToPurge);
12067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
12167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    }
12267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#if FONT_CACHE_STATS
12367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    ++g_PurgeCount;
12467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org#endif
12567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
12667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
1277d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.orgvoid GrFontCache::freePlotExceptFor(GrTextStrike* preserveStrike) {
128bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com    SkASSERT(NULL != preserveStrike);
12967ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    GrTextStrike* strike = fTail;
130bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com    GrMaskFormat maskFormat = preserveStrike->fMaskFormat;
1317359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com    while (strike) {
132bbe55fdf6608b8aec2e5d3945da6b1872b3a380fjvanverth@google.com        if (strike == preserveStrike || maskFormat != strike->fMaskFormat) {
1337359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com            strike = strike->fPrev;
1347359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com            continue;
1357359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        }
1367359eae7c6fce8cb88ae28ca7048283b77535db4bsalomon@google.com        GrTextStrike* strikeToPurge = strike;
13767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        strike = strikeToPurge->fPrev;
1387d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org        if (strikeToPurge->removeUnusedPlots()) {
1397d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org            if (strikeToPurge->fAtlas.isEmpty()) {
140b2e9fa529862bd1f7b983a17b3c72acfb3d0367dcommit-bot@chromium.org                this->purgeStrike(strikeToPurge);
14167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            }
14267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org            break;
14367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org        }
144ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
145ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
146ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
147515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
148ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrFontCache::validate() const {
149ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count = fCache.count();
150ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (0 == count) {
151f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!fHead);
152f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(!fTail);
153ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else if (1 == count) {
154f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fHead == fTail);
155ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    } else {
156f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(fHead != fTail);
157ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
158ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
159ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    int count2 = 0;
160ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    const GrTextStrike* strike = fHead;
161ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
162ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
163ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fNext;
164ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
165f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(count == count2);
166ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
167ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    count2 = 0;
168ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    strike = fTail;
169ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    while (strike) {
170ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        count2 += 1;
171ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        strike = strike->fPrev;
172ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
173f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(count == count2);
174ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
175ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
176ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
17703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#ifdef SK_DEVELOPER
17803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.orgvoid GrFontCache::dump() const {
17903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org    static int gDumpCount = 0;
18003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org    for (int i = 0; i < kMaskFormatCount; ++i) {
18103e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org        if (NULL != fAtlasMgr[i]) {
18203e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org            GrTexture* texture = fAtlasMgr[i]->getTexture();
18303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org            if (NULL != texture) {
18403e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org                SkString filename;
18503e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org                filename.printf("fontcache_%d%d.png", gDumpCount, i);
18603e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org                texture->savePixels(filename.c_str());
18703e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org            }
18803e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org        }
18903e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org    }
19003e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org    ++gDumpCount;
19103e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org}
19203e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org#endif
19303e3e89641c93df603dfb705d518848dfe81427ecommit-bot@chromium.org
194ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com///////////////////////////////////////////////////////////////////////////////
195ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
196515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
197ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    static int gCounter;
198ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
199ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
200d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
201d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#define DISTANCE_FIELD_PAD   4
202d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#define DISTANCE_FIELD_RANGE (4.0)
203d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
204d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
205ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com/*
206ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    The text strike is specific to a given font/style/matrix setup, which is
207ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    represented by the GrHostFontScaler object we are given in getGlyph().
208ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
209ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    We map a 32bit glyphID to a GrGlyph record, which in turn points to a
210ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    atlas and a position within that texture.
211ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
212ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
213ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
21498539c607b05f7e25406ae873bf1b24154a36a6freed@google.com                           GrMaskFormat format,
2157d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org                           GrAtlasMgr* atlasMgr) : fPool(64), fAtlas(atlasMgr) {
216ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey = key;
217ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->ref();
218ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
219ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontCache = cache;     // no need to ref, it won't go away before we do
220ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fAtlasMgr = atlasMgr;   // no need to ref, it won't go away before we do
221ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
22298539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    fMaskFormat = format;
22398539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
224515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
2253ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf(" GrTextStrike %p %d\n", this, gCounter);
226ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter += 1;
227ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
228ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
229ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
23067ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// these signatures are needed because they're used with
23167ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org// SkTDArray::visitAll() (see destructor & removeUnusedAtlases())
23267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void free_glyph(GrGlyph*& glyph) { glyph->free(); }
23367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
23467ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.orgstatic void invalidate_glyph(GrGlyph*& glyph) {
2357d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org    if (glyph->fPlot && glyph->fPlot->drawToken().isIssued()) {
2367d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org        glyph->fPlot = NULL;
23767ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    }
23867ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
239ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
240ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrTextStrike::~GrTextStrike() {
241ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fFontScalerKey->unref();
24267ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    fCache.getArray().visitAll(free_glyph);
243ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
244515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
245ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    gCounter -= 1;
2463ef80cf14c3222f705c291123106991e52061678reed@google.com//    GrPrintf("~GrTextStrike %p %d\n", this, gCounter);
247ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#endif
248ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
249ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
250ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
251ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                                     GrFontScaler* scaler) {
252fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkIRect bounds;
253ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
254ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return NULL;
255ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
256ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
257ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    GrGlyph* glyph = fPool.alloc();
258d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
259d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    // expand bounds to hold full distance field data
260d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (fUseDistanceField) {
261d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fLeft   -= DISTANCE_FIELD_PAD;
262d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fRight  += DISTANCE_FIELD_PAD;
263d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fTop    -= DISTANCE_FIELD_PAD;
264d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        bounds.fBottom += DISTANCE_FIELD_PAD;
265d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    }
266d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
267ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    glyph->init(packed, bounds);
268ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    fCache.insert(packed, glyph);
269ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return glyph;
270ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
271ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2727d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.orgbool GrTextStrike::removeUnusedPlots() {
27367ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org    fCache.getArray().visitAll(invalidate_glyph);
2747d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org    return fAtlasMgr->removeUnusedPlots(&fAtlas);
27567ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org}
27667ed64e9aa70f5a95a2d309f9b73dc0009f3ed8ccommit-bot@chromium.org
277d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
27849e80830e9c633dcb8e7596bda17ea004ae48bd4commit-bot@chromium.orgbool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
2790ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#if 0   // testing hack to force us to flush our cache often
2800ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    static int gCounter;
2810ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com    if ((++gCounter % 10) == 0) return false;
2820ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com#endif
2830ebe81a2b7a2dfd3b978520c2594e448bdbadca0reed@google.com
284f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(glyph);
285f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(scaler);
286f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fCache.contains(glyph));
28749e80830e9c633dcb8e7596bda17ea004ae48bd4commit-bot@chromium.org    SkASSERT(NULL == glyph->fPlot);
288ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
289a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkAutoRef ar(scaler);
29098539c607b05f7e25406ae873bf1b24154a36a6freed@google.com
29198539c607b05f7e25406ae873bf1b24154a36a6freed@google.com    int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
292d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
293d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    GrPlot* plot;
294d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
295d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    if (fUseDistanceField) {
296d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkASSERT(1 == bytesPerPixel);
297d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
298d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // we've already expanded the glyph dimensions to match the final size
299d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // but must shrink back down to get the packed glyph data
300d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int dfWidth = glyph->width();
301d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int dfHeight = glyph->height();
302d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int width = dfWidth - 2*DISTANCE_FIELD_PAD;
303d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        int height = dfHeight - 2*DISTANCE_FIELD_PAD;
304d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t stride = width*bytesPerPixel;
305d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
306d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t size = width * height * bytesPerPixel;
307d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> storage(size);
308d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride, storage.get())) {
309d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            return false;
310d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
311d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
312d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // alloc storage for distance field glyph
313d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t dfSize = dfWidth * dfHeight * bytesPerPixel;
314d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> dfStorage(dfSize);
315d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
316d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // copy glyph into distance field storage
317d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        sk_bzero(dfStorage.get(), dfSize);
318d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
319d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        unsigned char* ptr = (unsigned char*) storage.get();
320d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        unsigned char* dfPtr = (unsigned char*) dfStorage.get();
321d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t dfStride = dfWidth*bytesPerPixel;
322d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr += DISTANCE_FIELD_PAD*dfStride;
323d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr += DISTANCE_FIELD_PAD*bytesPerPixel;
324d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
325d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        for (int i = 0; i < height; ++i) {
326d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            memcpy(dfPtr, ptr, stride);
327d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
328d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            dfPtr += dfStride;
329d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            ptr += stride;
330d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
331d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
332d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // generate distance field data
333d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> distXStorage(dfWidth*dfHeight*sizeof(short));
334d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> distYStorage(dfWidth*dfHeight*sizeof(short));
335d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> outerDistStorage(dfWidth*dfHeight*sizeof(double));
336d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> innerDistStorage(dfWidth*dfHeight*sizeof(double));
337d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> gxStorage(dfWidth*dfHeight*sizeof(double));
338d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> gyStorage(dfWidth*dfHeight*sizeof(double));
339d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
340d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        short* distX = (short*) distXStorage.get();
341d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        short* distY = (short*) distYStorage.get();
342d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* outerDist = (double*) outerDistStorage.get();
343d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* innerDist = (double*) innerDistStorage.get();
344d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* gx = (double*) gxStorage.get();
345d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        double* gy = (double*) gyStorage.get();
346d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
347d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr = (unsigned char*) dfStorage.get();
348d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
349d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, outerDist);
350d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
351d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        for (int i = 0; i < dfWidth*dfHeight; ++i) {
352d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            *dfPtr = 255 - *dfPtr;
353d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            dfPtr++;
354d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
355d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        dfPtr = (unsigned char*) dfStorage.get();
356d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        sk_bzero(gx, sizeof(double)*dfWidth*dfHeight);
357d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        sk_bzero(gy, sizeof(double)*dfWidth*dfHeight);
358d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
359d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, innerDist);
360d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
361d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        for (int i = 0; i < dfWidth*dfHeight; ++i) {
362d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            unsigned char val;
363d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            double outerval = outerDist[i];
364d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            if (outerval < 0.0) {
365d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                outerval = 0.0;
366d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
367d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            double innerval = innerDist[i];
368d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            if (innerval < 0.0) {
369d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                innerval = 0.0;
370d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
371d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            double dist = outerval - innerval;
372d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            if (dist <= -DISTANCE_FIELD_RANGE) {
373d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                val = 255;
374d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            } else if (dist > DISTANCE_FIELD_RANGE) {
375d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                val = 0;
376d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            } else {
377d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                val = (unsigned char)((DISTANCE_FIELD_RANGE-dist)*128.0/DISTANCE_FIELD_RANGE);
378d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            }
379d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            *dfPtr++ = val;
380d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
381d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
382d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        // copy to atlas
383d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get(),
384d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                     &glyph->fAtlasLocation);
385d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
386d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com    } else {
387d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
388d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        size_t size = glyph->fBounds.area() * bytesPerPixel;
389d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        SkAutoSMalloc<1024> storage(size);
390d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
391d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                         glyph->height(),
392d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                         glyph->width() * bytesPerPixel,
393d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                         storage.get())) {
394d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com            return false;
395d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        }
396d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
397d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com        plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
398d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                     glyph->height(), storage.get(),
399d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com                                     &glyph->fAtlasLocation);
400d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#if SK_DISTANCEFIELD_FONTS
401ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
402d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com#endif
403ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4047d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org    if (NULL == plot) {
405ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return false;
406ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
407ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
4087d330eb19cd3c9278abce68ca0e3efabf2ec8f87commit-bot@chromium.org    glyph->fPlot = plot;
409ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return true;
410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
411d830d13c27437b4677a4a1abfa866d98dc2d2ab9jvanverth@google.com
412