static void xftfont_close (struct font *font) { struct x_display_info *xdi; struct xftfont_info *xftfont_info = (struct xftfont_info *) font; #ifdef HAVE_LIBOTF if (xftfont_info->otf) { OTF_close (xftfont_info->otf); xftfont_info->otf = NULL; } #endif /* See comment in xfont_close. */ if (xftfont_info->xftfont && ((xdi = x_display_info_for_display (xftfont_info->display)) && xftfont_info->x_display_id == xdi->x_id)) { block_input (); XftUnlockFace (xftfont_info->xftfont); XftFontClose (xftfont_info->display, xftfont_info->xftfont); unblock_input (); xftfont_info->xftfont = NULL; } }
static Lisp_Object xftfont_shape (Lisp_Object lgstring) { struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); struct xftfont_info *xftfont_info = (struct xftfont_info *) font; FT_Face ft_face; Lisp_Object val; ft_face = XftLockFace (xftfont_info->xftfont); xftfont_info->ft_size = ft_face->size; val = ftfont_driver.shape (lgstring); XftUnlockFace (xftfont_info->xftfont); return val; }
static void xftfont_close (FRAME_PTR f, struct font *font) { struct xftfont_info *xftfont_info = (struct xftfont_info *) font; #ifdef HAVE_LIBOTF if (xftfont_info->otf) OTF_close (xftfont_info->otf); #endif BLOCK_INPUT; XftUnlockFace (xftfont_info->xftfont); XftFontClose (xftfont_info->display, xftfont_info->xftfont); UNBLOCK_INPUT; }
static int _xft_Load(TextState * ts, const char *name) { XftFont *font; FontCtxXft *fdc; if (name[0] == '-') font = XftFontOpenXlfd(disp, Dpy.screen, name); else font = XftFontOpenName(disp, Dpy.screen, name); if (!font) return -1; #if 0 /* Debug */ { FT_Face ftf = XftLockFace(font); if (ftf == NULL) return -1; Eprintf("Font %s family_name=%s style_name=%s\n", name, ftf->family_name, ftf->style_name); XftUnlockFace(font); } #endif fdc = EMALLOC(FontCtxXft, 1); if (!fdc) return -1; fdc->font = font; ts->fdc = fdc; ts->need_utf8 = 1; ts->type = FONT_TYPE_XFT; ts->ops = &FontOps_xft; return 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); }