+
+ {
+ 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;
+ }
+ }