xref: /aosp_15_r20/frameworks/rs/rsFont.h (revision e1eccf28f96817838ad6867f7f39d2351ec11f56)
1*e1eccf28SAndroid Build Coastguard Worker /*
2*e1eccf28SAndroid Build Coastguard Worker  * Copyright (C) 2009 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker  *
4*e1eccf28SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker  *
8*e1eccf28SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker  *
10*e1eccf28SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker  * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker  */
16*e1eccf28SAndroid Build Coastguard Worker 
17*e1eccf28SAndroid Build Coastguard Worker #ifndef ANDROID_RS_FONT_H
18*e1eccf28SAndroid Build Coastguard Worker #define ANDROID_RS_FONT_H
19*e1eccf28SAndroid Build Coastguard Worker 
20*e1eccf28SAndroid Build Coastguard Worker #include "rsStream.h"
21*e1eccf28SAndroid Build Coastguard Worker #include <utils/KeyedVector.h>
22*e1eccf28SAndroid Build Coastguard Worker #include <utils/Unicode.h>
23*e1eccf28SAndroid Build Coastguard Worker 
24*e1eccf28SAndroid Build Coastguard Worker struct FT_LibraryRec_;
25*e1eccf28SAndroid Build Coastguard Worker struct FT_FaceRec_;
26*e1eccf28SAndroid Build Coastguard Worker struct FT_Bitmap_;
27*e1eccf28SAndroid Build Coastguard Worker 
28*e1eccf28SAndroid Build Coastguard Worker // ---------------------------------------------------------------------------
29*e1eccf28SAndroid Build Coastguard Worker namespace android {
30*e1eccf28SAndroid Build Coastguard Worker 
31*e1eccf28SAndroid Build Coastguard Worker namespace renderscript {
32*e1eccf28SAndroid Build Coastguard Worker 
33*e1eccf28SAndroid Build Coastguard Worker // Gamma (>= 1.0, <= 10.0)
34*e1eccf28SAndroid Build Coastguard Worker #define PROPERTY_TEXT_GAMMA "ro.text_gamma"
35*e1eccf28SAndroid Build Coastguard Worker #define PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD "ro.text_gamma.black_threshold"
36*e1eccf28SAndroid Build Coastguard Worker #define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "ro.text_gamma.white_threshold"
37*e1eccf28SAndroid Build Coastguard Worker 
38*e1eccf28SAndroid Build Coastguard Worker #define DEFAULT_TEXT_GAMMA 1.4f
39*e1eccf28SAndroid Build Coastguard Worker #define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64
40*e1eccf28SAndroid Build Coastguard Worker #define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192
41*e1eccf28SAndroid Build Coastguard Worker 
42*e1eccf28SAndroid Build Coastguard Worker class FontState;
43*e1eccf28SAndroid Build Coastguard Worker 
44*e1eccf28SAndroid Build Coastguard Worker class Font : public ObjectBase {
45*e1eccf28SAndroid Build Coastguard Worker public:
46*e1eccf28SAndroid Build Coastguard Worker     enum RenderMode {
47*e1eccf28SAndroid Build Coastguard Worker         FRAMEBUFFER,
48*e1eccf28SAndroid Build Coastguard Worker         BITMAP,
49*e1eccf28SAndroid Build Coastguard Worker         MEASURE,
50*e1eccf28SAndroid Build Coastguard Worker     };
51*e1eccf28SAndroid Build Coastguard Worker 
52*e1eccf28SAndroid Build Coastguard Worker     struct Rect {
53*e1eccf28SAndroid Build Coastguard Worker         int32_t left;
54*e1eccf28SAndroid Build Coastguard Worker         int32_t top;
55*e1eccf28SAndroid Build Coastguard Worker         int32_t right;
56*e1eccf28SAndroid Build Coastguard Worker         int32_t bottom;
setRect57*e1eccf28SAndroid Build Coastguard Worker         void set(int32_t l, int32_t r, int32_t t, int32_t b) {
58*e1eccf28SAndroid Build Coastguard Worker             left = l;
59*e1eccf28SAndroid Build Coastguard Worker             right = r;
60*e1eccf28SAndroid Build Coastguard Worker             top = t;
61*e1eccf28SAndroid Build Coastguard Worker             bottom = b;
62*e1eccf28SAndroid Build Coastguard Worker         }
63*e1eccf28SAndroid Build Coastguard Worker     };
64*e1eccf28SAndroid Build Coastguard Worker 
65*e1eccf28SAndroid Build Coastguard Worker     ~Font();
66*e1eccf28SAndroid Build Coastguard Worker 
67*e1eccf28SAndroid Build Coastguard Worker     // Currently files do not get serialized,
68*e1eccf28SAndroid Build Coastguard Worker     // but we need to inherit from ObjectBase for ref tracking
serialize(Context * rsc,OStream * stream)69*e1eccf28SAndroid Build Coastguard Worker     virtual void serialize(Context *rsc, OStream *stream) const {
70*e1eccf28SAndroid Build Coastguard Worker     }
getClassId()71*e1eccf28SAndroid Build Coastguard Worker     virtual RsA3DClassID getClassId() const {
72*e1eccf28SAndroid Build Coastguard Worker         return RS_A3D_CLASS_ID_UNKNOWN;
73*e1eccf28SAndroid Build Coastguard Worker     }
74*e1eccf28SAndroid Build Coastguard Worker 
75*e1eccf28SAndroid Build Coastguard Worker     static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi,
76*e1eccf28SAndroid Build Coastguard Worker                          const void *data = nullptr, uint32_t dataLen = 0);
77*e1eccf28SAndroid Build Coastguard Worker 
78*e1eccf28SAndroid Build Coastguard Worker protected:
79*e1eccf28SAndroid Build Coastguard Worker 
80*e1eccf28SAndroid Build Coastguard Worker     friend class FontState;
81*e1eccf28SAndroid Build Coastguard Worker 
82*e1eccf28SAndroid Build Coastguard Worker     // Pointer to the utf data, length of data, where to start, number of glyphs ot read
83*e1eccf28SAndroid Build Coastguard Worker     // (each glyph may be longer than a char because we are dealing with utf data)
84*e1eccf28SAndroid Build Coastguard Worker     // Last two variables are the initial pen position
85*e1eccf28SAndroid Build Coastguard Worker     void renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
86*e1eccf28SAndroid Build Coastguard Worker                    uint32_t start, int32_t numGlyphs,
87*e1eccf28SAndroid Build Coastguard Worker                    RenderMode mode = FRAMEBUFFER, Rect *bounds = nullptr,
88*e1eccf28SAndroid Build Coastguard Worker                    uint8_t *bitmap = nullptr, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
89*e1eccf28SAndroid Build Coastguard Worker 
90*e1eccf28SAndroid Build Coastguard Worker     void invalidateTextureCache();
91*e1eccf28SAndroid Build Coastguard Worker     struct CachedGlyphInfo
92*e1eccf28SAndroid Build Coastguard Worker     {
93*e1eccf28SAndroid Build Coastguard Worker         // Has the cache been invalidated?
94*e1eccf28SAndroid Build Coastguard Worker         bool mIsValid;
95*e1eccf28SAndroid Build Coastguard Worker         // Location of the cached glyph in the bitmap
96*e1eccf28SAndroid Build Coastguard Worker         // in case we need to resize the texture
97*e1eccf28SAndroid Build Coastguard Worker         uint32_t mBitmapMinX;
98*e1eccf28SAndroid Build Coastguard Worker         uint32_t mBitmapMinY;
99*e1eccf28SAndroid Build Coastguard Worker         uint32_t mBitmapWidth;
100*e1eccf28SAndroid Build Coastguard Worker         uint32_t mBitmapHeight;
101*e1eccf28SAndroid Build Coastguard Worker         // Also cache texture coords for the quad
102*e1eccf28SAndroid Build Coastguard Worker         float mBitmapMinU;
103*e1eccf28SAndroid Build Coastguard Worker         float mBitmapMinV;
104*e1eccf28SAndroid Build Coastguard Worker         float mBitmapMaxU;
105*e1eccf28SAndroid Build Coastguard Worker         float mBitmapMaxV;
106*e1eccf28SAndroid Build Coastguard Worker         // Minimize how much we call freetype
107*e1eccf28SAndroid Build Coastguard Worker         int32_t mGlyphIndex;
108*e1eccf28SAndroid Build Coastguard Worker         int32_t mAdvanceX;
109*e1eccf28SAndroid Build Coastguard Worker         int32_t mAdvanceY;
110*e1eccf28SAndroid Build Coastguard Worker         // Values below contain a glyph's origin in the bitmap
111*e1eccf28SAndroid Build Coastguard Worker         int32_t mBitmapLeft;
112*e1eccf28SAndroid Build Coastguard Worker         int32_t mBitmapTop;
113*e1eccf28SAndroid Build Coastguard Worker     };
114*e1eccf28SAndroid Build Coastguard Worker 
115*e1eccf28SAndroid Build Coastguard Worker     const char *mFontName;
116*e1eccf28SAndroid Build Coastguard Worker     float mFontSize;
117*e1eccf28SAndroid Build Coastguard Worker     uint32_t mDpi;
118*e1eccf28SAndroid Build Coastguard Worker 
119*e1eccf28SAndroid Build Coastguard Worker     explicit Font(Context *rsc);
120*e1eccf28SAndroid Build Coastguard Worker     bool init(const char *name, float fontSize, uint32_t dpi, const void *data = nullptr, uint32_t dataLen = 0);
121*e1eccf28SAndroid Build Coastguard Worker 
122*e1eccf28SAndroid Build Coastguard Worker     virtual void preDestroy() const;
123*e1eccf28SAndroid Build Coastguard Worker     FT_FaceRec_ *mFace;
124*e1eccf28SAndroid Build Coastguard Worker     bool mInitialized;
125*e1eccf28SAndroid Build Coastguard Worker     bool mHasKerning;
126*e1eccf28SAndroid Build Coastguard Worker 
127*e1eccf28SAndroid Build Coastguard Worker     DefaultKeyedVector<uint32_t, CachedGlyphInfo* > mCachedGlyphs;
128*e1eccf28SAndroid Build Coastguard Worker     CachedGlyphInfo* getCachedUTFChar(int32_t utfChar);
129*e1eccf28SAndroid Build Coastguard Worker 
130*e1eccf28SAndroid Build Coastguard Worker     CachedGlyphInfo *cacheGlyph(uint32_t glyph);
131*e1eccf28SAndroid Build Coastguard Worker     void updateGlyphCache(CachedGlyphInfo *glyph);
132*e1eccf28SAndroid Build Coastguard Worker     void measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds);
133*e1eccf28SAndroid Build Coastguard Worker     void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y);
134*e1eccf28SAndroid Build Coastguard Worker     void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y,
135*e1eccf28SAndroid Build Coastguard Worker                          uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
136*e1eccf28SAndroid Build Coastguard Worker };
137*e1eccf28SAndroid Build Coastguard Worker 
138*e1eccf28SAndroid Build Coastguard Worker class FontState {
139*e1eccf28SAndroid Build Coastguard Worker public:
140*e1eccf28SAndroid Build Coastguard Worker     FontState();
141*e1eccf28SAndroid Build Coastguard Worker     ~FontState();
142*e1eccf28SAndroid Build Coastguard Worker 
143*e1eccf28SAndroid Build Coastguard Worker     void init(Context *rsc);
144*e1eccf28SAndroid Build Coastguard Worker     void deinit(Context *rsc);
145*e1eccf28SAndroid Build Coastguard Worker 
146*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<Font> mDefault;
147*e1eccf28SAndroid Build Coastguard Worker 
148*e1eccf28SAndroid Build Coastguard Worker     void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
149*e1eccf28SAndroid Build Coastguard Worker                     uint32_t startIndex = 0, int numGlyphs = -1,
150*e1eccf28SAndroid Build Coastguard Worker                     Font::RenderMode mode = Font::FRAMEBUFFER,
151*e1eccf28SAndroid Build Coastguard Worker                     Font::Rect *bounds = nullptr,
152*e1eccf28SAndroid Build Coastguard Worker                     uint8_t *bitmap = nullptr, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
153*e1eccf28SAndroid Build Coastguard Worker 
154*e1eccf28SAndroid Build Coastguard Worker     void measureText(const char *text, uint32_t len, Font::Rect *bounds);
155*e1eccf28SAndroid Build Coastguard Worker 
156*e1eccf28SAndroid Build Coastguard Worker     void setFontColor(float r, float g, float b, float a);
157*e1eccf28SAndroid Build Coastguard Worker     void getFontColor(float *r, float *g, float *b, float *a) const;
158*e1eccf28SAndroid Build Coastguard Worker 
159*e1eccf28SAndroid Build Coastguard Worker protected:
160*e1eccf28SAndroid Build Coastguard Worker 
161*e1eccf28SAndroid Build Coastguard Worker     float mSurfaceWidth;
162*e1eccf28SAndroid Build Coastguard Worker     float mSurfaceHeight;
163*e1eccf28SAndroid Build Coastguard Worker 
164*e1eccf28SAndroid Build Coastguard Worker     friend class Font;
165*e1eccf28SAndroid Build Coastguard Worker 
166*e1eccf28SAndroid Build Coastguard Worker     struct CacheTextureLine {
167*e1eccf28SAndroid Build Coastguard Worker         uint32_t mMaxHeight;
168*e1eccf28SAndroid Build Coastguard Worker         uint32_t mMaxWidth;
169*e1eccf28SAndroid Build Coastguard Worker         uint32_t mCurrentRow;
170*e1eccf28SAndroid Build Coastguard Worker         uint32_t mCurrentCol;
171*e1eccf28SAndroid Build Coastguard Worker         bool mDirty;
172*e1eccf28SAndroid Build Coastguard Worker 
CacheTextureLineCacheTextureLine173*e1eccf28SAndroid Build Coastguard Worker         CacheTextureLine(uint32_t maxHeight, uint32_t maxWidth, uint32_t currentRow, uint32_t currentCol)
174*e1eccf28SAndroid Build Coastguard Worker             : mMaxHeight(maxHeight), mMaxWidth(maxWidth), mCurrentRow(currentRow),
175*e1eccf28SAndroid Build Coastguard Worker               mCurrentCol(currentCol), mDirty(false)  {
176*e1eccf28SAndroid Build Coastguard Worker         }
177*e1eccf28SAndroid Build Coastguard Worker 
178*e1eccf28SAndroid Build Coastguard Worker         bool fitBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
179*e1eccf28SAndroid Build Coastguard Worker     };
180*e1eccf28SAndroid Build Coastguard Worker 
181*e1eccf28SAndroid Build Coastguard Worker     std::vector<CacheTextureLine*> mCacheLines;
182*e1eccf28SAndroid Build Coastguard Worker     uint32_t getRemainingCacheCapacity();
183*e1eccf28SAndroid Build Coastguard Worker 
184*e1eccf28SAndroid Build Coastguard Worker     void precacheLatin(Font *font);
185*e1eccf28SAndroid Build Coastguard Worker     const char *mLatinPrecache;
186*e1eccf28SAndroid Build Coastguard Worker 
187*e1eccf28SAndroid Build Coastguard Worker     Context *mRSC;
188*e1eccf28SAndroid Build Coastguard Worker 
189*e1eccf28SAndroid Build Coastguard Worker     struct {
190*e1eccf28SAndroid Build Coastguard Worker         float mFontColor[4];
191*e1eccf28SAndroid Build Coastguard Worker         float mGamma;
192*e1eccf28SAndroid Build Coastguard Worker     } mConstants;
193*e1eccf28SAndroid Build Coastguard Worker     bool mConstantsDirty;
194*e1eccf28SAndroid Build Coastguard Worker 
195*e1eccf28SAndroid Build Coastguard Worker     float mBlackGamma;
196*e1eccf28SAndroid Build Coastguard Worker     float mWhiteGamma;
197*e1eccf28SAndroid Build Coastguard Worker 
198*e1eccf28SAndroid Build Coastguard Worker     float mBlackThreshold;
199*e1eccf28SAndroid Build Coastguard Worker     float mWhiteThreshold;
200*e1eccf28SAndroid Build Coastguard Worker 
201*e1eccf28SAndroid Build Coastguard Worker     // Free type library, we only need one copy
202*e1eccf28SAndroid Build Coastguard Worker #ifndef ANDROID_RS_SERIALIZE
203*e1eccf28SAndroid Build Coastguard Worker     FT_LibraryRec_ *mLibrary;
204*e1eccf28SAndroid Build Coastguard Worker     FT_LibraryRec_ *getLib();
205*e1eccf28SAndroid Build Coastguard Worker #endif //ANDROID_RS_SERIALIZE
206*e1eccf28SAndroid Build Coastguard Worker     std::vector<Font*> mActiveFonts;
207*e1eccf28SAndroid Build Coastguard Worker 
208*e1eccf28SAndroid Build Coastguard Worker     // Render state for the font
209*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<Allocation> mFontShaderFConstant;
210*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<ProgramFragment> mFontShaderF;
211*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<Sampler> mFontSampler;
212*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<ProgramStore> mFontProgramStore;
213*e1eccf28SAndroid Build Coastguard Worker     void initRenderState();
214*e1eccf28SAndroid Build Coastguard Worker 
215*e1eccf28SAndroid Build Coastguard Worker     // Texture to cache glyph bitmaps
216*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<Allocation> mTextTexture;
217*e1eccf28SAndroid Build Coastguard Worker     uint8_t *mCacheBuffer;
218*e1eccf28SAndroid Build Coastguard Worker     uint32_t mCacheWidth;
219*e1eccf28SAndroid Build Coastguard Worker     uint32_t mCacheHeight;
220*e1eccf28SAndroid Build Coastguard Worker 
221*e1eccf28SAndroid Build Coastguard Worker     void initTextTexture();
222*e1eccf28SAndroid Build Coastguard Worker 
223*e1eccf28SAndroid Build Coastguard Worker #ifndef ANDROID_RS_SERIALIZE
224*e1eccf28SAndroid Build Coastguard Worker     bool cacheBitmap(FT_Bitmap_ *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
225*e1eccf28SAndroid Build Coastguard Worker #endif //ANDROID_RS_SERIALIZE
getCacheTextureType()226*e1eccf28SAndroid Build Coastguard Worker     const Type* getCacheTextureType() {
227*e1eccf28SAndroid Build Coastguard Worker         return mTextTexture->getType();
228*e1eccf28SAndroid Build Coastguard Worker     }
229*e1eccf28SAndroid Build Coastguard Worker 
230*e1eccf28SAndroid Build Coastguard Worker     void flushAllAndInvalidate();
231*e1eccf28SAndroid Build Coastguard Worker 
232*e1eccf28SAndroid Build Coastguard Worker     // Pointer to vertex data to speed up frame to frame work
233*e1eccf28SAndroid Build Coastguard Worker     float *mTextMeshPtr;
234*e1eccf28SAndroid Build Coastguard Worker     uint32_t mCurrentQuadIndex;
235*e1eccf28SAndroid Build Coastguard Worker     uint32_t mMaxNumberOfQuads;
236*e1eccf28SAndroid Build Coastguard Worker 
237*e1eccf28SAndroid Build Coastguard Worker     void initVertexArrayBuffers();
238*e1eccf28SAndroid Build Coastguard Worker     ObjectBaseRef<Mesh> mMesh;
239*e1eccf28SAndroid Build Coastguard Worker 
240*e1eccf28SAndroid Build Coastguard Worker     bool mInitialized;
241*e1eccf28SAndroid Build Coastguard Worker 
242*e1eccf28SAndroid Build Coastguard Worker     void checkInit();
243*e1eccf28SAndroid Build Coastguard Worker 
244*e1eccf28SAndroid Build Coastguard Worker     void issueDrawCommand();
245*e1eccf28SAndroid Build Coastguard Worker 
246*e1eccf28SAndroid Build Coastguard Worker     void appendMeshQuad(float x1, float y1, float z1,
247*e1eccf28SAndroid Build Coastguard Worker                         float u1, float v1,
248*e1eccf28SAndroid Build Coastguard Worker                         float x2, float y2, float z2,
249*e1eccf28SAndroid Build Coastguard Worker                         float u2, float v2,
250*e1eccf28SAndroid Build Coastguard Worker                         float x3, float y3, float z3,
251*e1eccf28SAndroid Build Coastguard Worker                         float u3, float v3,
252*e1eccf28SAndroid Build Coastguard Worker                         float x4, float y4, float z4,
253*e1eccf28SAndroid Build Coastguard Worker                         float u4, float v4);
254*e1eccf28SAndroid Build Coastguard Worker };
255*e1eccf28SAndroid Build Coastguard Worker 
256*e1eccf28SAndroid Build Coastguard Worker } // namespace renderscript
257*e1eccf28SAndroid Build Coastguard Worker } // namespace android
258*e1eccf28SAndroid Build Coastguard Worker 
259*e1eccf28SAndroid Build Coastguard Worker #endif
260