9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync/* Copyright (c) 2001, Stanford University
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync * All rights reserved
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync *
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync * See the file LICENSE.txt for information on redistributing this software.
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync#include "chromium.h"
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync#include "cr_error.h"
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync#include "cr_mem.h"
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync#include "stub.h"
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync/** code borrowed from Mesa */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync/** Fill a BITMAP with a character C from thew current font
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync in the graphics context GC. WIDTH is the width in bytes
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync and HEIGHT is the height in bits.
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync Note that the generated bitmaps must be used with
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync Possible optimizations:
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync * use only one reusable pixmap with the maximum dimensions.
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync * draw the entire font into a single pixmap (careful with
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync proportional fonts!).
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync*/
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync/**
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync * Generate OpenGL-compatible bitmap.
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsyncstatic void
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsyncfill_bitmap(Display *dpy, Window win, GC gc,
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned int width, unsigned int height,
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync int x0, int y0, unsigned int c, GLubyte *bitmap)
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync{
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XImage *image;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned int x, y;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync Pixmap pixmap;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XChar2b char2b;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync pixmap = XCreatePixmap(dpy, win, 8*width, height, 1);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XSetForeground(dpy, gc, 0);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XFillRectangle(dpy, pixmap, gc, 0, 0, 8*width, height);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XSetForeground(dpy, gc, 1);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync char2b.byte1 = (c >> 8) & 0xff;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync char2b.byte2 = (c & 0xff);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync image = XGetImage(dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (image) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync for (y = 0; y < height; y++)
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync for (x = 0; x < 8*width; x++)
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (XGetPixel(image, x, y))
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync bitmap[width*(height - y - 1) + x/8] |= (1 << (7 - (x % 8)));
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XDestroyImage(image);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XFreePixmap(dpy, pixmap);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync}
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync/*
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync * determine if a given glyph is valid and return the
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync * corresponding XCharStruct.
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsyncstatic XCharStruct *isvalid(XFontStruct *fs, unsigned int which)
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync{
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned int rows, pages;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned int byte1 = 0, byte2 = 0;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync int i, valid = 1;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync rows = fs->max_byte1 - fs->min_byte1 + 1;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (rows == 1) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* "linear" fonts */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if ((fs->min_char_or_byte2 > which) ||
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync (fs->max_char_or_byte2 < which)) valid = 0;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync else {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* "matrix" fonts */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync byte2 = which & 0xff;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync byte1 = which >> 8;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if ((fs->min_char_or_byte2 > byte2) ||
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync (fs->max_char_or_byte2 < byte2) ||
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync (fs->min_byte1 > byte1) ||
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync (fs->max_byte1 < byte1)) valid = 0;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (valid) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (fs->per_char) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (rows == 1) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* "linear" fonts */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync return fs->per_char + (which-fs->min_char_or_byte2);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync else {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* "matrix" fonts */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync i = ((byte1 - fs->min_byte1) * pages) +
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync (byte2 - fs->min_char_or_byte2);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync return fs->per_char + i;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync else {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync return &fs->min_bounds;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync return NULL;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync}
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsyncvoid stubUseXFont( Display *dpy, Font font, int first, int count, int listbase )
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync{
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync Window win;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync Pixmap pixmap;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync GC gc;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XGCValues values;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned long valuemask;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XFontStruct *fs;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync GLint swapbytes, lsbfirst, rowlength;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync GLint skiprows, skippixels, alignment;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned int max_width, max_height, max_bm_width, max_bm_height;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync GLubyte *bm;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync int i;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync win = RootWindow(dpy, DefaultScreen(dpy));
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync fs = XQueryFont(dpy, font);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (!fs) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync crWarning("Couldn't get font structure information");
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync return;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* Allocate a bitmap that can fit all characters. */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync max_bm_width = (max_width + 7) / 8;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync max_bm_height = max_height;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync bm = (GLubyte *) crAlloc((max_bm_width * max_bm_height) * sizeof(GLubyte));
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (!bm) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XFreeFontInfo( NULL, fs, 1 );
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync crWarning("Couldn't allocate bitmap in glXUseXFont()");
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync return;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* Save the current packing mode for bitmaps. */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* Enforce a standard packing mode which is compatible with
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync fill_bitmap() from above. This is actually the default mode,
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync except for the (non)alignment. */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync values.foreground = BlackPixel(dpy, DefaultScreen (dpy));
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync values.background = WhitePixel(dpy, DefaultScreen (dpy));
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync values.font = fs->fid;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync valuemask = GCForeground | GCBackground | GCFont;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync gc = XCreateGC(dpy, pixmap, valuemask, &values);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XFreePixmap(dpy, pixmap);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync for (i = 0; i < count; i++) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned int width, height, bm_width, bm_height;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync GLfloat x0, y0, dx, dy;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XCharStruct *ch;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync int x, y;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync unsigned int c = first + i;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync int list = listbase + i;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync int valid;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* check on index validity and get the bounds */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync ch = isvalid(fs, c);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (!ch) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync ch = &fs->max_bounds;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync valid = 0;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync else {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync valid = 1;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* glBitmap()' parameters:
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync straight from the glXUseXFont(3) manpage. */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync width = ch->rbearing - ch->lbearing;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync height = ch->ascent + ch->descent;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync x0 = -ch->lbearing;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync y0 = ch->descent - 0; /* XXX used to subtract 1 here */
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /* but that caused a conformance failure */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync dx = ch->width;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync dy = 0;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* X11's starting point. */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync x = -ch->lbearing;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync y = ch->ascent;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* Round the width to a multiple of eight. We will use this also
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync for the pixmap for capturing the X11 font. This is slightly
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync inefficient, but it makes the OpenGL part real easy. */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync bm_width = (width + 7) / 8;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync bm_height = height;
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glNewList(list, GL_COMPILE);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync if (valid && (bm_width > 0) && (bm_height > 0)) {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync crMemset(bm, '\0', bm_width * bm_height);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glBitmap(width, height, x0, y0, dx, dy, bm);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync else {
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glEndList();
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync }
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync crFree(bm);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XFreeFontInfo(NULL, fs, 1);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync XFreeGC(dpy, gc);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync /* Restore saved packing modes. */
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
9a4748c9b04aa33bb54066d49bd27d4c9f0cf33evboxsync}