blob: 0e2ea548ba1fe80e32705ed814480dc31306f1da [file] [log] [blame]
Mike Reed052a05a2019-11-08 13:20:08 -05001/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "include/core/SkFont.h"
Ben Wagner81eabce2020-08-18 13:17:09 -04009#include "include/utils/SkCustomTypeface.h"
Mike Reed052a05a2019-11-08 13:20:08 -050010#include "src/core/SkAutoMalloc.h"
11#include "src/core/SkFontPriv.h"
Ben Wagner81eabce2020-08-18 13:17:09 -040012#include "src/core/SkPtrRecorder.h"
Mike Reed052a05a2019-11-08 13:20:08 -050013#include "src/core/SkReadBuffer.h"
14#include "src/core/SkWriteBuffer.h"
15#include "tests/Test.h"
Ben Wagner81eabce2020-08-18 13:17:09 -040016#include "tools/ToolUtils.h"
Mike Reed052a05a2019-11-08 13:20:08 -050017
18static SkFont serialize_deserialize(const SkFont& font, skiatest::Reporter* reporter) {
Ben Wagner81eabce2020-08-18 13:17:09 -040019 sk_sp<SkRefCntSet> typefaces = sk_make_sp<SkRefCntSet>();
Mike Reed052a05a2019-11-08 13:20:08 -050020 SkBinaryWriteBuffer wb;
Ben Wagner81eabce2020-08-18 13:17:09 -040021 wb.setTypefaceRecorder(typefaces);
Mike Reed052a05a2019-11-08 13:20:08 -050022
Ben Wagner81eabce2020-08-18 13:17:09 -040023 SkFontPriv::Flatten(font, wb);
Mike Reed052a05a2019-11-08 13:20:08 -050024 size_t size = wb.bytesWritten();
25 SkAutoMalloc storage(size);
26 wb.writeToMemory(storage.get());
27
Ben Wagner81eabce2020-08-18 13:17:09 -040028 int count = typefaces->count();
29 SkASSERT((!font.getTypeface() && count == 0) ||
30 ( font.getTypeface() && count == 1));
31 if (count) {
32 SkTypeface* typeface;
33 typefaces->copyToArray((SkRefCnt**)&typeface);
34 SkASSERT(typeface == font.getTypeface());
35 }
Mike Reed052a05a2019-11-08 13:20:08 -050036
Ben Wagner81eabce2020-08-18 13:17:09 -040037 SkReadBuffer rb(storage.get(), size);
38 sk_sp<SkTypeface> cloneTypeface = font.refTypeface();
39 if (count) {
40 rb.setTypefaceArray(&cloneTypeface, 1);
41 }
Mike Reed052a05a2019-11-08 13:20:08 -050042 SkFont clone;
43 REPORTER_ASSERT(reporter, SkFontPriv::Unflatten(&clone, rb));
44 return clone;
45}
46
47enum {
48 kForceAutoHinting = 1 << 0,
49 kEmbeddedBitmaps = 1 << 1,
50 kSubpixel = 1 << 2,
51 kLinearMetrics = 1 << 3,
52 kEmbolden = 1 << 4,
53 kBaselineSnap = 1 << 5,
54
55 kAllBits = 0x3F,
56};
57
58static void apply_flags(SkFont* font, unsigned flags) {
59 font->setForceAutoHinting(SkToBool(flags & kForceAutoHinting));
60 font->setEmbeddedBitmaps( SkToBool(flags & kEmbeddedBitmaps));
61 font->setSubpixel( SkToBool(flags & kSubpixel));
62 font->setLinearMetrics( SkToBool(flags & kLinearMetrics));
63 font->setEmbolden( SkToBool(flags & kEmbolden));
64 font->setBaselineSnap( SkToBool(flags & kBaselineSnap));
65}
66
67DEF_TEST(Font_flatten, reporter) {
Ben Wagner81eabce2020-08-18 13:17:09 -040068 const float sizes[] = {0, 0.001f, 1, 10, 10.001f, 100000.01f};
69 const float scales[] = {-5, 0, 1, 5};
70 const float skews[] = {-5, 0, 5};
Mike Reed052a05a2019-11-08 13:20:08 -050071 const SkFont::Edging edges[] = {
Ben Wagner81eabce2020-08-18 13:17:09 -040072 SkFont::Edging::kAlias, SkFont::Edging::kSubpixelAntiAlias
Mike Reed052a05a2019-11-08 13:20:08 -050073 };
74 const SkFontHinting hints[] = {
Ben Wagner81eabce2020-08-18 13:17:09 -040075 SkFontHinting::kNone, SkFontHinting::kFull
76 };
77 const unsigned int flags[] = {
78 kForceAutoHinting, kEmbeddedBitmaps, kSubpixel, kLinearMetrics, kEmbolden, kBaselineSnap,
79 kAllBits,
80 };
81 const sk_sp<SkTypeface> typefaces[] = {
82 nullptr, ToolUtils::sample_user_typeface()
Mike Reed052a05a2019-11-08 13:20:08 -050083 };
84
85 SkFont font;
86 for (float size : sizes) {
87 font.setSize(size);
88 for (float scale : scales) {
89 font.setScaleX(scale);
90 for (float skew : skews) {
91 font.setSkewX(skew);
92 for (auto edge : edges) {
93 font.setEdging(edge);
94 for (auto hint : hints) {
95 font.setHinting(hint);
Ben Wagner81eabce2020-08-18 13:17:09 -040096 for (auto flag : flags) {
97 apply_flags(&font, flag);
98 for (const sk_sp<SkTypeface>& typeface : typefaces) {
99 font.setTypeface(typeface);
100 SkFont clone = serialize_deserialize(font, reporter);
101 REPORTER_ASSERT(reporter, font == clone);
102 }
Mike Reed052a05a2019-11-08 13:20:08 -0500103 }
104 }
105 }
106 }
107 }
108 }
109}