From 84be220cd452a6bc19f32249ddd640639a7ffee3 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Tue, 20 Aug 2024 09:08:23 +0200 Subject: [PATCH] Xnest: replace XTextWidth[16]() by own implementation Signed-off-by: Enrico Weigelt, metux IT consult --- hw/xnest/GCOps.c | 12 +---- hw/xnest/XNFont.h | 2 - hw/xnest/xcb.c | 119 +++++++++++++++++++++++++++++++++++++++++++ hw/xnest/xnest-xcb.h | 3 ++ 4 files changed, 124 insertions(+), 12 deletions(-) diff --git a/hw/xnest/GCOps.c b/hw/xnest/GCOps.c index 70d43e1e8..b1a12121e 100644 --- a/hw/xnest/GCOps.c +++ b/hw/xnest/GCOps.c @@ -329,8 +329,6 @@ int xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, char *string) { - int width; - // we need to prepend a xTextElt struct before our actual characters // won't get more than 254 elements, since it's already processed by doPolyText() int const bufsize = sizeof(xTextElt) + count; @@ -350,17 +348,13 @@ xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, free(buffer); - width = XTextWidth(xnestFontStruct(pGC->font), string, count); - - return width + x; + return x + xnest_text_width(xnestFontPriv(pGC->font), string, count); } int xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, unsigned short *string) { - int width; - // we need to prepend a xTextElt struct before our actual characters // won't get more than 254 elements, since it's already processed by doPolyText() int const bufsize = sizeof(xTextElt) + count*2; @@ -380,9 +374,7 @@ xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, free(buffer); - width = XTextWidth16(xnestFontStruct(pGC->font), (XChar2b *) string, count); - - return width + x; + return x + xnest_text_width_16(xnestFontPriv(pGC->font), string, count); } void diff --git a/hw/xnest/XNFont.h b/hw/xnest/XNFont.h index da2253d52..db17b6fed 100644 --- a/hw/xnest/XNFont.h +++ b/hw/xnest/XNFont.h @@ -24,8 +24,6 @@ extern int xnestFontPrivateIndex; #define xnestFontPriv(pFont) \ ((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex)) -#define xnestFontStruct(pFont) (xnestFontPriv(pFont)->font_struct) - Bool xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont); Bool xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont); diff --git a/hw/xnest/xcb.c b/hw/xnest/xcb.c index 741054811..f298bab61 100644 --- a/hw/xnest/xcb.c +++ b/hw/xnest/xcb.c @@ -446,3 +446,122 @@ uint32_t xnest_visual_to_upstream_cmap(uint32_t visual) } return XCB_COLORMAP_NONE; } + +static inline char XN_CI_NONEXISTCHAR(xcb_charinfo_t *cs) +{ + return ((cs->character_width == 0) && \ + ((cs->right_side_bearing | cs->left_side_bearing | cs->ascent | cs->descent) == 0)); +} + +#define XN_CI_GET_CHAR_INFO_1D(font,col,def,cs) \ +do { \ + cs = def; \ + if (col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \ + if (font->chars == NULL) { \ + cs = &font->font_reply->min_bounds; \ + } else { \ + cs = (xcb_charinfo_t *)&font->chars[(col - font->font_reply->min_char_or_byte2)]; \ + if (XN_CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ +} while (0) + +#define XN_CI_GET_CHAR_INFO_2D(font,row,col,def,cs) \ +do { \ + cs = def; \ + if (row >= font->font_reply->min_byte1 && row <= font->font_reply->max_byte1 && \ + col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \ + if (font->chars == NULL) { \ + cs = &font->font_reply->min_bounds; \ + } else { \ + cs = (xcb_charinfo_t*)&font->chars[((row - font->font_reply->min_byte1) * \ + (font->font_reply->max_char_or_byte2 - \ + font->font_reply->min_char_or_byte2 + 1)) + \ + (col - font->font_reply->min_char_or_byte2)]; \ + if (XN_CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ +} while (0) + +#define XN_CI_GET_DEFAULT_INFO_2D(font,cs) \ +do { \ + unsigned int r = (font->font_reply->default_char >> 8); \ + unsigned int c = (font->font_reply->default_char & 0xff); \ + XN_CI_GET_CHAR_INFO_2D (font, r, c, NULL, cs); \ +} while (0) + +#define XN_CI_GET_ROWZERO_CHAR_INFO_2D(font,col,def,cs) \ +do { \ + cs = def; \ + if (font->font_reply->min_byte1 == 0 && \ + col >= font->font_reply->min_char_or_byte2 && col <= font->font_reply->max_char_or_byte2) { \ + if (font->chars == NULL) { \ + cs = &font->font_reply->min_bounds; \ + } else { \ + cs = (xcb_charinfo_t*)&font->chars[(col - font->font_reply->min_char_or_byte2)]; \ + if (XN_CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ +} while (0) + +int xnest_text_width(xnestPrivFont *font, const char *string, int count) +{ + xcb_charinfo_t *def; + + if (font->font_reply->max_byte1 == 0) + XN_CI_GET_CHAR_INFO_1D (font, font->font_reply->default_char, NULL, def); + else + XN_CI_GET_DEFAULT_INFO_2D (font, def); + + if (def && font->font_reply->min_bounds.character_width == font->font_reply->max_bounds.character_width) + return (font->font_reply->min_bounds.character_width * count); + + int width = 0, i = 0; + unsigned char *us; + for (i = 0, us = (unsigned char *) string; i < count; i++, us++) { + unsigned uc = (unsigned) *us; + xcb_charinfo_t *cs; + + if (font->font_reply->max_byte1 == 0) { + XN_CI_GET_CHAR_INFO_1D (font, uc, def, cs); + } else { + XN_CI_GET_ROWZERO_CHAR_INFO_2D (font, uc, def, cs); + } + + if (cs) width += cs->character_width; + } + + return width; +} + +int xnest_text_width_16 (xnestPrivFont *font, const uint16_t* str, int count) +{ + xcb_charinfo_t *def; + xcb_char2b_t *string = (xcb_char2b_t*)str; + + if (font->font_reply->max_byte1 == 0) + XN_CI_GET_CHAR_INFO_1D (font, font->font_reply->default_char, NULL, def); + else + XN_CI_GET_DEFAULT_INFO_2D (font, def); + + if (def && font->font_reply->min_bounds.character_width == font->font_reply->max_bounds.character_width) + return (font->font_reply->min_bounds.character_width * count); + + int width = 0; + for (int i = 0; i < count; i++, string++) { + xcb_charinfo_t *cs; + unsigned int r = (unsigned int) string->byte1; + unsigned int c = (unsigned int) string->byte2; + + if (font->font_reply->max_byte1 == 0) { + unsigned int ind = ((r << 8) | c); + XN_CI_GET_CHAR_INFO_1D (font, ind, def, cs); + } else { + XN_CI_GET_CHAR_INFO_2D (font, r, c, def, cs); + } + + if (cs) width += cs->character_width; + } + + return width; +} diff --git a/hw/xnest/xnest-xcb.h b/hw/xnest/xnest-xcb.h index 4eedbc953..efd68593d 100644 --- a/hw/xnest/xnest-xcb.h +++ b/hw/xnest/xnest-xcb.h @@ -72,4 +72,7 @@ typedef struct { uint16_t chars_len; } xnestPrivFont; +int xnest_text_width (xnestPrivFont *font, const char *string, int count); +int xnest_text_width_16 (xnestPrivFont *font, const uint16_t *string, int count); + #endif /* __XNEST__XCB_H */