/* 
  HPGL command IW (Input Window)
*/
int hpgs_reader_do_IW (hpgs_reader *reader)
{
  // get default input point.
  hpgs_point ll;
  hpgs_point ur;
  hpgs_point p;

  if (hpgs_reader_checkpath(reader)) return -1;

  while (reader->clipsave_depth > 0)
    {
      hpgs_cliprestore(reader->device);
      --reader->clipsave_depth;
    }

  if (reader->eoc) return 0;

  // read input point
  if (hpgs_reader_read_point(reader,&ll,0)) return -1;
  if (hpgs_reader_read_point(reader,&ur,0)) return -1;

  if (hpgs_clipsave(reader->device)) return -1;
  ++reader->clipsave_depth;

  if (hpgs_newpath(reader->device)) return -1;

  hpgs_matrix_xform (&p,&reader->total_matrix,&ll);
  if (hpgs_moveto(reader->device,&p)) return -1;
  p.x = ll.x;
  p.y = ur.y;
  hpgs_matrix_xform (&p,&reader->total_matrix,&p);
  if (hpgs_lineto(reader->device,&p)) return -1;
  hpgs_matrix_xform (&p,&reader->total_matrix,&ur);
  if (hpgs_lineto(reader->device,&p)) return -1;
  p.x = ur.x;
  p.y = ll.y;
  hpgs_matrix_xform (&p,&reader->total_matrix,&p);
  if (hpgs_lineto(reader->device,&p)) return -1;
  if (hpgs_closepath(reader->device)) return -1;
  if (hpgs_clip(reader->device,HPGS_TRUE)) return -1; 

  reader->have_current_point = 0;

  return hpgs_newpath(reader->device);
}
Beispiel #2
0
/*!
   Transforms the given bounding box \c bb with the matrix \c m.
   The result is the enclosing bounding box of the transformed 
   rectangle of the bounding box and is stored in \c res.
   The pointers \c bb and \c res may point to the same memory location.
 */
void hpgs_matrix_xform_bbox(hpgs_bbox *res,
                            const hpgs_matrix *m, const hpgs_bbox *bb)
{
  hpgs_point ll = { bb->llx, bb->lly };
  hpgs_point ur = { bb->urx, bb->ury };

  hpgs_point lr = { bb->llx, bb->ury };
  hpgs_point ul = { bb->urx, bb->lly };

  hpgs_matrix_xform(&ll,m,&ll);
  hpgs_matrix_xform(&ur,m,&ur);

  hpgs_matrix_xform(&lr,m,&lr);
  hpgs_matrix_xform(&ul,m,&ul);

  res->llx = HPGS_MIN(HPGS_MIN(ll.x,ur.x),HPGS_MIN(lr.x,ul.x));
  res->lly = HPGS_MIN(HPGS_MIN(ll.y,ur.y),HPGS_MIN(lr.y,ul.y));

  res->urx = HPGS_MAX(HPGS_MAX(ll.x,ur.x),HPGS_MAX(lr.x,ul.x));
  res->ury = HPGS_MAX(HPGS_MAX(ll.y,ur.y),HPGS_MAX(lr.y,ul.y));
}
/* 
  Change the page matrix according to this content bounding box.
*/
void hpgs_reader_set_page_matrix (hpgs_reader *reader, const hpgs_bbox *bb)
{
  hpgs_bbox rbb;
  double xscale,yscale;
  hpgs_point rcp;

  hpgs_matrix_ixform(&rcp,&reader->current_point,&reader->page_matrix);
  
  // save the content bounding box for propagating it to the
  // page_asset function.
  reader->content_bbox = *bb;

  if  (reader->page_mode == 0)
    {
      reader->page_bbox = *bb;
      hpgs_matrix_set_identity(&reader->page_matrix);
      reader->page_scale = 1.0;
      goto restore_cb;
    }

  reader->page_matrix.mxx =  cos(reader->page_angle * M_PI / 180.0);
  reader->page_matrix.mxy = -sin(reader->page_angle * M_PI / 180.0);

  reader->page_matrix.myx =  sin(reader->page_angle * M_PI / 180.0);
  reader->page_matrix.myy =  cos(reader->page_angle * M_PI / 180.0);
  
  reader->page_matrix.dx = 0.0;
  reader->page_matrix.dy = 0.0;

  if (reader->page_mode == 2) // dynamic page.
    {
      hpgs_matrix_xform_bbox(&rbb,&reader->page_matrix,bb);

      reader->page_bbox.llx = 0.0;
      reader->page_bbox.lly = 0.0;

      reader->page_bbox.urx = (rbb.urx-rbb.llx) + 2.0 * reader->page_border;
      reader->page_bbox.ury = (rbb.ury-rbb.lly) + 2.0 * reader->page_border;

      reader->page_matrix.dx = reader->page_border - rbb.llx;
      reader->page_matrix.dy = reader->page_border - rbb.lly;

      // do we fit on the maximal page size?
      if ((reader->page_width <= 0.0 || reader->page_bbox.urx <= reader->page_width) &&
          (reader->page_height <= 0.0 || reader->page_bbox.ury <= reader->page_height) )
        {
          reader->page_scale = 1.0;
          goto restore_cb;
        }

      if (reader->page_bbox.urx > reader->page_width)
        xscale = reader->page_width/reader->page_bbox.urx;
      else
        xscale = 1.0;

      if (reader->page_bbox.ury> reader->page_height)
        yscale = reader->page_height/reader->page_bbox.ury;
      else
        yscale = 1.0;

      reader->page_scale = HPGS_MIN(xscale,yscale);

      double rscale = 0.0;
      double xx = 1.0;

      // transform the scale to a human-interceptable scale.
      do
        {
          xx *= 0.1;
          rscale = floor(reader->page_scale / xx);
        }
      while (rscale < 2.0);

      reader->page_scale = rscale * xx;

      reader->page_matrix.mxx *= reader->page_scale;
      reader->page_matrix.mxy *= reader->page_scale;

      reader->page_matrix.myx *= reader->page_scale;
      reader->page_matrix.myy *= reader->page_scale;

      reader->page_matrix.dx *= reader->page_scale;
      reader->page_matrix.dy *= reader->page_scale;

      reader->page_bbox.urx *= reader->page_scale;
      reader->page_bbox.ury *= reader->page_scale;

      goto restore_cb;
    }

  // fixed page.
  reader->page_bbox.llx = 0.0;
  reader->page_bbox.lly = 0.0;

  reader->page_bbox.urx = reader->page_width;
  reader->page_bbox.ury = reader->page_height;

  hpgs_matrix_xform_bbox(&rbb,&reader->page_matrix,bb);

  xscale = (reader->page_width - 2.0 * reader->page_border) / (rbb.urx-rbb.llx);
  yscale = (reader->page_height - 2.0 * reader->page_border) / (rbb.ury-rbb.lly);
  
  reader->page_scale = HPGS_MIN(xscale,yscale);

  reader->page_matrix.mxx *= reader->page_scale;
  reader->page_matrix.mxy *= reader->page_scale;
  
  reader->page_matrix.myx *= reader->page_scale;
  reader->page_matrix.myy *= reader->page_scale;
  
  if (reader->page_scale == xscale)
    {
      reader->page_matrix.dx = reader->page_border - reader->page_scale * rbb.llx;
      reader->page_matrix.dy =
        0.5 * (reader->page_height - reader->page_scale * (rbb.ury-rbb.lly)) - reader->page_scale * rbb.lly;
    }
  else
    {
      reader->page_matrix.dx = 
        0.5 * (reader->page_width - reader->page_scale * (rbb.urx-rbb.llx)) - reader->page_scale * rbb.llx;
      reader->page_matrix.dy = reader->page_border - reader->page_scale * rbb.lly;
    }

 restore_cb:
  hpgs_matrix_xform(&reader->current_point,&reader->page_matrix,&rcp);
}