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