void newbaseline ( char *buf /* whatever followed "x X NewBaseline" */ ) { char *p; /* for eliminating white space etc. */ /* * * Called from devcntrl() whenever an "x X NewBaseline" command is recognized. We * assume whatever is in *buf is a set of parametric equations that describe the * new baseline. Equations for x(t), y(t), dx/dt, and dy/dt must be written in * PostScript, bracketed by { and } characters, and supplied in exactly that order. * In particular the equation for x must come first in *buf and it ends up as the * last one on the stack, while the equation for dy/dt comes last (in *buf) and * ends up on the top of the PostScript stack. For example if *buf is given by, * * {} {180 mul 3.1416 div cos} {pop 1} {180 mul 3.1416 div sin neg} * * text will be printed along the curve y = cos(x). * * Angles given in radians must be converted to degrees for the PostScript trig * functions, and things are scaled so that 1 unit maps into 1 inch. In the last * example the cosine curve that describes the baseline has an amplitude of 1 inch. * As another example of this rather confusing syntax if *buf is, * * {} {} {pop 1} {pop 1} * * the baseline will be the 45 degree line y = x. * * When any of the four functions is used they're called with a single number on * the stack that's equal to the current value of the parameter t. The coordinate * system axes run parallel to the PostScript coordinate system that's currently * being used. * */ for ( p = buf; *p; p++ ) /* eliminate trailing '\n' */ if ( *p == '\n' ) { *p = '\0'; break; } /* End if */ for ( p = buf; *p && (*p == ' ' || *p == ':'); p++ ) ; if ( *p != '\0' ) { /* something's there */ endtext(); getbaseline(); fprintf(tf, "mark resolution %s newbaseline\n", p); t_sf(1); resetpos(); } /* End if */ } /* End of newbaseline */
void settext(char *buf) { char *p; /* * * Does whatever is needed to ensure any text that follows will be set along the * curve described by the PostScript procedures listed in *buf. If *buf doesn't * contain anything useful (eg. just a newline) things are restored to whatever * they originally were. Doesn't work well if we try to start in the middle of a * line of text. * * The parametric equations needed are, * * x = f(t) * y = g(t) * dx/dt = f'(t) * dy/dt = g'(t) * * and must be given as proper PostScript procedures. The equation for x must come * first (ie. it ends up on the bottom of the stack) and the equation for dy/dt * must be given last (ie. it ends up on top of the stack). For example if *buf * is given by, * * {} {180 mul 3.1416 div cos} {pop 1} {180 mul 3.1416 div sin neg} * * text will be set along the curve y=cos(x). * */ endtext(); getbaseline(); for ( p = buf; *p && *p == ' '; p++ ) ; if ( *p && *p != '\n' ) { encoding = maxencoding + 2; fprintf(tf, "mark resolution %s newbaseline\n", buf); } else encoding = realencoding; fprintf(tf, "%d setdecoding\n", encoding); resetpos(); } /* End of settext */
void drawtext ( char *buf /* whatever followed "x X DrawText */ ) { char *p; /* for eliminating white space etc. */ /* * * Called from devcntrl() whenever an "x X DrawText command is recognized. *buf * should contain three arguments in the following order. First comes the text we * want to print along the current baseline. Right now the string should be given * as a PostScript string using characters '(' and ')' as the delimiters. Next in * *buf comes a justification mode that can be the words left, right, or center. * Last comes a number that represents the starting value of the parameter t that's * given as the argument to the parametric equations that describe the current * baseline. For example if *buf is given by, * * (hello world) left .5 * * hello world will be printed along the path described by the current baseline * and left justified at whatever (x(.5), y(.5)) happens to be. Usually will be * preceeded by an "x X NewBaseline" call that defines the current baseline. The * origin of the coordinate system used by the parametric equations will be the * current point. * */ for ( p = buf; *p; p++ ) /* eliminate trailing '\n' */ if ( *p == '\n' ) { *p = '\0'; break; } /* End if */ for ( p = buf; *p && (*p == ' ' || *p == ':'); p++ ) ; if ( *p != '\0' ) { /* something's there */ endtext(); getbaseline(); xymove(hpos, vpos); fprintf(tf, "mark %s drawfunnytext\n", p); resetpos(); } /* End if */ } /* End of drawtext */
void beginpath ( char *buf, /* whatever followed "x X BeginPath" */ int copy /* ignore *buf if FALSE */ ) { /* * * Called from devcntrl() whenever an "x X BeginPath" command is read. It's used * to mark the start of a sequence of drawing commands that should be grouped * together and treated as a single path. By default the drawing procedures in * *drawfile treat each drawing command as a separate object, and usually start * with a newpath (just as a precaution) and end with a stroke. The newpath and * stroke isolate individual drawing commands and make it impossible to deal with * composite objects. "x X BeginPath" can be used to mark the start of drawing * commands that should be grouped together and treated as a single object, and * part of what's done here ensures that the PostScript drawing commands defined * in *drawfile skip the newpath and stroke, until after the next "x X DrawPath" * command. At that point the path that's been built up can be manipulated in * various ways (eg. filled and/or stroked with a different line width). * * String *buf is unnecessary and is only included for compatibility with an early * verion of that's still in use. In that version "x X BeginObject" marked the * start of a graphical object, and whatever followed it was passed along in *buf * and copied to the output file. Color selection is one of the options that's * available in parsebuf(), so if we get here we add *colorfile to the output * file before doing anything important. * */ if ( inpath == FALSE ) { endtext(); getdraw(); getcolor(); fprintf(tf, "gsave\n"); fprintf(tf, "newpath\n"); fprintf(tf, "%d %d m\n", hpos, vpos); fprintf(tf, "/inpath true def\n"); if ( copy == TRUE ) fprintf(tf, "%s", buf); inpath = TRUE; } /* End if */ } /* End of beginpath */
void drvPDF::show_path() { // add_to_page(); // is done in drvbase !! endtext(); // close text if open const char *setrgbcolor = 0; const char *drawingop = 0; switch (currentShowType()) { case drvbase::stroke: // it's a stroke drawingop = "S"; setrgbcolor = "RG"; break; case drvbase::fill: drawingop = "f"; setrgbcolor = "rg"; break; case drvbase::eofill: drawingop = "f*"; setrgbcolor = "rg"; break; default: // cannot happen errf << "unexpected ShowType " << (int) currentShowType() << endl; exit(1); break; } // buffer.precision(3); // buffer.setf(ios::fixed); // buffer.width(0); // to force minimal width // buffer.unsetf(ios::showpoint); if (Verbose()) { buffer << "% path " << currentNr() << endl; } buffer << RND3(currentR()) << " " << RND3(currentG()) << " " << RND3(currentB()) << " " << setrgbcolor << endl; buffer << currentLineWidth() << " w" << endl; buffer << currentLineCap() << " J" << endl; buffer << currentLineJoin() << " j" << endl; buffer << dashPattern() << " d" << endl; print_coords(); buffer << drawingop << endl; }
void drvPDF::close_page() { endtext(); // close text if open streampos endpos = buffer.tellp(); outf << "<<" << endl; outf << "/Length " << endpos << endl; outf << ">>" << endl; outf << "stream" << endl; ifstream & instream = tempFile.asInput(); copy_file(instream, outf); // int ret = 0; // while ( (ret = instream.get()) != EOF ) { // outf << (char) ret ; // } outf << "endstream" << endl; endobject(); }
void picture ( char *buf /* stuff following 'x X PI' command */ ) { int poffset; /* page offset */ int indent; /* indent */ int length; /* line length */ int totrap; /* distance to next trap */ char name[4096]; /* picture file and page string */ char hwo[4096], *p; /* height, width and offset strings */ char flags[4096]; /* miscellaneous stuff */ int page = 1; /* page number pulled from name[] */ double frame[4]; /* height, width, y, and x offsets from hwo[] */ char units; /* scale indicator for frame dimensions */ int whiteout = 0; /* white out the box? */ int outline = 0; /* draw a box around the picture? */ int scaleboth = 0; /* scale both dimensions? */ double adjx = 0.5; /* left-right adjustment */ double adjy = 0.5; /* top-bottom adjustment */ double rot = 0; /* rotation in clockwise degrees */ FILE *fp_in; /* for *name */ int i; /* loop index */ /* * * Called from devcntrl() after an 'x X PI' command is found. The syntax of that * command is: * * x X PI:args * * with args separated by colons and given by: * * poffset * indent * length * totrap * file[(page)] * height[,width[,yoffset[,xoffset]]] * [flags] * * poffset, indent, length, and totrap are given in machine units. height, width, * and offset refer to the picture frame in inches, unless they're followed by * the u scale indicator. flags is a string that provides a little bit of control * over the placement of the picture in the frame. Rotation of the picture, in * clockwise degrees, is set by the a flag. If it's not followed by an angle * the current rotation angle is incremented by 90 degrees, otherwise the angle * is set by the number that immediately follows the a. * */ if ( picflag == OFF ) /* skip it */ return; endtext(); flags[0] = '\0'; /* just to be safe */ if ( sscanf(buf, "%d:%d:%d:%d:%[^:]:%[^:]:%[^:]", &poffset, &indent, &length, &totrap, name, hwo, flags) < 6 ) { error(NON_FATAL, "too few arguments to specify picture"); return; } /* End if */ if ( sscanf(name, "%*[^(](%d", &page) == 1 ) /* grab the page number */ strtok(name, "("); /* and separate it from the name */ if ( (fp_in = picopen(name)) == NULL ) { error(NON_FATAL, "can't open picture file %s", name); return; } /* End if */ frame[0] = frame[1] = -1; /* default frame height, width */ frame[2] = frame[3] = 0; /* and y and x offsets */ for ( i = 0, p = hwo-1; i < 4 && p != NULL; i++, p = strchr(p, ',') ) if ( sscanf(++p, "%lf%c", &frame[i], &units) == 2 ) if ( units == 'i' || units == ',' || units == '\0' ) frame[i] *= res; if ( frame[0] <= 0 ) /* check what we got for height */ frame[0] = totrap; if ( frame[1] <= 0 ) /* and width - check too big?? */ frame[1] = length - indent; frame[3] += poffset + indent; /* real x offset */ for ( i = 0; flags[i]; i++ ) switch ( flags[i] ) { case 'c': adjx = adjy = 0.5; break; /* move to the center */ case 'l': adjx = 0; break; /* left */ case 'r': adjx = 1; break; /* right */ case 't': adjy = 1; break; /* top */ case 'b': adjy = 0; break; /* or bottom justify */ case 'o': outline = 1; break; /* outline the picture */ case 'w': whiteout = 1; break; /* white out the box */ case 's': scaleboth = 1; break; /* scale both dimensions */ case 'a': if ( sscanf(&flags[i+1], "%lf", &rot) != 1 ) rot += 90; } /* End switch */ fprintf(tf, "save mark\n"); fprintf(tf, "[ /NamespacePush pdfmark\n"); ps_include(name, fp_in, tf, page, whiteout, outline, scaleboth, frame[3]+frame[1]/2, -vpos-frame[2]-frame[0]/2, frame[1], frame[0], adjx, adjy, -rot); fprintf(tf, "[ /NamespacePop pdfmark\n"); fprintf(tf, "cleartomark restore\n"); xymove(hpos, vpos); t_sf(1); fclose(fp_in); } /* End of picture */