[PATCH] glamor: store old fonts in double width textures.

Dave Airlie airlied at gmail.com
Mon Jan 11 20:22:32 PST 2016


From: Dave Airlie <airlied at redhat.com>

There is a problem with some fonts that the height necessary
to store the font is greater than the max texture size, which
causes a fallback to occur. We can avoid this by storing two
macro columns side-by-side in the texture and adjusting
the calculations to suit.

This fixes
xfd -fn -*-*-*-*-*-*-*-*-*-*-*-*-*-*
falling back here, when it picks
-arabic-newspaper-medium-r-normal--32-246-100-100-p-137-iso10646-1

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 glamor/glamor_font.c | 21 +++++++++++++++++----
 glamor/glamor_font.h |  2 +-
 glamor/glamor_text.c | 10 +++++++---
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c
index bda1b58..3c95324 100644
--- a/glamor/glamor_font.c
+++ b/glamor/glamor_font.c
@@ -77,11 +77,18 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
     glamor_font->glyph_width_bytes = glyph_width_bytes;
     glamor_font->glyph_height = glyph_height;
 
-    overall_width = glyph_width_bytes * num_cols;
-    overall_height = glyph_height * num_rows;
+    /*
+     * Layout the font two blocks of columns wide.
+     * This avoids a problem with some fonts that are too high to fit.
+     */
+    glamor_font->row_width = glyph_width_bytes * num_cols;
+
+    overall_width = glamor_font->row_width * ((num_rows > 1) ? 2 : 1);
+    overall_height = glyph_height * ((num_rows + 1) / 2);
 
     if (overall_width > glamor_priv->max_fbo_size ||
         overall_height > glamor_priv->max_fbo_size) {
+        /* fallback if we don't fit inside a texture */
         return NULL;
     }
     bits = malloc(overall_width * overall_height);
@@ -116,11 +123,17 @@ glamor_font_get(ScreenPtr screen, FontPtr font)
             (*font->get_glyphs)(font, 1, c, TwoD16Bit, &count, &glyph);
 
             if (count) {
-                char *dst = bits + row * glyph_height * overall_width +
-                    col * glyph_width_bytes;
+                char *dst;
                 char *src = glyph->bits;
                 unsigned y;
 
+                dst = bits;
+                /* get offset of start of first row */
+                dst += (row / 2) * glyph_height * overall_width;
+                /* add offset into second row */
+                dst += (row & 1) ? glamor_font->row_width : 0;
+
+                dst += col * glyph_width_bytes;
                 for (y = 0; y < GLYPHHEIGHTPIXELS(glyph); y++) {
                     memcpy(dst, src, GLYPHWIDTHBYTES(glyph));
                     dst += overall_width;
diff --git a/glamor/glamor_font.h b/glamor/glamor_font.h
index 36d2062..4d41e01 100644
--- a/glamor/glamor_font.h
+++ b/glamor/glamor_font.h
@@ -30,7 +30,7 @@ typedef struct {
     CARD8       default_col;
 
     GLuint      texture_id;
-
+    GLuint      row_width;
     CARD16      glyph_width_bytes;
     CARD16      glyph_width_pixels;
     CARD16      glyph_height;
diff --git a/glamor/glamor_text.c b/glamor/glamor_text.c
index 81a22a5..7204220 100644
--- a/glamor/glamor_text.c
+++ b/glamor/glamor_text.c
@@ -142,7 +142,7 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
             int     height = GLYPHHEIGHTPIXELS(ci);
             int     tx, ty = 0;
             int     row = 0, col;
-
+            Bool    second_row = false;
             x += ci->metrics.characterWidth;
 
             if (sixteen) {
@@ -153,8 +153,10 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
                     row = chars[0];
                     col = chars[1];
                 }
-                if (FONTLASTROW(font) != 0)
-                    ty = (row - firstRow) * glyph_spacing_y;
+                if (FONTLASTROW(font) != 0) {
+                    ty = ((row - firstRow) / 2) * glyph_spacing_y;
+                    second_row = (row - firstRow) & 1;
+                }
                 else
                     col += row << 8;
             } else {
@@ -165,6 +167,8 @@ glamor_text(DrawablePtr drawable, GCPtr gc,
             }
 
             tx = (col - firstCol) * glyph_spacing_x;
+            /* adjust for second row layout */
+            tx += second_row * glamor_font->row_width * 8;
 
             v[ 0] = x1;
             v[ 1] = y1;
-- 
2.4.3



More information about the xorg-devel mailing list