From 8116fd8a760b5935645def1b2c3b155c05927850 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 12 Jan 2016 14:19:24 +1000 Subject: [PATCH] glamor: store old fonts in double width textures. 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 Reviewed-by: Keith Packard Signed-off-by: Dave Airlie --- glamor/glamor_font.c | 25 +++++++++++++++++++++---- glamor/glamor_font.h | 2 +- glamor/glamor_text.c | 10 +++++++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/glamor/glamor_font.c b/glamor/glamor_font.c index 9b0dbd116..637e0dce1 100644 --- a/glamor/glamor_font.c +++ b/glamor/glamor_font.c @@ -77,8 +77,19 @@ 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; + + if (num_rows > 1) { + overall_width = glamor_font->row_width * 2; + overall_height = glyph_height * ((num_rows + 1) / 2); + } else { + overall_width = glamor_font->row_width; + overall_height = glyph_height; + } if (overall_width > glamor_priv->max_fbo_size || overall_height > glamor_priv->max_fbo_size) { @@ -117,11 +128,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 36d20624d..4d41e0196 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 81a22a5af..429f53b8a 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; - + int second_row = 0; 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;