Xnest: replace XTextWidth[16]() by own implementation

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2024-08-20 09:08:23 +02:00
parent 43b225c28c
commit 84be220cd4
4 changed files with 124 additions and 12 deletions

View File

@ -329,8 +329,6 @@ int
xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
char *string) char *string)
{ {
int width;
// we need to prepend a xTextElt struct before our actual characters // 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() // won't get more than 254 elements, since it's already processed by doPolyText()
int const bufsize = sizeof(xTextElt) + count; int const bufsize = sizeof(xTextElt) + count;
@ -350,17 +348,13 @@ xnestPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
free(buffer); free(buffer);
width = XTextWidth(xnestFontStruct(pGC->font), string, count); return x + xnest_text_width(xnestFontPriv(pGC->font), string, count);
return width + x;
} }
int int
xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count, xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
unsigned short *string) unsigned short *string)
{ {
int width;
// we need to prepend a xTextElt struct before our actual characters // 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() // won't get more than 254 elements, since it's already processed by doPolyText()
int const bufsize = sizeof(xTextElt) + count*2; int const bufsize = sizeof(xTextElt) + count*2;
@ -380,9 +374,7 @@ xnestPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int count,
free(buffer); free(buffer);
width = XTextWidth16(xnestFontStruct(pGC->font), (XChar2b *) string, count); return x + xnest_text_width_16(xnestFontPriv(pGC->font), string, count);
return width + x;
} }
void void

View File

@ -24,8 +24,6 @@ extern int xnestFontPrivateIndex;
#define xnestFontPriv(pFont) \ #define xnestFontPriv(pFont) \
((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex)) ((xnestPrivFont *)FontGetPrivate(pFont, xnestFontPrivateIndex))
#define xnestFontStruct(pFont) (xnestFontPriv(pFont)->font_struct)
Bool xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont); Bool xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont);
Bool xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont); Bool xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);

View File

@ -446,3 +446,122 @@ uint32_t xnest_visual_to_upstream_cmap(uint32_t visual)
} }
return XCB_COLORMAP_NONE; 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;
}

View File

@ -72,4 +72,7 @@ typedef struct {
uint16_t chars_len; uint16_t chars_len;
} xnestPrivFont; } 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 */ #endif /* __XNEST__XCB_H */