3 * Copyright 2010 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #include "GrTemplates.h"
11 #include "GrFontScaler.h"
12 #include "SkDescriptor.h"
13 #include "SkDistanceFieldGen.h"
14 #include "SkGlyphCache.h"
16 ///////////////////////////////////////////////////////////////////////////////
18 GrFontDescKey::GrFontDescKey(const SkDescriptor& desc) : fHash(desc.getChecksum()) {
19 size_t size = desc.getLength();
20 if (size <= sizeof(fStorage)) {
21 fDesc = GrTCast<SkDescriptor*>(fStorage);
23 fDesc = SkDescriptor::Alloc(size);
25 memcpy(fDesc, &desc, size);
28 GrFontDescKey::~GrFontDescKey() {
29 if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
30 SkDescriptor::Free(fDesc);
34 bool GrFontDescKey::lt(const GrFontDescKey& rh) const {
35 const SkDescriptor* srcDesc = (&rh)->fDesc;
36 size_t lenLH = fDesc->getLength();
37 size_t lenRH = srcDesc->getLength();
38 int cmp = memcmp(fDesc, srcDesc, SkTMin<size_t>(lenLH, lenRH));
46 bool GrFontDescKey::eq(const GrFontDescKey& rh) const {
47 const SkDescriptor* srcDesc = (&rh)->fDesc;
48 return fDesc->equals(*srcDesc);
51 ///////////////////////////////////////////////////////////////////////////////
53 GrFontScaler::GrFontScaler(SkGlyphCache* strike) {
58 GrFontScaler::~GrFontScaler() {
62 GrMaskFormat GrFontScaler::getMaskFormat() {
63 SkMask::Format format = fStrike->getMaskFormat();
65 case SkMask::kBW_Format:
66 // fall through to kA8 -- we store BW glyphs in our 8-bit cache
67 case SkMask::kA8_Format:
68 return kA8_GrMaskFormat;
69 case SkMask::kLCD16_Format:
70 return kA565_GrMaskFormat;
71 case SkMask::kLCD32_Format:
72 return kA888_GrMaskFormat;
73 case SkMask::kARGB32_Format:
74 return kARGB_GrMaskFormat;
76 SkDEBUGFAIL("unsupported SkMask::Format");
77 return kA8_GrMaskFormat;
81 const GrFontDescKey* GrFontScaler::getKey() {
83 fKey = SkNEW_ARGS(GrFontDescKey, (fStrike->getDescriptor()));
88 bool GrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
89 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
90 GrGlyph::UnpackFixedX(packed),
91 GrGlyph::UnpackFixedY(packed));
92 bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
97 bool GrFontScaler::getPackedGlyphDFBounds(GrGlyph::PackedID packed, SkIRect* bounds) {
98 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
99 GrGlyph::UnpackFixedX(packed),
100 GrGlyph::UnpackFixedY(packed));
101 bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
102 bounds->outset(SK_DistanceFieldPad, SK_DistanceFieldPad);
108 // expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to
109 // A8, RGB565, or RGBA8888.
110 template <typename INT_TYPE>
111 void expand_bits(INT_TYPE* dst,
117 for (int i = 0; i < height; ++i) {
118 int rowWritesLeft = width;
119 const uint8_t* s = src;
121 while (rowWritesLeft > 0) {
122 unsigned mask = *s++;
123 for (int i = 7; i >= 0 && rowWritesLeft; --i, --rowWritesLeft) {
124 *d++ = (mask & (1 << i)) ? (INT_TYPE)(~0UL) : 0;
127 dst = reinterpret_cast<INT_TYPE*>(reinterpret_cast<intptr_t>(dst) + dstRowBytes);
133 bool GrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
134 int width, int height,
135 int dstRB, void* dst) {
136 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
137 GrGlyph::UnpackFixedX(packed),
138 GrGlyph::UnpackFixedY(packed));
139 SkASSERT(glyph.fWidth == width);
140 SkASSERT(glyph.fHeight == height);
141 const void* src = fStrike->findImage(glyph);
146 int srcRB = glyph.rowBytes();
147 // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to
148 // check the glyph's format, not the strike's format, and to be able to convert to any of the
150 if (SkMask::kBW_Format == glyph.fMaskFormat) {
151 // expand bits to our mask type
152 const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
153 switch (this->getMaskFormat()) {
154 case kA8_GrMaskFormat:{
155 uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
156 expand_bits(bytes, bits, width, height, dstRB, srcRB);
159 case kA565_GrMaskFormat: {
160 uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst);
161 expand_bits(rgb565, bits, width, height, dstRB, srcRB);
164 case kA888_GrMaskFormat: {
165 uint32_t* rgba8888 = reinterpret_cast<uint32_t*>(dst);
166 expand_bits(rgba8888, bits, width, height, dstRB, srcRB);
170 SkFAIL("Invalid GrMaskFormat");
172 } else if (srcRB == dstRB) {
173 memcpy(dst, src, dstRB * height);
175 const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
176 for (int y = 0; y < height; y++) {
177 memcpy(dst, src, width * bbp);
178 src = (const char*)src + srcRB;
179 dst = (char*)dst + dstRB;
185 bool GrFontScaler::getPackedGlyphDFImage(GrGlyph::PackedID packed,
186 int width, int height,
188 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
189 GrGlyph::UnpackFixedX(packed),
190 GrGlyph::UnpackFixedY(packed));
191 SkASSERT(glyph.fWidth + 2*SK_DistanceFieldPad == width);
192 SkASSERT(glyph.fHeight + 2*SK_DistanceFieldPad == height);
193 const void* src = fStrike->findDistanceField(glyph);
198 memcpy(dst, src, width * height);
203 // we should just return const SkPath* (NULL means false)
204 bool GrFontScaler::getGlyphPath(uint16_t glyphID, SkPath* path) {
206 const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
207 const SkPath* skPath = fStrike->findPath(glyph);