1
2 /*
3 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10
11 #include "SkGr.h"
12 #include "SkDescriptor.h"
13 #include "SkGlyphCache.h"
14
15 class SkGrDescKey : public GrKey {
16 public:
17 explicit SkGrDescKey(const SkDescriptor& desc);
18 virtual ~SkGrDescKey();
19
20 protected:
21 // overrides
22 virtual bool lt(const GrKey& rh) const;
23 virtual bool eq(const GrKey& rh) const;
24
25 private:
26 SkDescriptor* fDesc;
27 enum {
28 kMaxStorageInts = 16
29 };
30 uint32_t fStorage[kMaxStorageInts];
31 };
32
33 ///////////////////////////////////////////////////////////////////////////////
34
SkGrDescKey(const SkDescriptor & desc)35 SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
36 size_t size = desc.getLength();
37 if (size <= sizeof(fStorage)) {
38 fDesc = GrTCast<SkDescriptor*>(fStorage);
39 } else {
40 fDesc = SkDescriptor::Alloc(size);
41 }
42 memcpy(fDesc, &desc, size);
43 }
44
~SkGrDescKey()45 SkGrDescKey::~SkGrDescKey() {
46 if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
47 SkDescriptor::Free(fDesc);
48 }
49 }
50
lt(const GrKey & rh) const51 bool SkGrDescKey::lt(const GrKey& rh) const {
52 const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
53 size_t lenLH = fDesc->getLength();
54 size_t lenRH = srcDesc->getLength();
55 int cmp = memcmp(fDesc, srcDesc, SkMin32(lenLH, lenRH));
56 if (0 == cmp) {
57 return lenLH < lenRH;
58 } else {
59 return cmp < 0;
60 }
61 }
62
eq(const GrKey & rh) const63 bool SkGrDescKey::eq(const GrKey& rh) const {
64 const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
65 return fDesc->equals(*srcDesc);
66 }
67
68 ///////////////////////////////////////////////////////////////////////////////
69
SkGrFontScaler(SkGlyphCache * strike)70 SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
71 fStrike = strike;
72 fKey = NULL;
73 }
74
~SkGrFontScaler()75 SkGrFontScaler::~SkGrFontScaler() {
76 GrSafeUnref(fKey);
77 }
78
getMaskFormat()79 GrMaskFormat SkGrFontScaler::getMaskFormat() {
80 SkMask::Format format = fStrike->getMaskFormat();
81 switch (format) {
82 case SkMask::kBW_Format:
83 // fall through to kA8 -- we store BW glyphs in our 8-bit cache
84 case SkMask::kA8_Format:
85 return kA8_GrMaskFormat;
86 case SkMask::kLCD16_Format:
87 return kA565_GrMaskFormat;
88 case SkMask::kLCD32_Format:
89 return kA888_GrMaskFormat;
90 default:
91 GrAssert(!"unsupported SkMask::Format");
92 return kA8_GrMaskFormat;
93 }
94 }
95
getKey()96 const GrKey* SkGrFontScaler::getKey() {
97 if (NULL == fKey) {
98 fKey = new SkGrDescKey(fStrike->getDescriptor());
99 }
100 return fKey;
101 }
102
getPackedGlyphBounds(GrGlyph::PackedID packed,GrIRect * bounds)103 bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
104 GrIRect* bounds) {
105 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
106 GrGlyph::UnpackFixedX(packed),
107 GrGlyph::UnpackFixedY(packed));
108 bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
109 return true;
110
111 }
112
bits_to_bytes(const uint8_t bits[],uint8_t bytes[],int count)113 static void bits_to_bytes(const uint8_t bits[], uint8_t bytes[], int count) {
114 while (count > 0) {
115 unsigned mask = *bits++;
116 for (int i = 7; i >= 0; --i) {
117 *bytes++ = (mask & (1 << i)) ? 0xFF : 0;
118 if (--count == 0) {
119 return;
120 }
121 }
122 }
123 }
124
getPackedGlyphImage(GrGlyph::PackedID packed,int width,int height,int dstRB,void * dst)125 bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
126 int width, int height,
127 int dstRB, void* dst) {
128 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
129 GrGlyph::UnpackFixedX(packed),
130 GrGlyph::UnpackFixedY(packed));
131 GrAssert(glyph.fWidth == width);
132 GrAssert(glyph.fHeight == height);
133 const void* src = fStrike->findImage(glyph);
134 if (NULL == src) {
135 return false;
136 }
137
138 int srcRB = glyph.rowBytes();
139 if (SkMask::kBW_Format == fStrike->getMaskFormat()) {
140 // expand bits to bytes
141 const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
142 uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
143 for (int y = 0; y < height; y++) {
144 bits_to_bytes(bits, bytes, width);
145 bits += srcRB;
146 bytes += dstRB;
147 }
148 } else if (srcRB == dstRB) {
149 memcpy(dst, src, dstRB * height);
150 } else {
151 const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
152 for (int y = 0; y < height; y++) {
153 memcpy(dst, src, width * bbp);
154 src = (const char*)src + srcRB;
155 dst = (char*)dst + dstRB;
156 }
157 }
158 return true;
159 }
160
161 // we should just return const SkPath* (NULL means false)
getGlyphPath(uint16_t glyphID,GrPath * path)162 bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, GrPath* path) {
163
164 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
165 const SkPath* skPath = fStrike->findPath(glyph);
166 if (skPath) {
167 *path = *skPath;
168 return true;
169 }
170 return false;
171 }
172
173
174
175