Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) | |
3 | * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. | |
4 | * | |
5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
6 | * copy of this software and associated documentation files (the "Software"), | |
7 | * to deal in the Software without restriction, including without limitation | |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
9 | * and/or sell copies of the Software, and to permit persons to whom the | |
10 | * Software is furnished to do so, subject to the following conditions: | |
11 | * | |
12 | * The above copyright notice including the dates of first publication and | |
13 | * either this permission notice or a reference to | |
14 | * http://oss.sgi.com/projects/FreeB/ | |
15 | * shall be included in all copies or substantial portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF | |
22 | * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
23 | * SOFTWARE. | |
24 | * | |
25 | * Except as contained in this notice, the name of Silicon Graphics, Inc. | |
26 | * shall not be used in advertising or otherwise to promote the sale, use or | |
27 | * other dealings in this Software without prior written authorization from | |
28 | * Silicon Graphics, Inc. | |
29 | */ | |
30 | ||
31 | #ifdef HAVE_DIX_CONFIG_H | |
32 | #include <dix-config.h> | |
33 | #endif | |
34 | ||
35 | #include "glxserver.h" | |
36 | #include "glxutil.h" | |
37 | #include "unpack.h" | |
38 | #include "indirect_dispatch.h" | |
39 | #include <GL/gl.h> | |
40 | #include <pixmapstr.h> | |
41 | #include <windowstr.h> | |
42 | #include <dixfontstr.h> | |
43 | ||
44 | /* | |
45 | ** Make a single GL bitmap from a single X glyph | |
46 | */ | |
47 | static int | |
48 | __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci) | |
49 | { | |
50 | int i, j; | |
51 | int widthPadded; /* width of glyph in bytes, as padded by X */ | |
52 | int allocBytes; /* bytes to allocate to store bitmap */ | |
53 | int w; /* width of glyph in bits */ | |
54 | int h; /* height of glyph */ | |
55 | register unsigned char *pglyph; | |
56 | register unsigned char *p; | |
57 | unsigned char *allocbuf; | |
58 | ||
59 | #define __GL_CHAR_BUF_SIZE 2048 | |
60 | unsigned char buf[__GL_CHAR_BUF_SIZE]; | |
61 | ||
62 | w = GLYPHWIDTHPIXELS(pci); | |
63 | h = GLYPHHEIGHTPIXELS(pci); | |
64 | widthPadded = GLYPHWIDTHBYTESPADDED(pci); | |
65 | ||
66 | /* | |
67 | ** Use the local buf if possible, otherwise malloc. | |
68 | */ | |
69 | allocBytes = widthPadded * h; | |
70 | if (allocBytes <= __GL_CHAR_BUF_SIZE) { | |
71 | p = buf; | |
72 | allocbuf = 0; | |
73 | } | |
74 | else { | |
75 | p = (unsigned char *) malloc(allocBytes); | |
76 | if (!p) | |
77 | return BadAlloc; | |
78 | allocbuf = p; | |
79 | } | |
80 | ||
81 | /* | |
82 | ** We have to reverse the picture, top to bottom | |
83 | */ | |
84 | ||
85 | pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h - 1) * widthPadded; | |
86 | for (j = 0; j < h; j++) { | |
87 | for (i = 0; i < widthPadded; i++) { | |
88 | p[i] = pglyph[i]; | |
89 | } | |
90 | pglyph -= widthPadded; | |
91 | p += widthPadded; | |
92 | } | |
93 | glBitmap(w, h, -pci->metrics.leftSideBearing, pci->metrics.descent, | |
94 | pci->metrics.characterWidth, 0, allocbuf ? allocbuf : buf); | |
95 | ||
96 | free(allocbuf); | |
97 | return Success; | |
98 | #undef __GL_CHAR_BUF_SIZE | |
99 | } | |
100 | ||
101 | /* | |
102 | ** Create a GL bitmap for each character in the X font. The bitmap is stored | |
103 | ** in a display list. | |
104 | */ | |
105 | ||
106 | static int | |
107 | MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base) | |
108 | { | |
109 | unsigned long i, nglyphs; | |
110 | CARD8 chs[2]; /* the font index we are going after */ | |
111 | CharInfoPtr pci; | |
112 | int rv; /* return value */ | |
113 | int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit; | |
114 | ||
115 | glPixelStorei(GL_UNPACK_SWAP_BYTES, FALSE); | |
116 | glPixelStorei(GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst); | |
117 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | |
118 | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); | |
119 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); | |
120 | glPixelStorei(GL_UNPACK_ALIGNMENT, GLYPHPADBYTES); | |
121 | for (i = 0; i < count; i++) { | |
122 | chs[0] = (first + i) >> 8; /* high byte is first byte */ | |
123 | chs[1] = first + i; | |
124 | ||
125 | (*pFont->get_glyphs) (pFont, 1, chs, (FontEncoding) encoding, | |
126 | &nglyphs, &pci); | |
127 | ||
128 | /* | |
129 | ** Define a display list containing just a glBitmap() call. | |
130 | */ | |
131 | glNewList(list_base + i, GL_COMPILE); | |
132 | if (nglyphs) { | |
133 | rv = __glXMakeBitmapFromGlyph(pFont, pci); | |
134 | if (rv) { | |
135 | return rv; | |
136 | } | |
137 | } | |
138 | glEndList(); | |
139 | } | |
140 | return Success; | |
141 | } | |
142 | ||
143 | /************************************************************************/ | |
144 | ||
145 | int | |
146 | __glXDisp_UseXFont(__GLXclientState * cl, GLbyte * pc) | |
147 | { | |
148 | ClientPtr client = cl->client; | |
149 | xGLXUseXFontReq *req; | |
150 | FontPtr pFont; | |
151 | GLuint currentListIndex; | |
152 | __GLXcontext *cx; | |
153 | int error; | |
154 | ||
155 | REQUEST_SIZE_MATCH(xGLXUseXFontReq); | |
156 | ||
157 | req = (xGLXUseXFontReq *) pc; | |
158 | cx = __glXForceCurrent(cl, req->contextTag, &error); | |
159 | if (!cx) { | |
160 | return error; | |
161 | } | |
162 | ||
163 | glGetIntegerv(GL_LIST_INDEX, (GLint *) ¤tListIndex); | |
164 | if (currentListIndex != 0) { | |
165 | /* | |
166 | ** A display list is currently being made. It is an error | |
167 | ** to try to make a font during another lists construction. | |
168 | */ | |
169 | client->errorValue = cx->id; | |
170 | return __glXError(GLXBadContextState); | |
171 | } | |
172 | ||
173 | /* | |
174 | ** Font can actually be either the ID of a font or the ID of a GC | |
175 | ** containing a font. | |
176 | */ | |
177 | ||
178 | error = dixLookupFontable(&pFont, req->font, client, DixReadAccess); | |
179 | if (error != Success) | |
180 | return error; | |
181 | ||
182 | return MakeBitmapsFromFont(pFont, req->first, req->count, req->listBase); | |
183 | } |