28constexpr int kGmWidth = 1000;
31constexpr float kLangYIncrementScale = 1.9;
37void comparePixels(
const SkBitmap& bitmapA,
48 for (int32_t
x = 0;
x < dimensions.
fWidth;
x++) {
49 for (int32_t
y = 0;
y < dimensions.
fHeight;
y++) {
59 if (
dr != 0 ||
dg != 0 || db != 0) {
73 std::string fontNameFilterRegexp,
74 std::string langFilterRegexp)
75 : fTestDataIterator(fontNameFilterRegexp, langFilterRegexp)
76 , fTestName(testName.c_str()) {
87 fTestDataIterator.
rewind();
98 fTestDataIterator.
rewind();
107 if (!testTypeface || !ftTypeface) {
108 *errorMsg =
"Unable to initialize typeface.";
112 auto configureFont = [](
SkFont& font) {
115 font.setSubpixel(
true);
119 SkFont font(testTypeface);
122 SkFont ftFont(ftTypeface);
123 configureFont(ftFont);
124 enum class DrawPhase { Fontations, FreeType, Comparison };
127 for (
auto phase : {DrawPhase::Fontations, DrawPhase::FreeType, DrawPhase::Comparison}) {
130 for (
auto& langEntry :
testSet.langSamples) {
131 auto shapeAndDrawToCanvas = [canvas,
paint, langEntry](
const SkFont& font,
133 std::string testString(langEntry.sampleShort.c_str(),
134 langEntry.sampleShort.size());
137 shaper->shape(testString.c_str(),
145 return blob->bounds();
148 auto roundToDevicePixels = [canvas](
SkPoint& point) {
154 bool inverseExists = ctm.
invert(&inverse);
157 point = inverse.
mapPoint(mappedRounded);
161 auto fontationsCoord = [yCoord, roundToDevicePixels]() {
163 roundToDevicePixels(fontationsCoord);
164 return fontationsCoord;
167 auto freetypeCoord = [yCoord, maxBounds, roundToDevicePixels]() {
169 2 *
kMargin + maxBounds.left() + maxBounds.width(), yCoord);
170 roundToDevicePixels(freetypeCoord);
171 return freetypeCoord;
175 case DrawPhase::Fontations: {
176 SkRect boundsFontations = shapeAndDrawToCanvas(font, fontationsCoord());
179 maxBounds.join(boundsFontations);
182 case DrawPhase::FreeType: {
183 shapeAndDrawToCanvas(ftFont, freetypeCoord());
186 case DrawPhase::Comparison: {
192 SkPoint copyBoxFontationsCoord = fontationsCoord();
193 SkPoint copyBoxFreetypeCoord = freetypeCoord();
194 SkRect copyBoxFontations(maxBounds);
195 copyBoxFontations.
roundOut(©BoxFontations);
196 SkRect copyBoxFreetype(copyBoxFontations);
197 copyBoxFontations.
offset(copyBoxFontationsCoord.
x(),
198 copyBoxFontationsCoord.
y());
199 copyBoxFreetype.
offset(copyBoxFreetypeCoord.
x(),
200 copyBoxFreetypeCoord.
y());
203 ctm.
mapRect(©BoxFontations, copyBoxFontations);
204 ctm.
mapRect(©BoxFreetype, copyBoxFreetype);
213 SkBitmap fontationsBitmap, freetypeBitmap, diffBitmap,
221 fontationsBitmap, copyBoxFontations.
x(), copyBoxFontations.
y());
223 freetypeBitmap, copyBoxFreetype.
x(), copyBoxFreetype.
y());
225 comparePixels(fontationsBitmap,
228 &highlightDiffBitmap);
233 3 *
kMargin + maxBounds.width() * 2, yCoord + maxBounds.top()));
235 4 *
kMargin + maxBounds.width() * 3, yCoord + maxBounds.top()));
238 diffBitmap, comparisonCoord.
x(), comparisonCoord.
y());
240 highlightDiffBitmap, whiteCoord.
x(), whiteCoord.
y());
245 yCoord += font.getSize() * kLangYIncrementScale;
254 using INHERITED =
GM;
259 std::unique_ptr<SkFontArguments::VariationPosition::Coordinate[]> fCoordinates;
265 "en_Latn|es_Latn|pt_Latn|id_Latn|ru_Cyrl|fr_Latn|tr_Latn|vi_Latn|de_"
266 "Latn|it_Latn|pl_Latn|nl_Latn|uk_Cyrl|gl_Latn|ro_Latn|cs_Latn|hu_Latn|"
267 "el_Grek|se_Latn|da_Latn|bg_Latn|sk_Latn|fi_Latn|bs_Latn|ca_Latn|no_"
268 "Latn|sr_Latn|sr_Cyrl|lt_Latn|hr_Latn|sl_Latn|uz_Latn|uz_Cyrl|lv_Latn|"
269 "et_Latn|az_Latn|az_Cyrl|la_Latn|tg_Latn|tg_Cyrl|sw_Latn|mn_Cyrl|kk_"
270 "Latn|kk_Cyrl|sq_Latn|af_Latn|ha_Latn|ky_Cyrl"));
273 "Noto Sans Devanagari",
278 "ar_Arab|uz_Arab|kk_Arab|ky_Arab"));
static const ConicPts testSet[]
#define SkGetPackedB32(packed)
#define SkGetPackedR32(packed)
#define SkGetPackedG32(packed)
static SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
constexpr SkColor SK_ColorBLACK
constexpr SkColor SK_ColorWHITE
@ kNone
glyph outlines unchanged
static int32_t SkAbs32(int32_t value)
SK_API SkString static SkString SkStringPrintf()
SK_API sk_sp< SkTypeface > SkTypeface_Make_Fontations(std::unique_ptr< SkStreamAsset > fontData, const SkFontArguments &args)
void allocPixels(const SkImageInfo &info, size_t rowBytes)
SkISize dimensions() const
SkColorType colorType() const
int bytesPerPixel() const
uint32_t * getAddr32(int x, int y) const
SkMatrix getLocalToDeviceAs3x3() const
bool writePixels(const SkImageInfo &info, const void *pixels, size_t rowBytes, int x, int y)
SkImageInfo imageInfo() const
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY)
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
SkPoint mapPoint(SkPoint pt) const
bool invert(SkMatrix *inverse) const
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
static std::unique_ptr< SkShaper > Make(sk_sp< SkFontMgr > fallback=nullptr)
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
const char * c_str() const
sk_sp< SkTextBlob > makeBlob()
static sk_sp< SkTypeface > MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
bool next(TestSet *testSet)
SkISize getISize() override
SkString getName() const override
FontationsFtCompareGM(std::string testName, std::string fontNameFilterRegexp, std::string langFilterRegexp)
DrawResult onDraw(SkCanvas *canvas, SkString *errorMsg) override
static constexpr SkISize Make(int32_t w, int32_t h)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkAlphaType alphaType() const
SkColorType colorType() const
static constexpr SkPoint Make(float x, float y)
constexpr float y() const
constexpr float x() const
static constexpr SkRect MakeEmpty()
constexpr float x() const
constexpr float y() const
void roundOut(SkIRect *dst) const
void offset(float dx, float dy)