SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange( SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot, int startId) { nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>); resetRange(nextSlot->get(), startId); return nextSlot->get(); }
int Random::next(int min, int max) { resetRange(min, max); return m_dist(m_rnd); }
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData( FontHandle fontHandle, int num_glyphs, const uint32_t* subsetGlyphIDs, uint32_t subsetGlyphIDsLength, bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) { // Assuming that on average, the ASCII representation of an advance plus // a space is 8 characters and the ASCII representation of a glyph id is 3 // characters, then the following cut offs for using different range types // apply: // The cost of stopping and starting the range is 7 characers // a. Removing 4 0's or don't care's is a win // The cost of stopping and starting the range plus a run is 22 // characters // b. Removing 3 repeating advances is a win // c. Removing 2 repeating advances and 3 don't cares is a win // When not currently in a range the cost of a run over a range is 16 // characaters, so: // d. Removing a leading 0/don't cares is a win because it is omitted // e. Removing 2 repeating advances is a win SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result; SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange; SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = NULL; Data lastAdvance = kInvalidAdvance; int repeatedAdvances = 0; int wildCardsInRun = 0; int trailingWildCards = 0; uint32_t subsetIndex = 0; // Limit the loop count to glyph id ranges provided. int firstIndex = 0; int lastIndex = num_glyphs; if (subsetGlyphIDs) { firstIndex = static_cast<int>(subsetGlyphIDs[0]); lastIndex = static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1; } curRange = appendRange(&result, firstIndex); for (int gId = firstIndex; gId <= lastIndex; gId++) { Data advance = kInvalidAdvance; if (gId < lastIndex) { // Get glyph id only when subset is NULL, or the id is in subset. if (!subsetGlyphIDs || (subsetIndex < subsetGlyphIDsLength && static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) { SkAssertResult(getAdvance(fontHandle, gId, &advance)); ++subsetIndex; } else { advance = kDontCareAdvance; } } if (advance == lastAdvance) { repeatedAdvances++; trailingWildCards = 0; } else if (advance == kDontCareAdvance) { wildCardsInRun++; trailingWildCards++; } else if (curRange->fAdvance.count() == repeatedAdvances + 1 + wildCardsInRun) { // All in run. if (lastAdvance == 0) { resetRange(curRange, gId); trailingWildCards = 0; } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) { finishRange(curRange, gId - 1, SkAdvancedTypefaceMetrics::WidthRange::kRun); prevRange = curRange; curRange = appendRange(&curRange->fNext, gId); trailingWildCards = 0; } repeatedAdvances = 0; wildCardsInRun = trailingWildCards; trailingWildCards = 0; } else { if (lastAdvance == 0 && repeatedAdvances + 1 + wildCardsInRun >= 4) { finishRange(curRange, gId - repeatedAdvances - wildCardsInRun - 2, SkAdvancedTypefaceMetrics::WidthRange::kRange); prevRange = curRange; curRange = appendRange(&curRange->fNext, gId); trailingWildCards = 0; } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) { finishRange(curRange, gId - trailingWildCards - 1, SkAdvancedTypefaceMetrics::WidthRange::kRange); prevRange = curRange; curRange = appendRange(&curRange->fNext, gId); trailingWildCards = 0; } else if (lastAdvance != 0 && (repeatedAdvances + 1 >= 3 || (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) { finishRange(curRange, gId - repeatedAdvances - wildCardsInRun - 2, SkAdvancedTypefaceMetrics::WidthRange::kRange); curRange = appendRange(&curRange->fNext, gId - repeatedAdvances - wildCardsInRun - 1); curRange->fAdvance.append(1, &lastAdvance); finishRange(curRange, gId - 1, SkAdvancedTypefaceMetrics::WidthRange::kRun); prevRange = curRange; curRange = appendRange(&curRange->fNext, gId); trailingWildCards = 0; } repeatedAdvances = 0; wildCardsInRun = trailingWildCards; trailingWildCards = 0; } curRange->fAdvance.append(1, &advance); if (advance != kDontCareAdvance) { lastAdvance = advance; } } if (curRange->fStartId == lastIndex) { SkASSERT(prevRange); SkASSERT(prevRange->fNext->fStartId == lastIndex); prevRange->fNext.reset(); } else { finishRange(curRange, lastIndex - 1, SkAdvancedTypefaceMetrics::WidthRange::kRange); } return result.release(); }
//----------------------------------------------------------------------------// // Generation Methods // //----------------------------------------------------------------------------// int Random::next() { resetRange(0, std::numeric_limits<int>::max()); return m_dist(m_rnd); }