/* 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); }
/*! Contructs a HPGL reader on the heap using the given input device \c in and the given output vector drawing device \c dev. The argument \c multipage specifies, whether the reader processes more than one page. The argument \c v specifies the verbosity of the HPGL reader. A value of 0 forces the reader to not report anything to \c hpgs_log(). Value of 1 or 2 give diagnostics output to \c hpgs_log() with increasing volume. You do not have to call neither \c hpgs_close on \c in nor \c hpgs_destroy on \c dev. In the case of an error, a null pointer is returned. This only happens, if the system is out of memory. */ hpgs_reader *hpgs_new_reader(hpgs_istream *in, hpgs_device *dev, hpgs_bool multipage, int v) { int i; hpgs_reader *ret = (hpgs_reader *)malloc(sizeof(hpgs_reader)); if (!ret) { hpgs_istream_close(in); if (dev) hpgs_device_destroy(dev); return 0; } ret->in = in; ret->device = dev; ret->verbosity = v; ret->lw_factor = 1.0; ret->plotsize_device = 0; ret->current_page = multipage ? 1 : -1; hpgs_matrix_set_identity(&ret->page_matrix); ret->page_scale = 1.0; ret->page_bbox.llx = 0.0; ret->page_bbox.lly = 0.0; ret->page_bbox.urx = 33600.0 * HP_TO_PT; ret->page_bbox.ury = 47520.0 * HP_TO_PT; ret->content_bbox = ret->page_bbox; ret->page_asset_ctxt = 0; ret->page_asset_func = 0; ret->frame_asset_ctxt = 0; ret->frame_asset_func = 0; ret->page_mode=0; ret->page_width = 0.0; ret->page_height = 0.0; ret->page_angle = 0.0; ret->page_border = 0.0; ret->pen_widths = NULL; ret->pen_colors = NULL; ret->poly_buffer = NULL; for (i=0;i<8;++i) ret->pcl_raster_data[i] = 0; ret->pcl_image=0; ret->png_dump_filename=0; ret->png_dump_count=0; ret->pcl_i_palette=-1; ret->interrupted = HPGS_FALSE; hpgs_reader_set_defaults (ret); return ret; }