float XftTextRenderer::measureRange(const WebCoreTextRun *run, const WebCoreTextStyle *style, int from, int to, float* widths) { XGlyphInfo extents; if (style->letterSpacing == 0 && !widths) { XftTextExtents16( xdisplay, font->xftFont, reinterpret_cast<const XftChar16*>(run->characters + from), to - from, &extents); return extents.xOff; } float w, totalLen = 0.0f; int i = 0; while (from < to) { XftTextExtents16(xdisplay, font->xftFont, reinterpret_cast<const XftChar16*>(run->characters + from), 1, &extents); w = extents.xOff + style->letterSpacing; totalLen += w; if (widths) widths[i++] = w; ++from; } return totalLen; }
int FontX11::get_string_width(const String& p_string) const { if (!font) return 0; XGlyphInfo ginfo; // this will dissapear at compile time switch(sizeof(String::CharType)) { case 1: { // ascii? XftTextExtents8( x11_display, font, (FcChar8*)p_string.c_str(), p_string.length(), &ginfo ); } break; case 2: { // ucs16 XftTextExtents16( x11_display, font, (FcChar16*)p_string.c_str(), p_string.length(), &ginfo ); } break; case 4: { // ucs32 XftTextExtents32( x11_display, font, (FcChar32*)p_string.c_str(), p_string.length(), &ginfo ); } break; } return ginfo.width; }
float XftTextRenderer::drawRange(const WebCoreTextRun *run, const WebCoreTextStyle *style, int from, int to, int x, int y, const XftColor* color, bool shouldMeasure) { int width = 0; XGlyphInfo extents; if (style->letterSpacing) { while (from<to) { XftTextExtents16(xdisplay, font->xftFont, reinterpret_cast<const XftChar16*>(run->characters + from), 1, &extents); XftDrawString16(xftdraw, color, font->xftFont, x, y, reinterpret_cast<const XftChar16*>(run->characters + from), 1); x += extents.xOff + style->letterSpacing; ++from; width += extents.xOff + style->letterSpacing; } return width; } else { if (shouldMeasure) { XftTextExtents16(xdisplay, font->xftFont, reinterpret_cast<const XftChar16*>(run->characters + from), to - from, &extents); width += extents.xOff; } XftDrawString16(xftdraw, color, font->xftFont, x, y, reinterpret_cast<const XftChar16*>(run->characters + from), to - from); } return width; }
void XftTextRenderer::drawHighlightForRun(const WebCoreTextRun *run, const WebCoreTextStyle *style, const WebCoreTextGeometry *geom) { assert(run); assert(style); assert(style->families); if (run->length == 0) return ; int x=0, y=0, w=0, h=0; XGlyphInfo extents; UniChar* uchars = dupCharsAndRemoveLF(run->characters, run->length); x = (int)geom->selectionMinX; y = (int)geom->y; if (run->from > 0) { XftTextExtents16( xdisplay, font->xftFont, reinterpret_cast<const XftChar16*>(uchars), run->from, &extents); x += extents.xOff /* + style->padding*/; // xOff == offset where the next char starts } XftTextExtents16( xdisplay, font->xftFont, reinterpret_cast<const XftChar16*>(uchars + run->from), run->to - run->from, &extents); w = (int)extents.width; h = (int)geom->selectionHeight; drawRect(x,y,w,h, &style->textColor); delete[] uchars; }
// selection point check int XftTextRenderer::pointToOffset(const WebCoreTextRun *run, const WebCoreTextStyle *style, int x, bool reversed, bool includePartialGlyphs) { assert(run); assert(style); assert(style->families); if (run->length == 0) return 0; XGlyphInfo extents; UniChar* uchars = dupCharsAndRemoveLF(run->characters, run->length); // binary search for offset in string for pixel position x int start, end; start = run->from; end = run->to; int xpos; int len_mid; while (start < end) { len_mid = ((end - start)+1) / 2; XftTextExtents16(xdisplay, font->xftFont, reinterpret_cast<const XftChar16*>(uchars + start), len_mid, &extents); xpos = extents.xOff; if (xpos < x) { start += len_mid; x -= xpos; } else if (xpos > x) { end -= len_mid; }else { start += len_mid; break; } } delete [] uchars; return start - run->from; }
unsigned int gui_wtext_width(struct gui_font *font, const wchar_t *text, size_t length) { XGlyphInfo extents; if (sizeof (wchar_t) == 4) { XftTextExtents32 (GUI_display, font->xft_font, (const unsigned int *) text, length, &extents); } else if (sizeof (wchar_t) == 2) { XftTextExtents16 (GUI_display, font->xft_font, (const unsigned short *) text, length, &extents); } else assert (!"Unexpected size of wchar_t"); return extents.xOff; }
static void ui_draw_full_move_str(int x, int y, int maxwidth, int movenum, const char* whitepgn, const char* blackpgn) { int numwidth = 0; if (movenum > 0) { char numstr[8]; snprintf(numstr, 8, "%d.", movenum); ui_draw_info_string_tag(numstr, x, y, maxwidth, NULL); int numcnt = strlen(numstr) > 7 ? strlen(numstr) : 7; numwidth = numcnt * ui_infofontchwidth; } x += numwidth; maxwidth -= numwidth; int whitewidth = 0; if (NULL != whitepgn && '\0' != (*whitepgn)) { ui_draw_info_string(whitepgn, x, y, maxwidth, &whitewidth); } else { XftChar16 dotch = 0x2026; // unicode ... character /* get width of three dots */ XGlyphInfo extents; XftTextExtents16(ui_display, ui_infofont, &dotch, 1, &extents); whitewidth = extents.width; XftDrawString16(ui_xftdraw, &ui_infocolor, ui_infofont, x, y, &dotch, 1); } whitewidth = whitewidth < (ui_infofontchwidth * 8) ? (ui_infofontchwidth * 8) : whitewidth; x += whitewidth + UI_SPACING_X_INFO; maxwidth -= whitewidth + UI_SPACING_X_INFO; if (NULL != blackpgn && '\0' != (*blackpgn)) { ui_draw_info_string(blackpgn, x, y, maxwidth, NULL); } }
static void ui_draw_string( const char* str, XftFont* font, XftColor* color, int x, int y, int maxwidth, int* width) { XftChar16 dotch = 0x2026; // unicode ... character /* get width of three dots */ XGlyphInfo extents; XftTextExtents16(ui_display, font, &dotch, 1, &extents); int sizepoints = extents.width; size_t cutlen = 0; XftTextExtentsUtf8(ui_display, font, (XftChar8*) str, strlen(str), &extents); int totlen = extents.width; while (totlen > maxwidth && cutlen < strlen(str)) { ++cutlen; XftTextExtentsUtf8(ui_display, font, (XftChar8*) str, strlen(str) - cutlen, &extents); totlen = extents.width + sizepoints; } if (NULL != width) { *width = 0; } if (totlen <= maxwidth) { XftDrawStringUtf8(ui_xftdraw, color, font, x, y, (XftChar8*) str, strlen(str) - cutlen); if (cutlen > 0) { XftDrawString16(ui_xftdraw, color, font, x + extents.width, y, &dotch, 1); } if (NULL != width) { *width = totlen; } } }
PlatformFont::CharInfo &x86UNIXFont::getCharInfo(const UTF16 ch) const { Display *display = XOpenDisplay(getenv("DISPLAY")); if (!display ) AssertFatal(false, "createFont: cannot connect to X server"); static PlatformFont::CharInfo c; dMemset(&c, 0, sizeof(c)); c.bitmapIndex = 0; c.xOffset = 0; c.yOffset = 0; XftFont *fontInfo = XftFontOpenName(display, DefaultScreen(display), mFontName); if (!fontInfo) AssertFatal(false, "createFont: cannot load font"); int screen = DefaultScreen(display); // Create the pixmap to draw on. Drawable pixmap = XCreatePixmap(display, DefaultRootWindow(display), fontInfo->max_advance_width, fontInfo->height, DefaultDepth(display, screen)); // And the Xft wrapper around it. XftDraw *draw = XftDrawCreate(display, pixmap, DefaultVisual(display, screen), DefaultColormap(display, screen)); // Allocate some colors, we don't use XftColorAllocValue here as that // Don't appear to function correctly (or I'm using it wrong) As we only do // this twice per new un cached font it isn't that big of a penalty. (Each // call to XftColorAllocName involves a round trip to the X Server) XftColor black, white; XftColorAllocName(display, DefaultVisual(display, screen), DefaultColormap(display, screen), "black", &black); // White XftColorAllocName(display, DefaultVisual(display, screen), DefaultColormap(display, screen), "white", &white); XGlyphInfo charinfo; XftTextExtents16(display, fontInfo, &ch, 1, &charinfo); c.height = fontInfo->height; c.xOrigin = 0; c.yOrigin = fontInfo->ascent; c.xIncrement = charinfo.xOff; c.width = charinfo.xOff; // kick out early if the character is undrawable if( c.width == 0 || c.height == 0) return c; // allocate a greyscale bitmap and clear it. int bitmapDataSize = c.width * c.height; c.bitmapData = new U8[bitmapDataSize]; dMemset(c.bitmapData, 0, bitmapDataSize); XftDrawRect (draw, &black, 0, 0, fontInfo->max_advance_width, fontInfo->height); XftDrawString16 (draw, &white, fontInfo, 0, fontInfo->ascent, &ch, 1); // grab the pixmap image XImage *ximage = XGetImage(display, pixmap, 0, 0, charinfo.xOff, fontInfo->height, AllPlanes, XYPixmap); if (!ximage) AssertFatal(false, "cannot get x image"); int x, y; // grab each pixel and store it in the scratchPad for(y = 0; y < fontInfo->height; y++) { for(x = 0; x < charinfo.xOff; x++) c.bitmapData[y * charinfo.xOff + x] = static_cast<U8>(XGetPixel(ximage, x, y)); } XDestroyImage(ximage); XftColorFree(display, DefaultVisual(display, screen), DefaultColormap(display, screen), &black); XftColorFree(display, DefaultVisual(display, screen), DefaultColormap(display, screen), &white); XftDrawDestroy(draw); XFreePixmap(display, pixmap); XCloseDisplay(display); return c; }