blob: 16e44b9d09d988b046cdb3f27407ac526a77b459 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
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
22class SkGrDescKey : public GrKey {
23public:
24 explicit SkGrDescKey(const SkDescriptor& desc);
25 virtual ~SkGrDescKey();
reed@google.com1fcd51e2011-01-05 15:50:27 +000026
reed@google.comac10a2d2010-12-22 21:39:39 +000027protected:
28 // overrides
29 virtual bool lt(const GrKey& rh) const;
30 virtual bool eq(const GrKey& rh) const;
reed@google.com1fcd51e2011-01-05 15:50:27 +000031
reed@google.comac10a2d2010-12-22 21:39:39 +000032private:
33 SkDescriptor* fDesc;
34 enum {
35 kMaxStorageInts = 16
36 };
37 uint32_t fStorage[kMaxStorageInts];
38};
39
40///////////////////////////////////////////////////////////////////////////////
41
42SkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
43 size_t size = desc.getLength();
44 if (size <= sizeof(fStorage)) {
reed@google.com1fcd51e2011-01-05 15:50:27 +000045 fDesc = GrTCast<SkDescriptor*>(fStorage);
reed@google.comac10a2d2010-12-22 21:39:39 +000046 } else {
47 fDesc = SkDescriptor::Alloc(size);
48 }
49 memcpy(fDesc, &desc, size);
50}
51
52SkGrDescKey::~SkGrDescKey() {
reed@google.com1fcd51e2011-01-05 15:50:27 +000053 if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
reed@google.comac10a2d2010-12-22 21:39:39 +000054 SkDescriptor::Free(fDesc);
55 }
56}
57
58bool 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
70bool SkGrDescKey::eq(const GrKey& rh) const {
71 const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
72 return fDesc->equals(*srcDesc);
73}
74
75///////////////////////////////////////////////////////////////////////////////
76
77SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
78 fStrike = strike;
79 fKey = NULL;
80}
81
82SkGrFontScaler::~SkGrFontScaler() {
83 GrSafeUnref(fKey);
84}
85
reed@google.com98539c62011-03-15 15:40:16 +000086GrMaskFormat SkGrFontScaler::getMaskFormat() {
87 SkMask::Format format = fStrike->getMaskFormat();
88 switch (format) {
89 case SkMask::kA8_Format:
90 return kA8_GrMaskFormat;
91 case SkMask::kLCD16_Format:
92 return kA565_GrMaskFormat;
93 default:
94 GrAssert(!"unsupported SkMask::Format");
95 return kA8_GrMaskFormat;
96 }
97}
98
reed@google.comac10a2d2010-12-22 21:39:39 +000099const GrKey* SkGrFontScaler::getKey() {
100 if (NULL == fKey) {
101 fKey = new SkGrDescKey(fStrike->getDescriptor());
102 }
103 return fKey;
104}
105
106bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
107 GrIRect* bounds) {
108 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
109 GrGlyph::UnpackFixedX(packed),
110 GrGlyph::UnpackFixedY(packed));
111 bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
112 return true;
reed@google.com1fcd51e2011-01-05 15:50:27 +0000113
reed@google.comac10a2d2010-12-22 21:39:39 +0000114}
115
116bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
117 int width, int height,
118 int dstRB, void* dst) {
119 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
120 GrGlyph::UnpackFixedX(packed),
121 GrGlyph::UnpackFixedY(packed));
122 GrAssert(glyph.fWidth == width);
123 GrAssert(glyph.fHeight == height);
124 const void* src = fStrike->findImage(glyph);
125 if (NULL == src) {
126 return false;
127 }
128
129 int srcRB = glyph.rowBytes();
130 if (srcRB == dstRB) {
131 memcpy(dst, src, dstRB * height);
132 } else {
reed@google.com98539c62011-03-15 15:40:16 +0000133 const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
reed@google.comac10a2d2010-12-22 21:39:39 +0000134 for (int y = 0; y < height; y++) {
reed@google.com98539c62011-03-15 15:40:16 +0000135 memcpy(dst, src, width * bbp);
reed@google.comac10a2d2010-12-22 21:39:39 +0000136 src = (const char*)src + srcRB;
137 dst = (char*)dst + dstRB;
138 }
139 }
140 return true;
141}
142
143bool SkGrFontScaler::getGlyphPath(uint16_t glyphID, GrPath* path) {
reed@google.com1fcd51e2011-01-05 15:50:27 +0000144
reed@google.comac10a2d2010-12-22 21:39:39 +0000145 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
146 const SkPath* skPath = fStrike->findPath(glyph);
147 if (skPath) {
148 SkGrPathIter iter(*skPath);
149 path->resetFromIter(&iter);
150 return true;
151 }
152 return false;
153}
154
155
156