Home | History | Annotate | Download | only in gpu
      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