1 /*
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"
9 #include "include/utils/SkCustomTypeface.h"
10 #include "src/core/SkAutoMalloc.h"
11 #include "src/core/SkFontPriv.h"
12 #include "src/core/SkPtrRecorder.h"
13 #include "src/core/SkReadBuffer.h"
14 #include "src/core/SkWriteBuffer.h"
15 #include "tests/Test.h"
16 #include "tools/ToolUtils.h"
17 
serialize_deserialize(const SkFont & font,skiatest::Reporter * reporter)18 static SkFont serialize_deserialize(const SkFont& font, skiatest::Reporter* reporter) {
19     sk_sp<SkRefCntSet> typefaces = sk_make_sp<SkRefCntSet>();
20     SkBinaryWriteBuffer wb;
21     wb.setTypefaceRecorder(typefaces);
22 
23     SkFontPriv::Flatten(font, wb);
24     size_t size = wb.bytesWritten();
25     SkAutoMalloc storage(size);
26     wb.writeToMemory(storage.get());
27 
28     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     }
36 
37     SkReadBuffer rb(storage.get(), size);
38     sk_sp<SkTypeface> cloneTypeface = font.refTypeface();
39     if (count) {
40         rb.setTypefaceArray(&cloneTypeface, 1);
41     }
42     SkFont clone;
43     REPORTER_ASSERT(reporter, SkFontPriv::Unflatten(&clone, rb));
44     return clone;
45 }
46 
47 enum {
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 
apply_flags(SkFont * font,unsigned flags)58 static 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 
DEF_TEST(Font_flatten,reporter)67 DEF_TEST(Font_flatten, reporter) {
68     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};
71     const SkFont::Edging edges[] = {
72         SkFont::Edging::kAlias, SkFont::Edging::kSubpixelAntiAlias
73     };
74     const SkFontHinting hints[] = {
75         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()
83     };
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);
96                         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                             }
103                         }
104                     }
105                 }
106             }
107         }
108     }
109 }
110