824N/A/*
824N/A * XDPSpreview.c
824N/A *
824N/A * (c) Copyright 1990-1994 Adobe Systems Incorporated.
824N/A * All rights reserved.
824N/A *
824N/A * Permission to use, copy, modify, distribute, and sublicense this software
824N/A * and its documentation for any purpose and without fee is hereby granted,
824N/A * provided that the above copyright notices appear in all copies and that
824N/A * both those copyright notices and this permission notice appear in
824N/A * supporting documentation and that the name of Adobe Systems Incorporated
824N/A * not be used in advertising or publicity pertaining to distribution of the
824N/A * software without specific, written prior permission. No trademark license
824N/A * to use the Adobe trademarks is hereby granted. If the Adobe trademark
824N/A * "Display PostScript"(tm) is used to describe this software, its
824N/A * functionality or for any other purpose, such use shall be limited to a
824N/A * statement that this software works in conjunction with the Display
824N/A * PostScript system. Proper trademark attribution to reflect Adobe's
824N/A * ownership of the trademark shall be given whenever any such reference to
824N/A * the Display PostScript system is made.
824N/A *
824N/A * ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
824N/A * ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
824N/A * ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
824N/A * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
824N/A * NON- INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
824N/A * TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
824N/A * DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
824N/A * NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
824N/A * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
824N/A * PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
824N/A *
824N/A * Adobe, PostScript, and Display PostScript are trademarks of Adobe Systems
824N/A * Incorporated which may be registered in certain jurisdictions
824N/A *
824N/A * Author: Adobe Systems Incorporated
824N/A */
824N/A/* $XFree86$ */
824N/A
824N/A#include <X11/Xlib.h>
824N/A#include <DPS/dpsXclient.h>
824N/A#include <DPS/XDPSlib.h>
824N/A#include <DPS/psops.h>
824N/A#include <stdio.h>
824N/A#include <stdlib.h>
824N/A
824N/A#ifndef NeXT
824N/A#include <unistd.h>
824N/A#endif
824N/A
824N/A#include <DPS/dpsXshare.h>
824N/A#include <DPS/dpsXpreview.h>
824N/A#include "XDPSpwraps.h"
824N/A#include "dpsXcommonI.h"
824N/A#include <math.h>
824N/A#include <X11/Xos.h>
824N/A
824N/A#if defined(hpux) || defined(AIXV3)
824N/A#define SELECT_TYPE int *
824N/A#else
824N/A#define SELECT_TYPE fd_set *
824N/A#endif
824N/A
824N/A#define BEGINDOCUMENTLEN 15 /* Length of "%%BeginDocument" */
824N/A#define BEGINBINARYLEN 14 /* Length of "%%BeginBinary:" */
824N/A
824N/Astatic int ParseFileForBBox(FILE *file, XRectangle *bb);
824N/Astatic void FillPixmapWithGray(
824N/A Screen *screen,
824N/A Drawable dest,
824N/A XRectangle *bbox,
824N/A int xOffset, int yOffset,
824N/A double pixelsPerPoint,
824N/A Bool createMask);
824N/A
824N/Astatic XDPSRewindFunction rewindFunction = XDPSFileRewindFunc;
824N/Astatic DPSPointer rewindClientData = NULL;
824N/Astatic XDPSGetsFunction getsFunction = XDPSFileGetsFunc;
824N/Astatic DPSPointer getsClientData = NULL;
824N/A
824N/Aint XDPSSetFileFunctions(
824N/A XDPSRewindFunction rewindFunc,
824N/A DPSPointer rewindData,
824N/A XDPSGetsFunction getsFunc,
824N/A DPSPointer getsData)
824N/A{
824N/A if (rewindFunc != NULL) {
824N/A rewindFunction = rewindFunc;
824N/A rewindClientData = rewindData;
824N/A }
824N/A if (getsFunc != NULL) {
824N/A getsFunction = getsFunc;
824N/A getsClientData = getsData;
824N/A }
824N/A return 0;
824N/A}
824N/A
824N/A/* ARGSUSED */
824N/A
824N/Avoid XDPSFileRewindFunc(FILE *f, DPSPointer data)
824N/A{
824N/A rewind(f);
824N/A}
824N/A
824N/A/* ARGSUSED */
824N/A
824N/Achar *XDPSFileGetsFunc(char *buf, int n, FILE *f, DPSPointer data)
824N/A{
824N/A return fgets(buf, n, f);
824N/A}
824N/A
824N/Avoid XDPSEmbeddedEPSFRewindFunc(FILE *f, DPSPointer data)
824N/A{
824N/A XDPSPosition *p = (XDPSPosition *) data;
824N/A
824N/A p->nestingLevel = 0;
824N/A p->continuedLine = False;
824N/A p->binaryCount = 0;
824N/A
824N/A if (fseek(f, p->startPos, SEEK_SET) != 0) {
824N/A (void) fseek(f, 0L, SEEK_END); /* Go to the end */
824N/A }
824N/A}
824N/A
824N/Astatic Bool imaging = False;
824N/A
824N/Achar *XDPSEmbeddedGetsFunc(char *buf, int n, FILE *f, DPSPointer data)
824N/A{
824N/A XDPSPosition *p = (XDPSPosition *) data;
824N/A int count;
824N/A unsigned len;
824N/A
824N/A if (fgets(buf, n, f) == NULL) {
824N/A if (imaging) p->startPos = -1;
824N/A return NULL;
824N/A }
824N/A
824N/A /* If previous call didn't get a whole line, we're somewhere in the
824N/A middle, so don't check for comments. Also, if we're in the middle of
824N/A binary data, don't look for comments either. */
824N/A
824N/A len = strlen(buf);
824N/A
824N/A if (p->binaryCount != 0) {
824N/A if (len > p->binaryCount) p->binaryCount = 0;
824N/A else p->binaryCount -= len;
824N/A
824N/A } else if (!p->continuedLine) {
824N/A if (strncmp(buf, "%%BeginDocument", BEGINDOCUMENTLEN) == 0) {
824N/A p->nestingLevel++;
824N/A
824N/A } else if (strncmp(buf, "%%BeginBinary:", BEGINBINARYLEN) == 0) {
824N/A count = sscanf(buf, "%%%%BeginBinary: %lu", &p->binaryCount);
824N/A if (count != 1) p->binaryCount = 0; /* Malformed comment */
824N/A
824N/A } else if (strcmp(buf, "%%EndDocument\n") == 0) {
824N/A if (p->nestingLevel == 0) {
824N/A if (imaging) p->startPos = ftell(f);
824N/A return NULL;
824N/A }
824N/A else p->nestingLevel--;
824N/A }
824N/A }
824N/A
824N/A if ((int)len == n-1 && buf[n-1] != '\n') p->continuedLine = True;
824N/A else p->continuedLine = False;
824N/A
824N/A return buf;
824N/A}
824N/A
824N/Aint XDPSCreatePixmapForEPSF(
824N/A DPSContext context,
824N/A Screen *screen,
824N/A FILE *epsf,
824N/A int depth,
824N/A double pixelsPerPoint,
824N/A Pixmap *pixmap,
824N/A XRectangle *pixelSize,
824N/A XRectangle *bbox)
824N/A{
824N/A Pixmap p;
824N/A int width, height;
824N/A XRectangle bb;
824N/A
824N/A if (screen == NULL || depth <= 0 ||
824N/A pixelsPerPoint <= 0) {
824N/A return dps_status_illegal_value;
824N/A }
824N/A
824N/A if (context == NULL) {
824N/A context = XDPSGetSharedContext(DisplayOfScreen(screen));
824N/A }
824N/A
824N/A (*rewindFunction)(epsf, rewindClientData);
824N/A
824N/A if (ParseFileForBBox(epsf, &bb) == dps_status_failure) {
824N/A return dps_status_failure;
824N/A }
824N/A
824N/A width = ceil(bb.width * pixelsPerPoint);
824N/A height = ceil(bb.height * pixelsPerPoint);
824N/A if (width <= 0 || height <= 0) return dps_status_failure;
824N/A
824N/A p = XCreatePixmap(DisplayOfScreen(screen), RootWindowOfScreen(screen),
824N/A width, height, depth);
824N/A
824N/A if (pixmap != NULL) *pixmap = p;
824N/A if (pixelSize != NULL) {
824N/A pixelSize->x = pixelSize->y = 0;
824N/A pixelSize->width = width;
824N/A pixelSize->height = height;
824N/A }
824N/A if (bbox != NULL) *bbox = bb;
824N/A
824N/A if (context != NULL) return dps_status_success;
824N/A else return dps_status_no_extension;
824N/A}
824N/A
824N/Astatic int ParseFileForBBox(FILE *file, XRectangle *bb)
824N/A{
824N/A#define BBOXLEN 14 /* Length of "%%BoundingBox:" */
824N/A#define BUFLEN 256
824N/A#define ATENDLEN 8 /* Length of "(atend)" plus one byte for \0 */
824N/A char buf[BUFLEN];
824N/A char buf2[ATENDLEN];
824N/A Bool atend = False; /* Found a %%BoundingBox: (atend) */
824N/A float x, y, r, t;
824N/A int n;
824N/A int nestingLevel = 0;
824N/A unsigned long binaryCount = 0;
824N/A Bool continuedLine = False;
824N/A unsigned len;
824N/A
824N/A while (1) {
824N/A if ((*getsFunction)(buf, BUFLEN, file, getsClientData) == NULL) {
824N/A return dps_status_failure;
824N/A }
824N/A
824N/A len = strlen(buf);
824N/A
824N/A /* If in binary data or continued line, ignore everything */
824N/A
824N/A if (binaryCount != 0) {
824N/A if (len > binaryCount) binaryCount = 0;
824N/A else binaryCount -= len;
824N/A
824N/A } else if (!continuedLine) {
824N/A if (strncmp(buf, "%%BeginBinary:", BEGINBINARYLEN) == 0) {
824N/A n = sscanf(buf, "%%%%BeginBinary: %lu", &binaryCount);
824N/A if (n != 1) binaryCount = 0; /* Malformed comment */
824N/A
824N/A } else if (strncmp(buf, "%%BeginDocument", BEGINDOCUMENTLEN) == 0) {
824N/A nestingLevel++;
824N/A
824N/A } else if (strcmp(buf, "%%EndDocument\n") == 0) {
824N/A nestingLevel--;
824N/A
824N/A /* Only check for bounding box comments at nesting level 0 */
824N/A
824N/A } else if (nestingLevel == 0) {
824N/A
824N/A /* If we haven't already hit an (atend), the end of the
824N/A comments is a good place to stop looking for the bbox */
824N/A
824N/A if (!atend && (strcmp(buf, "%%EndComments\n") == 0 ||
824N/A strcmp(buf, "%%EndProlog\n") == 0)) {
824N/A return dps_status_failure;
824N/A }
824N/A
824N/A if (strncmp(buf, "%%BoundingBox:", BBOXLEN) == 0) {
824N/A n = sscanf(buf, "%%%%BoundingBox: %f %f %f %f",
824N/A &x, &y, &r, &t);
824N/A
824N/A if (n != 4) {
824N/A n = sscanf(buf, "%%%%BoundingBox: %7s", buf2);
824N/A
824N/A if (n == 1 && strcmp(buf2, "(atend)") == 0) {
824N/A atend = True;
824N/A } else return dps_status_failure;
824N/A
824N/A } else {
824N/A bb->x = (int) x;
824N/A bb->y = (int) y;
824N/A bb->width = r - bb->x;
824N/A if ((float)((int) r) != r) bb->width++;
824N/A bb->height = t - bb->y;
824N/A if ((float)((int) t) != t) bb->height++;
824N/A return dps_status_success;
824N/A }
824N/A }
824N/A }
824N/A }
824N/A
824N/A /* See if this line fills the buffer */
824N/A if (len == BUFLEN-1 && buf[BUFLEN-1] != '\n') continuedLine = True;
824N/A }
824N/A
824N/A#undef ATENDLEN
824N/A#undef BUFLEN
824N/A#undef BBOXLEN
824N/A}
824N/A
824N/A#define mmPerPoint (25.4/72.0)
824N/A
824N/Adouble XDPSPixelsPerPoint(Screen *screen)
824N/A{
824N/A return (float) WidthOfScreen(screen) * mmPerPoint /
824N/A (float) WidthMMOfScreen(screen);
824N/A}
824N/A
824N/Astatic int timeStart = 200, maxDoubles = 3;
824N/A
824N/Avoid XDPSSetImagingTimeout(int timeout, int max)
824N/A{
824N/A timeStart = timeout;
824N/A maxDoubles = max;
824N/A}
824N/A
824N/Atypedef struct _StatusInfo {
824N/A DPSContext ctxt;
824N/A DPSPointer cookie;
824N/A Bool *doneFlag;
824N/A unsigned long startReqNum, endReqNum;
824N/A XDPSStatusProc oldProc;
824N/A struct _StatusInfo *next, *prev;
824N/A} StatusInfo;
824N/A
824N/Astatic StatusInfo *StatusList;
824N/A
824N/Astatic void SetUpStatusVariables(
824N/A DPSContext context,
824N/A DPSPointer cookie,
824N/A Bool *doneFlag,
824N/A unsigned long startReq,
824N/A XDPSStatusProc oldProc)
824N/A{
824N/A StatusInfo *info = (StatusInfo *) malloc(sizeof(StatusInfo));
824N/A
824N/A info->ctxt = context;
824N/A info->cookie = cookie;
824N/A info->doneFlag = doneFlag;
824N/A info->startReqNum = startReq;
824N/A info->endReqNum = 0xFFFFFFFF;
824N/A info->oldProc = oldProc;
824N/A if (StatusList != NULL) StatusList->prev = info;
824N/A info->next = StatusList;
824N/A info->prev = NULL;
824N/A StatusList = info;
824N/A}
824N/A
824N/Astatic void SetEndReqNum(
824N/A DPSContext context,
824N/A unsigned long endReq)
824N/A{
824N/A StatusInfo *info = StatusList;
824N/A
824N/A while (info != NULL && info->ctxt != context) info = info->next;
824N/A if (info != NULL) info->endReqNum = endReq;
824N/A}
824N/A
824N/Astatic void HandlePreviewStatus(
824N/A DPSContext context,
824N/A int status)
824N/A{
824N/A unsigned long serial;
824N/A Display *dpy;
824N/A StatusInfo *info = StatusList;
824N/A
824N/A while (info != NULL && info->ctxt != context) info = info->next;
824N/A if (info == NULL) return;
824N/A
824N/A (void) XDPSXIDFromContext(&dpy, context);
824N/A serial = LastKnownRequestProcessed(dpy);
824N/A
824N/A /* This event is from before our imaging; send to old status proc. */
824N/A if (serial < info->startReqNum) {
824N/A (*info->oldProc) (context, status);
824N/A return;
824N/A }
824N/A
824N/A /* This event is from during our imaging; ignore it */
824N/A if (serial < info->endReqNum) return;
824N/A
824N/A /* This event is juuuuust right. */
824N/A if (status == PSFROZEN) *info->doneFlag = True;
824N/A}
824N/A
824N/Astatic int FinishUp(
824N/A DPSContext context,
824N/A DPSPointer cookie)
824N/A{
824N/A static char restorebuf[] =
824N/A "\n$Adobe$DPS$Lib$Dict /EPSFsave get restore grestore\n";
824N/A StatusInfo *info = StatusList;
824N/A int err;
824N/A
824N/A /* Check the results of the imaging: Get the error status and restore the
824N/A context */
824N/A
824N/A _DPSPCheckForError(context, &err);
824N/A
824N/A /* Can't do this is a wrap because of restore semantics */
824N/A DPSWritePostScript(context, restorebuf, strlen(restorebuf));
824N/A
824N/A (void) XDPSPopContextParameters(cookie);
824N/A
824N/A /* See if we have an info record and delete it if so */
824N/A while (info != NULL && info->ctxt != context) info = info->next;
824N/A if (info != NULL) {
824N/A if (info == StatusList) StatusList = info->next;
824N/A else info->prev->next = info->next;
824N/A if (info->next != NULL) info->next->prev = info->prev;
824N/A XDPSRegisterStatusProc(context, info->oldProc);
824N/A free(info);
824N/A }
824N/A
824N/A if (err) return dps_status_postscript_error;
824N/A else return dps_status_success;
824N/A}
824N/A
824N/Aint XDPSCheckImagingResults(
824N/A DPSContext context,
824N/A Screen *screen)
824N/A{
824N/A StatusInfo *info = StatusList;
824N/A int status;
824N/A
824N/A if (context == NULL) {
824N/A context = XDPSGetSharedContext(DisplayOfScreen(screen));
824N/A if (context == NULL) return dps_status_no_extension;
824N/A }
824N/A
824N/A while (info != NULL && info->ctxt != context) info = info->next;
824N/A if (info == NULL) return dps_status_illegal_value;
824N/A
824N/A status = XDPSGetContextStatus(context);
824N/A if (status != PSFROZEN) return dps_status_imaging_incomplete;
824N/A
824N/A XDPSUnfreezeContext(context);
824N/A return FinishUp(context, info->cookie);
824N/A}
824N/A
824N/Astatic void msleep(int ms)
824N/A{
824N/A struct timeval incr;
824N/A
824N/A incr.tv_sec = ms / 1000;
824N/A incr.tv_usec = (ms % 1000) * 1000;
824N/A (void) select (0, (SELECT_TYPE) NULL, (SELECT_TYPE) NULL,
824N/A (SELECT_TYPE) NULL, &incr);
824N/A}
824N/A
824N/Aint XDPSImageFileIntoDrawable(
824N/A DPSContext context,
824N/A Screen *screen,
824N/A Drawable dest,
824N/A FILE *file,
824N/A int drawableHeight,
824N/A int drawableDepth,
824N/A XRectangle *bbox,
824N/A int xOffset, int yOffset,
824N/A double pixelsPerPoint,
824N/A Bool clear, Bool createMask,
824N/A Bool waitForCompletion,
824N/A Bool *doneFlag)
824N/A{
824N/A#define BUFSIZE 256
824N/A#define EXECLEN 6
824N/A char buf[BUFSIZE];
824N/A static char eobuf[] = "\n$Adobe$DPS$Lib$Dict /execSuccess true put\n\
824N/Astop\n\
824N/AMagic end of data line )))))))))) 99#2 2#99 <xyz> // 7gsad,32h4ghNmndFgj2\n";
824N/A XDPSStandardColormap maskMap;
824N/A XDPSStandardColormap rgbMap;
824N/A unsigned int flags = 0;
824N/A int status;
824N/A Bool inited;
824N/A DPSPointer cookie;
824N/A int doublings;
824N/A int ms;
824N/A XDPSStatusProc oldProc;
824N/A unsigned long startReqNum = 0, endReqNum;
824N/A
824N/A if (screen == NULL || dest == None ||
824N/A drawableHeight <= 0 || drawableDepth <= 0 ||
824N/A pixelsPerPoint <= 0) {
824N/A return dps_status_illegal_value;
824N/A }
824N/A
824N/A if (context == NULL) {
824N/A context = XDPSGetSharedContext(DisplayOfScreen(screen));
824N/A if (context == NULL) {
824N/A FillPixmapWithGray(screen, dest, bbox, xOffset, yOffset,
824N/A pixelsPerPoint,
824N/A createMask);
824N/A return dps_status_no_extension;
824N/A }
824N/A }
824N/A
824N/A (*rewindFunction)(file, rewindClientData);
824N/A
824N/A if (!waitForCompletion) {
824N/A DPSWaitContext(context);
824N/A /* Any status events before this point go to old handler */
824N/A startReqNum = NextRequest(DisplayOfScreen(screen));
824N/A }
824N/A
824N/A status = _XDPSTestComponentInitialized(context,
824N/A dps_init_bit_preview, &inited);
824N/A if (status != dps_status_success) return status;
824N/A if (!inited) {
824N/A (void) _XDPSSetComponentInitialized(context, dps_init_bit_preview);
824N/A _DPSPDefineExecFunction(context);
824N/A }
824N/A
824N/A if (createMask) {
824N/A if (drawableDepth != 1) return dps_status_illegal_value;
824N/A maskMap.colormap = None;
824N/A maskMap.red_max = 1;
824N/A maskMap.red_mult = -1;
824N/A maskMap.base_pixel = 1;
824N/A rgbMap.colormap = None;
824N/A rgbMap.red_max = rgbMap.green_max = rgbMap.blue_max =
824N/A rgbMap.red_mult = rgbMap.green_mult = rgbMap.blue_mult =
824N/A rgbMap.base_pixel = 0;
824N/A flags = XDPSContextGrayMap | XDPSContextRGBMap;
824N/A }
824N/A
824N/A status = XDPSPushContextParameters(context, screen, drawableDepth,
824N/A dest, drawableHeight,
824N/A &rgbMap, &maskMap,
824N/A flags | XDPSContextScreenDepth |
824N/A XDPSContextDrawable, &cookie);
824N/A
824N/A if (status != dps_status_success) return status;
824N/A
824N/A _DPSPSetMatrix(context, xOffset, yOffset, pixelsPerPoint);
824N/A
824N/A if (clear) _DPSPClearArea(context, (int) bbox->x, (int) bbox->y,
824N/A (int) bbox->width, (int) bbox->height);
824N/A
824N/A if (createMask) _DPSPSetMaskTransfer(context);
824N/A
824N/A /* Prepare to read PostScript code */
824N/A _DPSPSaveBeforeExec(context, !waitForCompletion);
824N/A DPSWritePostScript(context, "\nexec\n", EXECLEN);
824N/A
824N/A imaging = True;
824N/A while ((*getsFunction)(buf, BUFSIZE, file, getsClientData) != NULL) {
824N/A DPSWritePostScript(context, buf, strlen(buf));
824N/A }
824N/A imaging = False;
824N/A
824N/A /* This marks the end of the data stream */
824N/A DPSWritePostScript(context, eobuf, strlen(eobuf));
824N/A
824N/A if (!waitForCompletion) {
824N/A *doneFlag = False;
824N/A oldProc = XDPSRegisterStatusProc(context, HandlePreviewStatus);
824N/A SetUpStatusVariables(context, cookie, doneFlag, startReqNum, oldProc);
824N/A XDPSSetStatusMask(context, 0, 0, PSFROZENMASK);
824N/A
824N/A ms = timeStart;
824N/A
824N/A /* Check for done until we run out of time */
824N/A doublings = 0;
824N/A while (1) {
824N/A if (XDPSGetContextStatus(context) == PSFROZEN) {
824N/A waitForCompletion = True;
824N/A XDPSUnfreezeContext(context);
824N/A break;
824N/A }
824N/A if (doublings >= maxDoubles) break;
824N/A
824N/A /* Wait a while */
824N/A msleep(ms);
824N/A ms *= 2;
824N/A doublings++;
824N/A }
824N/A }
824N/A
824N/A /* If previous decided imaging is done, it changed waitForCompletion */
824N/A
824N/A if (waitForCompletion) return FinishUp(context, cookie);
824N/A else {
824N/A endReqNum = NextRequest(DisplayOfScreen(screen)) - 1;
824N/A SetEndReqNum(context, endReqNum);
824N/A return dps_status_imaging_incomplete;
824N/A }
824N/A#undef EXECLEN
824N/A#undef BUFSIZE
824N/A}
824N/A
824N/Astatic void FillPixmapWithGray(
824N/A Screen *screen,
824N/A Drawable dest,
824N/A XRectangle *bbox,
824N/A int xOffset, int yOffset,
824N/A double pixelsPerPoint,
824N/A Bool createMask)
824N/A{
824N/A int width, height, x, y;
824N/A GC gc;
824N/A XGCValues v;
824N/A static char grayBits[] = {0x01, 0x02};
824N/A Pixmap grayStipple;
824N/A Display *dpy = DisplayOfScreen(screen);
824N/A
824N/A width = ceil(bbox->width * pixelsPerPoint);
824N/A height = ceil(bbox->height * pixelsPerPoint);
824N/A x = (bbox->x + xOffset) * pixelsPerPoint;
824N/A y = (bbox->y + yOffset) * pixelsPerPoint;
824N/A
824N/A if (createMask) {
824N/A v.foreground = 1;
824N/A v.function = GXcopy;
824N/A
824N/A gc = XCreateGC(dpy, dest, GCForeground | GCFunction, &v);
824N/A XFillRectangle(dpy, dest, gc, x, y, width, height);
824N/A XFreeGC(dpy, gc);
824N/A return;
824N/A }
824N/A
824N/A grayStipple = XCreateBitmapFromData(dpy, dest, grayBits, 2, 2);
824N/A
824N/A v.foreground = BlackPixelOfScreen(screen);
824N/A v.background = WhitePixelOfScreen(screen);
824N/A v.function = GXcopy;
824N/A v.stipple = grayStipple;
824N/A v.fill_style = FillOpaqueStippled;
824N/A gc = XCreateGC(dpy, dest, GCForeground | GCBackground | GCFunction |
824N/A GCStipple | GCFillStyle, &v);
824N/A XFillRectangle(dpy, dest, gc, x, y, width, height);
824N/A XFreeGC(dpy, gc);
824N/A XFreePixmap(dpy, grayStipple);
824N/A}