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