LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkAdvancedTypefaceMetrics.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 118 0 0.0 %
Date: 2012-06-02 Functions: 11 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2011 Google Inc.
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #include "SkAdvancedTypefaceMetrics.h"
      11                 : #include "SkTypes.h"
      12                 : 
      13                 : #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
      14                 : #include <ft2build.h>
      15                 : #include FT_FREETYPE_H
      16                 : #endif
      17                 : 
      18                 : #ifdef SK_BUILD_FOR_MAC
      19                 : #import <ApplicationServices/ApplicationServices.h>
      20                 : #endif
      21                 : 
      22                 : #ifdef SK_BUILD_FOR_IOS
      23                 : #include <CoreText/CoreText.h>
      24                 : #include <CoreGraphics/CoreGraphics.h>
      25                 : #include <CoreFoundation/CoreFoundation.h>
      26                 : #endif
      27                 : 
      28                 : namespace skia_advanced_typeface_metrics_utils {
      29                 : 
      30                 : const int16_t kInvalidAdvance = SK_MinS16;
      31                 : const int16_t kDontCareAdvance = SK_MinS16 + 1;
      32                 : 
      33                 : template <typename Data>
      34               0 : void stripUninterestingTrailingAdvancesFromRange(
      35                 :                                                  SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
      36               0 :     SkASSERT(false);
      37               0 : }
      38                 : 
      39                 : template <>
      40               0 : void stripUninterestingTrailingAdvancesFromRange<int16_t>(
      41                 :                                                           SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
      42               0 :     SkASSERT(range);
      43                 :     
      44               0 :     int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
      45               0 :     if (range->fAdvance.count() < expectedAdvanceCount) {
      46               0 :         return;
      47                 :     }
      48                 :     
      49               0 :     for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
      50               0 :         if (range->fAdvance[i] != kDontCareAdvance &&
      51               0 :             range->fAdvance[i] != kInvalidAdvance &&
      52               0 :             range->fAdvance[i] != 0) {
      53               0 :             range->fEndId = range->fStartId + i;
      54               0 :             break;
      55                 :         }
      56                 :     }
      57                 : }
      58                 : 
      59                 : template <typename Data>
      60                 : void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
      61               0 :                 int startId) {
      62               0 :     range->fStartId = startId;
      63               0 :     range->fAdvance.setCount(0);
      64               0 : }
      65                 : 
      66                 : template <typename Data>
      67                 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
      68                 :         SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
      69               0 :         int startId) {
      70               0 :     nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
      71               0 :     resetRange(nextSlot->get(), startId);
      72               0 :     return nextSlot->get();
      73                 : }
      74                 : 
      75                 : template <typename Data>
      76               0 : void zeroWildcardsInRange(
      77                 :                           SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
      78               0 :     SkASSERT(false);
      79               0 : }
      80                 : 
      81                 : template <>
      82               0 : void zeroWildcardsInRange<int16_t>(
      83                 :                                    SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
      84               0 :     SkASSERT(range);
      85               0 :     if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) {
      86               0 :         return;
      87                 :     }
      88               0 :     SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
      89                 :     
      90                 :     // Zero out wildcards.
      91               0 :     for (int i = 0; i < range->fAdvance.count(); ++i) {
      92               0 :         if (range->fAdvance[i] == kDontCareAdvance) {
      93               0 :             range->fAdvance[i] = 0;
      94                 :         }
      95                 :     }
      96                 : }
      97                 :     
      98                 : template <typename Data>
      99                 : void finishRange(
     100                 :         SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
     101                 :         int endId,
     102                 :         typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
     103               0 :                 type) {
     104               0 :     range->fEndId = endId;
     105               0 :     range->fType = type;
     106               0 :     stripUninterestingTrailingAdvancesFromRange(range);
     107                 :     int newLength;
     108               0 :     if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
     109               0 :         newLength = range->fEndId - range->fStartId + 1;
     110                 :     } else {
     111               0 :         if (range->fEndId == range->fStartId) {
     112               0 :             range->fType =
     113                 :                 SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange;
     114                 :         }
     115               0 :         newLength = 1;
     116                 :     }
     117               0 :     SkASSERT(range->fAdvance.count() >= newLength);
     118               0 :     range->fAdvance.setCount(newLength);
     119               0 :     zeroWildcardsInRange(range);
     120               0 : }
     121                 : 
     122                 : template <typename Data, typename FontHandle>
     123                 : SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
     124                 :         FontHandle fontHandle,
     125                 :         int num_glyphs,
     126                 :         const uint32_t* subsetGlyphIDs,
     127                 :         uint32_t subsetGlyphIDsLength,
     128               0 :         bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
     129                 :     // Assuming that on average, the ASCII representation of an advance plus
     130                 :     // a space is 8 characters and the ASCII representation of a glyph id is 3
     131                 :     // characters, then the following cut offs for using different range types
     132                 :     // apply:
     133                 :     // The cost of stopping and starting the range is 7 characers
     134                 :     //  a. Removing 4 0's or don't care's is a win
     135                 :     // The cost of stopping and starting the range plus a run is 22
     136                 :     // characters
     137                 :     //  b. Removing 3 repeating advances is a win
     138                 :     //  c. Removing 2 repeating advances and 3 don't cares is a win
     139                 :     // When not currently in a range the cost of a run over a range is 16
     140                 :     // characaters, so:
     141                 :     //  d. Removing a leading 0/don't cares is a win because it is omitted
     142                 :     //  e. Removing 2 repeating advances is a win
     143                 : 
     144               0 :     SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
     145                 :     SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
     146               0 :     SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = NULL;
     147               0 :     Data lastAdvance = kInvalidAdvance;
     148               0 :     int repeatedAdvances = 0;
     149               0 :     int wildCardsInRun = 0;
     150               0 :     int leadingWildCards = 0;
     151               0 :     int trailingWildCards = 0;
     152               0 :     uint32_t subsetIndex = 0;
     153                 : 
     154                 :     // Limit the loop count to glyph id ranges provided.
     155               0 :     int firstIndex = 0;
     156               0 :     int lastIndex = num_glyphs;
     157               0 :     if (subsetGlyphIDs) {
     158               0 :         firstIndex = static_cast<int>(subsetGlyphIDs[0]);
     159               0 :         lastIndex =
     160                 :                 static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1;
     161                 :     }
     162               0 :     curRange = appendRange(&result, firstIndex);
     163                 : 
     164               0 :     for (int gId = firstIndex; gId <= lastIndex; gId++) {
     165               0 :         Data advance = kInvalidAdvance;
     166               0 :         if (gId < lastIndex) {
     167                 :             // Get glyph id only when subset is NULL, or the id is in subset.
     168               0 :             if (!subsetGlyphIDs ||
     169                 :                 (subsetIndex < subsetGlyphIDsLength &&
     170                 :                  static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
     171               0 :                 SkAssertResult(getAdvance(fontHandle, gId, &advance));
     172               0 :                 ++subsetIndex;
     173                 :             } else {
     174               0 :                 advance = kDontCareAdvance;
     175                 :             }
     176                 :         }
     177               0 :         if (advance == lastAdvance) {
     178               0 :             repeatedAdvances++;
     179               0 :             trailingWildCards = 0;
     180               0 :         } else if (advance == kDontCareAdvance) {
     181               0 :             wildCardsInRun++;
     182               0 :             trailingWildCards++;
     183               0 :         } else if (curRange->fAdvance.count() ==
     184                 :                    repeatedAdvances + 1 + wildCardsInRun) {  // All in run.
     185               0 :             if (lastAdvance == 0) {
     186               0 :                 resetRange(curRange, gId);
     187               0 :                 trailingWildCards = 0;
     188               0 :             } else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
     189               0 :                 finishRange(curRange, gId - 1,
     190                 :                             SkAdvancedTypefaceMetrics::WidthRange::kRun);
     191               0 :                 prevRange = curRange;
     192               0 :                 curRange = appendRange(&curRange->fNext, gId);
     193               0 :                 trailingWildCards = 0;
     194                 :             }
     195               0 :             repeatedAdvances = 0;
     196               0 :             wildCardsInRun = trailingWildCards;
     197               0 :             leadingWildCards = trailingWildCards;
     198               0 :             trailingWildCards = 0;
     199                 :         } else {
     200               0 :             if (lastAdvance == 0 &&
     201                 :                     repeatedAdvances + 1 + wildCardsInRun >= 4) {
     202               0 :                 finishRange(curRange,
     203                 :                             gId - repeatedAdvances - wildCardsInRun - 2,
     204                 :                             SkAdvancedTypefaceMetrics::WidthRange::kRange);
     205               0 :                 prevRange = curRange;
     206               0 :                 curRange = appendRange(&curRange->fNext, gId);
     207               0 :                 trailingWildCards = 0;
     208               0 :             } else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
     209               0 :                 finishRange(curRange,
     210                 :                             gId - trailingWildCards - 1,
     211                 :                             SkAdvancedTypefaceMetrics::WidthRange::kRange);
     212               0 :                 prevRange = curRange;
     213               0 :                 curRange = appendRange(&curRange->fNext, gId);
     214               0 :                 trailingWildCards = 0;
     215               0 :             } else if (lastAdvance != 0 &&
     216                 :                        (repeatedAdvances + 1 >= 3 ||
     217                 :                         (repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
     218               0 :                 finishRange(curRange,
     219                 :                             gId - repeatedAdvances - wildCardsInRun - 2,
     220                 :                             SkAdvancedTypefaceMetrics::WidthRange::kRange);
     221               0 :                 curRange =
     222                 :                     appendRange(&curRange->fNext,
     223                 :                                 gId - repeatedAdvances - wildCardsInRun - 1);
     224               0 :                 curRange->fAdvance.append(1, &lastAdvance);
     225               0 :                 finishRange(curRange, gId - 1,
     226                 :                             SkAdvancedTypefaceMetrics::WidthRange::kRun);
     227               0 :                 prevRange = curRange;
     228               0 :                 curRange = appendRange(&curRange->fNext, gId);
     229               0 :                 trailingWildCards = 0;
     230                 :             }
     231               0 :             repeatedAdvances = 0;
     232               0 :             wildCardsInRun = trailingWildCards;
     233               0 :             leadingWildCards = trailingWildCards;
     234               0 :             trailingWildCards = 0;
     235                 :         }
     236               0 :         curRange->fAdvance.append(1, &advance);
     237               0 :         if (advance != kDontCareAdvance) {
     238               0 :             lastAdvance = advance;
     239                 :         }
     240                 :     }
     241               0 :     if (curRange->fStartId == lastIndex) {
     242               0 :         SkASSERT(prevRange);
     243               0 :         SkASSERT(prevRange->fNext->fStartId == lastIndex);
     244               0 :         prevRange->fNext.reset();
     245                 :     } else {
     246               0 :         finishRange(curRange, lastIndex - 1,
     247                 :                     SkAdvancedTypefaceMetrics::WidthRange::kRange);
     248                 :     }
     249               0 :     return result.release();
     250                 : }
     251                 : 
     252                 : // Make AdvanceMetric template functions available for linking with typename
     253                 : // WidthRange and VerticalAdvanceRange.
     254                 : #if defined(SK_BUILD_FOR_WIN)
     255                 : template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
     256                 :         HDC hdc,
     257                 :         int num_glyphs,
     258                 :         const uint32_t* subsetGlyphIDs,
     259                 :         uint32_t subsetGlyphIDsLength,
     260                 :         bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
     261                 : #elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
     262                 : template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
     263                 :         FT_Face face,
     264                 :         int num_glyphs,
     265                 :         const uint32_t* subsetGlyphIDs,
     266                 :         uint32_t subsetGlyphIDsLength,
     267                 :         bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
     268                 : #elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
     269                 : template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
     270                 :         CTFontRef ctFont,
     271                 :         int num_glyphs,
     272                 :         const uint32_t* subsetGlyphIDs,
     273                 :         uint32_t subsetGlyphIDsLength,
     274                 :         bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data));
     275                 : #endif
     276                 : template void resetRange(
     277                 :         SkAdvancedTypefaceMetrics::WidthRange* range,
     278                 :         int startId);
     279                 : template SkAdvancedTypefaceMetrics::WidthRange* appendRange(
     280                 :         SkTScopedPtr<SkAdvancedTypefaceMetrics::WidthRange >* nextSlot,
     281                 :         int startId);
     282                 : template void finishRange<int16_t>(
     283                 :         SkAdvancedTypefaceMetrics::WidthRange* range,
     284                 :         int endId,
     285                 :         SkAdvancedTypefaceMetrics::WidthRange::MetricType type);
     286                 : 
     287                 : template void resetRange(
     288                 :         SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
     289                 :         int startId);
     290                 : template SkAdvancedTypefaceMetrics::VerticalAdvanceRange* appendRange(
     291                 :         SkTScopedPtr<SkAdvancedTypefaceMetrics::VerticalAdvanceRange >*
     292                 :             nextSlot,
     293                 :         int startId);
     294                 : template void finishRange<SkAdvancedTypefaceMetrics::VerticalMetric>(
     295                 :         SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
     296                 :         int endId,
     297                 :         SkAdvancedTypefaceMetrics::VerticalAdvanceRange::MetricType type);
     298                 : 
     299                 : } // namespace skia_advanced_typeface_metrics_utils

Generated by: LCOV version 1.7