Exemplo n.º 1
0
/*
 * ESC & l <lines> F
 *
 * Set text length (which indirectly sets the bottom margin).
 */
static int
set_text_length(pcl_args_t * pargs, pcl_state_t * pcs)
{
    coord len = uint_arg(pargs) * pcs->vmi_cp;

    if (len == 0) {
        len =
            pcs->xfm_state.pd_size.y - pcs->margins.top -
            inch2coord(1.0 / 2.0);
        if (len < 0) {
            len += inch2coord(1.0 / 2.0);
        }
    }
    if ((len >= 0) && (pcs->margins.top + len <= pcs->xfm_state.pd_size.y))
        pcs->margins.length = len;
    return 0;
}
Exemplo n.º 2
0
/*
 * ESC & l <lpi> D
 *
 * Set line spacing. Though it is not documented anywhere, various HP devices
 * agree that a zero operand specifies 12 lines per inch (NOT the default).
 */
static int
set_line_spacing(pcl_args_t * pargs, pcl_state_t * pcs)
{
    uint lpi = uint_arg(pargs);
    bool cursor_at_home = pcl_cursor_at_home_pos(pcs);

    if (lpi == 0)               /* 0 ==> 12 lines per inch */
        lpi = 12;
    if ((48 % lpi) == 0)        /* lpi must divide 48 */
        pcs->vmi_cp = inch2coord(1.0 / lpi);
    if (cursor_at_home)
        pcl_home_cursor(pcs);
    return 0;
}
Exemplo n.º 3
0
/*
 * Form the transformation matrix required to render a pattern.
 */
  void
pcl_xfm_get_pat_xfm(
    const pcl_state_t *     pcs,
    pcl_pattern_t *         pptrn,
    gs_matrix *             pmat
)
{
    const pcl_xfm_state_t * pxfmst = &(pcs->xfm_state);
    int                     rot = (pcs->pat_orient - pxfmst->lp_orient) & 0x3;

    *pmat = pxfmst->lp2dev_mtx;
    pmat->tx = pcs->pat_ref_pt.x;
    pmat->ty = pcs->pat_ref_pt.y;

    /* record the referenc point used in the rendering structure */
    pptrn->ref_pt = pcs->pat_ref_pt;

    /* rotate as necessar */
    if (rot != 0)
        gs_matrix_multiply(&(rot_mtx[rot]), pmat, pmat);

    /* scale to the appropriate resolution (before print direction rotation) */
    gs_matrix_scale( pmat,
                     inch2coord(1.0 / (floatp)pptrn->ppat_data->xres),
                     inch2coord(1.0 / (floatp)pptrn->ppat_data->yres),
                     pmat
                     );

    /* avoid parameters that are slightly different from integers */
    pmat->xx = adjust_param(pmat->xx);
    pmat->xy = adjust_param(pmat->xy);
    pmat->yx = adjust_param(pmat->yx);
    pmat->yy = adjust_param(pmat->yy);

    /* record the rotation used for rendering */
    pptrn->orient = pcs->pat_orient;
}
Exemplo n.º 4
0
/* If PJL FORMLINES is set use we always use that value to derive VMI,
   otherwise we use the HP documented default.  This may not be
   exactly what HP does, the state interaction between formlines,
   paper size, orientation each of which can have different values in
   PJL and PCL is quite difficult to figure out, we believe this is
   correct for the vast majority of cases. */
coord
pcl_vmi_default(pcl_state_t * pcs)
{
    coord vmi;

    if (!pjl_proc_compare(pcs->pjls,
                          pjl_proc_get_envvar(pcs->pjls,
                                              "FORMLINES_SET"), "ON")) {
        vmi = (pcs->margins.length /
               pjl_proc_vartoi(pcs->pjls,
                               pjl_proc_get_envvar(pcs->pjls, "formlines")));
    } else {
        vmi = inch2coord(8.0 / 48.0);
    }
    return vmi;
}
Exemplo n.º 5
0
/* set variables other than setting the page device that do not
   default to pcl reset values */
void
pxPassthrough_pcl_state_nonpage_exceptions(px_state_t * pxs)
{
    /* xl cursor -> pcl cursor position */
    gs_point xlcp, pclcp, dp;

    /* make the pcl ctm active, after resets the hpgl/2 ctm is
       active. */
    pcl_set_graphics_state(global_pcs);
    /* xl current point -> device point -> pcl current
       point.  If anything fails we assume the current
       point is not valid and use the cap from the pcl
       state initialization - pcl's origin */
    if (gs_currentpoint(pxs->pgs, &xlcp) ||
        gs_transform(pxs->pgs, xlcp.x, xlcp.y, &dp) ||
        gs_itransform(global_pcs->pgs, dp.x, dp.y, &pclcp)) {
        global_pcs->cap.x = 0;
        global_pcs->cap.y = inch2coord(2.0 / 6.0);      /* 1/6" off by 2x in resolution. */
        if (gs_debug_c('i'))
            dmprintf2(pxs->memory,
                      "passthrough: changing cap NO currentpoint (%d, %d) \n",
                      global_pcs->cap.x, global_pcs->cap.y);
    } else {
        if (gs_debug_c('i'))
            dmprintf8(pxs->memory,
                      "passthrough: changing cap from (%d,%d) (%d,%d) (%d, %d) (%d, %d) \n",
                      global_pcs->cap.x, global_pcs->cap.y, (coord) xlcp.x,
                      (coord) xlcp.y, (coord) dp.x, (coord) dp.y,
                      (coord) pclcp.x, (coord) pclcp.y);
        global_pcs->cap.x = (coord) pclcp.x;
        global_pcs->cap.y = (coord) pclcp.y;
    }
    if (global_pcs->underline_enabled)
        global_pcs->underline_start = global_pcs->cap;


    global_char_angle = pxs->pxgs->char_angle;
    global_char_shear.x = pxs->pxgs->char_shear.x;
    global_char_shear.y = pxs->pxgs->char_shear.y;
    global_char_scale.x = pxs->pxgs->char_scale.x;
    global_char_scale.y = pxs->pxgs->char_scale.y;
    global_char_bold_value = pxs->pxgs->char_bold_value;

}
Exemplo n.º 6
0
/*
 * ESC * r # A
 *
 * Start raster graphics mode.
 *
 * See the commment ahead of the procedure pcl_enter_graphics mode above for
 * a discussion of the rather curios manner in which the left raster graphics
 * margin is set below.
 */
  static int
start_graphics_mode(
    pcl_args_t *            pargs,
    pcl_state_t *           pcs
)
{
    pcl_gmode_entry_t       mode = (pcl_gmode_entry_t)uint_arg(pargs);
    pcl_raster_state_t *    prstate = &(pcs->raster_state);

    if (mode > SCALE_CUR_PTR)
        mode = NO_SCALE_LEFT_MARG;
    if (!prstate->graphics_mode) {
        int r90 = (pcs->xfm_state.lp_orient + pcs->xfm_state.print_dir) & 0x1;

        prstate->scale_raster = ((((int)mode) & 0x2) != 0);
        prstate->gmargin_cp = 0;
        if (prstate->pres_mode_3 && (r90 != 0))
            prstate->gmargin_cp += inch2coord(1.0 / 6.0);
        pcl_enter_graphics_mode(pcs, mode);
    }
    return 0;
}
Exemplo n.º 7
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.
     */
}