1 /*
2  * Copyright 2010 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 #ifndef GrGlyph_DEFINED
9 #define GrGlyph_DEFINED
10 
11 #include "GrDrawOpAtlas.h"
12 #include "GrRect.h"
13 #include "GrTypes.h"
14 
15 #include "SkChecksum.h"
16 #include "SkFixed.h"
17 #include "SkPath.h"
18 
19 struct GrGlyph {
20     enum MaskStyle {
21         kCoverage_MaskStyle,
22         kDistance_MaskStyle
23     };
24 
25     static GrMaskFormat FormatFromSkGlyph(const SkGlyph& glyph) {
26         SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
27         switch (format) {
28             case SkMask::kBW_Format:
29             case SkMask::kSDF_Format:
30                 // fall through to kA8 -- we store BW and SDF glyphs in our 8-bit cache
31             case SkMask::kA8_Format:
32                 return kA8_GrMaskFormat;
33             case SkMask::k3D_Format:
34                 return kA8_GrMaskFormat; // ignore the mul and add planes, just use the mask
35             case SkMask::kLCD16_Format:
36                 return kA565_GrMaskFormat;
37             case SkMask::kARGB32_Format:
38                 return kARGB_GrMaskFormat;
39             default:
40                 SkDEBUGFAIL("unsupported SkMask::Format");
41                 return kA8_GrMaskFormat;
42         }
43     }
44 
45     static GrIRect16 BoundsFromSkGlyph(const SkGlyph& glyph) {
46         return GrIRect16::MakeXYWH(glyph.fLeft,
47                                    glyph.fTop,
48                                    glyph.fWidth,
49                                    glyph.fHeight);
50     }
51 
52     static MaskStyle MaskStyleFromSkGlyph(const SkGlyph& skGlyph) {
53         return (SkMask::Format)skGlyph.fMaskFormat == SkMask::kSDF_Format
54            ? GrGlyph::MaskStyle::kDistance_MaskStyle
55            : GrGlyph::MaskStyle::kCoverage_MaskStyle;
56     }
57 
58     GrGlyph(const SkGlyph& skGlyph)
59         : fPackedID{skGlyph.getPackedID()}
60         , fMaskFormat{FormatFromSkGlyph(skGlyph)}
61         , fMaskStyle{MaskStyleFromSkGlyph(skGlyph)}
62         , fBounds{BoundsFromSkGlyph(skGlyph)} {}
63 
64 
65     SkRect destRect(SkPoint origin) {
66         return SkRect::MakeXYWH(
67                 SkIntToScalar(fBounds.fLeft) + origin.x(),
68                 SkIntToScalar(fBounds.fTop)  + origin.y(),
69                 SkIntToScalar(fBounds.width()),
70                 SkIntToScalar(fBounds.height()));
71     }
72 
73     SkRect destRect(SkPoint origin, SkScalar textScale) {
74         if (fMaskStyle == kCoverage_MaskStyle) {
75             return SkRect::MakeXYWH(
76                     SkIntToScalar(fBounds.fLeft)    * textScale + origin.x(),
77                     SkIntToScalar(fBounds.fTop)     * textScale + origin.y(),
78                     SkIntToScalar(fBounds.width())  * textScale,
79                     SkIntToScalar(fBounds.height()) * textScale);
80         } else {
81             return SkRect::MakeXYWH(
82                     (SkIntToScalar(fBounds.fLeft) + SK_DistanceFieldInset) * textScale + origin.x(),
83                     (SkIntToScalar(fBounds.fTop)  + SK_DistanceFieldInset) * textScale + origin.y(),
84                     (SkIntToScalar(fBounds.width())  - 2 * SK_DistanceFieldInset) * textScale,
85                     (SkIntToScalar(fBounds.height()) - 2 * SK_DistanceFieldInset) * textScale);
86         }
87     }
88 
89     int width() const { return fBounds.width(); }
90     int height() const { return fBounds.height(); }
91     uint32_t pageIndex() const { return GrDrawOpAtlas::GetPageIndexFromID(fID); }
92     MaskStyle maskStyle() const { return fMaskStyle; }
93 
94     // GetKey and Hash for the the hash table.
95     static const SkPackedGlyphID& GetKey(const GrGlyph& glyph) {
96         return glyph.fPackedID;
97     }
98 
99     static uint32_t Hash(SkPackedGlyphID key) {
100         return SkChecksum::Mix(key.hash());
101     }
102 
103     const SkPackedGlyphID  fPackedID;
104     const GrMaskFormat     fMaskFormat;
105     const MaskStyle        fMaskStyle;
106     const GrIRect16        fBounds;
107     SkIPoint16             fAtlasLocation{0, 0};
108     GrDrawOpAtlas::AtlasID fID{GrDrawOpAtlas::kInvalidAtlasID};
109 };
110 
111 #endif
112