/*! 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); }