SkAdvancedTypefaceMetrics: getAdvanceData uses std::function

Reduce templatedness.
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1955053002

Review-Url: https://codereview.chromium.org/1955053002
This commit is contained in:
halcanary 2016-05-09 06:34:39 -07:00 committed by Commit bot
parent 74e9a4dcd3
commit 57cd94a9de
7 changed files with 67 additions and 118 deletions

View File

@ -9,24 +9,6 @@
#include "SkAdvancedTypefaceMetrics.h"
#include "SkTypes.h"
#if defined(SK_BUILD_FOR_WIN)
#include <dwrite.h>
#endif
// forward declare structs needed for getAdvanceData() template for freetype
struct FT_FaceRec_;
typedef struct FT_FaceRec_* FT_Face;
#ifdef SK_BUILD_FOR_MAC
#import <ApplicationServices/ApplicationServices.h>
#endif
#ifdef SK_BUILD_FOR_IOS
#include <CoreText/CoreText.h>
#include <CoreGraphics/CoreGraphics.h>
#include <CoreFoundation/CoreFoundation.h>
#endif
SkAdvancedTypefaceMetrics::~SkAdvancedTypefaceMetrics() {}
const int16_t kInvalidAdvance = SK_MinS16;
@ -87,13 +69,11 @@ void SkAdvancedTypefaceMetrics::FinishRange(
zeroWildcardsInRange(range);
}
template <typename FontHandle>
void SkAdvancedTypefaceMetrics::setGlyphWidths(
FontHandle fontHandle,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(FontHandle fontHandle, int gId, int16_t* data)) {
SkAdvancedTypefaceMetrics::GetAdvance getAdvance) {
// 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
@ -135,7 +115,7 @@ void SkAdvancedTypefaceMetrics::setGlyphWidths(
if (!subsetGlyphIDs ||
(subsetIndex < subsetGlyphIDsLength &&
static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
SkAssertResult(getAdvance(fontHandle, gId, &advance));
SkAssertResult(getAdvance(gId, &advance));
++subsetIndex;
} else {
advance = kDontCareAdvance;
@ -212,41 +192,3 @@ void SkAdvancedTypefaceMetrics::setGlyphWidths(
fGlyphWidths.emplace_back(std::move(curRange));
}
}
// Make AdvanceMetric template functions available for linking with typename
// WidthRange and VerticalAdvanceRange.
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
FT_Face face,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
#if defined(SK_BUILD_FOR_WIN)
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
HDC hdc,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
IDWriteFontFace* fontFace,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(IDWriteFontFace* fontFace, int gId, int16_t* data));
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
CTFontRef ctFont,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(CTFontRef ctFont, int gId, int16_t* data));
#endif
// additional declaration needed for testing with a face of an unknown type
template void SkAdvancedTypefaceMetrics::setGlyphWidths(
void* fontData,
int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(void* fontData, int gId, int16_t* data));

View File

@ -55,14 +55,11 @@ public:
passes back advance data from the
typeface. Returns false on failure.
*/
template <typename FontHandle>
void setGlyphWidths(FontHandle fontHandle,
int num_glyphs,
typedef std::function<bool(int glyphId, int16_t* advanceData)> GetAdvance;
void setGlyphWidths(int num_glyphs,
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(FontHandle fontHandle,
int gId,
int16_t* data));
GetAdvance getAdvance);
SkString fFontName;

View File

@ -432,16 +432,6 @@ static bool GetLetterCBox(FT_Face face, char letter, FT_BBox* bbox) {
return true;
}
static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
FT_Fixed advance = 0;
if (FT_Get_Advances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) {
return false;
}
SkASSERT(data);
*data = advance;
return true;
}
static void populate_glyph_to_unicode(FT_Face& face, SkTDArray<SkUnichar>* glyphToUnicode) {
FT_Long numGlyphs = face->num_glyphs;
glyphToUnicode->setCount(SkToInt(numGlyphs));
@ -615,8 +605,19 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics(
SkAdvancedTypefaceMetrics::WidthRange::kRange);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->setGlyphWidths(face, face->num_glyphs, glyphIDs,
glyphIDsCount, &getWidthAdvance);
info->setGlyphWidths(
face->num_glyphs, glyphIDs, glyphIDsCount,
SkAdvancedTypefaceMetrics::GetAdvance(
[face](int gId, int16_t* data) {
FT_Fixed advance = 0;
if (FT_Get_Advances(face, gId, 1,
FT_LOAD_NO_SCALE, &advance)) {
return false;
}
SkASSERT(data);
*data = advance;
return true;
}));
}
}

View File

@ -1512,15 +1512,6 @@ static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount,
}
}
static bool getWidthAdvance(CTFontRef ctFont, int gId, int16_t* data) {
CGSize advance;
advance.width = 0;
CGGlyph glyph = gId;
CTFontGetAdvancesForGlyphs(ctFont, kCTFontHorizontalOrientation, &glyph, &advance, 1);
*data = sk_float_round2int(advance.width);
return true;
}
/** Assumes src and dst are not nullptr. */
static void CFStringToSkString(CFStringRef src, SkString* dst) {
// Reserve enough room for the worst-case string,
@ -1625,8 +1616,20 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics(
&range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->setGlyphWidths(ctFont.get(), SkToInt(glyphCount), glyphIDs,
glyphIDsCount, &getWidthAdvance);
CTFontRef borrowedCTFont = ctFont.get();
info->setGlyphWidths(
SkToInt(glyphCount), glyphIDs, glyphIDsCount,
SkAdvancedTypefaceMetrics::GetAdvance(
[borrowedCTFont](int gId, int16_t* data) {
CGSize advance;
advance.width = 0;
CGGlyph glyph = gId;
CTFontGetAdvancesForGlyphs(
borrowedCTFont, kCTFontHorizontalOrientation,
&glyph, &advance, 1);
*data = sk_float_round2int(advance.width);
return true;
}));
}
}
return info;

View File

@ -1717,20 +1717,6 @@ void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
*isLocalStream = this->fSerializeAsStream;
}
static bool getWidthAdvance(HDC hdc, int gId, int16_t* advance) {
// Initialize the MAT2 structure to the identify transformation matrix.
static const MAT2 mat2 = {SkScalarToFIXED(1), SkScalarToFIXED(0),
SkScalarToFIXED(0), SkScalarToFIXED(1)};
int flags = GGO_METRICS | GGO_GLYPH_INDEX;
GLYPHMETRICS gm;
if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, nullptr, &mat2)) {
return false;
}
SkASSERT(advance);
*advance = gm.gmCellIncX;
return true;
}
SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics(
PerGlyphInfo perGlyphInfo,
const uint32_t* glyphIDs,
@ -1839,8 +1825,25 @@ SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics(
&range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->setGlyphWidths(hdc, glyphCount, glyphIDs,
glyphIDsCount, &getWidthAdvance);
info->setGlyphWidths(
glyphCount, glyphIDs, glyphIDsCount,
SkAdvancedTypefaceMetrics::GetAdvance(
[hdc](int gId, int16_t* advance) {
// Initialize the MAT2 structure to
// the identify transformation matrix.
static const MAT2 mat2 = {
SkScalarToFIXED(1), SkScalarToFIXED(0),
SkScalarToFIXED(0), SkScalarToFIXED(1)};
int flags = GGO_METRICS | GGO_GLYPH_INDEX;
GLYPHMETRICS gm;
if (GDI_ERROR == GetGlyphOutline(
hdc, gId, flags, &gm, 0, nullptr, &mat2)) {
return false;
}
SkASSERT(advance);
*advance = gm.gmCellIncX;
return true;
}));
}
}

View File

@ -450,8 +450,13 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
&range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
info->fGlyphWidths.emplace_back(std::move(range));
} else {
info->setGlyphWidths(fDWriteFontFace.get(), glyphCount, glyphIDs,
glyphIDsCount, getWidthAdvance);
IDWriteFontFace* borrowedFontFace = fDWriteFontFace.get();
info->setGlyphWidths(
glyphCount, glyphIDs, glyphIDsCount,
SkAdvancedTypefaceMetrics::GetAdvance(
[borrowedFontFace](int gId, int16_t* data) {
return getWidthAdvance(borrowedFontFace, gId, data);
}));
}
}

View File

@ -150,19 +150,17 @@ class TestWData {
const int fSubsetLen;
const char* fExpected;
static bool getAdvance(void* tc, int gId, int16_t* advance) {
TestWData* testCase = (TestWData*)tc;
if (gId >= 0 && gId < testCase->fAdvancesLen) {
*advance = testCase->fAdvances[gId];
return true;
}
return false;
}
void runTest(skiatest::Reporter* reporter) {
SkAdvancedTypefaceMetrics metrics;
metrics.setGlyphWidths((void*)this, fAdvancesLen, fSubset, fSubsetLen,
getAdvance);
metrics.setGlyphWidths(
fAdvancesLen, fSubset, fSubsetLen,
std::function<bool(int, int16_t*)>([this](int gId, int16_t* advance) {
if (gId >= 0 && gId < fAdvancesLen) {
*advance = fAdvances[gId];
return true;
}
return false;
}));
SkString stringResult = stringify_advance_data(metrics.fGlyphWidths);
if (!stringResult.equals(fExpected)) {