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
__glXMakeBitmapFromGlyph(FontPtr font,CharInfoPtr pci)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
MakeBitmapsFromFont(FontPtr pFont,int first,int count,int list_base)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
__glXDisp_UseXFont(__GLXclientState * cl,GLbyte * pc)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     req = (xGLXUseXFontReq *) pc;
156     cx = __glXForceCurrent(cl, req->contextTag, &error);
157     if (!cx) {
158         return error;
159     }
160 
161     glGetIntegerv(GL_LIST_INDEX, (GLint *) &currentListIndex);
162     if (currentListIndex != 0) {
163         /*
164          ** A display list is currently being made.  It is an error
165          ** to try to make a font during another lists construction.
166          */
167         client->errorValue = cx->id;
168         return __glXError(GLXBadContextState);
169     }
170 
171     /*
172      ** Font can actually be either the ID of a font or the ID of a GC
173      ** containing a font.
174      */
175 
176     error = dixLookupFontable(&pFont, req->font, client, DixReadAccess);
177     if (error != Success)
178         return error;
179 
180     return MakeBitmapsFromFont(pFont, req->first, req->count, req->listBase);
181 }
182