VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/xfont.c@ 28516

Last change on this file since 28516 was 18882, checked in by vboxsync, 16 years ago

crOpenGL: exported the remaining Additions bits to OSE

  • Property svn:eol-style set to native
File size: 6.6 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "chromium.h"
8#include "cr_error.h"
9#include "cr_mem.h"
10#include "stub.h"
11
12/** code borrowed from Mesa */
13
14
15/** Fill a BITMAP with a character C from thew current font
16 in the graphics context GC. WIDTH is the width in bytes
17 and HEIGHT is the height in bits.
18
19 Note that the generated bitmaps must be used with
20
21 glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
22 glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
23 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
24 glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
25 glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
26 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
27
28 Possible optimizations:
29
30 * use only one reusable pixmap with the maximum dimensions.
31 * draw the entire font into a single pixmap (careful with
32 proportional fonts!).
33*/
34
35
36/**
37 * Generate OpenGL-compatible bitmap.
38 */
39static void
40fill_bitmap(Display *dpy, Window win, GC gc,
41 unsigned int width, unsigned int height,
42 int x0, int y0, unsigned int c, GLubyte *bitmap)
43{
44 XImage *image;
45 unsigned int x, y;
46 Pixmap pixmap;
47 XChar2b char2b;
48
49 pixmap = XCreatePixmap(dpy, win, 8*width, height, 1);
50 XSetForeground(dpy, gc, 0);
51 XFillRectangle(dpy, pixmap, gc, 0, 0, 8*width, height);
52 XSetForeground(dpy, gc, 1);
53
54 char2b.byte1 = (c >> 8) & 0xff;
55 char2b.byte2 = (c & 0xff);
56
57 XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
58
59 image = XGetImage(dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
60 if (image) {
61 /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */
62 for (y = 0; y < height; y++)
63 for (x = 0; x < 8*width; x++)
64 if (XGetPixel(image, x, y))
65 bitmap[width*(height - y - 1) + x/8] |= (1 << (7 - (x % 8)));
66 XDestroyImage(image);
67 }
68
69 XFreePixmap(dpy, pixmap);
70}
71
72/*
73 * determine if a given glyph is valid and return the
74 * corresponding XCharStruct.
75 */
76static XCharStruct *isvalid(XFontStruct *fs, unsigned int which)
77{
78 unsigned int rows, pages;
79 unsigned int byte1 = 0, byte2 = 0;
80 int i, valid = 1;
81
82 rows = fs->max_byte1 - fs->min_byte1 + 1;
83 pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
84
85 if (rows == 1) {
86 /* "linear" fonts */
87 if ((fs->min_char_or_byte2 > which) ||
88 (fs->max_char_or_byte2 < which)) valid = 0;
89 }
90 else {
91 /* "matrix" fonts */
92 byte2 = which & 0xff;
93 byte1 = which >> 8;
94 if ((fs->min_char_or_byte2 > byte2) ||
95 (fs->max_char_or_byte2 < byte2) ||
96 (fs->min_byte1 > byte1) ||
97 (fs->max_byte1 < byte1)) valid = 0;
98 }
99
100 if (valid) {
101 if (fs->per_char) {
102 if (rows == 1) {
103 /* "linear" fonts */
104 return fs->per_char + (which-fs->min_char_or_byte2);
105 }
106 else {
107 /* "matrix" fonts */
108 i = ((byte1 - fs->min_byte1) * pages) +
109 (byte2 - fs->min_char_or_byte2);
110 return fs->per_char + i;
111 }
112 }
113 else {
114 return &fs->min_bounds;
115 }
116 }
117 return NULL;
118}
119
120
121void stubUseXFont( Display *dpy, Font font, int first, int count, int listbase )
122{
123 Window win;
124 Pixmap pixmap;
125 GC gc;
126 XGCValues values;
127 unsigned long valuemask;
128 XFontStruct *fs;
129 GLint swapbytes, lsbfirst, rowlength;
130 GLint skiprows, skippixels, alignment;
131 unsigned int max_width, max_height, max_bm_width, max_bm_height;
132 GLubyte *bm;
133 int i;
134
135 win = RootWindow(dpy, DefaultScreen(dpy));
136
137 fs = XQueryFont(dpy, font);
138 if (!fs) {
139 crWarning("Couldn't get font structure information");
140 return;
141 }
142
143 /* Allocate a bitmap that can fit all characters. */
144 max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
145 max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
146 max_bm_width = (max_width + 7) / 8;
147 max_bm_height = max_height;
148
149 bm = (GLubyte *) crAlloc((max_bm_width * max_bm_height) * sizeof(GLubyte));
150 if (!bm) {
151 XFreeFontInfo( NULL, fs, 1 );
152 crWarning("Couldn't allocate bitmap in glXUseXFont()");
153 return;
154 }
155
156 /* Save the current packing mode for bitmaps. */
157 glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
158 glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
159 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
160 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
161 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
162 glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
163
164 /* Enforce a standard packing mode which is compatible with
165 fill_bitmap() from above. This is actually the default mode,
166 except for the (non)alignment. */
167 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
168 glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
169 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
170 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
171 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
172 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
173
174 pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
175 values.foreground = BlackPixel(dpy, DefaultScreen (dpy));
176 values.background = WhitePixel(dpy, DefaultScreen (dpy));
177 values.font = fs->fid;
178 valuemask = GCForeground | GCBackground | GCFont;
179 gc = XCreateGC(dpy, pixmap, valuemask, &values);
180 XFreePixmap(dpy, pixmap);
181
182 for (i = 0; i < count; i++) {
183 unsigned int width, height, bm_width, bm_height;
184 GLfloat x0, y0, dx, dy;
185 XCharStruct *ch;
186 int x, y;
187 unsigned int c = first + i;
188 int list = listbase + i;
189 int valid;
190
191 /* check on index validity and get the bounds */
192 ch = isvalid(fs, c);
193 if (!ch) {
194 ch = &fs->max_bounds;
195 valid = 0;
196 }
197 else {
198 valid = 1;
199 }
200
201 /* glBitmap()' parameters:
202 straight from the glXUseXFont(3) manpage. */
203 width = ch->rbearing - ch->lbearing;
204 height = ch->ascent + ch->descent;
205 x0 = -ch->lbearing;
206 y0 = ch->descent - 0; /* XXX used to subtract 1 here */
207 /* but that caused a conformace failure */
208 dx = ch->width;
209 dy = 0;
210
211 /* X11's starting point. */
212 x = -ch->lbearing;
213 y = ch->ascent;
214
215 /* Round the width to a multiple of eight. We will use this also
216 for the pixmap for capturing the X11 font. This is slightly
217 inefficient, but it makes the OpenGL part real easy. */
218 bm_width = (width + 7) / 8;
219 bm_height = height;
220
221 glNewList(list, GL_COMPILE);
222 if (valid && (bm_width > 0) && (bm_height > 0)) {
223 crMemset(bm, '\0', bm_width * bm_height);
224 fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
225 glBitmap(width, height, x0, y0, dx, dy, bm);
226 }
227 else {
228 glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
229 }
230 glEndList();
231 }
232
233 crFree(bm);
234 XFreeFontInfo(NULL, fs, 1);
235 XFreeGC(dpy, gc);
236
237 /* Restore saved packing modes. */
238 glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
239 glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
240 glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
241 glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
242 glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
243 glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
244}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette