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*) ¤tListIndex) ); 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