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/SkGraphics.h"
13 #include "include/core/SkPaint.h"
14 #include "include/core/SkPoint.h"
15 #include "include/core/SkRect.h"
16 #include "include/core/SkStream.h"
17 #include "include/core/SkTypeface.h"
18 #include "include/core/SkTypes.h"
19 #include "src/core/SkFontDescriptor.h"
20 #include "src/core/SkFontPriv.h"
21 #include "tests/Test.h"
22 
23 static const SkColor bgColor = SK_ColorWHITE;
24 
create(SkBitmap * bm,SkIRect bound)25 static void create(SkBitmap* bm, SkIRect bound) {
26     bm->allocN32Pixels(bound.width(), bound.height());
27 }
28 
drawBG(SkCanvas * canvas)29 static void drawBG(SkCanvas* canvas) {
30     canvas->drawColor(bgColor);
31 }
32 
33 /** Assumes that the ref draw was completely inside ref canvas --
34     implies that everything outside is "bgColor".
35     Checks that all overlap is the same and that all non-overlap on the
36     ref is "bgColor".
37  */
compare(const SkBitmap & ref,const SkIRect & iref,const SkBitmap & test,const SkIRect & itest)38 static bool compare(const SkBitmap& ref, const SkIRect& iref,
39                     const SkBitmap& test, const SkIRect& itest)
40 {
41     const int xOff = itest.fLeft - iref.fLeft;
42     const int yOff = itest.fTop - iref.fTop;
43 
44     for (int y = 0; y < test.height(); ++y) {
45         for (int x = 0; x < test.width(); ++x) {
46             SkColor testColor = test.getColor(x, y);
47             int refX = x + xOff;
48             int refY = y + yOff;
49             SkColor refColor;
50             if (refX >= 0 && refX < ref.width() &&
51                 refY >= 0 && refY < ref.height())
52             {
53                 refColor = ref.getColor(refX, refY);
54             } else {
55                 refColor = bgColor;
56             }
57             if (refColor != testColor) {
58                 return false;
59             }
60         }
61     }
62     return true;
63 }
64 
DEF_TEST(FontHostStream,reporter)65 DEF_TEST(FontHostStream, reporter) {
66     {
67         SkPaint paint;
68         paint.setColor(SK_ColorGRAY);
69 
70         SkFont font(SkTypeface::MakeFromName("Georgia", SkFontStyle()), 30);
71         font.setEdging(SkFont::Edging::kAlias);
72 
73         SkIRect origRect = SkIRect::MakeWH(64, 64);
74         SkBitmap origBitmap;
75         create(&origBitmap, origRect);
76         SkCanvas origCanvas(origBitmap);
77 
78         SkIRect streamRect = SkIRect::MakeWH(64, 64);
79         SkBitmap streamBitmap;
80         create(&streamBitmap, streamRect);
81         SkCanvas streamCanvas(streamBitmap);
82 
83         SkPoint point = SkPoint::Make(24, 32);
84 
85         // Test: origTypeface and streamTypeface from orig data draw the same
86         drawBG(&origCanvas);
87         origCanvas.drawString("A", point.fX, point.fY, font, paint);
88 
89         sk_sp<SkTypeface> typeface = font.refTypefaceOrDefault();
90         int ttcIndex;
91         std::unique_ptr<SkStreamAsset> fontData = typeface->openStream(&ttcIndex);
92         if (!fontData) {
93             // We're using a SkTypeface that can't give us a stream.
94             // This happens with portable or system fonts.  End the test now.
95             return;
96         }
97 
98         sk_sp<SkTypeface> streamTypeface(SkTypeface::MakeFromStream(std::move(fontData)));
99 
100         SkFontDescriptor desc;
101         bool isLocalStream = false;
102         streamTypeface->getFontDescriptor(&desc, &isLocalStream);
103         REPORTER_ASSERT(reporter, isLocalStream);
104 
105         font.setTypeface(streamTypeface);
106         drawBG(&streamCanvas);
107         streamCanvas.drawString("A", point.fX, point.fY, font, paint);
108 
109         REPORTER_ASSERT(reporter,
110                         compare(origBitmap, origRect, streamBitmap, streamRect));
111     }
112     //Make sure the typeface is deleted and removed.
113     SkGraphics::PurgeFontCache();
114 }
115