xfont.c revision 4642e01f
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#define NEED_REPLIES
32#ifdef HAVE_DIX_CONFIG_H
33#include <dix-config.h>
34#endif
35
36#include "glxserver.h"
37#include "glxutil.h"
38#include "unpack.h"
39#include "g_disptab.h"
40#include "glapitable.h"
41#include "glapi.h"
42#include "glthread.h"
43#include "dispatch.h"
44#include "indirect_dispatch.h"
45#include <GL/gl.h>
46#include <pixmapstr.h>
47#include <windowstr.h>
48#include <dixfontstr.h>
49
50extern XID clientErrorValue;	/* imported kludge from dix layer */
51
52/*
53** Make a single GL bitmap from a single X glyph
54*/
55static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci)
56{
57    int i, j;
58    int widthPadded;	/* width of glyph in bytes, as padded by X */
59    int allocBytes;	/* bytes to allocate to store bitmap */
60    int w;		/* width of glyph in bits */
61    int h;		/* height of glyph */
62    register unsigned char *pglyph;
63    register unsigned char *p;
64    unsigned char *allocbuf;
65#define __GL_CHAR_BUF_SIZE 2048
66    unsigned char buf[__GL_CHAR_BUF_SIZE];
67
68    w = GLYPHWIDTHPIXELS(pci);
69    h = GLYPHHEIGHTPIXELS(pci);
70    widthPadded = GLYPHWIDTHBYTESPADDED(pci);
71
72    /*
73    ** Use the local buf if possible, otherwise malloc.
74    */
75    allocBytes = widthPadded * h;
76    if (allocBytes <= __GL_CHAR_BUF_SIZE) {
77	p = buf;
78	allocbuf = 0;
79    } else {
80	p = (unsigned char *) xalloc(allocBytes);
81	if (!p)
82	    return BadAlloc;
83	allocbuf = p;
84    }
85
86    /*
87    ** We have to reverse the picture, top to bottom
88    */
89
90    pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h-1)*widthPadded;
91    for (j=0; j < h; j++) {
92	for (i=0; i < widthPadded; i++) {
93	    p[i] = pglyph[i];
94	}
95	pglyph -= widthPadded;
96	p += widthPadded;
97    }
98    CALL_Bitmap( GET_DISPATCH(), (w, h, -pci->metrics.leftSideBearing,
99				  pci->metrics.descent,
100				  pci->metrics.characterWidth, 0,
101				  allocbuf ? allocbuf : buf) );
102
103    if (allocbuf) {
104	xfree(allocbuf);
105    }
106    return Success;
107#undef __GL_CHAR_BUF_SIZE
108}
109
110/*
111** Create a GL bitmap for each character in the X font.  The bitmap is stored
112** in a display list.
113*/
114
115static int
116MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base)
117{
118    unsigned long   i, nglyphs;
119    CARD8	    chs[2];		/* the font index we are going after */
120    CharInfoPtr	    pci;
121    int rv;				/* return value */
122    int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit;
123
124    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, FALSE) );
125    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst) );
126    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, 0) );
127    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
128    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
129    CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, GLYPHPADBYTES) );
130    for (i=0; i < count; i++) {
131	chs[0] = (first + i) >> 8;	/* high byte is first byte */
132	chs[1] = first + i;
133
134	(*pFont->get_glyphs)(pFont, 1, chs, (FontEncoding)encoding,
135		&nglyphs, &pci);
136
137	/*
138	** Define a display list containing just a glBitmap() call.
139	*/
140	CALL_NewList( GET_DISPATCH(), (list_base + i, GL_COMPILE) );
141	if (nglyphs ) {
142	    rv = __glXMakeBitmapFromGlyph(pFont, pci);
143	    if (rv) {
144		return rv;
145	    }
146	}
147	CALL_EndList( GET_DISPATCH(), () );
148    }
149    return Success;
150}
151
152/************************************************************************/
153
154int __glXDisp_UseXFont(__GLXclientState *cl, GLbyte *pc)
155{
156    ClientPtr client = cl->client;
157    xGLXUseXFontReq *req;
158    FontPtr pFont;
159    GC *pGC;
160    GLuint currentListIndex;
161    __GLXcontext *cx;
162    int error;
163
164    req = (xGLXUseXFontReq *) pc;
165    cx = __glXForceCurrent(cl, req->contextTag, &error);
166    if (!cx) {
167	return error;
168    }
169
170    CALL_GetIntegerv( GET_DISPATCH(), (GL_LIST_INDEX, (GLint*) &currentListIndex) );
171    if (currentListIndex != 0) {
172	/*
173	** A display list is currently being made.  It is an error
174	** to try to make a font during another lists construction.
175	*/
176	client->errorValue = cx->id;
177	return __glXError(GLXBadContextState);
178    }
179
180    /*
181    ** Font can actually be either the ID of a font or the ID of a GC
182    ** containing a font.
183    */
184    pFont = (FontPtr)LookupIDByType(req->font, RT_FONT);
185    if (!pFont) {
186        pGC = (GC *)LookupIDByType(req->font, RT_GC);
187        if (!pGC) {
188	    client->errorValue = req->font;
189            return BadFont;
190	}
191	pFont = pGC->font;
192    }
193
194    return MakeBitmapsFromFont(pFont, req->first, req->count,
195				    req->listBase);
196}
197