Esempio n. 1
0
void
plD_line_ps(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
{
    PSDev *dev = (PSDev *) pls->dev;
    PLINT x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;

/* Rotate by 90 degrees */

    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x1, &y1);
    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x2, &y2);

    if (x1 == dev->xold && y1 == dev->yold && dev->ptcnt < 40) {
	if (pls->linepos + 12 > LINELENGTH) {
	    putc('\n', OF);
	    pls->linepos = 0;
	}
	else
	    putc(' ', OF);

	sprintf(outbuf, "%d %d D", x2, y2);
	dev->ptcnt++;
	pls->linepos += 12;
    }
    else {
	fprintf(OF, " Z\n");
	pls->linepos = 0;

	if (x1 == x2 && y1 == y2) /* must be a single dot, draw a circle */
	  sprintf(outbuf, "%d %d A", x1, y1);
	else
	  sprintf(outbuf, "%d %d M %d %d D", x1, y1, x2, y2);
	dev->llx = MIN(dev->llx, x1);
	dev->lly = MIN(dev->lly, y1);
	dev->urx = MAX(dev->urx, x1);
	dev->ury = MAX(dev->ury, y1);
	dev->ptcnt = 1;
	pls->linepos += 24;
    }
    dev->llx = MIN(dev->llx, x2);
    dev->lly = MIN(dev->lly, y2);
    dev->urx = MAX(dev->urx, x2);
    dev->ury = MAX(dev->ury, y2);

    fprintf(OF, "%s", outbuf);
    pls->bytecnt += 1 + strlen(outbuf);
    dev->xold = x2;
    dev->yold = y2;
}
Esempio n. 2
0
static void
fill_polygon(PLStream *pls)
{
    PSDev *dev = (PSDev *) pls->dev;
    PLINT n, ix = 0, iy = 0;
    PLINT x, y;

    fprintf(OF, " Z\n");

    for (n = 0; n < pls->dev_npts; n++) {
	x = pls->dev_x[ix++];
	y = pls->dev_y[iy++];

/* Rotate by 90 degrees */

	plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &x, &y);

/* First time through start with a x y moveto */

	if (n == 0) {
	    sprintf(outbuf, "%d %d M", x, y);
	    dev->llx = MIN(dev->llx, x);
	    dev->lly = MIN(dev->lly, y);
	    dev->urx = MAX(dev->urx, x);
	    dev->ury = MAX(dev->ury, y);
	    fprintf(OF, "%s", outbuf);
	    pls->bytecnt += strlen(outbuf);
	    continue;
	}

	if (pls->linepos + 21 > LINELENGTH) {
	    putc('\n', OF);
	    pls->linepos = 0;
	}
	else
	    putc(' ', OF);

	pls->bytecnt++;

	sprintf(outbuf, "%d %d D", x, y);
	dev->llx = MIN(dev->llx, x);
	dev->lly = MIN(dev->lly, y);
	dev->urx = MAX(dev->urx, x);
	dev->ury = MAX(dev->ury, y);

	fprintf(OF, "%s", outbuf);
	pls->bytecnt += strlen(outbuf);
	pls->linepos += 21;
    }
    dev->xold = PL_UNDEFINED;
    dev->yold = PL_UNDEFINED;
    fprintf(OF, " F ");
}
Esempio n. 3
0
void
plD_line_ljii(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
{
    PLDev *dev = (PLDev *) pls->dev;
    int i;
    int xx1 = x1a, yy1 = y1a, xx2 = x2a, yy2 = y2a;
    PLINT x1b, y1b, x2b, y2b;
    PLFLT length, fx, fy, dx, dy;

/* Take mirror image, since PCL expects (0,0) to be at top left */

    yy1 = dev->ymax - (yy1 - dev->ymin);
    yy2 = dev->ymax - (yy2 - dev->ymin);

/* Rotate by 90 degrees */

    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx1, &yy1);
    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx2, &yy2);

    x1b = xx1, x2b = xx2, y1b = yy1, y2b = yy2;
    length = (PLFLT) sqrt((double)
		     ((x2b - x1b) * (x2b - x1b) + (y2b - y1b) * (y2b - y1b)));

    if (length == 0.)
	length = 1.;
    dx = (xx2 - xx1) / length;
    dy = (yy2 - yy1) / length;

    fx = xx1;
    fy = yy1;
    setpoint((PLINT) xx1, (PLINT) yy1);
    setpoint((PLINT) xx2, (PLINT) yy2);

    for (i = 1; i <= (int) length; i++)
	setpoint((PLINT) (fx += dx), (PLINT) (fy += dy));
}
Esempio n. 4
0
void
plD_line_ljiip(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
{
    PLDev *dev = (PLDev *) pls->dev;
    int xx1 = x1a, yy1 = y1a, xx2 = x2a, yy2 = y2a;
    int abs_dx, abs_dy, dx, dy, incx, incy;
    int i, j, width, residual;
    PLFLT tmp;

    width = MIN(pls->width, MAX_WID);
 
/* Take mirror image, since PCL expects (0,0) to be at top left */

    yy1 = dev->ymax - (yy1 - dev->ymin);
    yy2 = dev->ymax - (yy2 - dev->ymin);

/* Rotate by 90 degrees */

    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx1, &yy1);
    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx2, &yy2);

    dx = xx2 - xx1;
    dy = yy2 - yy1;

    if (dx < 0) {
	abs_dx = -dx;
	incx = -1;
    }
    else {
	abs_dx = dx;
	incx = 1;
    }
    if (dy < 0) {
	abs_dy = -dy;
	incy = -1;
    }
    else {
	abs_dy = dy;
	incy = 1;
    }

/* make pixel width narrower for diag lines */

    if (abs_dy <= abs_dx) {
	if (abs_dx == 0)
	    tmp = 1.0;
	else
	    tmp = 1.0 - (PLFLT) abs_dy / abs_dx;
    }
    else {
	tmp = 1.0 - (PLFLT) abs_dx / abs_dy;
    }

    width = floor(0.5 + width * (tmp*tmp*tmp*(1.0-0.707107) + 0.707107));

    if (width < 1) width = 1;
    if (width > 1) {
	for (i = 0; i < width; i++) {
	    for (j = 0; j < width; j++) {
	        setpoint((PLINT) (xx1+i), (PLINT) (yy1+j));
	        setpoint((PLINT) (xx2+i), (PLINT) (yy2+j));
	    }
	}
    }
    if (abs_dx >= abs_dy) {
	residual = -(abs_dx >> 1);
	if (width == 1) {
            for (i = 0; i <= abs_dx; i++, xx1 += incx) {
                setpoint((PLINT) (xx1), (PLINT) (yy1));
                if ((residual += abs_dy) >= 0) {
                    residual -= abs_dx;
                    yy1 += incy;
                }
            }
	}
	else {
	    for (i = 0; i <= abs_dx; i++, xx1 += incx) {
	       for (j = 0; j < width; j++) {
	           setpoint((PLINT) (xx1), (PLINT) (yy1+j));
	           setpoint((PLINT) (xx1+width-1), (PLINT) (yy1+j));
	       }
	       if ((residual += abs_dy) >= 0) {
		   residual -= abs_dx;
		   yy1 += incy;
	       }
	    }
	}
    }
Esempio n. 5
0
void
proc_str (PLStream *pls, EscText *args)
{
  PLFLT *t = args->xform, tt[4]; /* Transform matrices */
  PLFLT theta;  /* Rotation angle and shear from the matrix */
  PLFLT ft_ht, offset; /* Font height and offset */
  PLFLT cs,sn,l1,l2;
  PSDev *dev = (PSDev *) pls->dev;
  char *font, esc;
  /* Be generous.  Used to store lots of font changes which take
   * 3 characters per change.*/
  #define PROC_STR_STRING_LENGTH 1000
  unsigned char *strp, str[PROC_STR_STRING_LENGTH], *cur_strp, 
     cur_str[PROC_STR_STRING_LENGTH];
  float font_factor = 1.4;
  PLINT clxmin, clxmax, clymin, clymax; /* Clip limits */
  PLINT clipx[4],clipy[4]; /* Current clip limits */

  PLFLT scale = 1., up = 0.; /* Font scaling and shifting parameters */

  int i=0; /* String index */

  short text_len;

   /* unicode only! so test for it. */
   if (args->unicode_array_len>0)
     {
	int j,s,f;
	char  *fonts[PROC_STR_STRING_LENGTH];
	int nlookup;
	const Unicode_to_Type1_table *lookup;
	const PLUNICODE *cur_text;
	const PLUNICODE *cur_text_limit;
	PLUNICODE fci;
	/* translate from unicode into type 1 font index. */
	/*
	 * Choose the font family, style, variant, and weight using
	 * the FCI (font characterization integer).
	 */

	plgesc(&esc);
	plgfci(&fci);
	font = plP_FCI2FontName(fci, Type1Lookup, N_Type1Lookup);
	if (font == NULL) {
	   fprintf(stderr, "fci = 0x%x, font name pointer = NULL \n", fci);
	   plabort("proc_str: FCI inconsistent with Type1Lookup; "
		   "internal PLplot error");
	   return;
	}
	/*pldebug("proc_str", "fci = 0x%x, font name = %s\n", fci, font);*/
	if (!strcmp(font, "Symbol")) {
	   nlookup = number_of_entries_in_unicode_to_symbol_table;
	   lookup = unicode_to_symbol_lookup_table;
	}
	else {
	   nlookup = number_of_entries_in_unicode_to_standard_table;
	   lookup = unicode_to_standard_lookup_table;
	}
	cur_text =  args->unicode_array;
	for (f=s=j=0; j < args->unicode_array_len; j++) {
	   if (cur_text[j] & PL_FCI_MARK) {
	      /* process an FCI by saving it and escaping cur_str
	       * with an escff to make it a 2-character escape
	       * that is not used in legacy Hershey code
	       */
	      if ((f < PROC_STR_STRING_LENGTH) && (s+3 < PROC_STR_STRING_LENGTH)) {
		 fonts[f] = plP_FCI2FontName(cur_text[j], Type1Lookup, N_Type1Lookup);
		 if (fonts[f] == NULL) {
		    fprintf(stderr, "string-supplied FCI = 0x%x, font name pointer = NULL \n", cur_text[j]);
		    plabort("proc_str: string-supplied FCI inconsistent with Type1Lookup;");
		    return;
		 }
		 /*pldebug("proc_str", "string-supplied FCI = 0x%x, font name = %s\n", cur_text[j], fonts[f]);*/
		 if (!strcmp(fonts[f++], "Symbol")) {
		    lookup = unicode_to_symbol_lookup_table;
		    nlookup = number_of_entries_in_unicode_to_symbol_table;
		 }
		 else {
		    lookup = unicode_to_standard_lookup_table;
		    nlookup = number_of_entries_in_unicode_to_standard_table;
		 }
		 cur_str[s++] = esc;
		 cur_str[s++] = 'f';
		 cur_str[s++] = 'f';
	      }
	   }
	   else if (s+1 < PROC_STR_STRING_LENGTH) {
	      cur_str[s++] = plunicode2type1(cur_text[j], lookup, nlookup);
	      /*pldebug("proc_str", "unicode = 0x%x, type 1 code = %d\n",
	                cur_text[j], cur_str[j]);*/
	   }
	}
	cur_str[s] = '\0';
	
	/* finish previous polyline */
	
	dev->xold = PL_UNDEFINED;
	dev->yold = PL_UNDEFINED;
	
	/* Determine the font height */
	ft_ht = pls->chrht * 72.0/25.4; /* ft_ht in points, ht is in mm */
	
	
	/* The transform matrix has only rotations and shears; extract them */
	theta = acos(t[0]) * 180. / PI;  /* Determine the rotation (in degrees)... */
	if (t[2] < 0.) theta *= -1.;     /* ... and sign ... */
	cs = cos(theta*PI/180.);
	sn = sin(theta*PI/180.);
	tt[0] = t[0]*cs + t[2]*sn;
	tt[1] = t[1]*cs + t[3]*sn;
	tt[2] = -t[0]*sn + t[2]*cs;
	tt[3] = -t[1]*sn + t[3]*cs;
	
	/* 
	 * Reference point conventions:
	 *   If base = 0, it is aligned with the center of the text box
	 *   If base = 1, it is aligned with the baseline of the text box
	 *   If base = 2, it is aligned with the top of the text box
	 *
	 * Currently plplot only uses base=0
	 * Postscript uses base=1
	 *
	 * We must calculate the difference between the two and apply the offset.
	 */ 
	
	if (args->base == 2) /* not supported by plplot */
	  offset = ENLARGE * ft_ht / 2.; /* half font height */
	else if (args->base == 1)
	  offset = 0.;
	else
	  offset = -ENLARGE * ft_ht / 2.;
	
	args->y += offset*cos(theta*PI/180.);
	args->x -= offset*sin(theta*PI/180.);
	
	/* Apply plplot difilt transformations */
	difilt(&args->x, &args->y, 1, &clxmin, &clxmax, &clymin, &clymax);
	
	/* ps driver is rotated by default */
	plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, 
		 &(args->x), &(args->y));
	
	/* Determine the adjustment for page orientation */
	theta += 90. - 90.*pls->diorot;
	
	/* Output */
	/* Set clipping */
	clipx[0]=pls->clpxmi;
	clipx[2]=pls->clpxma;
	clipy[0]=pls->clpymi;
	clipy[2]=pls->clpyma;
	clipx[1]=clipx[2];
	clipy[1]=clipy[0];
	clipx[3]=clipx[0];
	clipy[3]=clipy[2];
	difilt(clipx, clipy, 4, &clxmin, &clxmax, &clymin, &clymax);
	plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
	         &clipx[0], &clipy[0]);
	plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
	         &clipx[1], &clipy[1]);
	plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
	         &clipx[2], &clipy[2]);
	plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax,
	         &clipx[3], &clipy[3]);
	fprintf(OF," gsave %d %d %d %d %d %d %d %d CL\n",clipx[0],clipy[0],clipx[1],clipy[1],clipx[2],clipy[2],clipx[3],clipy[3]);
	
	/* move to string reference point */
	fprintf(OF, " %d %d M\n", args->x, args->y );
	
	/* Save the current position and set the string rotation */
	fprintf(OF, "gsave %.3f R\n",theta);
	
	/* Purge escape sequences from string, so that postscript can find it's 
	 * length.  The string length is computed with the current font, and can
	 * thus be wrong if there are font change escape sequences in the string 
	 */
	
	esc_purge(str, cur_str);
	
	fprintf(OF, "/%s %.3f SF\n", font,font_factor * ENLARGE * ft_ht);    
	
	/* Output string, while escaping the '(', ')' and '\' characters.
	 * this string is output for measurement purposes only.
	 */
	fprintf(OF, "%.3f (", - args->just);
	while (str[i]!='\0') {
	   if (str[i]=='(' || str[i]==')' || str[i]=='\\')
	     fprintf(OF,"\\%c",str[i]);
	   else
	     fprintf(OF,"%c",str[i]);
	   i++;
	}
	fprintf(OF,") SW\n");
	
	
	/* Parse string for PLplot escape sequences and print everything out */
	
	cur_strp = cur_str;
	f = 0;
	do {
	   
	   strp = str;
	   
	   if (*cur_strp == esc) {
	      cur_strp++;
	      
	      if (*cur_strp == esc) { /* <esc><esc> */
		 *strp++ = *cur_strp++;
	      }
	      else if (*cur_strp == 'f') {
		 cur_strp++;
		 if (*cur_strp++ != 'f') {
		    /* escff occurs because of logic above. But any suffix
		     * other than "f" should never happen. */
		    plabort("proc_str, internal PLplot logic error;"
			    "wrong escf escape sequence");
		    return;
		 }
		 font = fonts[f++];
		 /*pldebug("proc_str", "string-specified fci = 0x%x, font name = %s\n", fci, font);*/
		 continue;
	      }
	      else switch (*cur_strp++) {
		 
	       case 'd':
	       case 'D':
		 if(up>0.) scale *= 1.25;  /* Subscript scaling parameter */
		 else scale *= 0.8;  /* Subscript scaling parameter */
		 up -= font_factor * ENLARGE * ft_ht / 2.;
		 break;
		 
	       case 'u':
	       case 'U':
		 if(up<0.) scale *= 1.25;  /* Subscript scaling parameter */
		 else scale *= 0.8;  /* Subscript scaling parameter */
		 up += font_factor * ENLARGE * ft_ht / 2.;
		 break;
		 
		 /* ignore the next sequences */
		 
	       case '+':
	       case '-':
	       case 'b':
	       case 'B':
		 plwarn("'+', '-', and 'b/B' text escape sequences not processed.");
		 break;
	      }
	   }
	   
	   /* copy from current to next token, adding a postscript escape 
	    * char '\' if necessary 
	    */
	   while(*cur_strp && *cur_strp != esc) {
	      if (*cur_strp == '(' || *cur_strp == ')' || *cur_strp == '\\')
		*strp++ = '\\';
	      *strp++ = *cur_strp++;
	   }
	   *strp = '\0';
	   
	   if(fabs(up)<0.001) up = 0.; /* Watch out for small differences */
	   
	   /* Apply the scaling and the shear */
	   fprintf(OF, "/%s [%.3f %.3f %.3f %.3f 0 0] SF\n",
		   font,
		   tt[0]*font_factor * ENLARGE * ft_ht * scale,
		   tt[2]*font_factor * ENLARGE * ft_ht * scale,
		   tt[1]*font_factor * ENLARGE * ft_ht * scale,
		   tt[3]*font_factor * ENLARGE * ft_ht * scale);
	   
	   /* if up/down escape sequences, save current point and adjust baseline;
	    * take the shear into account */
	   if(up!=0.) fprintf(OF, "gsave %.3f %.3f rmoveto\n",up*tt[1],up*tt[3]);
	   
	   /* print the string */
	   fprintf(OF, "(%s) show\n", str);  
	   
	   /* back to baseline */
	   if (up!=0.) fprintf(OF, "grestore (%s) stringwidth rmoveto\n", str);
	   
	}while(*cur_strp);
	
	fprintf(OF, "grestore\n");
	fprintf(OF, "grestore\n");
	
	/*
	 * keep driver happy -- needed for background and orientation.
	 * arghhh! can't calculate it, as I only have the string reference
	 * point, not its extent!
	 * Still a hack - but at least it takes into account the string
	 * length and justification. Character width is assumed to be
	 * 0.6 * character height. Add on an extra 1.5 * character height 
	 * for safety. 
	 */
	cs = cos(theta/180.*PI);
	sn = sin(theta/180.*PI);
	l1 = -i*args->just;
	l2 = i*(1.-args->just);
	/* Factor of 0.6 is an empirical fudge to convert character 
	 * height to average character width */
	l1 *= 0.6;
	l2 *= 0.6;
	
	dev->llx = MIN(dev->llx, args->x + (MIN(l1*cs,l2*cs)-1.5) * font_factor * ft_ht * ENLARGE );
	dev->lly = MIN(dev->lly, args->y + (MIN(l1*sn,l2*sn)-1.5) * font_factor * ft_ht * ENLARGE );
	dev->urx = MAX(dev->urx, args->x + (MAX(l1*cs,l2*cs)+1.5) * font_factor * ft_ht * ENLARGE );
	dev->ury = MAX(dev->ury, args->y + (MAX(l1*sn,l2*sn)+1.5) * font_factor * ft_ht * ENLARGE );

     }
}