C++程序  |  172行  |  4.67 KB

/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H
#define ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H

#include <GLES2/gl2.h>

#include <SkPaint.h>

#include <utils/String16.h>

#include "utils/Compare.h"
#include "utils/GenerationCache.h"
#include "FontRenderer.h"
#include "Texture.h"

namespace android {
namespace uirenderer {

struct ShadowText {
    ShadowText(): radius(0), len(0), textSize(0.0f), typeface(NULL) {
    }

    ShadowText(SkPaint* paint, uint32_t radius, uint32_t len, const char* srcText,
            const float* positions):
            radius(radius), len(len), positions(positions) {
        // TODO: Propagate this through the API, we should not cast here
        text = (const char16_t*) srcText;

        textSize = paint->getTextSize();
        typeface = paint->getTypeface();

        flags = 0;
        if (paint->isFakeBoldText()) {
            flags |= Font::kFakeBold;
        }

        const float skewX = paint->getTextSkewX();
        italicStyle = *(uint32_t*) &skewX;

        const float scaleXFloat = paint->getTextScaleX();
        scaleX = *(uint32_t*) &scaleXFloat;
    }

    ~ShadowText() {
    }

    uint32_t radius;
    uint32_t len;
    float textSize;
    SkTypeface* typeface;
    uint32_t flags;
    uint32_t italicStyle;
    uint32_t scaleX;
    const char16_t* text;
    const float* positions;
    String16 str;
    Vector<float> positionsCopy;

    void copyTextLocally() {
        str.setTo((const char16_t*) text, len >> 1);
        text = str.string();
        if (positions != NULL) {
            positionsCopy.clear();
            positionsCopy.appendArray(positions, len);
            positions = positionsCopy.array();
        }
    }

    bool operator<(const ShadowText& rhs) const {
        LTE_INT(len) {
            LTE_INT(radius) {
                LTE_FLOAT(textSize) {
                    LTE_INT(typeface) {
                        LTE_INT(flags) {
                            LTE_INT(italicStyle) {
                                LTE_INT(scaleX) {
                                    int cmp = memcmp(text, rhs.text, len);
                                    if (cmp < 0) return true;
                                    if (cmp == 0 && rhs.positions != NULL) {
                                        if (positions == NULL) return true;
                                        return memcmp(positions, rhs.positions, len << 2) < 0;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }
}; // struct ShadowText

/**
 * Alpha texture used to represent a shadow.
 */
struct ShadowTexture: public Texture {
    ShadowTexture(): Texture() {
    }

    float left;
    float top;
}; // struct ShadowTexture

class TextDropShadowCache: public OnEntryRemoved<ShadowText, ShadowTexture*> {
public:
    TextDropShadowCache();
    TextDropShadowCache(uint32_t maxByteSize);
    ~TextDropShadowCache();

    /**
     * Used as a callback when an entry is removed from the cache.
     * Do not invoke directly.
     */
    void operator()(ShadowText& text, ShadowTexture*& texture);

    ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len,
            int numGlyphs, uint32_t radius, const float* positions);

    /**
     * Clears the cache. This causes all textures to be deleted.
     */
    void clear();

    void setFontRenderer(FontRenderer& fontRenderer) {
        mRenderer = &fontRenderer;
    }

    /**
     * Sets the maximum size of the cache in bytes.
     */
    void setMaxSize(uint32_t maxSize);
    /**
     * Returns the maximum size of the cache in bytes.
     */
    uint32_t getMaxSize();
    /**
     * Returns the current size of the cache in bytes.
     */
    uint32_t getSize();

private:
    void init();

    GenerationCache<ShadowText, ShadowTexture*> mCache;

    uint32_t mSize;
    uint32_t mMaxSize;
    FontRenderer* mRenderer;
    bool mDebugEnabled;
}; // class TextDropShadowCache

}; // namespace uirenderer
}; // namespace android

#endif // ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H