458e50203abed482088dfa01cdd9187bf52ffa6c
[sdk] / ecere / src / gfx / newFonts / fontRenderer.ec
1 /* *****************************************************************************
2  * Original Version Copyright (c) 2007-2014 Alexis Naveros.
3  *
4  * Ecere Corporation has unlimited/unrestricted rights.
5  * *****************************************************************************/
6 import "Color"
7
8 #define _Noreturn
9
10 #include <math.h>
11 #include <stdlib.h>
12
13 #if !defined(_GLES)
14    #define SHADERS
15 #endif
16
17 #if !defined(__ANDROID__) && !defined(__EMSCRIPTEN__) && !defined(__ODROID__)
18 #  if defined(SHADERS)
19 //#     include "gl_core_3_3.h"
20 #     include "gl_compat_4_4.h"     // FIXME: no glPushAttrib() in core profile
21 #  else
22 #     include "gl_compat_4_4.h"
23 #  endif
24 #endif
25
26 #if defined(__EMSCRIPTEN__)
27 #if !defined(_GLES2)
28    #define _GLES2
29 #endif
30    #include <GLES2/gl2.h>
31 #endif
32
33 #include "cc.h"
34 #include "mm.h"
35
36 import "fmFontManager"
37 import "textureManager"
38 import "drawManager"
39
40 #define DM_ENABLE_EXT_COLOR (1)
41
42 public class FontRenderer : FontManagerRenderer
43 {
44    DrawManager dm;
45    Texture texture;
46    int textureWidth, textureHeight;
47    int channelcount;
48
49    int imagecount;
50    int imageAlloc;
51    DMImage *imageList;
52
53    ColorAlpha stateColor;
54    ColorAlpha stateExtColor;
55    ColorAlpha stateCursorColor;
56    uint32 stateLayer;
57
58    imageAlloc = 512;
59    imageList = new DMImage[imageAlloc];
60
61    stateColor = white;
62    stateCursorColor = white;
63    stateLayer = DM_LAYER_ABOVE;
64
65 public:
66
67    property DrawManager drawManager { set { dm = value; } }
68
69    bool init(int channelCount)
70    {
71       this.channelcount = channelCount;
72       return true;
73    }
74
75    ~FontRenderer()
76    {
77       delete texture;
78       delete imageList;
79    }
80
81    bool createTexture( int width, int height )
82    {
83       IMGImage image
84       {
85          format = { width = width, height = height, type = grayScale, bytesPerPixel = channelcount, bytesPerLine = width };
86       };
87
88       delete texture;
89
90       texture = { 0 << DM_TEXTURE_ORDER_SHIFT };
91       texture.build(image, 0, 0.0, 0 );
92
93       textureWidth = width;
94       textureHeight = height;
95       return true;
96    }
97
98    int resizeTexture( int width, int height )
99    {
100      int retval;
101
102      // Reuse create to resize too.
103      delete imageList;
104      imagecount = 0;
105      imageAlloc = 512;
106      imageList = new DMImage[imageAlloc];
107
108      retval = createTexture( width, height );
109      return retval;
110    }
111
112    void updateTexture( int *rect, const byte* data )
113    {
114      if(texture)
115      {
116 #if defined(SHADERS) && !defined(__EMSCRIPTEN__)
117         int glformat = GL_RED;
118 #else
119         int glformat = GL_ALPHA;
120 #endif
121         int w = rect[2] - rect[0];
122         int h = rect[3] - rect[1];
123
124         if( channelcount == 1 );
125 #if !defined(__EMSCRIPTEN__)
126         else if( channelcount == 2 )
127           glformat = GL_RG;
128 #endif
129         else if( channelcount == 3 )
130           glformat = GL_RGB;
131         else if( channelcount == 4 )
132           glformat = GL_RGBA;
133
134         // FIXME: no glPushAttrib() in core profile
135 #if !defined(__EMSCRIPTEN__)
136         glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
137         glPushAttrib( GL_TEXTURE_BIT );
138 #endif
139         glBindTexture( GL_TEXTURE_2D, texture.glTex );
140         glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
141 #if !defined(__EMSCRIPTEN__)
142         glPixelStorei( GL_UNPACK_ROW_LENGTH, textureWidth );
143         glPixelStorei( GL_UNPACK_SKIP_PIXELS, rect[0] );
144         glPixelStorei( GL_UNPACK_SKIP_ROWS, rect[1] );
145 #endif
146         glTexSubImage2D( GL_TEXTURE_2D, 0, rect[0], rect[1], w, h, glformat, GL_UNSIGNED_BYTE, data );
147 #if !defined(__EMSCRIPTEN__)
148         glPopAttrib();
149         glPopClientAttrib();
150 #endif
151
152       #if 0
153         IMGImage image;
154         image.format.width = textureWidth;
155         image.format.height = textureHeight;
156         image.format.type = channelcount == 4 ? IMG_FORMAT_TYPE_RGBA32 : IMG_FORMAT_TYPE_GRAYSCALE;
157         image.format.bytesPerPixel = channelcount;
158         image.format.bytesPerLine = image.format.width * image.format.bytesPerPixel;
159         image.data = data;
160         imgWritePngFile( "zzz2.png", &image, 1.0 );
161       #endif
162      }
163    }
164
165    void flush( )
166    {
167       dm.flushImages( );
168    }
169
170    int registerImage( int offsetx, int offsety, int width, int height )
171    {
172       int imageindex = imagecount;
173       DMImage *image;
174
175       if( imagecount >= imageAlloc )
176       {
177          imageAlloc <<= 1;
178          imageList = renew imageList DMImage[imageAlloc];
179       }
180       imagecount++;
181
182       image = &imageList[ imageindex ];
183    #if 1
184       image->defineImage( texture, offsetx, offsety, width, height, 1, DM_PROGRAM_ALPHABLEND_INTENSITY_EXTCOLOR, stateLayer );
185    #elif 1
186       image->defineImage( texture, offsetx, offsety, width, height, 1, DM_PROGRAM_ALPHABLEND_INTENSITY, stateLayer );
187    #elif 1
188       image->defineImage( texture, offsetx, offsety, width, height, 1, DM_PROGRAM_ALPHABLEND, stateLayer );
189    #else
190       image->defineImage( texture, offsetx, offsety, width, height, 1, DM_PROGRAM_NORMAL, stateLayer );
191    #endif
192
193       return imageindex;
194    }
195
196    void drawImage( int targetx, int targety, int imageindex )
197    {
198       DMImage *image = &imageList[ imageindex ];
199    #if DM_ENABLE_EXT_COLOR
200       dm.drawImageExtColor( image, targetx, targety, image->sizex, image->sizey, stateColor, stateExtColor );
201    #else
202       dm.drawImage( image, targetx, targety, image->sizex, image->sizey, stateColor );
203    #endif
204    }
205
206    void drawImageCursor( int targetx, int targety, int imageindex )
207    {
208       DMImage *image = &imageList[ imageindex ];
209    #if DM_ENABLE_EXT_COLOR
210       dm.drawImageExtColor( image, targetx, targety, image->sizex, image->sizey, stateCursorColor, stateExtColor );
211    #else
212       dm.drawImage( image, targetx, targety, image->sizex, image->sizey, stateCursorColor );
213    #endif
214    }
215
216    void drawImageAlt( byte *texdata, int targetx, int targety, int offsetx, int offsety, int width, int height )
217    {
218
219    }
220
221    void drawImageFloat( float targetx, float targety, float angsin, float angcos, int imageindex )
222    {
223       DMImage *image = &imageList[ imageindex ];
224
225       /* 0.2588190451, 0.965925826289 */
226
227    #if DM_ENABLE_EXT_COLOR
228       dm.drawImageFloatExtColor( image, targetx, targety, (float)image->sizex, (float)image->sizey, angsin, angcos, stateColor, stateExtColor );
229    #else
230       dm.drawImageFloat( image, targetx, targety, (float)image->sizex, (float)image->sizey, angsin, angcos, stateColor );
231    #endif
232    }
233
234    void resetImages( )
235    {
236       imagecount = 0;
237    }
238
239    void setColor( ColorAlpha color )
240    {
241       stateColor = { color.a, { color.color.b, color.color.g, color.color.r } };
242    }
243
244    void setExtColor( ColorAlpha color )
245    {
246       stateExtColor = { color.a, { color.color.b, color.color.g, color.color.r } };
247    }
248
249    void setCursorColor( ColorAlpha color )
250    {
251       stateCursorColor = { color.a, { color.color.b, color.color.g, color.color.r } };
252    }
253
254    void setLayer( uint32 layerIndex )
255    {
256       stateLayer = layerIndex;
257    }
258 }