… | |
… | |
100 | } |
100 | } |
101 | |
101 | |
102 | static void |
102 | static void |
103 | font_render_glyph (Glyph *glyph, PangoFont *font, int glyph_index) |
103 | font_render_glyph (Glyph *glyph, PangoFont *font, int glyph_index) |
104 | { |
104 | { |
|
|
105 | FT_Face face; |
|
|
106 | |
105 | if (glyph_index & PANGO_GLYPH_UNKNOWN_FLAG) |
107 | if (glyph_index & PANGO_GLYPH_UNKNOWN_FLAG) |
106 | { |
108 | { |
107 | PangoFontMetrics *metrics; |
109 | PangoFontMetrics *metrics; |
108 | |
110 | |
109 | if (!font) |
111 | if (!font) |
… | |
… | |
120 | pango_font_metrics_unref (metrics); |
122 | pango_font_metrics_unref (metrics); |
121 | |
123 | |
122 | return; |
124 | return; |
123 | } |
125 | } |
124 | |
126 | |
125 | FT_Face face = pango_opengl_font_get_face (font); |
127 | face = pango_opengl_font_get_face (font); |
126 | |
128 | |
127 | if (face) |
129 | if (face) |
128 | { |
130 | { |
129 | PangoOpenGLFont *glfont = (PangoOpenGLFont *)font; |
131 | PangoOpenGLFont *glfont = (PangoOpenGLFont *)font; |
130 | |
132 | |
… | |
… | |
144 | } |
146 | } |
145 | |
147 | |
146 | typedef struct glyph_info { |
148 | typedef struct glyph_info { |
147 | tc_area tex; |
149 | tc_area tex; |
148 | int left, top; |
150 | int left, top; |
|
|
151 | int generation; |
149 | } glyph_info; |
152 | } glyph_info; |
150 | |
153 | |
151 | static void |
154 | static void |
152 | free_glyph_info (glyph_info *g) |
155 | free_glyph_info (glyph_info *g) |
153 | { |
156 | { |
… | |
… | |
157 | |
160 | |
158 | static void |
161 | static void |
159 | draw_glyph (PangoRenderer *renderer_, PangoFont *font, PangoGlyph glyph, double x, double y) |
162 | draw_glyph (PangoRenderer *renderer_, PangoFont *font, PangoGlyph glyph, double x, double y) |
160 | { |
163 | { |
161 | PangoOpenGLRenderer *renderer = PANGO_OPENGL_RENDERER (renderer_); |
164 | PangoOpenGLRenderer *renderer = PANGO_OPENGL_RENDERER (renderer_); |
|
|
165 | glyph_info *g; |
|
|
166 | float x1, y1, x2, y2; |
162 | |
167 | |
163 | if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) |
168 | if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) |
164 | { |
169 | { |
165 | glyph = pango_opengl_get_unknown_glyph (font); |
170 | glyph = pango_opengl_get_unknown_glyph (font); |
166 | |
171 | |
167 | if (glyph == PANGO_GLYPH_EMPTY) |
172 | if (glyph == PANGO_GLYPH_EMPTY) |
168 | glyph = PANGO_GLYPH_UNKNOWN_FLAG; |
173 | glyph = PANGO_GLYPH_UNKNOWN_FLAG; |
169 | } |
174 | } |
170 | |
175 | |
171 | glyph_info *g = _pango_opengl_font_get_cache_glyph_data (font, glyph); |
176 | g = _pango_opengl_font_get_cache_glyph_data (font, glyph); |
172 | |
177 | |
173 | if (!g) |
178 | if (!g || g->generation != tc_generation) |
174 | { |
179 | { |
175 | Glyph bm; |
180 | Glyph bm; |
176 | font_render_glyph (&bm, font, glyph); |
181 | font_render_glyph (&bm, font, glyph); |
177 | |
182 | |
|
|
183 | if (g) |
|
|
184 | g->generation = tc_generation; |
|
|
185 | else |
|
|
186 | { |
178 | g = g_slice_new (glyph_info); |
187 | g = g_slice_new (glyph_info); |
|
|
188 | |
|
|
189 | _pango_opengl_font_set_glyph_cache_destroy (font, (GDestroyNotify)free_glyph_info); |
|
|
190 | _pango_opengl_font_set_cache_glyph_data (font, glyph, g); |
|
|
191 | } |
|
|
192 | |
|
|
193 | if (renderer->curtex) |
|
|
194 | glEnd (); |
179 | |
195 | |
180 | tc_get (&g->tex, bm.width, bm.height); |
196 | tc_get (&g->tex, bm.width, bm.height); |
181 | |
197 | |
182 | g->left = bm.left; |
198 | g->left = bm.left; |
183 | g->top = bm.top; |
199 | g->top = bm.top; |
184 | |
|
|
185 | if (renderer->curtex) |
|
|
186 | { |
|
|
187 | glEnd (); |
|
|
188 | renderer->curtex = 0; |
|
|
189 | } |
|
|
190 | |
200 | |
191 | glBindTexture (GL_TEXTURE_2D, g->tex.name); |
201 | glBindTexture (GL_TEXTURE_2D, g->tex.name); |
192 | glPixelStorei (GL_UNPACK_ROW_LENGTH, bm.stride); |
202 | glPixelStorei (GL_UNPACK_ROW_LENGTH, bm.stride); |
193 | glPixelStorei (GL_UNPACK_ALIGNMENT, 1); |
203 | glPixelStorei (GL_UNPACK_ALIGNMENT, 1); |
194 | glTexSubImage2D (GL_TEXTURE_2D, 0, g->tex.x, g->tex.y, bm.width, bm.height, GL_ALPHA, GL_UNSIGNED_BYTE, bm.bitmap); |
204 | glTexSubImage2D (GL_TEXTURE_2D, 0, g->tex.x, g->tex.y, bm.width, bm.height, GL_ALPHA, GL_UNSIGNED_BYTE, bm.bitmap); |
195 | glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); |
205 | glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); |
196 | glPixelStorei (GL_UNPACK_ALIGNMENT, 4); |
206 | glPixelStorei (GL_UNPACK_ALIGNMENT, 4); |
197 | |
207 | |
198 | _pango_opengl_font_set_glyph_cache_destroy (font, (GDestroyNotify)free_glyph_info); |
208 | renderer->curtex = g->tex.name; |
199 | _pango_opengl_font_set_cache_glyph_data (font, glyph, g); |
209 | glBegin (GL_QUADS); |
200 | } |
210 | } |
201 | |
211 | |
202 | x += g->left; |
212 | x += g->left; |
203 | y -= g->top; |
213 | y -= g->top; |
204 | |
214 | |
205 | float x1 = g->tex.x * (1. / TC_WIDTH ); |
215 | x1 = g->tex.x * (1. / TC_WIDTH ); |
206 | float y1 = g->tex.y * (1. / TC_HEIGHT); |
216 | y1 = g->tex.y * (1. / TC_HEIGHT); |
207 | float x2 = g->tex.w * (1. / TC_WIDTH ) + x1; |
217 | x2 = g->tex.w * (1. / TC_WIDTH ) + x1; |
208 | float y2 = g->tex.h * (1. / TC_HEIGHT) + y1; |
218 | y2 = g->tex.h * (1. / TC_HEIGHT) + y1; |
209 | |
219 | |
210 | if (g->tex.name != renderer->curtex) |
220 | if (g->tex.name != renderer->curtex) |
211 | { |
221 | { |
212 | if (renderer->curtex) |
222 | if (renderer->curtex) |
213 | glEnd (); |
223 | glEnd (); |
214 | |
224 | |
215 | glBindTexture (GL_TEXTURE_2D, g->tex.name); |
225 | glBindTexture (GL_TEXTURE_2D, g->tex.name); |
216 | renderer->curtex = g->tex.name; |
226 | renderer->curtex = g->tex.name; |
|
|
227 | |
217 | glBegin (GL_QUADS); |
228 | glBegin (GL_QUADS); |
218 | } |
229 | } |
219 | |
230 | |
220 | glTexCoord2f (x1, y1); glVertex2i (x , y ); |
231 | glTexCoord2f (x1, y1); glVertex2i (x , y ); |
221 | glTexCoord2f (x2, y1); glVertex2i (x + g->tex.w, y ); |
232 | glTexCoord2f (x2, y1); glVertex2i (x + g->tex.w, y ); |