void ZLEwlPaintContext::drawString(int x, int y, const char *str, int len, bool rtl) { if (!g_utf8_validate(str, len, 0)) { return; } pango_shape(str, len, &myAnalysis, myString); PangoRectangle logR; PangoRectangle inkR; pango_glyph_string_extents(myString, myAnalysis.font, &inkR, &logR); int s_width; if(PANGO_RBEARING(inkR) > PANGO_RBEARING(logR)) s_width = PANGO_RBEARING(inkR); else { s_width = PANGO_LBEARING(inkR); if(s_width < 0) s_width = - s_width + logR.width; else s_width = logR.width; } if(!ft2bmp) ft2bmp = createFTBitmap( (s_width + PANGO_SCALE / 2) / PANGO_SCALE, (logR.height + PANGO_SCALE / 2) / PANGO_SCALE); else modifyFTBitmap( ft2bmp, (s_width + PANGO_SCALE / 2) / PANGO_SCALE, (logR.height + PANGO_SCALE / 2) / PANGO_SCALE); int lb; lb = (PANGO_LBEARING(inkR) + PANGO_SCALE / 2) / PANGO_SCALE; if(lb > 0) lb = 0; pango_ft2_render(ft2bmp, myAnalysis.font, myString, -lb , ft2bmp->rows - 1 - myDescent); unsigned char val; unsigned char *p_ft = (unsigned char *)ft2bmp->buffer; for(int i = ft2bmp->rows - 1; i >= 0; i--) { for (int k = 0; k < ft2bmp->width; k++) { if((x + k) < 0) continue; if(p_ft[k] == 0) continue; val = (unsigned char)~p_ft[k]; val /= 64; xcb_image_put_pixel (image, x + k, y - i + myDescent, pal[val]); } p_ft += ft2bmp->pitch; } }