This is eps2.c in view mode; [Download] [Up]
#include <stdio.h> #include <X11/StringDefs.h> #include <X11/Intrinsic.h> #include <X11/Shell.h> #include <DPS/dpsXclient.h> #include <DPS/dpsXcommon.h> #include <DPS/dpsXshare.h> #include <ieeefp.h> int isinf(double d) {return !finite(d);} /* * The following declarations are part of the mechanism that * calls the Redisplay procedure whenever the contents need * to be updated. */ typedef struct { float rotate; float scalex; float scaley; } ApplicationData, *ApplicationDataPtr; void Redisplay(); double PixelsPerPoint(Screen *); int getBoundingBox(FILE *, XRectangle *); Boolean imageFile(FILE *); String translations = "<Expose> : Redisplay()"; XtActionsRec actions[] = { {"Redisplay", Redisplay} }; Display *display; /* Connection to the X server */ Window window; /* Window that we'll draw in */ GC gc; /* X graphics context */ DPSContext ctxt; FILE *epsf; Pixmap pixmap; XRectangle pixelSize, pixmapSize2, pixmapSize2; XRectangle bbox, pixmapSize, scaled_pixmapSize; ApplicationData data; static XtResource resources[] = { { "rotate", "Rotate", XtRFloat, sizeof (float), XtOffset(ApplicationDataPtr, rotate), XtRString,"0.0" }, { "scalex", "Scalex", XtRFloat, sizeof (float), XtOffset(ApplicationDataPtr, scalex), XtRString,"1.0" }, { "scaley", "Scaley", XtRFloat, sizeof (float), XtOffset(ApplicationDataPtr, scaley), XtRString,"1.0" } }; static XrmOptionDescRec options[] = { {"-rotate", "*rotate", XrmoptionSepArg, NULL}, {"-scalex", "*scalex", XrmoptionSepArg, NULL}, {"-scaley", "*scaley", XrmoptionSepArg, NULL} }; void main(argc, argv) int argc; char **argv; { Widget appShell, w; XtAppContext app; int retval; Bool doneFlag; char *file; int depth; double pixelsperpoint; Pixmap pixmap2; /* * The call to XtAppInitialize creates a connection to the * X server. We extract that connection with the call to * XtDisplay() */ appShell = XtAppInitialize(&app, "Demo", options, XtNumber(options), &argc, argv, NULL, NULL, 0); /* * Retrieve the resources. */ XtGetApplicationResources(appShell, &data, resources, XtNumber(resources), NULL, 0); if(argc < 2) { fprintf(stderr,"Usage: %s eps-file\n",argv[0]); exit(1); } file = argv[1]; display = XtDisplay(appShell); depth = DefaultDepthOfScreen(XtScreen(appShell)); pixelsperpoint = PixelsPerPoint(XtScreen(appShell)); /* * XtAppAddActions adds Redisplay as an action procedure that * is called when an Expose event is received by the widget. */ XtAppAddActions(app, actions, XtNumber(actions)); /* * Now we can create the window. First we set up some parameters * like width and height. The call to XtVaCreateManagedWidget and * XtRealize create and initialize the window. We extract the * window identifier with the XtWindow call. */ epsf = fopen(file, "r"); if(epsf == NULL) { perror(file); exit(1); } retval = getBoundingBox(epsf, &bbox); switch(retval) { case dps_status_success: break; case dps_status_failure: fprintf(stderr,"File is not an EPS file\n"); exit(1); } pixmapSize.x = (short)(bbox.x * pixelsperpoint * data.scalex); pixmapSize.y = (short)(bbox.y * pixelsperpoint * data.scaley); pixmapSize.width = (unsigned short)(bbox.width * pixelsperpoint * data.scalex); pixmapSize.height = (unsigned short)(bbox.height * pixelsperpoint * data.scaley); w = XtVaCreateManagedWidget("da", coreWidgetClass, appShell, XtNwidth, pixmapSize.width, XtNheight, pixmapSize.height, XtNtranslations, XtParseTranslationTable(translations), NULL); XtRealizeWidget(appShell); window = XtWindow(w); pixmap = XCreatePixmap(display, window, pixmapSize.width, pixmapSize.height, depth); /* * The following creates an X graphics context */ gc = XCreateGC(display, window, 0, NULL); /* * Create a context to which the PostScript language code * will be sent */ ctxt = XDPSCreateSimpleContext(display, pixmap, gc, 0, pixmapSize.height, DPSDefaultTextBackstop, DPSDefaultErrorProc, (DPSSpace) NULL); switch(retval) { case dps_status_success: break; case dps_status_unregistered_context: fprintf(stderr,"Context not registered\n"); exit(1); case dps_status_illegal_value: printf("XDPSSetContextDrawable: Invalid context drawable height\n"); exit(1); default: fprintf(stderr, "Internal error %d\n", retval); exit(1); } /* * This is where I am having the problem. I can't figure out the * appropriate parameter to PSWTransformBeforeEPSF() in order to * scale x and y and rotate about the center */ PSWTransformBeforeEPSF(ctxt, (float)bbox.width * data.scalex / 2, /* Find center */ (float)bbox.height * data.scaley / 2, data.scalex, data.scaley, data.rotate, -(float)bbox.x - (float)bbox.width / 2, -(float)bbox.y - (float)bbox.height / 2); PSWDefineExecFunction(ctxt); imageFile(epsf); XtAppMainLoop(app); } /* The Redisplay procedure is called whenever the */ /* contents of the window needs to be repainted. */ void Redisplay(w, event, params, num) Widget w; XEvent *event; String *params; Cardinal *num; { XCopyArea(XtDisplay(w), pixmap, window, gc, 0, 0, pixmapSize.width, pixmapSize.height, 0, 0); /*DPSPrintf(ctxt, "[3] 0 setdash (Hello World) false charpath stroke ");*/ } int getBoundingBox(file, bb) FILE *file; XRectangle *bb; { #define BBOXLEN 14 /* Length of "%%BoundingBox:" */ #define BUFLEN 256 #define ATENDLEN 8 /* Length of "(atend)" plus one byte for \0 */ #define BEGINDOCUMENTLEN 15 /* Length of "%%BeginDocument" */ #define BEGINBINARYLEN 14 /* Length of "%%BeginBinary:" */ char buf[BUFLEN]; char buf2[ATENDLEN]; Bool atend = False; /* Found a %%BoundingBox: (atend) */ short r, t; int n; int nestingLevel = 0; unsigned long binaryCount = 0; Bool continuedLine = False; int len; while (1) { if (fgets(buf, BUFLEN, file) == NULL) { return dps_status_failure; } len = strlen(buf); /* If in binary data or continued line, ignore everything */ if (binaryCount != 0) { if (len > binaryCount) binaryCount = 0; else binaryCount -= len; } else if (!continuedLine) { if (strncmp(buf, "%%BeginBinary:", BEGINBINARYLEN) == 0) { n = sscanf(buf, "%%%%BeginBinary: %lu", &binaryCount); if (n != 1) binaryCount = 0; /* Malformed comment */ } else if (strncmp(buf, "%%BeginDocument", BEGINDOCUMENTLEN) == 0) { nestingLevel++; } else if (strcmp(buf, "%%EndDocument\n") == 0) { nestingLevel--; /* Only check for bounding box comments at nesting level 0 */ } else if (nestingLevel == 0) { /* If we haven't already hit an (atend), the end of the comments is a good place to stop looking for the bbox */ if (!atend && (strcmp(buf, "%%EndComments\n") == 0 || strcmp(buf, "%%EndProlog\n") == 0)) { return dps_status_failure; } if (strncmp(buf, "%%BoundingBox:", BBOXLEN) == 0) { n = sscanf(buf, "%%%%BoundingBox: %hd %hd %hd %hd", &bb->x, &bb->y, &r, &t); if (n != 4) { n = sscanf(buf, "%%%%BoundingBox: %7s", buf2); if (n == 1 && strcmp(buf2, "(atend)") == 0) { atend = True; } else return dps_status_failure; } else { bb->width = r - bb->x; bb->height = t - bb->y; return dps_status_success; } } } } /* See if this line fills the buffer */ if (len == BUFLEN-1 && buf[BUFLEN-1] != '\n') continuedLine = True; } #undef ATENDLEN #undef BUFLEN #undef BBOXLEN #undef BEGINDOCUMENTLEN #undef BEGINBINARYLEN } Boolean imageFile(FILE *epsf) { #define BUFSIZE 256 #define EXECLEN 6 /* Length of "\nexec\n" */ char buf[BUFSIZE]; static char eobuf[] = "/execSuccess true def\n\ stop\n\ Magic end of data line )))))))))) 99#2 2#99 <xyz> // 7gsad,32h4ghNmndFgj2\n"; static char restorebuf[] = "\nEPSFsave restore\n"; int err; /* ** Reset to beginning of file */ rewind(epsf); /* ** Prepare to execute PostScript code */ PSWBeginEPSF(ctxt); DPSWritePostScript(ctxt, "\nexec\n", EXECLEN); /* ** Copy file to context */ while (fgets(buf, BUFSIZE, epsf) != NULL) { DPSWritePostScript(ctxt, buf, strlen(buf)); } /* ** Mark the end of the data stream */ DPSWritePostScript(ctxt, eobuf, strlen(eobuf)); /* ** Check the results of the imaging: Get the error status and restore the ** context */ PSWEndEPSF(ctxt, &err); /* ** Can't do this is a wrap because of restore semantics */ DPSWritePostScript(ctxt, restorebuf, strlen(restorebuf)); return err; #undef EXECLEN #undef BUFSIZE } /* end imageFile() */ double PixelsPerPoint(Screen *screen) { return (double) ((double)WidthOfScreen(screen) * (double)(25.4 / 72.0) / (double)(WidthMMOfScreen(screen))); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.