Home | History | Annotate | Download | only in gpu
      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 
     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 
     45 SkGrDescKey::~SkGrDescKey() {
     46     if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
     47         SkDescriptor::Free(fDesc);
     48     }
     49 }
     50 
     51 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 
     63 bool SkGrDescKey::eq(const GrKey& rh) const {
     64     const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
     65     return fDesc->equals(*srcDesc);
     66 }
     67 
     68 ///////////////////////////////////////////////////////////////////////////////
     69 
     70 SkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
     71     fStrike = strike;
     72     fKey = NULL;
     73 }
     74 
     75 SkGrFontScaler::~SkGrFontScaler() {
     76     GrSafeUnref(fKey);
     77 }
     78 
     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 
     96 const GrKey* SkGrFontScaler::getKey() {
     97     if (NULL == fKey) {
     98         fKey = new SkGrDescKey(fStrike->getDescriptor());
     99     }
    100     return fKey;
    101 }
    102 
    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 
    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 
    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)
    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