diff options
author | root <root@zombrain.(none)> | 2011-07-25 08:54:41 (GMT) |
---|---|---|
committer | root <root@zombrain.(none)> | 2011-07-25 08:54:41 (GMT) |
commit | ab4fcaad149d4bdccefa8f693c2a8e044b40dd4c (patch) | |
tree | c95c280caabc70e7aedbde723e38820047357be7 /glx/xfont.c |
initial state (xorg-server 1.10.2)
Diffstat (limited to 'glx/xfont.c')
-rw-r--r-- | glx/xfont.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/glx/xfont.c b/glx/xfont.c new file mode 100644 index 0000000..84a301f --- /dev/null +++ b/glx/xfont.c @@ -0,0 +1,186 @@ +/* + * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) + * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice including the dates of first publication and + * either this permission notice or a reference to + * http://oss.sgi.com/projects/FreeB/ + * shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the name of Silicon Graphics, Inc. + * shall not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization from + * Silicon Graphics, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "glxserver.h" +#include "glxutil.h" +#include "unpack.h" +#include "glapitable.h" +#include "glapi.h" +#include "glthread.h" +#include "dispatch.h" +#include "indirect_dispatch.h" +#include <GL/gl.h> +#include <pixmapstr.h> +#include <windowstr.h> +#include <dixfontstr.h> + +/* +** Make a single GL bitmap from a single X glyph +*/ +static int __glXMakeBitmapFromGlyph(FontPtr font, CharInfoPtr pci) +{ + int i, j; + int widthPadded; /* width of glyph in bytes, as padded by X */ + int allocBytes; /* bytes to allocate to store bitmap */ + int w; /* width of glyph in bits */ + int h; /* height of glyph */ + register unsigned char *pglyph; + register unsigned char *p; + unsigned char *allocbuf; +#define __GL_CHAR_BUF_SIZE 2048 + unsigned char buf[__GL_CHAR_BUF_SIZE]; + + w = GLYPHWIDTHPIXELS(pci); + h = GLYPHHEIGHTPIXELS(pci); + widthPadded = GLYPHWIDTHBYTESPADDED(pci); + + /* + ** Use the local buf if possible, otherwise malloc. + */ + allocBytes = widthPadded * h; + if (allocBytes <= __GL_CHAR_BUF_SIZE) { + p = buf; + allocbuf = 0; + } else { + p = (unsigned char *) malloc(allocBytes); + if (!p) + return BadAlloc; + allocbuf = p; + } + + /* + ** We have to reverse the picture, top to bottom + */ + + pglyph = FONTGLYPHBITS(FONTGLYPHS(font), pci) + (h-1)*widthPadded; + for (j=0; j < h; j++) { + for (i=0; i < widthPadded; i++) { + p[i] = pglyph[i]; + } + pglyph -= widthPadded; + p += widthPadded; + } + CALL_Bitmap( GET_DISPATCH(), (w, h, -pci->metrics.leftSideBearing, + pci->metrics.descent, + pci->metrics.characterWidth, 0, + allocbuf ? allocbuf : buf) ); + + free(allocbuf); + return Success; +#undef __GL_CHAR_BUF_SIZE +} + +/* +** Create a GL bitmap for each character in the X font. The bitmap is stored +** in a display list. +*/ + +static int +MakeBitmapsFromFont(FontPtr pFont, int first, int count, int list_base) +{ + unsigned long i, nglyphs; + CARD8 chs[2]; /* the font index we are going after */ + CharInfoPtr pci; + int rv; /* return value */ + int encoding = (FONTLASTROW(pFont) == 0) ? Linear16Bit : TwoD16Bit; + + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SWAP_BYTES, FALSE) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_LSB_FIRST, BITMAP_BIT_ORDER == LSBFirst) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, 0) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) ); + CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ALIGNMENT, GLYPHPADBYTES) ); + for (i=0; i < count; i++) { + chs[0] = (first + i) >> 8; /* high byte is first byte */ + chs[1] = first + i; + + (*pFont->get_glyphs)(pFont, 1, chs, (FontEncoding)encoding, + &nglyphs, &pci); + + /* + ** Define a display list containing just a glBitmap() call. + */ + CALL_NewList( GET_DISPATCH(), (list_base + i, GL_COMPILE) ); + if (nglyphs ) { + rv = __glXMakeBitmapFromGlyph(pFont, pci); + if (rv) { + return rv; + } + } + CALL_EndList( GET_DISPATCH(), () ); + } + return Success; +} + +/************************************************************************/ + +int __glXDisp_UseXFont(__GLXclientState *cl, GLbyte *pc) +{ + ClientPtr client = cl->client; + xGLXUseXFontReq *req; + FontPtr pFont; + GLuint currentListIndex; + __GLXcontext *cx; + int error; + + REQUEST_SIZE_MATCH(xGLXUseXFontReq); + + req = (xGLXUseXFontReq *) pc; + cx = __glXForceCurrent(cl, req->contextTag, &error); + if (!cx) { + return error; + } + + CALL_GetIntegerv( GET_DISPATCH(), (GL_LIST_INDEX, (GLint*) ¤tListIndex) ); + if (currentListIndex != 0) { + /* + ** A display list is currently being made. It is an error + ** to try to make a font during another lists construction. + */ + client->errorValue = cx->id; + return __glXError(GLXBadContextState); + } + + /* + ** Font can actually be either the ID of a font or the ID of a GC + ** containing a font. + */ + + error = dixLookupFontable(&pFont, req->font, client, DixReadAccess); + if (error != Success) + return error; + + return MakeBitmapsFromFont(pFont, req->first, req->count, + req->listBase); +} |