Provide windows font host implementation needed to support TrueType text in pdf backend.
- Move AdvanceMetric template functions into new file SkAdvancedTypefaceMetrics.cpp
Review URL: http://codereview.appspot.com/4174041
git-svn-id: http://skia.googlecode.com/svn/trunk@789 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 1b1d47b..7f1e377 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -73,6 +73,8 @@
#define SkASSERT_CONTINUE(pred)
#endif
+using namespace skia_advanced_typeface_metrics_utils;
+
//////////////////////////////////////////////////////////////////////////
struct SkFaceRec;
@@ -331,98 +333,14 @@
return true;
}
-static int16_t getWidthAdvance(FT_Face face, int gId) {
+static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
FT_Fixed advance = 0;
- SkAssertResult(getAdvances(face, gId, 1, FT_LOAD_NO_SCALE, &advance) == 0);
- return advance;
-}
-
-template <typename Data>
-static void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
- int startId) {
- range->fStartId = startId;
- range->fAdvance.setCount(0);
-}
-
-template <typename Data>
-static SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
- SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
- int startId) {
- nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
- resetRange(nextSlot->get(), startId);
- return nextSlot->get();
-}
-
-template <typename Data>
-static void finishRange(
- SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
- int endId,
- typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
- type) {
- range->fEndId = endId;
- range->fType = type;
- int newLength;
- if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange)
- newLength = endId - range->fStartId + 1;
- else
- newLength = 1;
- SkASSERT(range->fAdvance.count() >= newLength);
- range->fAdvance.setCount(newLength);
-}
-
-template <typename Data>
-static SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
- FT_Face face, Data (*getAdvance)(FT_Face face, int gId)) {
- // Assuming that an ASCII representation of a width or a glyph id is,
- // on average, 3 characters long gives the following cut offs for
- // using different range types:
- // When currently in a range
- // - Removing 4 0's is a win
- // - Removing 5 repeats is a win
- // When not currently in a range
- // - Removing 1 0 is a win
- // - Removing 3 repeats is a win
-
- SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
- SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
- curRange = appendRange(&result, 0);
- Data lastAdvance = SHRT_MIN;
- int repeats = 0;
- for (int gId = 0; gId < face->num_glyphs; gId++) {
- Data advance = getAdvance(face, gId);
- if (advance == lastAdvance) {
- repeats++;
- } else if (curRange->fAdvance.count() == repeats + 1) {
- if (lastAdvance == 0 && repeats >= 0) {
- resetRange(curRange, gId);
- } else if (repeats >= 2) {
- finishRange(curRange, gId - 1,
- SkAdvancedTypefaceMetrics::WidthRange::kRun);
- curRange = appendRange(&curRange->fNext, gId);
- }
- repeats = 0;
- } else {
- if (lastAdvance == 0 && repeats >= 3) {
- finishRange(curRange, gId - repeats - 2,
- SkAdvancedTypefaceMetrics::WidthRange::kRange);
- curRange = appendRange(&curRange->fNext, gId);
- } else if (repeats >= 4) {
- finishRange(curRange, gId - repeats - 2,
- SkAdvancedTypefaceMetrics::WidthRange::kRange);
- curRange = appendRange(&curRange->fNext, gId - repeats - 1);
- curRange->fAdvance.append(1, &lastAdvance);
- finishRange(curRange, gId - 1,
- SkAdvancedTypefaceMetrics::WidthRange::kRun);
- curRange = appendRange(&curRange->fNext, gId);
- }
- repeats = 0;
- }
- curRange->fAdvance.append(1, &advance);
- lastAdvance = advance;
+ if (getAdvances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) {
+ return false;
}
- finishRange(curRange, face->num_glyphs - 1,
- SkAdvancedTypefaceMetrics::WidthRange::kRange);
- return result.release();
+ SkASSERT(data);
+ *data = advance;
+ return true;
}
// static
@@ -499,6 +417,7 @@
// Figure out a good guess for StemV - Min width of i, I, !, 1.
// This probably isn't very good with an italic font.
int16_t min_width = SHRT_MAX;
+ info->fStemV = 0;
char stem_chars[] = {'i', 'I', '!', '1'};
for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
FT_BBox bbox;
@@ -550,7 +469,7 @@
info->fGlyphWidths->fAdvance.append(1, &advance);
finishRange(info->fGlyphWidths.get(), 0,
SkAdvancedTypefaceMetrics::WidthRange::kDefault);
- } else if(!cid) {
+ } else if (!cid) {
appendRange(&info->fGlyphWidths, 0);
// So as to not blow out the stack, get advances in batches.
for (int gID = 0; gID < face->num_glyphs; gID += 128) {
@@ -568,7 +487,8 @@
finishRange(info->fGlyphWidths.get(), face->num_glyphs - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
} else {
- info->fGlyphWidths.reset(getAdvanceData(face, &getWidthAdvance));
+ info->fGlyphWidths.reset(
+ getAdvanceData(face, face->num_glyphs, &getWidthAdvance));
}
if (info->fType == SkAdvancedTypefaceMetrics::kType1_Font) {