#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;
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
if (!subsetGlyphIDs ||
(subsetIndex < subsetGlyphIDsLength &&
static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
- SkAssertResult(getAdvance(fontHandle, gId, &advance));
+ SkAssertResult(getAdvance(gId, &advance));
++subsetIndex;
} else {
advance = kDontCareAdvance;
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));
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;
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));
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;
+ }));
}
}
}
}
-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,
&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;
*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,
&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;
+ }));
}
}
&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);
+ }));
}
}
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)) {