xref: /aosp_15_r20/external/skia/tests/FontTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/core/SkFontTypes.h"
10 #include "include/core/SkRefCnt.h"
11 #include "include/core/SkTypeface.h"
12 #include "include/core/SkTypes.h"
13 #include "include/private/base/SkTo.h"
14 #include "src/base/SkAutoMalloc.h"
15 #include "src/core/SkFontPriv.h"
16 #include "src/core/SkPtrRecorder.h"
17 #include "src/core/SkReadBuffer.h"
18 #include "src/core/SkWriteBuffer.h"
19 #include "tests/Test.h"
20 #include "tools/ToolUtils.h"
21 #include "tools/fonts/FontToolUtils.h"
22 
23 #include <cstddef>
24 
serialize_deserialize(const SkFont & font,skiatest::Reporter * reporter)25 static SkFont serialize_deserialize(const SkFont& font, skiatest::Reporter* reporter) {
26     sk_sp<SkRefCntSet> typefaces = sk_make_sp<SkRefCntSet>();
27     SkBinaryWriteBuffer wb({});
28     wb.setTypefaceRecorder(typefaces);
29 
30     SkFontPriv::Flatten(font, wb);
31     size_t size = wb.bytesWritten();
32     SkAutoMalloc storage(size);
33     wb.writeToMemory(storage.get());
34 
35     int count = typefaces->count();
36     SkASSERT((!font.getTypeface() && count == 0) ||
37              ( font.getTypeface() && count == 1));
38     if (count) {
39         SkTypeface* typeface;
40         typefaces->copyToArray((SkRefCnt**)&typeface);
41         SkASSERT(typeface == font.getTypeface());
42     }
43 
44     SkReadBuffer rb(storage.get(), size);
45     sk_sp<SkTypeface> cloneTypeface = font.refTypeface();
46     if (count) {
47         rb.setTypefaceArray(&cloneTypeface, 1);
48     }
49     SkFont clone;
50     REPORTER_ASSERT(reporter, SkFontPriv::Unflatten(&clone, rb));
51     return clone;
52 }
53 
54 enum {
55     kForceAutoHinting      = 1 << 0,
56     kEmbeddedBitmaps       = 1 << 1,
57     kSubpixel              = 1 << 2,
58     kLinearMetrics         = 1 << 3,
59     kEmbolden              = 1 << 4,
60     kBaselineSnap          = 1 << 5,
61 
62     kAllBits = 0x3F,
63 };
64 
apply_flags(SkFont * font,unsigned flags)65 static void apply_flags(SkFont* font, unsigned flags) {
66     font->setForceAutoHinting(SkToBool(flags & kForceAutoHinting));
67     font->setEmbeddedBitmaps( SkToBool(flags & kEmbeddedBitmaps));
68     font->setSubpixel(        SkToBool(flags & kSubpixel));
69     font->setLinearMetrics(   SkToBool(flags & kLinearMetrics));
70     font->setEmbolden(        SkToBool(flags & kEmbolden));
71     font->setBaselineSnap(    SkToBool(flags & kBaselineSnap));
72 }
73 
DEF_TEST(Font_flatten,reporter)74 DEF_TEST(Font_flatten, reporter) {
75     const float sizes[] = {0, 0.001f, 1, 10, 10.001f, 100000.01f};
76     const float scales[] = {-5, 0, 1, 5};
77     const float skews[] = {-5, 0, 5};
78     const SkFont::Edging edges[] = {
79         SkFont::Edging::kAlias, SkFont::Edging::kSubpixelAntiAlias
80     };
81     const SkFontHinting hints[] = {
82         SkFontHinting::kNone, SkFontHinting::kFull
83     };
84     const unsigned int flags[] = {
85         kForceAutoHinting, kEmbeddedBitmaps, kSubpixel, kLinearMetrics, kEmbolden, kBaselineSnap,
86         kAllBits,
87     };
88     const sk_sp<SkTypeface> typefaces[] = {
89         nullptr, ToolUtils::SampleUserTypeface()
90     };
91 
92     SkFont font;
93     for (float size : sizes) {
94         font.setSize(size);
95         for (float scale : scales) {
96             font.setScaleX(scale);
97             for (float skew : skews) {
98                 font.setSkewX(skew);
99                 for (auto edge : edges) {
100                     font.setEdging(edge);
101                     for (auto hint : hints) {
102                         font.setHinting(hint);
103                         for (auto flag : flags) {
104                             apply_flags(&font, flag);
105                             for (const sk_sp<SkTypeface>& typeface : typefaces) {
106                                 font.setTypeface(typeface);
107                                 SkFont clone = serialize_deserialize(font, reporter);
108                                 REPORTER_ASSERT(reporter, font == clone);
109                             }
110                         }
111                     }
112                 }
113             }
114         }
115     }
116 }
117