105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2010 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger */
805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkGr.h"
1205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkDescriptor.h"
1305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger#include "SkGlyphCache.h"
1405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerclass SkGrDescKey : public GrKey {
1605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerpublic:
1705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    explicit SkGrDescKey(const SkDescriptor& desc);
1805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    virtual ~SkGrDescKey();
1905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerprotected:
2105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    // overrides
2205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    virtual bool lt(const GrKey& rh) const;
2305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    virtual bool eq(const GrKey& rh) const;
2405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
2505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerprivate:
2605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    SkDescriptor* fDesc;
2705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    enum {
2805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        kMaxStorageInts = 16
2905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    };
3005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    uint32_t fStorage[kMaxStorageInts];
3105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger};
3205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
3405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
3505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGrDescKey::SkGrDescKey(const SkDescriptor& desc) : GrKey(desc.getChecksum()) {
3605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    size_t size = desc.getLength();
3705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (size <= sizeof(fStorage)) {
3805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fDesc = GrTCast<SkDescriptor*>(fStorage);
3905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
4005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fDesc = SkDescriptor::Alloc(size);
4105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
4205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    memcpy(fDesc, &desc, size);
4305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
4405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
4505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGrDescKey::~SkGrDescKey() {
4605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (fDesc != GrTCast<SkDescriptor*>(fStorage)) {
4705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        SkDescriptor::Free(fDesc);
4805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
4905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
5005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
5105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGrDescKey::lt(const GrKey& rh) const {
5205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
5305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    size_t lenLH = fDesc->getLength();
5405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    size_t lenRH = srcDesc->getLength();
5505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    int cmp = memcmp(fDesc, srcDesc, SkMin32(lenLH, lenRH));
5605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (0 == cmp) {
5705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return lenLH < lenRH;
5805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
5905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return cmp < 0;
6005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
6105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
6205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
6305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGrDescKey::eq(const GrKey& rh) const {
6405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkDescriptor* srcDesc = ((const SkGrDescKey*)&rh)->fDesc;
6505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return fDesc->equals(*srcDesc);
6605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
6705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
6805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
6905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
7005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGrFontScaler::SkGrFontScaler(SkGlyphCache* strike) {
7105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fStrike = strike;
7205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    fKey = NULL;
7305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
7405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
7505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek SollenbergerSkGrFontScaler::~SkGrFontScaler() {
7605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrSafeUnref(fKey);
7705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
7805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
79137a4ca42423bbb6d683067ea544c9a48f18f06cDerek SollenbergerGrMaskFormat SkGrFontScaler::getMaskFormat() {
80137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    SkMask::Format format = fStrike->getMaskFormat();
81137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    switch (format) {
8287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        case SkMask::kBW_Format:
8387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            // fall through to kA8 -- we store BW glyphs in our 8-bit cache
84137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        case SkMask::kA8_Format:
85137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger            return kA8_GrMaskFormat;
86137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        case SkMask::kLCD16_Format:
87137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger            return kA565_GrMaskFormat;
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        case SkMask::kLCD32_Format:
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return kA888_GrMaskFormat;
90137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        default:
91137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger            GrAssert(!"unsupported SkMask::Format");
92137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger            return kA8_GrMaskFormat;
93137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger    }
94137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger}
95137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger
9605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerconst GrKey* SkGrFontScaler::getKey() {
9705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == fKey) {
9805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        fKey = new SkGrDescKey(fStrike->getDescriptor());
9905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
10005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return fKey;
10105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
10205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
10305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed,
10405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                          GrIRect* bounds) {
10505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
10605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                              GrGlyph::UnpackFixedX(packed),
10705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                              GrGlyph::UnpackFixedY(packed));
10805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
10905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return true;
11005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
11205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
11387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenbergerstatic void bits_to_bytes(const uint8_t bits[], uint8_t bytes[], int count) {
11487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    while (count > 0) {
11587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        unsigned mask = *bits++;
11687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        for (int i = 7; i >= 0; --i) {
11787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            *bytes++ = (mask & (1 << i)) ? 0xFF : 0;
11887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            if (--count == 0) {
11987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger                return;
12087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            }
12187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        }
12287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    }
12387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger}
12487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger
12505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed,
12605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         int width, int height,
12705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                         int dstRB, void* dst) {
12805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed),
12905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                              GrGlyph::UnpackFixedX(packed),
13005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger                                              GrGlyph::UnpackFixedY(packed));
13105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(glyph.fWidth == width);
13205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    GrAssert(glyph.fHeight == height);
13305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const void* src = fStrike->findImage(glyph);
13405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (NULL == src) {
13505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return false;
13605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
13705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
13805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    int srcRB = glyph.rowBytes();
13987b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    if (SkMask::kBW_Format == fStrike->getMaskFormat()) {
14087b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        // expand bits to bytes
14187b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
14287b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
14387b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        for (int y = 0; y < height; y++) {
14487b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            bits_to_bytes(bits, bytes, width);
14587b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            bits += srcRB;
14687b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger            bytes += dstRB;
14787b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger        }
14887b8e645865f9633f410c02252a0fd3feb18f09bDerek Sollenberger    } else if (srcRB == dstRB) {
14905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        memcpy(dst, src, dstRB * height);
15005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    } else {
151137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger        const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat());
15205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        for (int y = 0; y < height; y++) {
153137a4ca42423bbb6d683067ea544c9a48f18f06cDerek Sollenberger            memcpy(dst, src, width * bbp);
15405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            src = (const char*)src + srcRB;
15505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger            dst = (char*)dst + dstRB;
15605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        }
15705b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
15805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return true;
15905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
16005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
1610b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// we should just return const SkPath* (NULL means false)
16205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenbergerbool SkGrFontScaler::getGlyphPath(uint16_t glyphID, GrPath* path) {
16305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
16405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkGlyph& glyph = fStrike->getGlyphIDMetrics(glyphID);
16505b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    const SkPath* skPath = fStrike->findPath(glyph);
16605b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    if (skPath) {
1670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        *path = *skPath;
16805b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger        return true;
16905b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    }
17005b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger    return false;
17105b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger}
17205b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
17305b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
17405b6b4d746867a9fb02e14edfe1bf3685abeb813Derek Sollenberger
175