00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifdef __VMS
00032 #include <GL/vms_x_fix.h>
00033 #endif
00034
00035 #include "glxheader.h"
00036 #include "context.h"
00037 #include "imports.h"
00038 #include "xfonts.h"
00039
00040
00041
00042
00043 #ifdef DEBUG
00044 #undef _R
00045 #undef _G
00046 #undef _B
00047 #include <ctype.h>
00048
00049 int debug_xfonts = 0;
00050
00051 static void
00052 dump_char_struct(XCharStruct * ch, char *prefix)
00053 {
00054 printf("%slbearing = %d, rbearing = %d, width = %d\n",
00055 prefix, ch->lbearing, ch->rbearing, ch->width);
00056 printf("%sascent = %d, descent = %d, attributes = %u\n",
00057 prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
00058 }
00059
00060 static void
00061 dump_font_struct(XFontStruct * font)
00062 {
00063 printf("ascent = %d, descent = %d\n", font->ascent, font->descent);
00064 printf("char_or_byte2 = (%u,%u)\n",
00065 font->min_char_or_byte2, font->max_char_or_byte2);
00066 printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
00067 printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False");
00068 printf("default_char = %c (\\%03o)\n",
00069 (char) (isprint(font->default_char) ? font->default_char : ' '),
00070 font->default_char);
00071 dump_char_struct(&font->min_bounds, "min> ");
00072 dump_char_struct(&font->max_bounds, "max> ");
00073 #if 0
00074 for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) {
00075 char prefix[8];
00076 sprintf(prefix, "%d> ", c);
00077 dump_char_struct(&font->per_char[c], prefix);
00078 }
00079 #endif
00080 }
00081
00082 static void
00083 dump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap)
00084 {
00085 unsigned int x, y;
00086
00087 printf(" ");
00088 for (x = 0; x < 8 * width; x++)
00089 printf("%o", 7 - (x % 8));
00090 putchar('\n');
00091 for (y = 0; y < height; y++) {
00092 printf("%3o:", y);
00093 for (x = 0; x < 8 * width; x++)
00094 putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x %
00095 8))))
00096 ? '*' : '.');
00097 printf(" ");
00098 for (x = 0; x < width; x++)
00099 printf("0x%02x, ", bitmap[width * (height - y - 1) + x]);
00100 putchar('\n');
00101 }
00102 }
00103 #endif
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 static void
00133 fill_bitmap(Display * dpy, Window win, GC gc,
00134 unsigned int width, unsigned int height,
00135 int x0, int y0, unsigned int c, GLubyte * bitmap)
00136 {
00137 XImage *image;
00138 unsigned int x, y;
00139 Pixmap pixmap;
00140 XChar2b char2b;
00141
00142 pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
00143 XSetForeground(dpy, gc, 0);
00144 XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
00145 XSetForeground(dpy, gc, 1);
00146
00147 char2b.byte1 = (c >> 8) & 0xff;
00148 char2b.byte2 = (c & 0xff);
00149
00150 XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
00151
00152 image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
00153 if (image) {
00154
00155 for (y = 0; y < height; y++)
00156 for (x = 0; x < 8 * width; x++)
00157 if (XGetPixel(image, x, y))
00158 bitmap[width * (height - y - 1) + x / 8] |=
00159 (1 << (7 - (x % 8)));
00160 XDestroyImage(image);
00161 }
00162
00163 XFreePixmap(dpy, pixmap);
00164 }
00165
00166
00167
00168
00169
00170 static XCharStruct *
00171 isvalid(XFontStruct * fs, unsigned int which)
00172 {
00173 unsigned int rows, pages;
00174 unsigned int byte1 = 0, byte2 = 0;
00175 int i, valid = 1;
00176
00177 rows = fs->max_byte1 - fs->min_byte1 + 1;
00178 pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
00179
00180 if (rows == 1) {
00181
00182 if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
00183 valid = 0;
00184 }
00185 else {
00186
00187 byte2 = which & 0xff;
00188 byte1 = which >> 8;
00189 if ((fs->min_char_or_byte2 > byte2) ||
00190 (fs->max_char_or_byte2 < byte2) ||
00191 (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
00192 valid = 0;
00193 }
00194
00195 if (valid) {
00196 if (fs->per_char) {
00197 if (rows == 1) {
00198
00199 return (fs->per_char + (which - fs->min_char_or_byte2));
00200 }
00201 else {
00202
00203 i = ((byte1 - fs->min_byte1) * pages) +
00204 (byte2 - fs->min_char_or_byte2);
00205 return (fs->per_char + i);
00206 }
00207 }
00208 else {
00209 return (&fs->min_bounds);
00210 }
00211 }
00212 return (NULL);
00213 }
00214
00215
00216 void
00217 Fake_glXUseXFont(Font font, int first, int count, int listbase)
00218 {
00219 Display *dpy;
00220 Window win;
00221 Pixmap pixmap;
00222 GC gc;
00223 XGCValues values;
00224 unsigned long valuemask;
00225 XFontStruct *fs;
00226 GLint swapbytes, lsbfirst, rowlength;
00227 GLint skiprows, skippixels, alignment;
00228 unsigned int max_width, max_height, max_bm_width, max_bm_height;
00229 GLubyte *bm;
00230 int i;
00231
00232 dpy = glXGetCurrentDisplay();
00233 if (!dpy)
00234 return;
00235 win = RootWindow(dpy, DefaultScreen(dpy));
00236
00237 fs = XQueryFont(dpy, font);
00238 if (!fs) {
00239 _mesa_error(NULL, GL_INVALID_VALUE,
00240 "Couldn't get font structure information");
00241 return;
00242 }
00243
00244
00245 max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
00246 max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
00247 max_bm_width = (max_width + 7) / 8;
00248 max_bm_height = max_height;
00249
00250 bm = (GLubyte *) MALLOC((max_bm_width * max_bm_height) * sizeof(GLubyte));
00251 if (!bm) {
00252 XFreeFontInfo(NULL, fs, 1);
00253 _mesa_error(NULL, GL_OUT_OF_MEMORY,
00254 "Couldn't allocate bitmap in glXUseXFont()");
00255 return;
00256 }
00257
00258 #if 0
00259
00260 pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
00261 firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
00262 lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
00263 rows = fs->max_byte1 - fs->min_byte1 + 1;
00264 unsigned int first_char, last_char, pages, rows;
00265 #endif
00266
00267
00268 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
00269 glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
00270 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
00271 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
00272 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
00273 glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
00274
00275
00276
00277
00278 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
00279 glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
00280 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00281 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
00282 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
00283 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00284
00285 pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
00286 values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
00287 values.background = WhitePixel(dpy, DefaultScreen(dpy));
00288 values.font = fs->fid;
00289 valuemask = GCForeground | GCBackground | GCFont;
00290 gc = XCreateGC(dpy, pixmap, valuemask, &values);
00291 XFreePixmap(dpy, pixmap);
00292
00293 #ifdef DEBUG
00294 if (debug_xfonts)
00295 dump_font_struct(fs);
00296 #endif
00297
00298 for (i = 0; i < count; i++) {
00299 unsigned int width, height, bm_width, bm_height;
00300 GLfloat x0, y0, dx, dy;
00301 XCharStruct *ch;
00302 int x, y;
00303 unsigned int c = first + i;
00304 int list = listbase + i;
00305 int valid;
00306
00307
00308 ch = isvalid(fs, c);
00309 if (!ch) {
00310 ch = &fs->max_bounds;
00311 valid = 0;
00312 }
00313 else {
00314 valid = 1;
00315 }
00316
00317 #ifdef DEBUG
00318 if (debug_xfonts) {
00319 char s[7];
00320 sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
00321 dump_char_struct(ch, s);
00322 }
00323 #endif
00324
00325
00326
00327 width = ch->rbearing - ch->lbearing;
00328 height = ch->ascent + ch->descent;
00329 x0 = -ch->lbearing;
00330 y0 = ch->descent - 0;
00331
00332 dx = ch->width;
00333 dy = 0;
00334
00335
00336 x = -ch->lbearing;
00337 y = ch->ascent;
00338
00339
00340
00341
00342 bm_width = (width + 7) / 8;
00343 bm_height = height;
00344
00345 glNewList(list, GL_COMPILE);
00346 if (valid && (bm_width > 0) && (bm_height > 0)) {
00347
00348 MEMSET(bm, '\0', bm_width * bm_height);
00349 fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
00350
00351 glBitmap(width, height, x0, y0, dx, dy, bm);
00352 #ifdef DEBUG
00353 if (debug_xfonts) {
00354 printf("width/height = %u/%u\n", width, height);
00355 printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height);
00356 dump_bitmap(bm_width, bm_height, bm);
00357 }
00358 #endif
00359 }
00360 else {
00361 glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
00362 }
00363 glEndList();
00364 }
00365
00366 FREE(bm);
00367 XFreeFontInfo(NULL, fs, 1);
00368 XFreeGC(dpy, gc);
00369
00370
00371 glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
00372 glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
00373 glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
00374 glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
00375 glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
00376 glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
00377 }