void gx_forward_get_initial_matrix(gx_device * dev, gs_matrix * pmat) { gx_device_forward * const fdev = (gx_device_forward *)dev; gx_device *tdev = fdev->target; if (tdev == 0) gx_default_get_initial_matrix(dev, pmat); else dev_proc(tdev, get_initial_matrix)(tdev, pmat); }
/* we only do it if Ghostview is active. */ static void x_get_initial_matrix(gx_device * dev, gs_matrix * pmat) { gx_device_X *xdev = (gx_device_X *) dev; if (!xdev->ghostview) { gx_default_get_initial_matrix(dev, pmat); return; } pmat->xx = xdev->initial_matrix.xx; pmat->xy = xdev->initial_matrix.xy; pmat->yx = xdev->initial_matrix.yx; pmat->yy = xdev->initial_matrix.yy; pmat->tx = xdev->initial_matrix.tx; pmat->ty = xdev->initial_matrix.ty; }
/* modified from gdevsppr.c. */ static void fmlbp_get_initial_matrix(gx_device *dev, gs_matrix *pmat) { gx_default_get_initial_matrix(dev, pmat); pmat->tx -= (dev->l_margin * dev->x_pixels_per_inch); pmat->ty -= (dev->t_margin * dev->y_pixels_per_inch); }
void eprn_get_initial_matrix(gx_device *device, gs_matrix *mptr) { eprn_Device *dev = (eprn_Device *)device; float /* The following two arrays are oriented w.r.t. pixmap device space, i.e., the index 0 refers to the x coordinate (horizontal) and the index 1 to the y coordinate (vertical) in pixmap device space. */ extension[2], /* media extension in pixels */ pixels_per_bp[2]; /* resolution */ int j, quarters; #ifdef EPRN_TRACE if_debug0(EPRN_TRACE_CHAR, "! eprn_get_initial_matrix()...\n"); #endif /* We need 'default_orientation' and also the margins. */ if (dev->eprn.code == ms_none) { #ifdef EPRN_TRACE if_debug0(EPRN_TRACE_CHAR, "! eprn_get_initial_matrix(): code is still ms_none.\n"); #endif if (eprn_set_page_layout(dev) != 0) eprintf(" Processing can't be stopped at this point although this error " "occurred.\n"); /* The current function has a signature without the ability to signal an error condition. */ } quarters = dev->eprn.default_orientation + (dev->MediaSize[0] <= dev->MediaSize[1]? 0: 1); /* Number of quarter-circle rotations by +90 degrees necessary to obtain default user space starting with the y axis upwards in pixmap device space. It's not documented, but 'MediaSize' is the requested "PageSize" page device parameter value and hence is to be interpreted in default (not default default!) user space. The condition above therefore tests whether landscape orientation has been requested. */ /* Soft tumble option: rotate default user space by 180 degrees on every second page */ if (dev->eprn.soft_tumble && dev->ShowpageCount % 2 != 0) quarters += 2; /* Prepare auxiliary data */ for (j = 0; j < 2; j++) pixels_per_bp[j] = dev->HWResolution[j]/BP_PER_IN; /* 'HWResolution[]' contains the standard PostScript page device parameter 'HWResolution' which is defined in pixels per inch with respect to device space. */ if (quarters % 2 == 0) { /* Default user space and pixmap device space agree in what is "horizontal" and what is "vertical". */ extension[0] = dev->MediaSize[0]; extension[1] = dev->MediaSize[1]; } else { extension[0] = dev->MediaSize[1]; extension[1] = dev->MediaSize[0]; } /* Convert from bp to pixels: */ for (j = 0; j < 2; j++) extension[j] *= pixels_per_bp[j]; /* Note that we are using the user-specified extension of the sheet, not the "official" one we could obtain in most cases from 'size'. */ switch (quarters % 4) { case 0: /* The y axis of default user space points upwards in pixmap device space. The CTM is uniquely characterized by the following mappings from default user space to pixmap device space: (0, 0) -> (0, height in pixels) (width in bp, 0) -> (width in pixels, height in pixels) (0, height in bp) -> (0, 0) 'width' and 'height' refer to the sheet's extension as seen from pixmap device space, i.e., width in pixels == extension[0] and height in pixels == extension[1]. From the PLR we find that the CTM is a PostScript matrix [a b c d tx ty] used for mapping user space coordinates (x, y) to device space coordinates (x', y') as follows: x' = a*x + c*y + tx y' = b*x + d*y + ty Ghostscript's matrix type 'gs_matrix' writes its structure components 'xx' etc. in storage layout order into a PostScript matrix (see write_matrix() in iutil.c), hence we obtain by comparison with gsmatrix.h the PostScript matrix [ xx xy yx yy tx ty ]. The correspondence can also be seen by comparison of the equations above with the code in gs_point_transform() in gsmatrix.c. It would, however, still be reassuring to have a corresponding statement in ghostscript's documentation. */ gx_default_get_initial_matrix(device, mptr); /* Of course, I could also set this directly: mptr->xx = pixels_per_bp[0]; mptr->xy = 0; mptr->yx = 0; mptr->yy = -pixels_per_bp[1]; mptr->tx = 0; mptr->ty = extension[1]; Doing it in this way is, however, more stable against dramatic changes in ghostscript. */ break; case 1: /* The y axis of default user space points to the left in pixmap device space. The CTM is uniquely characterized by the following mappings from default user space to pixmap device space: (0, 0) -> (width in pixels, height in pixels) (height in bp, 0) -> (width in pixels, 0) (0, width in bp) -> (0, height in pixels) */ mptr->xx = 0; mptr->xy = -pixels_per_bp[1]; mptr->yx = -pixels_per_bp[0]; mptr->yy = 0; mptr->tx = extension[0]; mptr->ty = extension[1]; break; case 2: /* The y axis of default user space points downwards in pixmap device space. The CTM is uniquely characterized by the following mappings from default user space to pixmap device space: (0, 0) -> (width in pixels, 0) (width in bp, 0) -> (0, 0) (0, height in bp) -> (width in pixels, height in pixels) */ mptr->xx = -pixels_per_bp[0]; mptr->xy = 0; mptr->yx = 0; mptr->yy = pixels_per_bp[1]; mptr->tx = extension[0]; mptr->ty = 0; break; case 3: /* The y axis of default user space points to the right in pixmap device space. The CTM is uniquely characterized by the following mappings from default user space to pixmap device space: (0, 0) -> (0, 0) (height in bp, 0) -> (0, height in pixels) (0, width in bp) -> (width in pixels, 0) */ mptr->xx = 0; mptr->xy = pixels_per_bp[1]; mptr->yx = pixels_per_bp[0]; mptr->yy = 0; mptr->tx = 0; mptr->ty = 0; break; } /* Finally, shift the device space origin to the top-left corner of the printable area. I am deliberately not using the corresponding shift feature in gx_device_set_margins() because it achieves its effect by using the 'Margins' array which should remain at the user's disposal for correcting misadjustments. In addition, gx_device_set_margins() will not work correctly for quarters % 4 != 0 anyway. */ { gs_matrix translation; /* Translation of pixmap device space origin by top and left margins in pixmap device space */ gs_make_translation( -dev->eprn.right_shift*pixels_per_bp[0], -dev->eprn.down_shift *pixels_per_bp[1], &translation); /* Multiply the initial matrix from the right with the translation matrix, i.e., in going from user to device space the translation will be applied last. */ gs_matrix_multiply(mptr, &translation, mptr); } #ifdef EPRN_TRACE if_debug6(EPRN_TRACE_CHAR, " Returning [%g %g %g %g %g %g].\n", mptr->xx, mptr->xy, mptr->yx, mptr->yy, mptr->tx, mptr->ty); #endif return; }
/* Shift the origin from the top left corner of the pysical page to the first printable pixel, as defined by the top and left margins. */ static void bj10v_get_initial_matrix(gx_device *dev, gs_matrix *pmat) { gx_default_get_initial_matrix(dev, pmat); pmat->tx -= dev_l_margin(dev) * dev->x_pixels_per_inch; pmat->ty -= dev_t_margin(dev) * dev->y_pixels_per_inch; }