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:
parent
74e9a4dcd3
commit
57cd94a9de
@ -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));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user