Ejemplo n.º 1
0
int
gs_rotate(gs_state * pgs, floatp ang)
{
    int code = gs_matrix_rotate(&ctm_only(pgs), ang,
                                &ctm_only_writable(pgs));

    pgs->ctm_inverse_valid = false, pgs->char_tm_valid = false;
#ifdef DEBUG
    if (gs_debug_c('x'))
        dlprintf1("[x]rotate: %f\n", ang), trace_ctm(pgs);
#endif
    return code;
}
Ejemplo n.º 2
0
/*
 * Compute the adjustment matrix for scaling and/or rotating the page
 * to match the medium.  If the medium is completely flexible in a given
 * dimension (e.g., roll media in one dimension, or displays in both),
 * we must adjust its size in that dimension to match the request.
 * We recognize this by an unreasonably small medium->p.{x,y}.
 */
static void 
make_adjustment_matrix(const gs_point * request, const gs_rect * medium,
		       gs_matrix * pmat, bool scale, int rotate)
{
    double rx = request->x, ry = request->y;
    double mx = medium->q.x, my = medium->q.y;

    /* Rotate the request if necessary. */ 
    if (rotate & 1) {
	double temp = rx;

	rx = ry, ry = temp;
    }
    /* If 'medium' is flexible, adjust 'mx' and 'my' towards 'rx' and 'ry',
       respectively. Note that 'mx' and 'my' have just acquired the largest
       permissible value, medium->q. */
    if (medium->p.x < mx) {	/* non-empty width range */
	if (rx < medium->p.x)
	    mx = medium->p.x;	/* use minimum of the range */
	else if (rx < mx)
	    mx = rx;		/* fits */
		/* else leave mx == medium->q.x, i.e., the maximum */
    }
    if (medium->p.y < my) {	/* non-empty height range */
	if (ry < medium->p.y)
	    my = medium->p.y;	/* use minimum of the range */
	else if (ry < my)
	    my = ry;		/* fits */
	    /* else leave my == medium->q.y, i.e., the maximum */
    }

    /* Translate to align the centers. */ 
    gs_make_translation(mx / 2, my / 2, pmat);

    /* Rotate if needed. */ 
    if (rotate)
	gs_matrix_rotate(pmat, 90.0 * rotate, pmat);

    /* Scale if needed. */ 
    if (scale) {
	double xfactor = mx / rx;
	double yfactor = my / ry;
	double factor = min(xfactor, yfactor);

	if (factor < 1)
	    gs_matrix_scale(pmat, factor, factor, pmat);
    }
    /* Now translate the origin back, */ 
    /* using the original, unswapped request. */ 
    gs_matrix_translate(pmat, -request->x / 2, -request->y / 2, pmat);
}
Ejemplo n.º 3
0
static int
pdf_dsc_process(gx_device_pdf * pdev, const gs_param_string_array * pma)
{
    /*
     * The Adobe "Distiller Parameters" documentation says that Distiller
     * looks at DSC comments, but it doesn't say which ones.  We look at
     * the ones that we see how to map directly to obvious PDF constructs.
     */
    int code = 0;
    uint i;

    /*
     * If ParseDSCComments is false, all DSC comments are ignored, even if
     * ParseDSCComentsForDocInfo or PreserveEPSInfo is true.
     */
    if (!pdev->ParseDSCComments)
	return 0;

    for (i = 0; i + 1 < pma->size && code >= 0; i += 2) {
	const gs_param_string *pkey = &pma->data[i];
	const gs_param_string *pvalue = &pma->data[i + 1];
	const char *key;
	int code;

	/*
	 * %%For, %%Creator, and %%Title are recognized only if either
	 * ParseDSCCommentsForDocInfo or PreserveEPSInfo is true.
	 * The other DSC comments are always recognized.
	 *
	 * Acrobat Distiller sets CreationDate and ModDate to the current
	 * time, not the value of %%CreationDate.  We think this is wrong,
	 * but we do the same -- we ignore %%CreationDate here.
	 */

	if (pdf_key_eq(pkey, "Creator"))
	    key = "/Creator";
	else if (pdf_key_eq(pkey, "Title"))
	    key = "/Title";
	else if (pdf_key_eq(pkey, "For"))
	    key = "/Author";
	else {
	    pdf_page_dsc_info_t *ppdi;
            char scan_buf[200]; /* arbitrary */

	    if ((ppdi = &pdev->doc_dsc_info,
		 pdf_key_eq(pkey, "Orientation")) ||
		(ppdi = &pdev->page_dsc_info,
		 pdf_key_eq(pkey, "PageOrientation"))
		) {
		if (pvalue->size == 1 && pvalue->data[0] >= '0' &&
		    pvalue->data[0] <= '3'
		    )
		    ppdi->orientation = pvalue->data[0] - '0';
		else
		    ppdi->orientation = -1;
	    } else if ((ppdi = &pdev->doc_dsc_info,
			pdf_key_eq(pkey, "ViewingOrientation")) ||
		       (ppdi = &pdev->page_dsc_info,
			pdf_key_eq(pkey, "PageViewingOrientation"))
		       ) {
		gs_matrix mat;
		int orient;

		if(pvalue->size >= sizeof(scan_buf) - 1)
		    continue;	/* error */
                memcpy(scan_buf, pvalue->data, pvalue->size);
                scan_buf[pvalue->size] = 0;
                if (sscanf(scan_buf, "[%g %g %g %g]",
			   &mat.xx, &mat.xy, &mat.yx, &mat.yy) != 4
		    )
		    continue;	/* error */
		for (orient = 0; orient < 4; ++orient) {
		    if (mat.xx == 1 && mat.xy == 0 && mat.yx == 0 && mat.yy == 1)
			break;
		    gs_matrix_rotate(&mat, -90.0, &mat);
		}
		if (orient == 4) /* error */
		    orient = -1;
		ppdi->viewing_orientation = orient;
	    } else {
		gs_rect box;

		if (pdf_key_eq(pkey, "EPSF")) {
		    pdev->is_EPS = (pvalue->size >= 1 && pvalue->data[0] != '0');
		    continue;
		}
		/*
		 * We only parse the BoundingBox for the sake of
		 * AutoPositionEPSFiles.
		 */
		if (pdf_key_eq(pkey, "BoundingBox"))
		    ppdi = &pdev->doc_dsc_info;
		else if (pdf_key_eq(pkey, "PageBoundingBox"))
		    ppdi = &pdev->page_dsc_info;
		else
		    continue;
		if(pvalue->size >= sizeof(scan_buf) - 1)
		    continue;	/* error */
                memcpy(scan_buf, pvalue->data, pvalue->size);
                scan_buf[pvalue->size] = 0;
		if (sscanf(scan_buf, "[%lg %lg %lg %lg]",
			   &box.p.x, &box.p.y, &box.q.x, &box.q.y) != 4
		    )
		    continue;	/* error */
		ppdi->bounding_box = box;
	    }
	    continue;
	}

	if (pdev->ParseDSCCommentsForDocInfo || pdev->PreserveEPSInfo)
	    code = cos_dict_put_c_key_string(pdev->Info, key,
					     pvalue->data, pvalue->size);
    }
    return code;
}
Ejemplo n.º 4
0
/*
 * Reset all parameters which must be reset whenever the page size changes.
 *
 * The third operand indicates if this routine is being called as part of
 * an initial reset. In that case, done't call HPGL's reset - the reset
 * will do that later.
 */
static void
new_page_size(pcl_state_t * pcs,
              const pcl_paper_size_t * psize,
              bool reset_initial, bool for_passthrough)
{
    double width_pts = psize->width * 0.01;
    double height_pts = psize->height * 0.01;
    float page_size[2];
    float old_page_size[2];
    gs_state *pgs = pcs->pgs;
    gs_matrix mat;
    bool changed_page_size;

    page_size[0] = width_pts;
    page_size[1] = height_pts;

    old_page_size[0] = gs_currentdevice(pcs->pgs)->MediaSize[0];
    old_page_size[1] = gs_currentdevice(pcs->pgs)->MediaSize[1];

    put_param1_float_array(pcs, "PageSize", page_size);

    /*
     * Reset the default transformation.
     *
     * The graphic library provides a coordinate system in points, with the
     * origin at the lower left corner of the page. The PCL code uses a
     * coordinate system in centi-points, with the origin at the upper left
     * corner of the page.
     */
    gs_setdefaultmatrix(pgs, NULL);
    gs_initmatrix(pgs);
    gs_currentmatrix(pgs, &mat);

    if (pcs->personality != rtl) {
        gs_matrix_translate(&mat, 0.0, height_pts, &mat);
        gs_matrix_scale(&mat, 0.01, -0.01, &mat);
    } else {
        gs_matrix_rotate(&mat, -90, &mat);
        gs_matrix_scale(&mat, -0.01, 0.01, &mat);
    }

    gs_setdefaultmatrix(pgs, &mat);
    pcs->xfm_state.paper_size = psize;
    pcs->overlay_enabled = false;
    update_xfm_state(pcs, reset_initial);
    reset_margins(pcs, for_passthrough);

    /* check if update_xfm_state changed the page size */
    changed_page_size = !((int)old_page_size[0] == pcs->xfm_state.paper_size->width/100 && 
                          (int)old_page_size[1] == pcs->xfm_state.paper_size->height/100);

    /*
     * make sure underlining is disabled (homing the cursor may cause
     * an underline to be put out.
     */
    pcs->underline_enabled = false;
    pcl_home_cursor(pcs);
    /*
     * this is were we initialized the cursor position
     */
    pcs->cursor_moved = false;

    pcl_xfm_reset_pcl_pat_ref_pt(pcs);

    if (!reset_initial)
        hpgl_do_reset(pcs, pcl_reset_page_params);

    if (pcs->end_page == pcl_end_page_top) {    /* don't erase in snippet mode */
        if (pcs->page_marked || changed_page_size) {
            gs_erasepage(pcs->pgs);
            pcs->page_marked = false;
        }
    }
}