URI:
       tbbox.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tbbox.c (5575B)
       ---
            1 /*
            2  *
            3  * Boundingbox code for PostScript translators. The boundingbox for each page
            4  * is accumulated in bbox - the one for the whole document goes in docbbox. A
            5  * call to writebbox() puts out an appropriate comment, updates docbbox, and
            6  * resets bbox for the next page. The assumption made at the end of writebbox()
            7  * is that we're really printing the current page only if output is now going
            8  * to stdout - a valid assumption for all supplied translators. Needs the math
            9  * library.
           10  *
           11  */
           12 
           13 #include <stdio.h>
           14 #include <string.h>
           15 #include <ctype.h>
           16 #include <sys/types.h>
           17 #include <fcntl.h>
           18 #include <math.h>
           19 
           20 #include "comments.h"                        /* PostScript file structuring comments */
           21 #include "gen.h"                        /* a few general purpose definitions */
           22 #include "ext.h"                        /* external variable declarations */
           23 
           24 typedef struct bbox {
           25         int        set;
           26         double        llx, lly;
           27         double        urx, ury;
           28 } Bbox;
           29 
           30 Bbox        bbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
           31 Bbox        docbbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
           32 
           33 double        ctm[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
           34 double        matrix1[6], matrix2[6];
           35 
           36 /*****************************************************************************/
           37 
           38 void
           39 cover(x, y)
           40 
           41     double        x, y;
           42 
           43 {
           44 
           45 /*
           46  *
           47  * Adds point (x, y) to bbox. Coordinates are in user space - the transformation
           48  * to default coordinates happens in writebbox().
           49  *
           50  */
           51 
           52     if ( bbox.set == FALSE ) {
           53         bbox.llx = bbox.urx = x;
           54         bbox.lly = bbox.ury = y;
           55         bbox.set = TRUE;
           56     } else {
           57         if ( x < bbox.llx )
           58             bbox.llx = x;
           59         if ( y < bbox.lly )
           60             bbox.lly = y;
           61         if ( x > bbox.urx )
           62             bbox.urx = x;
           63         if ( y > bbox.ury )
           64             bbox.ury = y;
           65     }        /* End else */
           66 
           67 }   /* End of cover */
           68 
           69 /*****************************************************************************/
           70 void        resetbbox(int);
           71 
           72 void
           73 writebbox(fp, keyword, slop)
           74 
           75     FILE        *fp;                        /* the comment is written here */
           76     char        *keyword;                /* the boundingbox comment string */
           77     int                slop;                        /* expand (or contract?) the box a bit */
           78 
           79 {
           80 
           81     Bbox        ubbox;                        /* user space bounding box */
           82     double        x, y;
           83 
           84 /*
           85  *
           86  * Transforms the numbers in the bbox[] using ctm[], adjusts the corners a bit
           87  * (depending on slop) and then writes comment. If *keyword is BoundingBox use
           88  * whatever's been saved in docbbox, otherwise assume the comment is just for
           89  * the current page.
           90  *
           91  */
           92 
           93     if ( strcmp(keyword, BOUNDINGBOX) == 0 )
           94         bbox = docbbox;
           95 
           96     if ( bbox.set == TRUE ) {
           97         ubbox = bbox;
           98         bbox.set = FALSE;                /* so cover() works properly */
           99         x = ctm[0] * ubbox.llx + ctm[2] * ubbox.lly + ctm[4];
          100         y = ctm[1] * ubbox.llx + ctm[3] * ubbox.lly + ctm[5];
          101         cover(x, y);
          102         x = ctm[0] * ubbox.llx + ctm[2] * ubbox.ury + ctm[4];
          103         y = ctm[1] * ubbox.llx + ctm[3] * ubbox.ury + ctm[5];
          104         cover(x, y);
          105         x = ctm[0] * ubbox.urx + ctm[2] * ubbox.ury + ctm[4];
          106         y = ctm[1] * ubbox.urx + ctm[3] * ubbox.ury + ctm[5];
          107         cover(x, y);
          108         x = ctm[0] * ubbox.urx + ctm[2] * ubbox.lly + ctm[4];
          109         y = ctm[1] * ubbox.urx + ctm[3] * ubbox.lly + ctm[5];
          110         cover(x, y);
          111         bbox.llx -= slop + 0.5;
          112         bbox.lly -= slop + 0.5;
          113         bbox.urx += slop + 0.5;
          114         bbox.ury += slop + 0.5;
          115         fprintf(fp, "%s %d %d %d %d\n", keyword, (int)bbox.llx, (int)bbox.lly,(int)bbox.urx, (int)bbox.ury);
          116         bbox = ubbox;
          117     }        /* End if */
          118 
          119     resetbbox((fp == stdout) ? TRUE : FALSE);
          120 
          121 }   /* End of writebbox */
          122 
          123 /*****************************************************************************/
          124 void
          125 resetbbox(output)
          126 
          127     int                output;
          128 
          129 {
          130 
          131 /*
          132  *
          133  * Adds bbox to docbbox and resets bbox for the next page. Only update docbbox
          134  * if we really did output on the last page.
          135  *
          136  */
          137 
          138     if ( docbbox.set == TRUE ) {
          139         cover(docbbox.llx, docbbox.lly);
          140         cover(docbbox.urx, docbbox.ury);
          141     }        /* End if */
          142 
          143     if ( output == TRUE ) {
          144         docbbox = bbox;
          145         docbbox.set = TRUE;
          146     }        /* End if */
          147 
          148     bbox.set = FALSE;
          149 
          150 }   /* End of resetbbox */
          151 
          152 /*****************************************************************************/
          153 void
          154 scale(sx, sy)
          155 
          156     double        sx, sy;
          157 
          158 {
          159 
          160 /*
          161  *
          162  * Scales the default matrix.
          163  *
          164  */
          165 
          166     matrix1[0] = sx;
          167     matrix1[1] = 0;
          168     matrix1[2] = 0;
          169     matrix1[3] = sy;
          170     matrix1[4] = 0;
          171     matrix1[5] = 0;
          172 
          173     concat(matrix1);
          174 
          175 }   /* End of scale */
          176 
          177 /*****************************************************************************/
          178 void
          179 translate(tx, ty)
          180 
          181     double        tx, ty;
          182 
          183 {
          184 
          185 /*
          186  *
          187  * Translates the default matrix.
          188  *
          189  */
          190 
          191     matrix1[0] = 1.0;
          192     matrix1[1] = 0.0;
          193     matrix1[2] = 0.0;
          194     matrix1[3] = 1.0;
          195     matrix1[4] = tx;
          196     matrix1[5] = ty;
          197 
          198     concat(matrix1);
          199 
          200 }   /* End of translate */
          201 
          202 /*****************************************************************************/
          203 void
          204 rotate(angle)
          205 
          206     double        angle;
          207 
          208 {
          209 
          210 /*
          211  *
          212  * Rotates by angle degrees.
          213  *
          214  */
          215 
          216     angle *= 3.1416 / 180;
          217 
          218     matrix1[0] = matrix1[3] = cos(angle);
          219     matrix1[1] = sin(angle);
          220     matrix1[2] = -matrix1[1];
          221     matrix1[4] = 0.0;
          222     matrix1[5] = 0.0;
          223 
          224     concat(matrix1);
          225 
          226 }   /* End of rotate */
          227 
          228 /*****************************************************************************/
          229 
          230 void
          231 concat(m1)
          232 
          233     double        m1[];
          234 
          235 {
          236 
          237     double        m2[6];
          238 
          239 /*
          240  *
          241  * Replaces the ctm[] by the result of the matrix multiplication m1[] x ctm[].
          242  *
          243  */
          244 
          245     m2[0] = ctm[0];
          246     m2[1] = ctm[1];
          247     m2[2] = ctm[2];
          248     m2[3] = ctm[3];
          249     m2[4] = ctm[4];
          250     m2[5] = ctm[5];
          251 
          252     ctm[0] = m1[0] * m2[0] + m1[1] * m2[2];
          253     ctm[1] = m1[0] * m2[1] + m1[1] * m2[3];
          254     ctm[2] = m1[2] * m2[0] + m1[3] * m2[2];
          255     ctm[3] = m1[2] * m2[1] + m1[3] * m2[3];
          256     ctm[4] = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
          257     ctm[5] = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
          258 
          259 }   /* End of concat */
          260 
          261 /*****************************************************************************/