plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

bbox.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 /*****************************************************************************/