Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 1999  Brian Paul   All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * OTHER DEALINGS IN THE SOFTWARE.
23
 */
24
 
25
 
26
/* xfonts.c -- glXUseXFont() for Mesa written by
27
 * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
28
 */
29
 
30
/*
31
  This was take from Mesa and modified to work in the real GLX structure.
32
  It provides a fully client side implementation of glXUseXFont and is
33
  called by that routine when direct rendering is enabled.
34
*/
35
 
36
#ifdef GLX_DIRECT_RENDERING
37
 
38
#include "glxclient.h"
39
 
40
/* Some debugging info.  */
41
 
42
#ifdef DEBUG
43
#undef _R
44
#undef _G
45
#undef _B
46
#include 
47
 
48
int debug_xfonts = 0;
49
 
50
static void
51
dump_char_struct(XCharStruct * ch, char *prefix)
52
{
53
   printf("%slbearing = %d, rbearing = %d, width = %d\n",
54
          prefix, ch->lbearing, ch->rbearing, ch->width);
55
   printf("%sascent = %d, descent = %d, attributes = %u\n",
56
          prefix, ch->ascent, ch->descent, (unsigned int) ch->attributes);
57
}
58
 
59
static void
60
dump_font_struct(XFontStruct * font)
61
{
62
   printf("ascent = %d, descent = %d\n", font->ascent, font->descent);
63
   printf("char_or_byte2 = (%u,%u)\n",
64
          font->min_char_or_byte2, font->max_char_or_byte2);
65
   printf("byte1 = (%u,%u)\n", font->min_byte1, font->max_byte1);
66
   printf("all_chars_exist = %s\n", font->all_chars_exist ? "True" : "False");
67
   printf("default_char = %c (\\%03o)\n",
68
          (char) (isprint(font->default_char) ? font->default_char : ' '),
69
          font->default_char);
70
   dump_char_struct(&font->min_bounds, "min> ");
71
   dump_char_struct(&font->max_bounds, "max> ");
72
#if 0
73
   for (c = font->min_char_or_byte2; c <= font->max_char_or_byte2; c++) {
74
      char prefix[8];
75
      sprintf(prefix, "%d> ", c);
76
      dump_char_struct(&font->per_char[c], prefix);
77
   }
78
#endif
79
}
80
 
81
static void
82
dump_bitmap(unsigned int width, unsigned int height, GLubyte * bitmap)
83
{
84
   unsigned int x, y;
85
 
86
   printf("    ");
87
   for (x = 0; x < 8 * width; x++)
88
      printf("%o", 7 - (x % 8));
89
   putchar('\n');
90
   for (y = 0; y < height; y++) {
91
      printf("%3o:", y);
92
      for (x = 0; x < 8 * width; x++)
93
         putchar((bitmap[width * (height - y - 1) + x / 8] & (1 << (7 - (x %
94
                                                                         8))))
95
                 ? '*' : '.');
96
      printf("   ");
97
      for (x = 0; x < width; x++)
98
         printf("0x%02x, ", bitmap[width * (height - y - 1) + x]);
99
      putchar('\n');
100
   }
101
}
102
#endif /* DEBUG */
103
 
104
 
105
/* Implementation.  */
106
 
107
/* Fill a BITMAP with a character C from thew current font
108
   in the graphics context GC.  WIDTH is the width in bytes
109
   and HEIGHT is the height in bits.
110
 
111
   Note that the generated bitmaps must be used with
112
 
113
        glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
114
        glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
115
        glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
116
        glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
117
        glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
118
        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
119
 
120
   Possible optimizations:
121
 
122
     * use only one reusable pixmap with the maximum dimensions.
123
     * draw the entire font into a single pixmap (careful with
124
       proportional fonts!).
125
*/
126
 
127
 
128
/*
129
 * Generate OpenGL-compatible bitmap.
130
 */
131
static void
132
fill_bitmap(Display * dpy, Window win, GC gc,
133
            unsigned int width, unsigned int height,
134
            int x0, int y0, unsigned int c, GLubyte * bitmap)
135
{
136
   XImage *image;
137
   unsigned int x, y;
138
   Pixmap pixmap;
139
   XChar2b char2b;
140
 
141
   pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
142
   XSetForeground(dpy, gc, 0);
143
   XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
144
   XSetForeground(dpy, gc, 1);
145
 
146
   char2b.byte1 = (c >> 8) & 0xff;
147
   char2b.byte2 = (c & 0xff);
148
 
149
   XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
150
 
151
   image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
152
   if (image) {
153
      /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
154
      for (y = 0; y < height; y++)
155
         for (x = 0; x < 8 * width; x++)
156
            if (XGetPixel(image, x, y))
157
               bitmap[width * (height - y - 1) + x / 8] |=
158
                  (1 << (7 - (x % 8)));
159
      XDestroyImage(image);
160
   }
161
 
162
   XFreePixmap(dpy, pixmap);
163
}
164
 
165
/*
166
 * determine if a given glyph is valid and return the
167
 * corresponding XCharStruct.
168
 */
169
static XCharStruct *
170
isvalid(XFontStruct * fs, int which)
171
{
172
   unsigned int rows, pages;
173
   int byte1 = 0, byte2 = 0;
174
   int i, valid = 1;
175
 
176
   rows = fs->max_byte1 - fs->min_byte1 + 1;
177
   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
178
 
179
   if (rows == 1) {
180
      /* "linear" fonts */
181
      if ((fs->min_char_or_byte2 > which) || (fs->max_char_or_byte2 < which))
182
         valid = 0;
183
   }
184
   else {
185
      /* "matrix" fonts */
186
      byte2 = which & 0xff;
187
      byte1 = which >> 8;
188
      if ((fs->min_char_or_byte2 > byte2) ||
189
          (fs->max_char_or_byte2 < byte2) ||
190
          (fs->min_byte1 > byte1) || (fs->max_byte1 < byte1))
191
         valid = 0;
192
   }
193
 
194
   if (valid) {
195
      if (fs->per_char) {
196
         if (rows == 1) {
197
            /* "linear" fonts */
198
            return (fs->per_char + (which - fs->min_char_or_byte2));
199
         }
200
         else {
201
            /* "matrix" fonts */
202
            i = ((byte1 - fs->min_byte1) * pages) +
203
               (byte2 - fs->min_char_or_byte2);
204
            return (fs->per_char + i);
205
         }
206
      }
207
      else {
208
         return (&fs->min_bounds);
209
      }
210
   }
211
   return (NULL);
212
}
213
 
214
_X_HIDDEN void
215
DRI_glXUseXFont(struct glx_context *CC, Font font, int first, int count, int listbase)
216
{
217
   Display *dpy;
218
   Window win;
219
   Pixmap pixmap;
220
   GC gc;
221
   XGCValues values;
222
   unsigned long valuemask;
223
   XFontStruct *fs;
224
 
225
   GLint swapbytes, lsbfirst, rowlength;
226
   GLint skiprows, skippixels, alignment;
227
 
228
   unsigned int max_width, max_height, max_bm_width, max_bm_height;
229
   GLubyte *bm;
230
 
231
   int i;
232
 
233
   dpy = CC->currentDpy;
234
   win = CC->currentDrawable;
235
 
236
   fs = XQueryFont(dpy, font);
237
   if (!fs) {
238
      __glXSetError(CC, GL_INVALID_VALUE);
239
      return;
240
   }
241
 
242
   /* Allocate a bitmap that can fit all characters.  */
243
   max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
244
   max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
245
   max_bm_width = (max_width + 7) / 8;
246
   max_bm_height = max_height;
247
 
248
   bm = malloc((max_bm_width * max_bm_height) * sizeof(GLubyte));
249
   if (!bm) {
250
      XFreeFontInfo(NULL, fs, 1);
251
      __glXSetError(CC, GL_OUT_OF_MEMORY);
252
      return;
253
   }
254
 
255
#if 0
256
   /* get the page info */
257
   pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
258
   firstchar = (fs->min_byte1 << 8) + fs->min_char_or_byte2;
259
   lastchar = (fs->max_byte1 << 8) + fs->max_char_or_byte2;
260
   rows = fs->max_byte1 - fs->min_byte1 + 1;
261
   unsigned int first_char, last_char, pages, rows;
262
#endif
263
 
264
   /* Save the current packing mode for bitmaps.  */
265
   glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
266
   glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
267
   glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
268
   glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
269
   glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
270
   glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
271
 
272
   /* Enforce a standard packing mode which is compatible with
273
      fill_bitmap() from above.  This is actually the default mode,
274
      except for the (non)alignment.  */
275
   glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
276
   glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
277
   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
278
   glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
279
   glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
280
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
281
 
282
   pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
283
   values.foreground = BlackPixel(dpy, DefaultScreen(dpy));
284
   values.background = WhitePixel(dpy, DefaultScreen(dpy));
285
   values.font = fs->fid;
286
   valuemask = GCForeground | GCBackground | GCFont;
287
   gc = XCreateGC(dpy, pixmap, valuemask, &values);
288
   XFreePixmap(dpy, pixmap);
289
 
290
#ifdef DEBUG
291
   if (debug_xfonts)
292
      dump_font_struct(fs);
293
#endif
294
 
295
   for (i = 0; i < count; i++) {
296
      unsigned int width, height, bm_width, bm_height;
297
      GLfloat x0, y0, dx, dy;
298
      XCharStruct *ch;
299
      int x, y;
300
      unsigned int c = first + i;
301
      int list = listbase + i;
302
      int valid;
303
 
304
      /* check on index validity and get the bounds */
305
      ch = isvalid(fs, c);
306
      if (!ch) {
307
         ch = &fs->max_bounds;
308
         valid = 0;
309
      }
310
      else {
311
         valid = 1;
312
      }
313
 
314
#ifdef DEBUG
315
      if (debug_xfonts) {
316
         char s[7];
317
         sprintf(s, isprint(c) ? "%c> " : "\\%03o> ", c);
318
         dump_char_struct(ch, s);
319
      }
320
#endif
321
 
322
      /* glBitmap()' parameters:
323
         straight from the glXUseXFont(3) manpage.  */
324
      width = ch->rbearing - ch->lbearing;
325
      height = ch->ascent + ch->descent;
326
      x0 = -ch->lbearing;
327
      y0 = ch->descent - 1;
328
      dx = ch->width;
329
      dy = 0;
330
 
331
      /* X11's starting point.  */
332
      x = -ch->lbearing;
333
      y = ch->ascent;
334
 
335
      /* Round the width to a multiple of eight.  We will use this also
336
         for the pixmap for capturing the X11 font.  This is slightly
337
         inefficient, but it makes the OpenGL part real easy.  */
338
      bm_width = (width + 7) / 8;
339
      bm_height = height;
340
 
341
      glNewList(list, GL_COMPILE);
342
      if (valid && (bm_width > 0) && (bm_height > 0)) {
343
 
344
         memset(bm, '\0', bm_width * bm_height);
345
         fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
346
 
347
         glBitmap(width, height, x0, y0, dx, dy, bm);
348
#ifdef DEBUG
349
         if (debug_xfonts) {
350
            printf("width/height = %u/%u\n", width, height);
351
            printf("bm_width/bm_height = %u/%u\n", bm_width, bm_height);
352
            dump_bitmap(bm_width, bm_height, bm);
353
         }
354
#endif
355
      }
356
      else {
357
         glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
358
      }
359
      glEndList();
360
   }
361
 
362
   free(bm);
363
   XFreeFontInfo(NULL, fs, 1);
364
   XFreeGC(dpy, gc);
365
 
366
   /* Restore saved packing modes.  */
367
   glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
368
   glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
369
   glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
370
   glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
371
   glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
372
   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
373
}
374
 
375
#endif