diff options
author | joye <joye> | 2014-04-21 19:24:22 (GMT) |
---|---|---|
committer | joye <joye> | 2014-04-21 19:24:22 (GMT) |
commit | eaf99c3984bb2b1356ef98b3366bf6073dfaded0 (patch) | |
tree | 3ec8ff64d9d08cc1fe123043ed7bfdb0e97f368a /src/bltGrPostscriptOp.C | |
parent | e86eb701dfbb89a9dc00f2c943abb10e4f254b70 (diff) | |
download | blt-eaf99c3984bb2b1356ef98b3366bf6073dfaded0.zip blt-eaf99c3984bb2b1356ef98b3366bf6073dfaded0.tar.gz blt-eaf99c3984bb2b1356ef98b3366bf6073dfaded0.tar.bz2 |
*** empty log message ***
Diffstat (limited to 'src/bltGrPostscriptOp.C')
-rw-r--r-- | src/bltGrPostscriptOp.C | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/src/bltGrPostscriptOp.C b/src/bltGrPostscriptOp.C index a15e67b..ed79088 100644 --- a/src/bltGrPostscriptOp.C +++ b/src/bltGrPostscriptOp.C @@ -29,6 +29,229 @@ extern "C" { #include "bltGraph.h" +#include "bltOp.h" }; #include "bltGrPageSetupOp.h" +#include "bltPs.h" + +static int CgetOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "cget option"); + return TCL_ERROR; + } + + PageSetup *setupPtr = graphPtr->pageSetup_; + Tcl_Obj* objPtr = Tk_GetOptionValue(interp, + (char*)setupPtr, + setupPtr->optionTable, + objv[3], graphPtr->tkwin_); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; +} + +static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + PageSetup* setupPtr = graphPtr->pageSetup_; + if (objc <= 4) { + Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char*)setupPtr, + setupPtr->optionTable, + (objc == 4) ? objv[3] : NULL, + graphPtr->tkwin_); + if (objPtr == NULL) + return TCL_ERROR; + else + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } + else + return PageSetupObjConfigure(interp, graphPtr, objc-3, objv+3); +} + +static int OutputOp(Graph* graphPtr, Tcl_Interp* interp, + int objc, Tcl_Obj* const objv[]) +{ + const char *fileName = NULL; + Tcl_Channel channel = NULL; + if (objc > 3) { + fileName = Tcl_GetString(objv[3]); + if (fileName[0] != '-') { + objv++, objc--; /* First argument is the file name. */ + channel = Tcl_OpenFileChannel(interp, fileName, "w", 0666); + if (!channel) + return TCL_ERROR; + + if (Tcl_SetChannelOption(interp, channel, "-translation", "binary") + != TCL_OK) + return TCL_ERROR; + } + } + + PostScript *psPtr = Blt_Ps_Create(graphPtr->interp_, graphPtr->pageSetup_); + + if (PageSetupObjConfigure(interp, graphPtr, objc-3, objv+3) != TCL_OK) { + if (channel) + Tcl_Close(interp, channel); + Blt_Ps_Free(psPtr); + return TCL_ERROR; + } + + if (graphPtr->print(fileName, psPtr) != TCL_OK) { + if (channel) + Tcl_Close(interp, channel); + Blt_Ps_Free(psPtr); + return TCL_ERROR; + } + + int length; + const char *buffer = Blt_Ps_GetValue(psPtr, &length); + if (channel) { + int nBytes = Tcl_Write(channel, buffer, length); + if (nBytes < 0) { + Tcl_AppendResult(interp, "error writing file \"", fileName, "\": ", + Tcl_PosixError(interp), (char *)NULL); + if (channel) + Tcl_Close(interp, channel); + Blt_Ps_Free(psPtr); + return TCL_ERROR; + } + Tcl_Close(interp, channel); + } + else + Tcl_SetStringObj(Tcl_GetObjResult(interp), buffer, length); + + Blt_Ps_Free(psPtr); + return TCL_OK; +} + +static Blt_OpSpec psOps[] = + { + {"cget", 2, (void*)CgetOp, 4, 4, "option",}, + {"configure", 2, (void*)ConfigureOp, 3, 0, "?option value?...",}, + {"output", 1, (void*)OutputOp, 3, 0, "?fileName? ?option value?...",}, + }; + +static int nPsOps = sizeof(psOps) / sizeof(Blt_OpSpec); + +typedef int (GraphPsProc)(Graph* graphPtr, Tcl_Interp* interp, int objc, + Tcl_Obj* const objv[]); + +int Blt_PostScriptOp(Graph* graphPtr, Tcl_Interp* interp, int objc, + Tcl_Obj* const objv[]) +{ + GraphPsProc* proc = (GraphPsProc*)Blt_GetOpFromObj(interp, nPsOps, psOps, BLT_OP_ARG2, objc, objv, 0); + if (!proc) + return TCL_ERROR; + + return (*proc)(graphPtr, interp, objc, objv); +} + +// Support + +static void AddComments(Blt_Ps ps, const char **comments) +{ + const char **p; + for (p = comments; *p; p += 2) { + if (*(p+1) == NULL) { + break; + } + Blt_Ps_Format(ps, "%% %s: %s\n", *p, *(p+1)); + } +} + +int PostScriptPreamble(Graph* graphPtr, const char *fileName, Blt_Ps ps) +{ + PageSetup *setupPtr = graphPtr->pageSetup_; + time_t ticks; + char date[200]; /* Holds the date string from ctime() */ + char *newline; + + if (fileName == NULL) { + fileName = Tk_PathName(graphPtr->tkwin_); + } + Blt_Ps_Append(ps, "%!PS-Adobe-3.0 EPSF-3.0\n"); + + /* + * The "BoundingBox" comment is required for EPS files. The box + * coordinates are integers, so we need round away from the center of the + * box. + */ + Blt_Ps_Format(ps, "%%%%BoundingBox: %d %d %d %d\n", + setupPtr->left, setupPtr->paperHeight - setupPtr->top, + setupPtr->right, setupPtr->paperHeight - setupPtr->bottom); + + Blt_Ps_Append(ps, "%%Pages: 0\n"); + + Blt_Ps_Format(ps, "%%%%Creator: (%s %s %s)\n", + PACKAGE_NAME, PACKAGE_VERSION, Tk_Class(graphPtr->tkwin_)); + + ticks = time((time_t *) NULL); + strcpy(date, ctime(&ticks)); + newline = date + strlen(date) - 1; + if (*newline == '\n') { + *newline = '\0'; + } + Blt_Ps_Format(ps, "%%%%CreationDate: (%s)\n", date); + Blt_Ps_Format(ps, "%%%%Title: (%s)\n", fileName); + Blt_Ps_Append(ps, "%%DocumentData: Clean7Bit\n"); + if (setupPtr->landscape) { + Blt_Ps_Append(ps, "%%Orientation: Landscape\n"); + } else { + Blt_Ps_Append(ps, "%%Orientation: Portrait\n"); + } + Blt_Ps_Append(ps, "%%DocumentNeededResources: font Helvetica Courier\n"); + AddComments(ps, setupPtr->comments); + Blt_Ps_Append(ps, "%%EndComments\n\n"); + if (Blt_Ps_IncludeFile(graphPtr->interp_, ps, "bltGraph.pro") != TCL_OK) { + return TCL_ERROR; + } + if (setupPtr->footer) { + const char *who; + + who = getenv("LOGNAME"); + if (who == NULL) { + who = "???"; + } + Blt_Ps_VarAppend(ps, + "8 /Helvetica SetFont\n", + "10 30 moveto\n", + "(Date: ", date, ") show\n", + "10 20 moveto\n", + "(File: ", fileName, ") show\n", + "10 10 moveto\n", + "(Created by: ", who, "@", Tcl_GetHostName(), ") show\n", + "0 0 moveto\n", + (char *)NULL); + } + /* + * Set the conversion from PostScript to X11 coordinates. Scale pica to + * pixels and flip the y-axis (the origin is the upperleft corner). + */ + Blt_Ps_VarAppend(ps, + "% Transform coordinate system to use X11 coordinates\n\n", + "% 1. Flip y-axis over by reversing the scale,\n", + "% 2. Translate the origin to the other side of the page,\n", + "% making the origin the upper left corner\n", (char *)NULL); + Blt_Ps_Format(ps, "1 -1 scale\n"); + /* Papersize is in pixels. Translate the new origin *after* changing the + * scale. */ + Blt_Ps_Format(ps, "0 %d translate\n\n", -setupPtr->paperHeight); + Blt_Ps_VarAppend(ps, "% User defined page layout\n\n", + "% Set color level\n", (char *)NULL); + Blt_Ps_Format(ps, "%% Set origin\n%d %d translate\n\n", + setupPtr->left, setupPtr->bottom); + if (setupPtr->landscape) { + Blt_Ps_Format(ps, + "%% Landscape orientation\n0 %g translate\n-90 rotate\n", + ((double)graphPtr->width_ * setupPtr->scale)); + } + Blt_Ps_Append(ps, "\n%%EndSetup\n\n"); + return TCL_OK; +} + |