xref: /aosp_15_r20/external/skia/tests/FontHostStreamTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2011 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/SkBitmap.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkColor.h"
11 #include "include/core/SkFont.h"
12 #include "include/core/SkFontMgr.h"
13 #include "include/core/SkFontStyle.h"
14 #include "include/core/SkGraphics.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkPoint.h"
17 #include "include/core/SkRect.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkStream.h"
20 #include "include/core/SkTypeface.h"
21 #include "include/core/SkTypes.h"
22 #include "src/core/SkFontDescriptor.h"
23 #include "src/core/SkFontPriv.h"
24 #include "tests/Test.h"
25 #include "tools/fonts/FontToolUtils.h"
26 
27 #include <memory>
28 #include <utility>
29 
30 static const SkColor bgColor = SK_ColorWHITE;
31 
create(SkBitmap * bm,SkIRect bound)32 static void create(SkBitmap* bm, SkIRect bound) {
33     bm->allocN32Pixels(bound.width(), bound.height());
34 }
35 
drawBG(SkCanvas * canvas)36 static void drawBG(SkCanvas* canvas) {
37     canvas->drawColor(bgColor);
38 }
39 
40 /** Assumes that the ref draw was completely inside ref canvas --
41     implies that everything outside is "bgColor".
42     Checks that all overlap is the same and that all non-overlap on the
43     ref is "bgColor".
44  */
compare(const SkBitmap & ref,const SkIRect & iref,const SkBitmap & test,const SkIRect & itest)45 static bool compare(const SkBitmap& ref, const SkIRect& iref,
46                     const SkBitmap& test, const SkIRect& itest)
47 {
48     const int xOff = itest.fLeft - iref.fLeft;
49     const int yOff = itest.fTop - iref.fTop;
50 
51     for (int y = 0; y < test.height(); ++y) {
52         for (int x = 0; x < test.width(); ++x) {
53             SkColor testColor = test.getColor(x, y);
54             int refX = x + xOff;
55             int refY = y + yOff;
56             SkColor refColor;
57             if (refX >= 0 && refX < ref.width() &&
58                 refY >= 0 && refY < ref.height())
59             {
60                 refColor = ref.getColor(refX, refY);
61             } else {
62                 refColor = bgColor;
63             }
64             if (refColor != testColor) {
65                 return false;
66             }
67         }
68     }
69     return true;
70 }
71 
DEF_TEST(FontHostStream,reporter)72 DEF_TEST(FontHostStream, reporter) {
73     {
74         SkPaint paint;
75         paint.setColor(SK_ColorGRAY);
76 
77         SkFont font(ToolUtils::CreateTestTypeface("Georgia", SkFontStyle()), 30);
78         font.setEdging(SkFont::Edging::kAlias);
79 
80         const SkIRect origRect = SkIRect::MakeWH(64, 64);
81         SkBitmap origBitmap;
82         create(&origBitmap, origRect);
83         SkCanvas origCanvas(origBitmap);
84 
85         SkPoint point = SkPoint::Make(24, 32);
86 
87         // Test: origTypeface and streamTypeface from orig data draw the same
88         drawBG(&origCanvas);
89         origCanvas.drawString("A", point.fX, point.fY, font, paint);
90 
91         sk_sp<SkFontMgr> mgr = ToolUtils::TestFontMgr();
92         sk_sp<SkTypeface> typeface = font.refTypeface();
93         SkASSERT_RELEASE(typeface);
94 
95         {
96             SkDynamicMemoryWStream wstream;
97             typeface->serialize(&wstream, SkTypeface::SerializeBehavior::kDoIncludeData);
98             std::unique_ptr<SkStreamAsset> stream = wstream.detachAsStream();
99             sk_sp<SkTypeface> deserializedTypeface = SkTypeface::MakeDeserialize(&*stream, mgr);
100             if (!deserializedTypeface) {
101                 REPORTER_ASSERT(reporter, deserializedTypeface);
102                 return;
103             }
104 
105             SkFontDescriptor desc;
106             bool mustSerializeData = false;
107             deserializedTypeface->getFontDescriptor(&desc, &mustSerializeData);
108             REPORTER_ASSERT(reporter, mustSerializeData);
109 
110             SkBitmap deserializedBitmap;
111             create(&deserializedBitmap, origRect);
112             SkCanvas deserializedCanvas(deserializedBitmap);
113 
114             font.setTypeface(deserializedTypeface);
115             drawBG(&deserializedCanvas);
116             deserializedCanvas.drawString("A", point.fX, point.fY, font, paint);
117 
118             REPORTER_ASSERT(reporter, compare(origBitmap, origRect, deserializedBitmap, origRect));
119         }
120 
121         {
122             int ttcIndex;
123             std::unique_ptr<SkStreamAsset> fontData = typeface->openStream(&ttcIndex);
124             if (!fontData) {
125                 REPORTER_ASSERT(reporter, fontData);
126                 return;
127             }
128 
129             sk_sp<SkTypeface> streamTypeface(mgr->makeFromStream(std::move(fontData), 0));
130             if (!streamTypeface) {
131                 // TODO: enable assert after SkTypeface::MakeFromStream uses factories
132                 //REPORTER_ASSERT(reporter, streamTypeface);
133                 return;
134             }
135 
136             SkBitmap streamBitmap;
137             create(&streamBitmap, origRect);
138             SkCanvas streamCanvas(streamBitmap);
139 
140             SkFontDescriptor desc;
141             bool mustSerializeData = false;
142             streamTypeface->getFontDescriptor(&desc, &mustSerializeData);
143             REPORTER_ASSERT(reporter, mustSerializeData);
144 
145             font.setTypeface(streamTypeface);
146             drawBG(&streamCanvas);
147             streamCanvas.drawString("A", point.fX, point.fY, font, paint);
148 
149             REPORTER_ASSERT(reporter, compare(origBitmap, origRect, streamBitmap, origRect));
150         }
151     }
152     //Make sure the typeface is deleted and removed.
153     SkGraphics::PurgeFontCache();
154 }
155