180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkAdvancedTypefaceMetrics.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypes.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined(SK_BUILD_FOR_WIN)
14363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include <dwrite.h>
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
187839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger// forward declare structs needed for getAdvanceData() template for freetype
197839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstruct FT_FaceRec;
207839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergertypedef struct FT_FaceRec_* FT_Face;
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_BUILD_FOR_MAC
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#import <ApplicationServices/ApplicationServices.h>
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_BUILD_FOR_IOS
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <CoreText/CoreText.h>
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <CoreGraphics/CoreGraphics.h>
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <CoreFoundation/CoreFoundation.h>
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace skia_advanced_typeface_metrics_utils {
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst int16_t kInvalidAdvance = SK_MinS16;
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst int16_t kDontCareAdvance = SK_MinS16 + 1;
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename Data>
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid stripUninterestingTrailingAdvancesFromRange(
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(false);
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <>
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid stripUninterestingTrailingAdvancesFromRange<int16_t>(
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                                          SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(range);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (range->fAdvance.count() < expectedAdvanceCount) {
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (range->fAdvance[i] != kDontCareAdvance &&
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            range->fAdvance[i] != kInvalidAdvance &&
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            range->fAdvance[i] != 0) {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            range->fEndId = range->fStartId + i;
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            break;
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename Data>
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                int startId) {
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    range->fStartId = startId;
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    range->fAdvance.setCount(0);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename Data>
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int startId) {
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    resetRange(nextSlot->get(), startId);
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return nextSlot->get();
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename Data>
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid zeroWildcardsInRange(
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                          SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(false);
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <>
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid zeroWildcardsInRange<int16_t>(
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                   SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(range);
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) {
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Zero out wildcards.
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < range->fAdvance.count(); ++i) {
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (range->fAdvance[i] == kDontCareAdvance) {
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            range->fAdvance[i] = 0;
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename Data>
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid finishRange(
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int endId,
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                type) {
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    range->fEndId = endId;
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    range->fType = type;
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stripUninterestingTrailingAdvancesFromRange(range);
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int newLength;
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        newLength = range->fEndId - range->fStartId + 1;
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (range->fEndId == range->fStartId) {
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            range->fType =
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange;
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        newLength = 1;
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(range->fAdvance.count() >= newLength);
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    range->fAdvance.setCount(newLength);
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    zeroWildcardsInRange(range);
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <typename Data, typename FontHandle>
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        FontHandle fontHandle,
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int num_glyphs,
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint32_t* subsetGlyphIDs,
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t subsetGlyphIDsLength,
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Assuming that on average, the ASCII representation of an advance plus
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // a space is 8 characters and the ASCII representation of a glyph id is 3
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // characters, then the following cut offs for using different range types
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // apply:
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // The cost of stopping and starting the range is 7 characers
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //  a. Removing 4 0's or don't care's is a win
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // The cost of stopping and starting the range plus a run is 22
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // characters
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //  b. Removing 3 repeating advances is a win
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //  c. Removing 2 repeating advances and 3 don't cares is a win
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // When not currently in a range the cost of a run over a range is 16
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // characaters, so:
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //  d. Removing a leading 0/don't cares is a win because it is omitted
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //  e. Removing 2 repeating advances is a win
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkAutoTDelete<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = NULL;
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Data lastAdvance = kInvalidAdvance;
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int repeatedAdvances = 0;
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int wildCardsInRun = 0;
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int trailingWildCards = 0;
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t subsetIndex = 0;
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Limit the loop count to glyph id ranges provided.
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int firstIndex = 0;
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int lastIndex = num_glyphs;
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (subsetGlyphIDs) {
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        firstIndex = static_cast<int>(subsetGlyphIDs[0]);
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        lastIndex =
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1;
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    curRange = appendRange(&result, firstIndex);
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int gId = firstIndex; gId <= lastIndex; gId++) {
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        Data advance = kInvalidAdvance;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (gId < lastIndex) {
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            // Get glyph id only when subset is NULL, or the id is in subset.
172910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger            SkASSERT(!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength &&
173910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger                    static_cast<uint32_t>(gId) <= subsetGlyphIDs[subsetIndex]));
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (!subsetGlyphIDs ||
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                (subsetIndex < subsetGlyphIDsLength &&
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                 static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkAssertResult(getAdvance(fontHandle, gId, &advance));
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                ++subsetIndex;
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else {
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                advance = kDontCareAdvance;
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (advance == lastAdvance) {
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            repeatedAdvances++;
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            trailingWildCards = 0;
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else if (advance == kDontCareAdvance) {
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            wildCardsInRun++;
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            trailingWildCards++;
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else if (curRange->fAdvance.count() ==
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                   repeatedAdvances + 1 + wildCardsInRun) {  // All in run.
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (lastAdvance == 0) {
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                resetRange(curRange, gId);
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                trailingWildCards = 0;
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                finishRange(curRange, gId - 1,
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            SkAdvancedTypefaceMetrics::WidthRange::kRun);
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                prevRange = curRange;
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                curRange = appendRange(&curRange->fNext, gId);
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                trailingWildCards = 0;
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            repeatedAdvances = 0;
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            wildCardsInRun = trailingWildCards;
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            trailingWildCards = 0;
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (lastAdvance == 0 &&
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    repeatedAdvances + 1 + wildCardsInRun >= 4) {
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                finishRange(curRange,
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            gId - repeatedAdvances - wildCardsInRun - 2,
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            SkAdvancedTypefaceMetrics::WidthRange::kRange);
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                prevRange = curRange;
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                curRange = appendRange(&curRange->fNext, gId);
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                trailingWildCards = 0;
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                finishRange(curRange,
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            gId - trailingWildCards - 1,
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            SkAdvancedTypefaceMetrics::WidthRange::kRange);
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                prevRange = curRange;
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                curRange = appendRange(&curRange->fNext, gId);
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                trailingWildCards = 0;
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            } else if (lastAdvance != 0 &&
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                       (repeatedAdvances + 1 >= 3 ||
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                finishRange(curRange,
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            gId - repeatedAdvances - wildCardsInRun - 2,
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            SkAdvancedTypefaceMetrics::WidthRange::kRange);
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                curRange =
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    appendRange(&curRange->fNext,
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                gId - repeatedAdvances - wildCardsInRun - 1);
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                curRange->fAdvance.append(1, &lastAdvance);
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                finishRange(curRange, gId - 1,
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            SkAdvancedTypefaceMetrics::WidthRange::kRun);
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                prevRange = curRange;
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                curRange = appendRange(&curRange->fNext, gId);
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                trailingWildCards = 0;
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            repeatedAdvances = 0;
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            wildCardsInRun = trailingWildCards;
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            trailingWildCards = 0;
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        curRange->fAdvance.append(1, &advance);
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (advance != kDontCareAdvance) {
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            lastAdvance = advance;
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (curRange->fStartId == lastIndex) {
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(prevRange);
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(prevRange->fNext->fStartId == lastIndex);
2480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        prevRange->fNext.free();
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        finishRange(curRange, lastIndex - 1,
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    SkAdvancedTypefaceMetrics::WidthRange::kRange);
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return result.detach();
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Make AdvanceMetric template functions available for linking with typename
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// WidthRange and VerticalAdvanceRange.
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if defined(SK_BUILD_FOR_WIN)
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        HDC hdc,
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int num_glyphs,
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint32_t* subsetGlyphIDs,
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t subsetGlyphIDsLength,
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        IDWriteFontFace* fontFace,
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int num_glyphs,
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint32_t* subsetGlyphIDs,
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t subsetGlyphIDsLength,
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool (*getAdvance)(IDWriteFontFace* fontFace, int gId, int16_t* data));
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        FT_Face face,
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int num_glyphs,
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint32_t* subsetGlyphIDs,
27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t subsetGlyphIDsLength,
27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        CTFontRef ctFont,
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int num_glyphs,
28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint32_t* subsetGlyphIDs,
28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t subsetGlyphIDsLength,
28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data));
28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate void resetRange(
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAdvancedTypefaceMetrics::WidthRange* range,
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int startId);
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate SkAdvancedTypefaceMetrics::WidthRange* appendRange(
2900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkAutoTDelete<SkAdvancedTypefaceMetrics::WidthRange >* nextSlot,
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int startId);
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate void finishRange<int16_t>(
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAdvancedTypefaceMetrics::WidthRange* range,
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int endId,
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAdvancedTypefaceMetrics::WidthRange::MetricType type);
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate void resetRange(
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int startId);
30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate SkAdvancedTypefaceMetrics::VerticalAdvanceRange* appendRange(
3010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkAutoTDelete<SkAdvancedTypefaceMetrics::VerticalAdvanceRange >*
30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            nextSlot,
30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int startId);
30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate void finishRange<SkAdvancedTypefaceMetrics::VerticalMetric>(
30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int endId,
30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkAdvancedTypefaceMetrics::VerticalAdvanceRange::MetricType type);
30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// additional declaration needed for testing with a face of an unknown type
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        void* fontData,
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        int num_glyphs,
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const uint32_t* subsetGlyphIDs,
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t subsetGlyphIDsLength,
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        bool (*getAdvance)(void* fontData, int gId, int16_t* data));
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} // namespace skia_advanced_typeface_metrics_utils
318