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