Beispiel #1
0
void
XftTextRender32LE (Display	    *dpy,
		   int		    op,
		   Picture	    src,
		   XftFont	    *pub,
		   Picture	    dst,
		   int		    srcx,
		   int		    srcy,
		   int		    x,
		   int		    y,
		   _Xconst FcChar8  *string,
		   int		    len)
{
    FT_UInt	    *glyphs, glyphs_local[NUM_LOCAL];
    int		    i;

    if (len <= NUM_LOCAL)
	glyphs = glyphs_local;
    else
    {
	glyphs = malloc (len * sizeof (FT_UInt));
	if (!glyphs)
	    return;
    }
    for (i = 0; i < len; i++)
	glyphs[i] = XftCharIndex (dpy, pub, 
				  (string[i*4]) |
				  (string[i*4+1] << 8) |
				  (string[i*4+2] << 16) |
				  (string[i*4+3] << 24));
    XftGlyphRender (dpy, op, src, pub, dst, 
		     srcx, srcy, x, y, glyphs, len);
    if (glyphs != glyphs_local)
	free (glyphs);
}
Beispiel #2
0
void
XftCharFontSpecRender (Display			*dpy,
		       int			op,
		       Picture			src,
		       Picture			dst,
		       int			srcx,
		       int			srcy,
		       _Xconst XftCharFontSpec	*chars,
		       int			len)
{
    XftGlyphFontSpec	*glyphs, glyphs_local[NUM_LOCAL];
    int			i;

    if (len <= NUM_LOCAL)
	glyphs = glyphs_local;
    else
    {
	glyphs = malloc (len * sizeof (XftGlyphFontSpec));
	if (!glyphs)
	    return;
    }
    for (i = 0; i < len; i++)
    {
	glyphs[i].font = chars[i].font;
	glyphs[i].glyph = XftCharIndex(dpy, glyphs[i].font, chars[i].ucs4);
	glyphs[i].x = chars[i].x;
	glyphs[i].y = chars[i].y;
    }

    XftGlyphFontSpecRender (dpy, op, src, dst, srcx, srcy, glyphs, len);
    if (glyphs != glyphs_local)
	free (glyphs);
}
Beispiel #3
0
static unsigned
xftfont_encode_char (struct font *font, int c)
{
  struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
  unsigned code = XftCharIndex (xftfont_info->display, xftfont_info->xftfont,
				(FcChar32) c);

  return (code ? code : FONT_INVALID_CODE);
}
Beispiel #4
0
void
XftTextRenderUtf16 (Display	    *dpy,
		    int		    op,
		    Picture	    src,
		    XftFont	    *pub,
		    Picture	    dst,
		    int		    srcx,
		    int		    srcy,
		    int		    x,
		    int		    y,
		    _Xconst FcChar8 *string,
		    FcEndian	    endian,
		    int		    len)
{
    FT_UInt	    *glyphs, *glyphs_new, glyphs_local[NUM_LOCAL];
    FcChar32	    ucs4;
    int		    i;
    int		    l;
    int		    size;

    i = 0;
    glyphs = glyphs_local;
    size = NUM_LOCAL;
    while (len && (l = FcUtf16ToUcs4 (string, endian, &ucs4, len)) > 0)
    {
	if (i == size)
	{
	    glyphs_new = malloc (size * 2 * sizeof (FT_UInt));
	    if (!glyphs_new)
	    {
		if (glyphs != glyphs_local)
		    free (glyphs);
		return;
	    }
	    memcpy (glyphs_new, glyphs, size * sizeof (FT_UInt));
	    size *= 2;
	    if (glyphs != glyphs_local)
		free (glyphs);
	    glyphs = glyphs_new;
	}
	glyphs[i++] = XftCharIndex (dpy, pub, ucs4);
	string += l;
	len -= l;
    }
    XftGlyphRender (dpy, PictOpOver, src, pub, dst,
		     srcx, srcy, x, y, glyphs, i);
    if (glyphs != glyphs_local)
	free (glyphs);
}
	void draw_string(drawable_type dw, const nana::point& pos, const nana::char_t * str, std::size_t len)
	{
#if defined(NANA_WINDOWS)
		::TextOut(dw->context, pos.x, pos.y, str, static_cast<int>(len));
#elif defined(NANA_X11)
		auto disp = ::nana::detail::platform_spec::instance().open_display();
	#if defined(NANA_UNICODE)
		/*
		std::string utf8str = nana::charset(nana::string(str, len));
		XftFont * fs = reinterpret_cast<XftFont*>(dw->font->handle);
		::XftDrawStringUtf8(dw->xftdraw, &(dw->xft_fgcolor), fs, pos.x, pos.y + fs->ascent,
							reinterpret_cast<XftChar8*>(const_cast<char*>(utf8str.c_str())), utf8str.size());
		*/
		auto fs = reinterpret_cast<XftFont*>(dw->font->handle);

		//Fixed missing array declaration by dareg
		std::unique_ptr<FT_UInt[]> glyphs_ptr(new FT_UInt[len]);
		auto glyphs = glyphs_ptr.get();
		const auto endstr = str + len;
		for(auto chr = str; chr != endstr; ++chr)
		{
			(*glyphs++) = XftCharIndex(disp, fs, *chr);
		}
		XftDrawGlyphs(dw->xftdraw, &(dw->xft_fgcolor), fs, pos.x, pos.y + fs->ascent, glyphs_ptr.get(), len);
	#else
		XFontSet fs = reinterpret_cast<XFontSet>(dw->font->handle);
		XFontSetExtents * ext = ::XExtentsOfFontSet(fs);
		XFontStruct ** fontstructs;
		char ** font_names;
		int size = ::XFontsOfFontSet(fs, &fontstructs, &font_names);
		unsigned ascent = 0;
		unsigned descent = 0;
		XFontStruct **fontstructs_end = fontstructs + size;
		for(XFontStruct** i = fontstructs; i < fontstructs_end; ++i)
		{
			if(ascent < (*i)->ascent)
				ascent = (*i)->ascent;
			if(descent < (*i)->descent)
				descent = (*i)->descent;
		}
		XmbDrawString(display, dw->pixmap, reinterpret_cast<XFontSet>(dw->font->handle), dw->context, pos.x, pos.y + ascent + descent, buf, len);
	#endif
#endif
	}
Beispiel #6
0
void
Tk_DrawChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    CONST char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XColor xcolor;
    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler = Tk_CreateErrorHandler(display, -1, -1, -1,
		NULL, (ClientData) NULL);

	XftDrawChange(fontPtr->ftDraw, drawable);
	Tk_DeleteErrorHandler(handler);
    }
    XGetGCValues(display, gc, GCForeground, &values);
    if (values.foreground != fontPtr->color.pixel) {
	xcolor.pixel = values.foreground;
	XQueryColor(display, DefaultColormap(display, fontPtr->screen),
		&xcolor);
	fontPtr->color.color.red = xcolor.red;
	fontPtr->color.color.green = xcolor.green;
	fontPtr->color.color.blue = xcolor.blue;
	fontPtr->color.color.alpha = 0xffff;
	fontPtr->color.pixel = values.foreground;
    }
    nspec = 0;
    while (numBytes > 0 && x <= maxCoord && y <= maxCoord) {
	XftFont *ftFont;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    return;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c);
	if (ftFont) {
	    specs[nspec].font = ftFont;
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    specs[nspec].x = x;
	    specs[nspec].y = y;
	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);
	    x += metrics.xOff;
	    y += metrics.yOff;
	    nspec++;
	    if (nspec == NUM_SPEC) {
		XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color,
			specs, nspec);
		nspec = 0;
	    }
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec);
    }
}
Beispiel #7
0
void
TkDrawAngledChars(
    Display *display,		/* Display on which to draw. */
    Drawable drawable,		/* Window or pixmap in which to draw. */
    GC gc,			/* Graphics context for drawing characters. */
    Tk_Font tkfont,		/* Font in which characters will be drawn;
				 * must be the same as font used in GC. */
    const char *source,		/* UTF-8 string to be displayed. Need not be
				 * '\0' terminated. All Tk meta-characters
				 * (tabs, control characters, and newlines)
				 * should be stripped out of the string that
				 * is passed to this function. If they are not
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -1000;	/* Should be good enough... */
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XColor xcolor;
    int xStart = x, yStart = y;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
#ifdef XFT_HAS_FIXED_ROTATED_PLACEMENT
    int clen, nglyph;
    FT_UInt glyphs[NUM_SPEC];
    XGlyphInfo metrics;
    XftFont *currentFtFont;
    int originX, originY;

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

	XftDrawChange(fontPtr->ftDraw, drawable);
	Tk_DeleteErrorHandler(handler);
    }

    XGetGCValues(display, gc, GCForeground, &values);
    if (values.foreground != fontPtr->color.pixel) {
	xcolor.pixel = values.foreground;
	XQueryColor(display, DefaultColormap(display, fontPtr->screen),
		&xcolor);
	fontPtr->color.color.red = xcolor.red;
	fontPtr->color.color.green = xcolor.green;
	fontPtr->color.color.blue = xcolor.blue;
	fontPtr->color.color.alpha = 0xffff;
	fontPtr->color.pixel = values.foreground;
    }
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }

    nglyph = 0;
    currentFtFont = NULL;
    originX = originY = 0;		/* lint */

    while (numBytes > 0 && x <= maxCoord && x >= minCoord && y <= maxCoord
	    && y >= minCoord) {
	XftFont *ftFont;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	if (!ftFont) {
	    continue;
	}

	if (ftFont != currentFtFont || nglyph == NUM_SPEC) {
	    if (nglyph) {
		/*
		 * We pass multiple glyphs at once to enable the code to
		 * perform better rendering of sub-pixel inter-glyph spacing.
		 * If only the current Xft implementation could make use of
		 * this information... but we'll be ready when it does!
		 */

		XftDrawGlyphs(fontPtr->ftDraw, &fontPtr->color, currentFtFont,
			originX, originY, glyphs, nglyph);
	    }
	    originX = ROUND16(x);
	    originY = ROUND16(y);
	    if (nglyph) {
		XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
			nglyph, &metrics);
		nglyph = 0;
		x += metrics.xOff;
		y += metrics.yOff;
	    }
	    currentFtFont = ftFont;
	}
	glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
    }
    if (nglyph) {
	XftDrawGlyphs(fontPtr->ftDraw, &fontPtr->color, currentFtFont,
		originX, originY, glyphs, nglyph);
    }
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
    } else {
	Tk_ErrorHandler handler =
		Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);

	XftDrawChange(fontPtr->ftDraw, drawable);
	Tk_DeleteErrorHandler(handler);
    }
    XGetGCValues(display, gc, GCForeground, &values);
    if (values.foreground != fontPtr->color.pixel) {
	xcolor.pixel = values.foreground;
	XQueryColor(display, DefaultColormap(display, fontPtr->screen),
		&xcolor);
	fontPtr->color.color.red = xcolor.red;
	fontPtr->color.color.green = xcolor.green;
	fontPtr->color.color.blue = xcolor.blue;
	fontPtr->color.color.alpha = 0xffff;
	fontPtr->color.pixel = values.foreground;
    }
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0 && x <= maxCoord && x >= minCoord
	    && y <= maxCoord && y >= minCoord) {
	XftFont *ftFont, *ft0Font;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
	     */

	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {
	    specs[nspec].font = ftFont;
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    specs[nspec].x = ROUND16(x);
	    specs[nspec].y = ROUND16(y);
	    XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
		    &metrics);
	    x += metrics.xOff*cosA + metrics.yOff*sinA;
	    y += metrics.yOff*cosA - metrics.xOff*sinA;
	    nspec++;
	    if (nspec == NUM_SPEC) {
		XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color,
			specs, nspec);
		nspec = 0;
	    }
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec);
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */

  doUnderlineStrikeout:
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, None);
    }
    if (fontPtr->font.fa.underline || fontPtr->font.fa.overstrike) {
	XPoint points[5];
	double width = (x - xStart) * cosA + (yStart - y) * sinA;
	double barHeight = fontPtr->font.underlineHeight;
	double dy = fontPtr->font.underlinePos;

	if (fontPtr->font.fa.underline != 0) {
	    if (fontPtr->font.underlineHeight == 1) {
		dy++;
	    }
	    points[0].x = xStart + ROUND16(dy*sinA);
	    points[0].y = yStart + ROUND16(dy*cosA);
	    points[1].x = xStart + ROUND16(dy*sinA + width*cosA);
	    points[1].y = yStart + ROUND16(dy*cosA - width*sinA);
	    if (fontPtr->font.underlineHeight == 1) {
		XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin);
	    } else {
		points[2].x = xStart + ROUND16(dy*sinA + width*cosA
			+ barHeight*sinA);
		points[2].y = yStart + ROUND16(dy*cosA - width*sinA
			+ barHeight*cosA);
		points[3].x = xStart + ROUND16(dy*sinA + barHeight*sinA);
		points[3].y = yStart + ROUND16(dy*cosA + barHeight*cosA);
		points[4].x = points[0].x;
		points[4].y = points[0].y;
		XFillPolygon(display, drawable, gc, points, 5, Complex,
			CoordModeOrigin);
		XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
	    }
	}
	if (fontPtr->font.fa.overstrike != 0) {
	    dy = -fontPtr->font.fm.descent
		   - (fontPtr->font.fm.ascent) / 10;
	    points[0].x = xStart + ROUND16(dy*sinA);
	    points[0].y = yStart + ROUND16(dy*cosA);
	    points[1].x = xStart + ROUND16(dy*sinA + width*cosA);
	    points[1].y = yStart + ROUND16(dy*cosA - width*sinA);
	    if (fontPtr->font.underlineHeight == 1) {
		XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin);
	    } else {
		points[2].x = xStart + ROUND16(dy*sinA + width*cosA
			+ barHeight*sinA);
		points[2].y = yStart + ROUND16(dy*cosA - width*sinA
			+ barHeight*cosA);
		points[3].x = xStart + ROUND16(dy*sinA + barHeight*sinA);
		points[3].y = yStart + ROUND16(dy*cosA + barHeight*cosA);
		points[4].x = points[0].x;
		points[4].y = points[0].y;
		XFillPolygon(display, drawable, gc, points, 5, Complex,
			CoordModeOrigin);
		XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
	    }
	}
    }
}