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