• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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