--- deliantra/Deliantra-Client/pango-render.c 2007/08/11 11:41:24 1.9 +++ deliantra/Deliantra-Client/pango-render.c 2018/11/18 03:06:13 1.20 @@ -40,7 +40,7 @@ int flags; rc_t *rc; // rendercache rc_key_t key; // current render key - rc_array_t *arr; + rc_t::array_t *arr; }; G_DEFINE_TYPE (PangoOpenGLRenderer, pango_opengl_renderer, PANGO_TYPE_RENDERER) @@ -62,7 +62,7 @@ size = (size + 4095) & ~4095; free (buffer); alloc = size; - buffer = malloc (size); + buffer = (char *)malloc (size); } return buffer; @@ -92,7 +92,7 @@ glyph->top = top; glyph->left = left; - glyph->bitmap = temp_buffer (width * height); + glyph->bitmap = (uint8_t *)temp_buffer (width * height); memset (glyph->bitmap, 0, glyph->stride * height); for (i = width; i--; ) @@ -161,12 +161,48 @@ g_slice_free (glyph_info, g); } +static int apple_nvidia_bug_workaround; + +static void +apple_nvidia_bug (int enable) +{ + apple_nvidia_bug_workaround = enable; +} + +static void +tex_update (int name, int x, int y, int w, int stride, int h, void *bm) +{ + glBindTexture (GL_TEXTURE_2D, name); + + if (!apple_nvidia_bug_workaround) + { + glPixelStorei (GL_UNPACK_ROW_LENGTH, stride); + /*glPixelStorei (GL_UNPACK_ALIGNMENT, 1); expected cfplus default */ + glTexSubImage2D (GL_TEXTURE_2D, 0, x, y, w, h, GL_ALPHA, GL_UNSIGNED_BYTE, bm); + /*glPixelStorei (GL_UNPACK_ALIGNMENT, 4);*/ + glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + } + else + { + /* starting with 10.5.5 (or 10.5.6), pple's nvidia driver corrupts textures */ + /* when glTexSubImage is used, so do it the horribly slow way, */ + /* reading/patching/uploading the full texture one each change */ + int r; + + glGetTexImage (GL_TEXTURE_2D, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tc_temptile); + + for (r = 0; r < h; ++r) + memcpy (tc_temptile + (y + r) * TC_WIDTH + x, (char *)bm + r * stride, w); + + glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tc_temptile); + } +} + static void draw_glyph (PangoRenderer *renderer_, PangoFont *font, PangoGlyph glyph, double x, double y) { PangoOpenGLRenderer *renderer = PANGO_OPENGL_RENDERER (renderer_); glyph_info *g; - float x1, y1, x2, y2; if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) { @@ -176,16 +212,14 @@ glyph = PANGO_GLYPH_UNKNOWN_FLAG; } - g = _pango_opengl_font_get_cache_glyph_data (font, glyph); + g = (glyph_info *)_pango_opengl_font_get_cache_glyph_data (font, glyph); if (!g || g->generation != tc_generation) { Glyph bm; font_render_glyph (&bm, font, glyph); - if (g) - g->generation = tc_generation; - else + if (!g) { g = g_slice_new (glyph_info); @@ -193,37 +227,27 @@ _pango_opengl_font_set_cache_glyph_data (font, glyph, g); } - tc_get (&g->tex, bm.width, bm.height); + g->generation = tc_generation; g->left = bm.left; g->top = bm.top; - 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); + tc_get (&g->tex, bm.width, bm.height); + + if (bm.width && bm.height) + tex_update (g->tex.name, g->tex.x, g->tex.y, bm.width, bm.stride, bm.height, bm.bitmap); } x += g->left; y -= g->top; - x1 = g->tex.x * (1. / TC_WIDTH ); - y1 = g->tex.y * (1. / TC_HEIGHT); - x2 = g->tex.w * (1. / TC_WIDTH ) + x1; - y2 = g->tex.h * (1. / TC_HEIGHT) + y1; - if (g->tex.name != renderer->key.texname) { renderer->key.texname = g->tex.name; - renderer->arr = rc_array (renderer->rc, &renderer->key); + renderer->arr = &renderer->rc->array (renderer->key); } - 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); + renderer->arr->glyph (g->tex.x, g->tex.y, g->tex.w, g->tex.h, x, y); } static void @@ -238,22 +262,22 @@ { PangoOpenGLRenderer *renderer = (PangoOpenGLRenderer *)renderer_; rc_key_t key = renderer->key; - rc_array_t *arr; key.mode = GL_QUADS; key.format = GL_V2F; key.texname = 0; - arr = rc_array (renderer->rc, &key); + auto &arr = renderer->rc->array (key); - rc_v2f (arr, x11, y1); - rc_v2f (arr, x21, y1); - rc_v2f (arr, x22, y2); - rc_v2f (arr, x12, y2); + arr.v2f (x11, y1); + arr.v2f (x21, y1); + arr.v2f (x22, y2); + arr.v2f (x12, y2); } -void +void pango_opengl_render_layout_subpixel (PangoLayout *layout, + rc_t *rc, int x, int y, float r, float g, float b, float a, int flags) @@ -268,39 +292,26 @@ renderer = _pango_opengl_font_map_get_renderer (PANGO_OPENGL_FONT_MAP (fontmap)); gl = PANGO_OPENGL_RENDERER (renderer); - gl->rc = rc_alloc (); - gl->r = r; - gl->g = g; - gl->b = b; - gl->a = a; + gl->rc = rc; + 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 +void pango_opengl_render_layout (PangoLayout *layout, + rc_t *rc, int x, int y, 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, flags); + pango_opengl_render_layout_subpixel ( + layout, rc, x * PANGO_SCALE, y * PANGO_SCALE, r, g, b, a, flags + ); } static void @@ -326,17 +337,17 @@ renderer->strikethrough = FALSE; gl->key.mode = GL_QUADS; - gl->key.format = GL_T2F_V3F; + gl->key.format = 0; // glyphs gl->key.texname = 0; for (l = run->item->analysis.extra_attrs; l; l = l->next) { - PangoAttribute *attr = l->data; + PangoAttribute *attr = (PangoAttribute *)l->data; switch (attr->klass->type) { case PANGO_ATTR_UNDERLINE: - renderer->underline = ((PangoAttrInt *)attr)->value; + renderer->underline = (PangoUnderline)((PangoAttrInt *)attr)->value; break; case PANGO_ATTR_STRIKETHROUGH: @@ -358,7 +369,7 @@ g = fg->green * (255.f / 65535.f); b = fg->blue * (255.f / 65535.f); } - else + else { r = gl->r * 255.f; g = gl->g * 255.f;