--- deliantra/Deliantra-Client/pango-render.c 2006/07/04 23:44:23 1.2 +++ deliantra/Deliantra-Client/pango-render.c 2007/08/11 11:41:24 1.9 @@ -37,7 +37,10 @@ { PangoRenderer parent_instance; float r, g, b, a; // modulate - GLuint curtex; // current texture + int flags; + rc_t *rc; // rendercache + rc_key_t key; // current render key + rc_array_t *arr; }; G_DEFINE_TYPE (PangoOpenGLRenderer, pango_opengl_renderer, PANGO_TYPE_RENDERER) @@ -148,6 +151,7 @@ typedef struct glyph_info { tc_area tex; int left, top; + int generation; } glyph_info; static void @@ -174,33 +178,32 @@ g = _pango_opengl_font_get_cache_glyph_data (font, glyph); - if (!g) + if (!g || g->generation != tc_generation) { Glyph bm; font_render_glyph (&bm, font, glyph); - g = g_slice_new (glyph_info); + if (g) + g->generation = tc_generation; + else + { + g = g_slice_new (glyph_info); + + _pango_opengl_font_set_glyph_cache_destroy (font, (GDestroyNotify)free_glyph_info); + _pango_opengl_font_set_cache_glyph_data (font, glyph, g); + } tc_get (&g->tex, bm.width, bm.height); g->left = bm.left; g->top = bm.top; - if (renderer->curtex) - { - glEnd (); - renderer->curtex = 0; - } - glBindTexture (GL_TEXTURE_2D, g->tex.name); glPixelStorei (GL_UNPACK_ROW_LENGTH, bm.stride); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D (GL_TEXTURE_2D, 0, g->tex.x, g->tex.y, bm.width, bm.height, GL_ALPHA, GL_UNSIGNED_BYTE, bm.bitmap); glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); glPixelStorei (GL_UNPACK_ALIGNMENT, 4); - - _pango_opengl_font_set_glyph_cache_destroy (font, (GDestroyNotify)free_glyph_info); - _pango_opengl_font_set_cache_glyph_data (font, glyph, g); } x += g->left; @@ -211,20 +214,16 @@ x2 = g->tex.w * (1. / TC_WIDTH ) + x1; y2 = g->tex.h * (1. / TC_HEIGHT) + y1; - if (g->tex.name != renderer->curtex) + if (g->tex.name != renderer->key.texname) { - if (renderer->curtex) - glEnd (); - - glBindTexture (GL_TEXTURE_2D, g->tex.name); - renderer->curtex = g->tex.name; - glBegin (GL_QUADS); + renderer->key.texname = g->tex.name; + renderer->arr = rc_array (renderer->rc, &renderer->key); } - glTexCoord2f (x1, y1); glVertex2i (x , y ); - glTexCoord2f (x2, y1); glVertex2i (x + g->tex.w, y ); - glTexCoord2f (x2, y2); glVertex2i (x + g->tex.w, y + g->tex.h); - glTexCoord2f (x1, y2); glVertex2i (x , y + g->tex.h); + rc_t2f_v3f (renderer->arr, x1, y1, x , y , 0); + rc_t2f_v3f (renderer->arr, x2, y1, x + g->tex.w, y , 0); + rc_t2f_v3f (renderer->arr, x2, y2, x + g->tex.w, y + g->tex.h, 0); + rc_t2f_v3f (renderer->arr, x1, y2, x , y + g->tex.h, 0); } static void @@ -238,57 +237,77 @@ double x22) { PangoOpenGLRenderer *renderer = (PangoOpenGLRenderer *)renderer_; + rc_key_t key = renderer->key; + rc_array_t *arr; - if (renderer->curtex) - { - glEnd (); - renderer->curtex = 0; - } - - glDisable (GL_TEXTURE_2D); - - glBegin (GL_QUADS); - glVertex2d (x11, y1); - glVertex2d (x12, y1); - glVertex2d (x22, y2); - glVertex2d (x21, y2); - glEnd (); - - glEnable (GL_TEXTURE_2D); + key.mode = GL_QUADS; + key.format = GL_V2F; + key.texname = 0; + + arr = rc_array (renderer->rc, &key); + + rc_v2f (arr, x11, y1); + rc_v2f (arr, x21, y1); + rc_v2f (arr, x22, y2); + rc_v2f (arr, x12, y2); } void pango_opengl_render_layout_subpixel (PangoLayout *layout, int x, int y, - float r, float g, float b, float a) + float r, float g, float b, float a, + int flags) { PangoContext *context; PangoFontMap *fontmap; PangoRenderer *renderer; + PangoOpenGLRenderer *gl; context = pango_layout_get_context (layout); fontmap = pango_context_get_font_map (context); renderer = _pango_opengl_font_map_get_renderer (PANGO_OPENGL_FONT_MAP (fontmap)); + gl = PANGO_OPENGL_RENDERER (renderer); - PANGO_OPENGL_RENDERER (renderer)->r = r; - PANGO_OPENGL_RENDERER (renderer)->g = g; - PANGO_OPENGL_RENDERER (renderer)->b = b; - PANGO_OPENGL_RENDERER (renderer)->a = a; + gl->rc = rc_alloc (); + gl->r = r; + gl->g = g; + gl->b = b; + gl->a = a; + gl->flags = flags; + glEnable (GL_TEXTURE_2D); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable (GL_BLEND); + gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, + GL_ONE , GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_ALPHA_TEST); + glAlphaFunc (GL_GREATER, 0.01f); + pango_renderer_draw_layout (renderer, layout, x, y); + + rc_draw (gl->rc); + + glDisable (GL_ALPHA_TEST); + glDisable (GL_BLEND); + glDisable (GL_TEXTURE_2D); + + rc_free (gl->rc); } void pango_opengl_render_layout (PangoLayout *layout, int x, int y, - float r, float g, float b, float a) + float r, float g, float b, float a, + int flags) { - pango_opengl_render_layout_subpixel (layout, x * PANGO_SCALE, y * PANGO_SCALE, r, g, b, a); + pango_opengl_render_layout_subpixel (layout, x * PANGO_SCALE, y * PANGO_SCALE, r, g, b, a, flags); } static void pango_opengl_renderer_init (PangoOpenGLRenderer *renderer) { + memset (&renderer->key, 0, sizeof (rc_key_t)); + renderer->r = 1.; renderer->g = 1.; renderer->b = 1.; @@ -298,13 +317,18 @@ static void prepare_run (PangoRenderer *renderer, PangoLayoutRun *run) { - PangoOpenGLRenderer *glrenderer = (PangoOpenGLRenderer *)renderer; + PangoOpenGLRenderer *gl = (PangoOpenGLRenderer *)renderer; PangoColor *fg = 0; GSList *l; + unsigned char r, g, b, a; renderer->underline = PANGO_UNDERLINE_NONE; renderer->strikethrough = FALSE; + gl->key.mode = GL_QUADS; + gl->key.format = GL_T2F_V3F; + gl->key.texname = 0; + for (l = run->item->analysis.extra_attrs; l; l = l->next) { PangoAttribute *attr = l->data; @@ -329,38 +353,43 @@ } if (fg) - glColor4f (fg->red / 65535., fg->green / 65535., fg->blue / 65535., glrenderer->a); + { + r = fg->red * (255.f / 65535.f); + g = fg->green * (255.f / 65535.f); + b = fg->blue * (255.f / 65535.f); + } else - glColor4f (glrenderer->r, glrenderer->g, glrenderer->b, glrenderer->a); + { + r = gl->r * 255.f; + g = gl->g * 255.f; + b = gl->b * 255.f; + } + + a = gl->a * 255.f; + + if (gl->flags & FLAG_INVERSE) + { + r ^= 0xffU; + g ^= 0xffU; + b ^= 0xffU; + } + + gl->key.r = r; + gl->key.g = g; + gl->key.b = b; + gl->key.a = a; } static void draw_begin (PangoRenderer *renderer_) { PangoOpenGLRenderer *renderer = (PangoOpenGLRenderer *)renderer_; - - renderer->curtex = 0; - - glEnable (GL_TEXTURE_2D); - glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable (GL_BLEND); - gl_BlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, - GL_ONE , GL_ONE_MINUS_SRC_ALPHA); - glEnable (GL_ALPHA_TEST); - glAlphaFunc (GL_GREATER, 0.01f); } static void draw_end (PangoRenderer *renderer_) { PangoOpenGLRenderer *renderer = (PangoOpenGLRenderer *)renderer_; - - if (renderer->curtex) - glEnd (); - - glDisable (GL_ALPHA_TEST); - glDisable (GL_BLEND); - glDisable (GL_TEXTURE_2D); } static void