summaryrefslogtreecommitdiffstats
path: root/libs/hwui/FontRenderer.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/FontRenderer.h')
-rw-r--r--libs/hwui/FontRenderer.h257
1 files changed, 257 insertions, 0 deletions
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
new file mode 100644
index 0000000..96c92d5
--- /dev/null
+++ b/libs/hwui/FontRenderer.h
@@ -0,0 +1,257 @@
+/*
+ * 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_UI_FONT_RENDERER_H
+#define ANDROID_UI_FONT_RENDERER_H
+
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+
+#include <SkScalerContext.h>
+#include <SkPaint.h>
+
+#include <GLES2/gl2.h>
+
+#include "Rect.h"
+#include "Properties.h"
+
+namespace android {
+namespace uirenderer {
+
+class FontRenderer;
+
+/**
+ * Represents a font, defined by a Skia font id and a font size. A font is used
+ * to generate glyphs and cache them in the FontState.
+ */
+class Font {
+public:
+ ~Font();
+
+ /**
+ * Renders the specified string of text.
+ * If bitmap is specified, it will be used as the render target
+ */
+ void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+ int numGlyphs, int x, int y,
+ uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
+ /**
+ * Creates a new font associated with the specified font state.
+ */
+ static Font* create(FontRenderer* state, uint32_t fontId, float fontSize);
+
+protected:
+ friend class FontRenderer;
+
+ enum RenderMode {
+ FRAMEBUFFER,
+ BITMAP,
+ MEASURE,
+ };
+
+ void renderUTF(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+ int numGlyphs, int x, int y, RenderMode mode,
+ uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
+ Rect *bounds);
+
+ void measureUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+ int numGlyphs, Rect *bounds);
+
+ struct CachedGlyphInfo {
+ // Has the cache been invalidated?
+ bool mIsValid;
+ // Location of the cached glyph in the bitmap
+ // in case we need to resize the texture or
+ // render to bitmap
+ uint32_t mStartX;
+ uint32_t mStartY;
+ uint32_t mBitmapWidth;
+ uint32_t mBitmapHeight;
+ // Also cache texture coords for the quad
+ float mBitmapMinU;
+ float mBitmapMinV;
+ float mBitmapMaxU;
+ float mBitmapMaxV;
+ // Minimize how much we call freetype
+ uint32_t mGlyphIndex;
+ uint32_t mAdvanceX;
+ uint32_t mAdvanceY;
+ // Values below contain a glyph's origin in the bitmap
+ int32_t mBitmapLeft;
+ int32_t mBitmapTop;
+ };
+
+ Font(FontRenderer* state, uint32_t fontId, float fontSize);
+
+ DefaultKeyedVector<int32_t, CachedGlyphInfo*> mCachedGlyphs;
+
+ void invalidateTextureCache();
+
+ CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
+ void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
+ void measureCachedGlyph(CachedGlyphInfo *glyph, int x, int y, Rect *bounds);
+ void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
+ void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y,
+ uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
+
+ CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
+
+ FontRenderer* mState;
+ uint32_t mFontId;
+ float mFontSize;
+};
+
+class FontRenderer {
+public:
+ FontRenderer();
+ ~FontRenderer();
+
+ void init();
+ void deinit();
+
+ void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
+ void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
+ uint32_t len, int numGlyphs, int x, int y);
+
+ struct DropShadow {
+ DropShadow() { };
+
+ DropShadow(const DropShadow& dropShadow):
+ width(dropShadow.width), height(dropShadow.height),
+ image(dropShadow.image), penX(dropShadow.penX),
+ penY(dropShadow.penY) {
+ }
+
+ uint32_t width;
+ uint32_t height;
+ uint8_t* image;
+ int32_t penX;
+ int32_t penY;
+ };
+
+ // After renderDropShadow returns, the called owns the memory in DropShadow.image
+ // and is responsible for releasing it when it's done with it
+ DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
+ uint32_t len, int numGlyphs, uint32_t radius);
+
+ GLuint getTexture() {
+ checkInit();
+ return mTextureId;
+ }
+
+protected:
+ friend class Font;
+
+ struct CacheTextureLine {
+ uint16_t mMaxHeight;
+ uint16_t mMaxWidth;
+ uint32_t mCurrentRow;
+ uint32_t mCurrentCol;
+ bool mDirty;
+
+ CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
+ uint32_t currentCol):
+ mMaxHeight(maxHeight),
+ mMaxWidth(maxWidth),
+ mCurrentRow(currentRow),
+ mCurrentCol(currentCol),
+ mDirty(false) {
+ }
+
+ bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
+ if (glyph.fHeight > mMaxHeight) {
+ return false;
+ }
+
+ if (mCurrentCol + glyph.fWidth < mMaxWidth) {
+ *retOriginX = mCurrentCol;
+ *retOriginY = mCurrentRow;
+ mCurrentCol += glyph.fWidth;
+ mDirty = true;
+ return true;
+ }
+
+ return false;
+ }
+ };
+
+ uint32_t getCacheWidth() const {
+ return mCacheWidth;
+ }
+
+ uint32_t getCacheHeight() const {
+ return mCacheHeight;
+ }
+
+ void initTextTexture();
+ bool cacheBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY);
+
+ void flushAllAndInvalidate();
+ void initVertexArrayBuffers();
+
+ void checkInit();
+
+ String16 mLatinPrecache;
+ void precacheLatin(SkPaint* paint);
+
+ void issueDrawCommand();
+ void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
+ float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
+ float x4, float y4, float z4, float u4, float v4);
+
+ uint32_t mCacheWidth;
+ uint32_t mCacheHeight;
+
+ Vector<CacheTextureLine*> mCacheLines;
+ uint32_t getRemainingCacheCapacity();
+
+ Font* mCurrentFont;
+ Vector<Font*> mActiveFonts;
+
+ // Texture to cache glyph bitmaps
+ uint8_t* mTextTexture;
+ const uint8_t* getTextTextureData() const {
+ return mTextTexture;
+ }
+ GLuint mTextureId;
+ void checkTextureUpdate();
+ bool mUploadTexture;
+
+ // Pointer to vertex data to speed up frame to frame work
+ float *mTextMeshPtr;
+ uint32_t mCurrentQuadIndex;
+ uint32_t mMaxNumberOfQuads;
+
+ uint32_t mIndexBufferID;
+
+ const Rect* mClip;
+
+ bool mInitialized;
+
+ void computeGaussianWeights(float* weights, int32_t radius);
+ void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
+ int32_t width, int32_t height);
+ void verticalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,
+ int32_t width, int32_t height);
+ void blurImage(uint8_t* image, int32_t width, int32_t height, int32_t radius);
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_UI_FONT_RENDERER_H