skia2/tests/FontTest.cpp
Ben Wagner 81eabce6a3 SkCustomTypefaceBuilder to set SkFontStyle
Allow the user of SkCustomTypefaceBuilder to set the SkFontStyle of the
resulting SkTypeface. This allows users to build font families.

Fix the Font_flatten test to actually work (instead of relying on the
magic behavior of nullptr for SkTypeface), add a test with the custom
typeface, and reduce the number of times the inner loop runs from
302,400 times to 4,032 times so that the test finishes in a reasonable
amount of time.

Bug: skia:10630
Change-Id: I0b5e939552ee4a9a1249eefbb7a7279a59b38e5a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/311596
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Xiao Yu <xster@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
2020-08-19 00:09:55 +00:00

110 lines
3.6 KiB
C++

/*
* Copyright 2019 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkFont.h"
#include "include/utils/SkCustomTypeface.h"
#include "src/core/SkAutoMalloc.h"
#include "src/core/SkFontPriv.h"
#include "src/core/SkPtrRecorder.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"
#include "tests/Test.h"
#include "tools/ToolUtils.h"
static SkFont serialize_deserialize(const SkFont& font, skiatest::Reporter* reporter) {
sk_sp<SkRefCntSet> typefaces = sk_make_sp<SkRefCntSet>();
SkBinaryWriteBuffer wb;
wb.setTypefaceRecorder(typefaces);
SkFontPriv::Flatten(font, wb);
size_t size = wb.bytesWritten();
SkAutoMalloc storage(size);
wb.writeToMemory(storage.get());
int count = typefaces->count();
SkASSERT((!font.getTypeface() && count == 0) ||
( font.getTypeface() && count == 1));
if (count) {
SkTypeface* typeface;
typefaces->copyToArray((SkRefCnt**)&typeface);
SkASSERT(typeface == font.getTypeface());
}
SkReadBuffer rb(storage.get(), size);
sk_sp<SkTypeface> cloneTypeface = font.refTypeface();
if (count) {
rb.setTypefaceArray(&cloneTypeface, 1);
}
SkFont clone;
REPORTER_ASSERT(reporter, SkFontPriv::Unflatten(&clone, rb));
return clone;
}
enum {
kForceAutoHinting = 1 << 0,
kEmbeddedBitmaps = 1 << 1,
kSubpixel = 1 << 2,
kLinearMetrics = 1 << 3,
kEmbolden = 1 << 4,
kBaselineSnap = 1 << 5,
kAllBits = 0x3F,
};
static void apply_flags(SkFont* font, unsigned flags) {
font->setForceAutoHinting(SkToBool(flags & kForceAutoHinting));
font->setEmbeddedBitmaps( SkToBool(flags & kEmbeddedBitmaps));
font->setSubpixel( SkToBool(flags & kSubpixel));
font->setLinearMetrics( SkToBool(flags & kLinearMetrics));
font->setEmbolden( SkToBool(flags & kEmbolden));
font->setBaselineSnap( SkToBool(flags & kBaselineSnap));
}
DEF_TEST(Font_flatten, reporter) {
const float sizes[] = {0, 0.001f, 1, 10, 10.001f, 100000.01f};
const float scales[] = {-5, 0, 1, 5};
const float skews[] = {-5, 0, 5};
const SkFont::Edging edges[] = {
SkFont::Edging::kAlias, SkFont::Edging::kSubpixelAntiAlias
};
const SkFontHinting hints[] = {
SkFontHinting::kNone, SkFontHinting::kFull
};
const unsigned int flags[] = {
kForceAutoHinting, kEmbeddedBitmaps, kSubpixel, kLinearMetrics, kEmbolden, kBaselineSnap,
kAllBits,
};
const sk_sp<SkTypeface> typefaces[] = {
nullptr, ToolUtils::sample_user_typeface()
};
SkFont font;
for (float size : sizes) {
font.setSize(size);
for (float scale : scales) {
font.setScaleX(scale);
for (float skew : skews) {
font.setSkewX(skew);
for (auto edge : edges) {
font.setEdging(edge);
for (auto hint : hints) {
font.setHinting(hint);
for (auto flag : flags) {
apply_flags(&font, flag);
for (const sk_sp<SkTypeface>& typeface : typefaces) {
font.setTypeface(typeface);
SkFont clone = serialize_deserialize(font, reporter);
REPORTER_ASSERT(reporter, font == clone);
}
}
}
}
}
}
}
}