Пример #1
0
/*
 * Get the effective printing region in raster space
 */
static void
get_raster_print_rect( const gs_memory_t *mem, 
		       const gs_rect *      plp_print_rect,
		       gs_rect *            prst_print_rect,
		       const gs_matrix *    prst2lp
		       )
{
    gs_matrix            lp2rst;

    pcl_invert_mtx(prst2lp, &lp2rst);
    pcl_transform_rect(mem, plp_print_rect, prst_print_rect, &lp2rst);
    intersect_with_positive_quadrant(prst_print_rect);
}
Пример #2
0
/*
 * Preserve the current point and text margin set by transfroming them into
 * logical page space.
 */
static void
preserve_cap_and_margins(const pcl_state_t * pcs,
                         gs_point * pcur_pt, gs_rect * ptext_rect)
{
    pcur_pt->x = (double)pcs->cap.x;
    pcur_pt->y = (double)pcs->cap.y;
    gs_point_transform(pcur_pt->x,
                       pcur_pt->y, &(pcs->xfm_state.pd2lp_mtx), pcur_pt);
    ptext_rect->p.x = (double)pcs->margins.left;
    ptext_rect->p.y = (double)pcs->margins.top;
    ptext_rect->q.x = (double)pcs->margins.right;
    ptext_rect->q.y = (double)(pcs->margins.top + pcs->margins.length);
    pcl_transform_rect(pcs->memory, ptext_rect, ptext_rect,
                       &(pcs->xfm_state.pd2lp_mtx));
}
Пример #3
0
/*
 * Convert the current point and text margin set back into "pseudo print
 * direction" space.
 */
static void
restore_cap_and_margins(pcl_state_t * pcs,
                        const gs_point * pcur_pt, const gs_rect * ptext_rect)
{
    gs_matrix lp2pd;
    gs_point tmp_pt;
    gs_rect tmp_rect;

    pcl_invert_mtx(&(pcs->xfm_state.pd2lp_mtx), &lp2pd);
    gs_point_transform(pcur_pt->x, pcur_pt->y, &lp2pd, &tmp_pt);
    pcs->cap.x = (coord) tmp_pt.x;
    pcs->cap.y = (coord) tmp_pt.y;
    pcl_transform_rect(pcs->memory, ptext_rect, &tmp_rect, &lp2pd);
    pcs->margins.left = (coord) tmp_rect.p.x;
    pcs->margins.top = (coord) tmp_rect.p.y;
    pcs->margins.right = (coord) tmp_rect.q.x;
    pcs->margins.length = (coord) tmp_rect.q.y - pcs->margins.top;
}
Пример #4
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.
     */
}