/* <matrix> defaultmatrix <matrix> */ static int zdefaultmatrix(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_matrix mat; gs_defaultmatrix(igs, &mat); return write_matrix(op, &mat); }
int gs_initmatrix(gs_state * pgs) { gs_matrix imat; gs_defaultmatrix(pgs, &imat); update_ctm(pgs, imat.tx, imat.ty); set_ctm_only(pgs, imat); #ifdef DEBUG if (gs_debug_c('x')) dlprintf("[x]initmatrix:\n"), trace_ctm(pgs); #endif return 0; }
/* Get the default clipping box. */ int gx_default_clip_box(const gs_state * pgs, gs_fixed_rect * pbox) { register gx_device *dev = gs_currentdevice(pgs); gs_rect bbox; gs_matrix imat; int code; if (dev->ImagingBBox_set) { /* Use the ImagingBBox, relative to default user space. */ gs_defaultmatrix(pgs, &imat); bbox.p.x = dev->ImagingBBox[0]; bbox.p.y = dev->ImagingBBox[1]; bbox.q.x = dev->ImagingBBox[2]; bbox.q.y = dev->ImagingBBox[3]; } else { /* Use the MediaSize indented by the HWMargins, */ /* relative to unrotated user space adjusted by */ /* the Margins. (We suspect this isn't quite right, */ /* but the whole issue of "margins" is such a mess that */ /* we don't think we can do any better.) */ (*dev_proc(dev, get_initial_matrix)) (dev, &imat); /* Adjust for the Margins. */ imat.tx += dev->Margins[0] * dev->HWResolution[0] / dev->MarginsHWResolution[0]; imat.ty += dev->Margins[1] * dev->HWResolution[1] / dev->MarginsHWResolution[1]; bbox.p.x = dev->HWMargins[0]; bbox.p.y = dev->HWMargins[1]; bbox.q.x = dev->MediaSize[0] - dev->HWMargins[2]; bbox.q.y = dev->MediaSize[1] - dev->HWMargins[3]; } code = gs_bbox_transform(&bbox, &imat, &bbox); if (code < 0) return code; /* Round the clipping box so that it doesn't get ceilinged. */ pbox->p.x = fixed_rounded(float2fixed(bbox.p.x)); pbox->p.y = fixed_rounded(float2fixed(bbox.p.y)); pbox->q.x = fixed_rounded(float2fixed(bbox.q.x)); pbox->q.y = fixed_rounded(float2fixed(bbox.q.y)); return 0; }
/* * Update the transformations stored in the PCL state. This will also update * the device clipping region information in device and logical page space. * The text region margins are preserved. * * This routine should be called for: * * changes in the paper size * transition from page front to page back for duplexing * (this facility is not currently implemented) * change of left or top offset registration * change of logical page orientation * change of print direction * * The paper size, left/top offsets, logical page orientation, and print * direction should be set before this procedure is called. */ static void update_xfm_state( pcl_state_t * pcs, bool reset_initial ) { pcl_xfm_state_t * pxfmst = &(pcs->xfm_state); const pcl_paper_size_t * psize = pxfmst->paper_size; coord offset; gs_matrix pg2dev, pg2lp; gs_rect print_rect, dev_rect, text_rect; gs_point cur_pt; floatp loff = pxfmst->left_offset_cp; floatp toff = pxfmst->top_offset_cp; /* preserve the current point and text rectangle in logical page space */ if ( !reset_initial ) preserve_cap_and_margins(pcs, &cur_pt, &text_rect); /* get the page to device transformation */ gs_defaultmatrix(pcs->pgs, &pg2dev); /* * Get the logical to page space transformation, and the dimensions of the * logical page. * * NOT YET IMPLEMENT - if on back of a duplex page, change size of offsets * * if (duplex_back(pcs)) { * loff = -loff; * toff = -toff; * } */ pcl_make_rotation( pxfmst->lp_orient, (floatp)(psize->width), (floatp)(psize->height), &(pxfmst->lp2pg_mtx) ); pxfmst->lp2pg_mtx.tx += loff; pxfmst->lp2pg_mtx.ty += toff; if ( pcs->personality == rtl ) offset = 0; else offset = ( (pxfmst->lp_orient & 0x1) != 0 ? psize->offset_landscape : psize->offset_portrait ); /* we need an extra 1/10 inch on each side to support 80 characters vs. 78 at 10 cpi. Only apply to A4. */ if ( ( pcs->wide_a4 ) && (psize->width == 59520) && (psize->height == 84168) ) offset -= inch2coord(1.0/10.0); gs_matrix_translate( &(pxfmst->lp2pg_mtx), (floatp)offset, 0.0, &(pxfmst->lp2pg_mtx) ); if ((pxfmst->lp_orient & 0x1) != 0) { pxfmst->lp_size.x = psize->height - 2 * offset; pxfmst->lp_size.y = psize->width; } else { pxfmst->lp_size.x = psize->width - 2 * offset; pxfmst->lp_size.y = psize->height; } /* then the logical page to device transformation */ gs_matrix_multiply(&(pxfmst->lp2pg_mtx), &pg2dev, &(pxfmst->lp2dev_mtx)); pg2dev.ty = round(pg2dev.ty); pg2dev.tx = round(pg2dev.tx); pxfmst->lp2dev_mtx.tx = round(pxfmst->lp2dev_mtx.tx); pxfmst->lp2dev_mtx.ty = round(pxfmst->lp2dev_mtx.ty); /* the "pseudo page direction to logical page/device transformations */ pcl_make_rotation( pxfmst->print_dir, (floatp)pxfmst->lp_size.x, (floatp)pxfmst->lp_size.y, &(pxfmst->pd2lp_mtx) ); gs_matrix_multiply( &(pxfmst->pd2lp_mtx), &(pxfmst->lp2dev_mtx), &(pxfmst->pd2dev_mtx) ); /* calculate the print direction page size */ if ((pxfmst->print_dir) & 0x1) { pxfmst->pd_size.x = pxfmst->lp_size.y; pxfmst->pd_size.y = pxfmst->lp_size.x; } else pxfmst->pd_size = pxfmst->lp_size; { gx_device *pdev = gs_currentdevice(pcs->pgs); /* We must not set up a clipping region beyond the hardware margins of the device, but the pcl language definition requires hardware margins to be 1/6". We set all margins to the the maximum of the PCL language defined 1/6" and the actual hardware margin. If 1/6" is not available pcl will not work correctly all of the time. */ if ( pcs->personality == rtl ) { print_rect.p.x = inch2coord(pdev->HWMargins[0] / 72.0); print_rect.p.y = inch2coord(pdev->HWMargins[1]) / 72.0; print_rect.q.x = psize->width - inch2coord(pdev->HWMargins[2] / 72.0); print_rect.q.y = psize->height - inch2coord(pdev->HWMargins[3] / 72.0); } else { print_rect.p.x = max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[0] / 72.0)); print_rect.p.y = max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[1]) / 72.0); print_rect.q.x = psize->width - max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[2] / 72.0)); print_rect.q.y = psize->height - max(PRINTABLE_MARGIN_CP, inch2coord(pdev->HWMargins[3] / 72.0)); } pcl_transform_rect(pcs->memory, &print_rect, &dev_rect, &pg2dev); pxfmst->dev_print_rect.p.x = float2fixed(round(dev_rect.p.x)); pxfmst->dev_print_rect.p.y = float2fixed(round(dev_rect.p.y)); pxfmst->dev_print_rect.q.x = float2fixed(round(dev_rect.q.x)); pxfmst->dev_print_rect.q.y = float2fixed(round(dev_rect.q.y)); } pcl_invert_mtx(&(pxfmst->lp2pg_mtx), &pg2lp); pcl_transform_rect(pcs->memory, &print_rect, &(pxfmst->lp_print_rect), &pg2lp); /* restablish the current point and text region */ if ( !reset_initial ) restore_cap_and_margins(pcs, &cur_pt, &text_rect); /* * No need to worry about pat_orient or pat_ref_pt; these will always * be recalculated just prior to use. */ }