81eabce6a3
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>
110 lines
3.6 KiB
C++
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|