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