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 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 52 SkGrDescKey::~SkGrDescKey() { 53 if (fDesc != GrTCast<SkDescriptor*>(fStorage)) { 54 SkDescriptor::Free(fDesc); 55 } 56 } 57 58 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 70 bool SkGrDescKey::eq(const GrKey& rh) const { 71 const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc; 72 return fDesc->equals(*srcDesc); 73 } 74 75 /////////////////////////////////////////////////////////////////////////////// 76 77 SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) { 78 fStrike = strike; 79 fKey = NULL; 80 } 81 82 SkGrFontScaler::~SkGrFontScaler() { 83 GrSafeUnref(fKey); 84 } 85 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 101 const GrKey* SkGrFontScaler::getKey() { 102 if (NULL == fKey) { 103 fKey = new SkGrDescKey(fStrike->getDescriptor()); 104 } 105 return fKey; 106 } 107 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 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 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) 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