+ overall = data->cache->extents;
+ tex_width = data->cache->tex_width;
+ tex_height = data->cache->tex_height;
+ }
+ else
+ string_to_texture (data, string, &overall, &tex_width, &tex_height);
+
+ {
+ int ofront, oblend;
+ Bool alpha_p, blend_p, light_p, gen_s_p, gen_t_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_FRONT_FACE, &ofront);
+ glGetIntegerv (GL_BLEND_DST, &oblend);
+ glGetFloatv (GL_TEXTURE_MATRIX, omatrix);
+ blend_p = glIsEnabled (GL_BLEND);
+ alpha_p = glIsEnabled (GL_ALPHA_TEST);
+ light_p = glIsEnabled (GL_LIGHTING);
+ gen_s_p = glIsEnabled (GL_TEXTURE_GEN_S);
+ gen_t_p = glIsEnabled (GL_TEXTURE_GEN_T);
+
+ glPushMatrix();
+
+ glNormal3f (0, 0, 1);
+ glFrontFace (GL_CW);
+
+ glMatrixMode (GL_TEXTURE);
+ glLoadIdentity ();
+ glMatrixMode (GL_MODELVIEW);
+
+ enable_texture_string_parameters();
+
+ /* Draw a quad with that texture on it, possibly using a cached texture.
+ Position the XCharStruct origin at 0,0 in the scene.
+ */
+ qx0 = overall.lbearing;
+ qy0 = -overall.descent;
+ qx1 = overall.rbearing;
+ qy1 = overall.ascent;
+
+ tx0 = 0;
+ ty1 = 0;
+ tx1 = (overall.rbearing - overall.lbearing) / (GLfloat) tex_width;
+ ty0 = (overall.ascent + overall.descent) / (GLfloat) tex_height;
+
+ glFrontFace (GL_CCW);
+ 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);
+ if (light_p) glEnable (GL_LIGHTING);
+ if (gen_s_p) glEnable (GL_TEXTURE_GEN_S);
+ if (gen_t_p) glEnable (GL_TEXTURE_GEN_T);
+
+ 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->extents = overall;
+ cache->tex_width = tex_width;
+ cache->tex_height = tex_height;
+ }
+ }
+}
+
+
+/* Draws the string on the window at the given pixel position.
+ Newlines and tab stops are honored.
+ Any numbers inside [] will be rendered as a subscript.
+ Assumes the font has been loaded as with load_texture_font().
+
+ Position is 0 for center, 1 for top left, 2 for bottom left.
+ */
+void
+print_texture_label (Display *dpy,
+ texture_font_data *data,
+ int window_width, int window_height,
+ int position,
+ const char *string)
+{
+ GLfloat color[4];
+
+ Bool tex_p = glIsEnabled (GL_TEXTURE_2D);
+ Bool texs_p = glIsEnabled (GL_TEXTURE_GEN_S);
+ Bool text_p = glIsEnabled (GL_TEXTURE_GEN_T);
+ Bool depth_p = glIsEnabled (GL_DEPTH_TEST);
+ Bool cull_p = glIsEnabled (GL_CULL_FACE);
+ Bool fog_p = glIsEnabled (GL_FOG);
+ GLint ovp[4];
+
+# ifndef HAVE_JWZGLES
+ GLint opoly[2];
+ glGetIntegerv (GL_POLYGON_MODE, opoly);
+# endif
+
+ glGetIntegerv (GL_VIEWPORT, ovp);
+
+ glGetFloatv (GL_CURRENT_COLOR, color);
+
+ glEnable (GL_TEXTURE_2D);
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glPolygonMode (GL_FRONT, GL_FILL);
+
+ glDisable (GL_TEXTURE_GEN_S);
+ glDisable (GL_TEXTURE_GEN_T);
+ glDisable (GL_CULL_FACE);
+ glDisable (GL_FOG);
+
+ glDisable (GL_DEPTH_TEST);
+
+ /* Each matrix mode has its own stack, so we need to push/pop
+ them separately.
+ */
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ {
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ {
+ XCharStruct cs;
+ int ascent, descent;
+ int x, y, w, h, swap;
+ int rot = (int) current_device_rotation();
+
+ glLoadIdentity();
+ glViewport (0, 0, window_width, window_height);
+ glOrtho (0, window_width, 0, window_height, -1, 1);
+
+ while (rot <= -180) rot += 360;
+ while (rot > 180) rot -= 360;
+
+ texture_string_metrics (data, string, &cs, &ascent, &descent);
+ h = cs.ascent + cs.descent;
+ w = cs.width;
+
+# ifdef USE_IPHONE
+ {
+ /* Size of the font is in points, so scale iOS pixels to points. */
+ GLfloat scale = window_width / 768.0;
+ if (scale < 1) scale = 1;
+
+ /* jwxyz-XLoadFont has already doubled the font size, to compensate
+ for physically smaller screens. Undo that, since OpenGL hacks
+ use full-resolution framebuffers, unlike X11 hacks. */
+ scale /= 2;
+
+ window_width /= scale;
+ window_height /= scale;
+ glScalef (scale, scale, scale);
+ }
+# endif /* USE_IPHONE */
+
+ if (rot > 135 || rot < -135) /* 180 */