xfont.c revision 35c4bbdf
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*/ 47static 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 106static int 107MakeBitmapsFromFont(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 145int 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} 184