Exemplo n.º 1
0
/*! \internal
    This is basically a substitute for glxUseXFont() which can only
    handle XLFD fonts. This version relies on XFT v2 to render the
    glyphs, but it works with all fonts that XFT2 provides - both
    antialiased and aliased bitmap and outline fonts.
*/
void qgl_use_font(QFontEngineXft *engine, int first, int count, int listBase)
{
    GLfloat color[4];
    glGetFloatv(GL_CURRENT_COLOR, color);

    // save the pixel unpack state
    GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_alignment;
    glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes);
    glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst);
    glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength);
    glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows);
    glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels);
    glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_alignment);

    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    Bool antialiased = False;
#if 0 // disable antialias support for now
    XftPatternGetBool(engine->pattern(), XFT_ANTIALIAS, 0, &antialiased);
#endif
#ifdef QT_XFT2
    FT_Face face = XftLockFace(engine->font());
#else
    FT_Face face = engine->face();
#endif
    // start generating font glyphs
    for (int i = first; i < count; ++i) {
	int list = listBase + i;
	GLfloat x0, y0, dx, dy;

	FT_Error err;

	err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
	if (err) {
	    qDebug("failed loading glyph %d from font", i);
	    Q_ASSERT(!err);
	}
	err = FT_Render_Glyph(face->glyph, (antialiased ? ft_render_mode_normal
					    : ft_render_mode_mono));
	if (err) {
	    qDebug("failed rendering glyph %d from font", i);
	    Q_ASSERT(!err);
	}

	FT_Bitmap bm = face->glyph->bitmap;
	x0 = face->glyph->metrics.horiBearingX >> 6;
	y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6;
	dx = face->glyph->metrics.horiAdvance >> 6;
	dy = 0;
 	int sz = bm.pitch * bm.rows;
	uint *aa_glyph = 0;
	uchar *ua_glyph = 0;

	if (antialiased)
	    aa_glyph = new uint[sz];
	else
	    ua_glyph = new uchar[sz];

	// convert to GL format
	for (int y = 0; y < bm.rows; ++y) {
	    for (int x = 0; x < bm.pitch; ++x) {
		int c1 = y*bm.pitch + x;
		int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x;
		if (antialiased) {
		    aa_glyph[c1] = (int(color[0]*255) << 24)
					 | (int(color[1]*255) << 16)
					 | (int(color[2]*255) << 8) | bm.buffer[c2];
		} else {
		    ua_glyph[c1] = bm.buffer[c2];
		}
	    }
	}

	glNewList(list, GL_COMPILE);
	if (antialiased) {
	    // calling glBitmap() is just a trick to move the current
	    // raster pos, since glGet*() won't work in display lists
	    glBitmap(0, 0, 0, 0, x0, -y0, 0);
	    glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph);
	    glBitmap(0, 0, 0, 0, dx-x0, y0, 0);
	} else {
	    glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph);
	}
	glEndList();
	antialiased ? delete[] aa_glyph : delete[] ua_glyph;
    }

#ifdef QT_XFT2
    XftUnlockFace(engine->font());
#endif

    // restore pixel unpack settings
    glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes);
    glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength);
    glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows);
    glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels);
    glPixelStorei(GL_UNPACK_ALIGNMENT, gl_alignment);
}
Exemplo n.º 2
0
XFontStruct*
XftCoreOpen (Display *dpy, XftPattern *pattern)
{
    XftCoreFont	*cf;
    char	*xlfd;
    char	*xlfd_pixel = 0;
    char	*i, *o;
    int		d;
    Bool	scalable;
    double	pixel_size;
    int		pixel_int;
    XFontStruct	*ret;

#if 0
    printf ("Core ");
    XftPatternPrint (pattern);
#endif
    if (XftPatternGetString (pattern, XFT_XLFD, 0, &xlfd) != XftResultMatch)
	return 0;
    if (XftPatternGetBool (pattern, XFT_SCALABLE, 0, &scalable) != XftResultMatch)
	return 0;
    if (scalable)
    {
	if (XftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &pixel_size) != XftResultMatch)
	    return 0;
	pixel_int = (int) (pixel_size + 0.5);
	if (pixel_int)
	{
	    xlfd_pixel = (char *) malloc (strlen (xlfd) + 32);
	    i = xlfd;
	    o = xlfd_pixel;
	    d = 0;
	    while (d != 7 && *i)
	    {
		if ((*o++ = *i++) == '-')
		    d++;
	    }
	    if (*i)
	    {
		sprintf (o, "%d", pixel_int);
		o += strlen (o);
		while (*i != '-')
		    ++i;
	    }
	    while ((*o++ = *i++));
#if 0
	    printf ("original %s sized %s\n", xlfd, xlfd_pixel);
#endif
	    xlfd = xlfd_pixel;
	}
    }
    for (cf = _XftCoreFonts; cf; cf = cf->next)
    {
	if (cf->display == dpy &&
	    !_XftStrCmpIgnoreCase (cf->xlfd, xlfd))
	{
	    cf->ref++;
	    if (_XftFontDebug () & XFT_DBG_REF)
	    {
		printf ("Xlfd \"%s\" matches existing font (%d)\n",
			xlfd, cf->ref);
	    }
	    break;
	}
    }
    if (!cf)
    {
	ret = XLoadQueryFont (dpy, xlfd);
	if (!ret)
	    return 0;

	cf = (XftCoreFont *) malloc (sizeof (XftCoreFont) +
				     strlen (xlfd) + 1);
	if (!cf)
	{
	    XFreeFont (dpy, ret);
	    return 0;
	}
	
        if (_XftFontDebug () & XFT_DBG_REF)
	    printf ("Xlfd \"%s\" matches new font\n", xlfd);
	
	cf->next = _XftCoreFonts;
	_XftCoreFonts = cf;
	cf->ref = 1;
	
	cf->font = ret;
	cf->xlfd = (char *) (cf + 1);
	strcpy (cf->xlfd, xlfd);
    }
    if (xlfd_pixel)
	free (xlfd_pixel);
    return cf->font;
}