+ else
+ {
+ Window window = RootWindow (data->dpy, 0);
+ XGCValues gcv;
+ GC gc;
+
+ XGetWindowAttributes (data->dpy, window, &xgwa);
+ width = iterate_texture_string (data, string, 0, 0, 0, 0, &height);
+ p = XCreatePixmap (data->dpy, window,
+ width + margin*2,
+ height + margin*2,
+ xgwa.depth);
+ gcv.foreground = BlackPixelOfScreen (xgwa.screen);
+ gc = XCreateGC (data->dpy, p, GCForeground, &gcv);
+ XFillRectangle (data->dpy, p, gc, 0, 0,
+ width + margin*2,
+ height + margin*2);
+ XFreeGC (data->dpy, gc);
+ }
+
+ /* Draw the string into the pixmap, unless it's cached.
+ */
+ if (!cache->string)
+ {
+ XRenderColor rcolor;
+ XftColor xftcolor;
+ XftDraw *xftdraw;
+ rcolor.red = rcolor.green = rcolor.blue = rcolor.alpha = 0xFFFF;
+ XftColorAllocValue (data->dpy, xgwa.visual, xgwa.colormap,
+ &rcolor, &xftcolor);
+ xftdraw = XftDrawCreate (data->dpy, p, xgwa.visual, xgwa.colormap);
+ iterate_texture_string (data, string, xftdraw, &xftcolor,
+ margin, 0, 0);
+ XftDrawDestroy (xftdraw);
+ XftColorFree (data->dpy, xgwa.visual, xgwa.colormap, &xftcolor);
+ }
+
+ {
+ GLint old_texture;
+ int ofront, oblend;
+ Bool alpha_p, blend_p;
+ GLfloat omatrix[16];
+ GLfloat qx0, qy0, qx1, qy1;
+ GLfloat tx0, ty0, tx1, ty1;
+
+ /* Save the prevailing texture environment, and set up ours.
+ */
+ glGetIntegerv (GL_TEXTURE_BINDING_2D, &old_texture);
+ glGetIntegerv (GL_FRONT_FACE, &ofront);
+ glGetIntegerv (GL_BLEND_DST, &oblend);
+ glGetFloatv (GL_TEXTURE_MATRIX, omatrix);
+ blend_p = glIsEnabled (GL_BLEND);
+ alpha_p = glIsEnabled (GL_ALPHA_TEST);
+
+ clear_gl_error ();
+
+ glPushMatrix();
+
+ glNormal3f (0, 0, 1);
+ glFrontFace (GL_CW);
+
+ glMatrixMode (GL_TEXTURE);
+ glLoadIdentity ();
+ glMatrixMode (GL_MODELVIEW);
+
+ glBindTexture (GL_TEXTURE_2D, cache->texid);
+ check_gl_error ("texture font binding");
+
+ glEnable(GL_TEXTURE_2D);
+
+ /* Copy the bits from the Pixmap into a texture, unless it's cached.
+ */
+ if (cache->string)
+ {
+ width2 = data->cache->width2;
+ height2 = data->cache->height2;
+ if (p) abort();
+ }
+ else
+ {
+ width2 = width + margin*2;
+ height2 = height + margin*2;
+ bitmap_to_texture (data->dpy, p, xgwa.visual, xgwa.depth,
+ &width2, &height2);
+ XFreePixmap (data->dpy, p);
+ }
+
+
+ /* Texture-rendering parameters to make font pixmaps tolerable to look at.
+ */
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_LINEAR);
+
+ /* LOD bias is part of OpenGL 1.4.
+ GL_EXT_texture_lod_bias has been present since the original iPhone.
+ */
+# if !defined(GL_TEXTURE_LOD_BIAS) && defined(GL_TEXTURE_LOD_BIAS_EXT)
+# define GL_TEXTURE_LOD_BIAS GL_TEXTURE_LOD_BIAS_EXT
+# endif
+# ifdef GL_TEXTURE_LOD_BIAS
+ glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.25);
+# endif
+ clear_gl_error(); /* invalid enum on iPad 3 */
+
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ /* Don't write the transparent parts of the quad into the depth buffer. */
+ glAlphaFunc (GL_GREATER, 0.01);
+ glEnable (GL_ALPHA_TEST);
+ glEnable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* Draw a quad with that texture on it, possibly using a cached texture.
+ */
+ qx0 = -margin;
+ qy0 = line_height + margin;
+ qx1 = width + margin;
+ qy1 = line_height - height - margin;
+
+ tx0 = 0;
+ ty0 = 0;
+ tx1 = (width + margin*2) / (GLfloat) width2;
+ ty1 = (height + margin*2) / (GLfloat) height2;
+
+ glBegin (GL_QUADS);
+ glTexCoord2f (tx0, ty0); glVertex3f (qx0, qy0, 0);
+ glTexCoord2f (tx1, ty0); glVertex3f (qx1, qy0, 0);
+ glTexCoord2f (tx1, ty1); glVertex3f (qx1, qy1, 0);
+ glTexCoord2f (tx0, ty1); glVertex3f (qx0, qy1, 0);
+ glEnd();
+
+ glPopMatrix();
+
+ /* Reset to the caller's texture environment.
+ */
+ glBindTexture (GL_TEXTURE_2D, old_texture);
+ glFrontFace (ofront);
+ if (!alpha_p) glDisable (GL_ALPHA_TEST);
+ if (!blend_p) glDisable (GL_BLEND);
+ glBlendFunc (GL_SRC_ALPHA, oblend);
+
+ glMatrixMode (GL_TEXTURE);
+ glMultMatrixf (omatrix);
+ glMatrixMode (GL_MODELVIEW);
+
+ check_gl_error ("texture font print");
+
+ /* Store this string into the cache, unless that's where it came from.
+ */
+ if (!cache->string)
+ {
+ cache->string = strdup (string);
+ cache->width = width;
+ cache->height = height;
+ cache->width2 = width2;
+ cache->height2 = height2;
+ }
+ }