Esempio n. 1
0
/* scalefont */
int
gs_scalefont(gs_font_dir *pdir, const gs_font *pfont, floatp scale,
  gs_font **ppfont, gs_font **pdfont)
{	gs_matrix mat;
	gs_make_scaling(scale, scale, &mat);
	return gs_makefont(pdir, pfont, &mat, ppfont, pdfont);
}
Esempio n. 2
0
/* <sx> <sy> <matrix> scale <matrix> */
static int
zscale(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;
    double scale[2];

    if ((code = num_params(op, 2, scale)) >= 0) {
        code = gs_scale(igs, scale[0], scale[1]);
        if (code < 0)
            return code;
    } else {			/* matrix operand */
        gs_matrix mat;

        /* The num_params failure might be a stack underflow. */
        check_op(2);
        if ((code = num_params(op - 1, 2, scale)) < 0 ||
            (code = gs_make_scaling(scale[0], scale[1], &mat)) < 0 ||
            (code = write_matrix(op, &mat)) < 0
            ) {			/* Might be a stack underflow. */
            check_op(3);
            return code;
        }
        op[-2] = *op;
    }
    pop(2);
    return code;
}
Esempio n. 3
0
/* <font> <scale> scalefont <new_font> */
static int
zscalefont(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;
    double scale;
    gs_matrix mat;

    if ((code = real_param(op, &scale)) < 0)
        return code;
    if ((code = gs_make_scaling(scale, scale, &mat)) < 0)
        return code;
    return make_font(i_ctx_p, &mat);
}
Esempio n. 4
0
int
pxSetPageScale(px_args_t *par, px_state_t *pxs)
{	
    int code;
    real sx = 1;
    real sy = 1;
    static const real units_conversion_table[3][3] = {
        { 1, 25.4, 254 },     /* in -> in, mill, 1/10 mill */
        { 0.0394, 1, 10 },    /* mill -> in, mill, 1/10 mill */
        { 0.00394, .1, 1 }    /* 1/10 mill -> in, mill, 1/10 mill */ 
    };

    /* measuure and units of measure.  Actually session user units
       divided by new user unit, bizarre. */
    if ( par->pv[1] && par->pv[2] ) {
        /* new user measure */
        real nux = real_value(par->pv[2], 0);
        real nuy = real_value(par->pv[2], 1);
        if ( nux != 0 && nuy != 0 ) {
            /* new measure */
            pxeMeasure_t mt = par->pv[1]->value.i;
            /* convert to session units */
            real factor = units_conversion_table[pxs->measure][mt];
            real sux = nux * factor;
            real suy = nuy * factor;
            sx = pxs->units_per_measure.x / sux;
            sy = pxs->units_per_measure.y / suy;
            /* check for overflow.  NB we should do a better job here */
            if ( fabs(sx) > 1000.0 ) {
                dprintf2("warning probable overflow avoided for scaling factors %f %f\n", 
			 sx, sy );
                sx = sy = 1;
            }
        }
    } else if ( par->pv[0] ) { /* page scale */
        sx = real_value(par->pv[0], 0);
        sy = real_value(par->pv[0], 1);
    }
    code = gs_scale(pxs->pgs, sx, sy);
    if ( code < 0 )
        return code;
    /* Post-multiply the text CTM by the scale matrix. */
    { 
        gs_matrix smat;
        px_gstate_t *pxgs = pxs->pxgs;
        gs_make_scaling(sx, sy, &smat);
        gs_matrix_multiply(&pxgs->text_ctm, &smat, &pxgs->text_ctm);
    }
    return 0;
}
Esempio n. 5
0
static int
vu_begin_image(px_state_t * pxs)
{
    px_vendor_state_t *v_state = pxs->vendor_state;
    gs_image_t image = v_state->image;
    px_bitmap_params_t params;
    gs_point origin;
    int code;

    if (v_state->color_space == eGraySub)
	params.color_space = eGray;
    else
	params.color_space = eSRGB;
    params.width = params.dest_width = v_state->SourceWidth;
    params.height = params.dest_height = v_state->BlockHeight;
    params.depth = 8;
    params.indexed = false;
    code = px_image_color_space(&image, &params,
				(const gs_string *)&pxs->pxgs->palette,
				pxs->pgs);
    if (code < 0) {
	return code;
    }

    /* Set up the image parameters. */
    if (gs_currentpoint(pxs->pgs, &origin) < 0)
	return_error(errorCurrentCursorUndefined);
    image.Width = v_state->SourceWidth;
    image.Height = v_state->BlockHeight;
    {
	gs_matrix imat, dmat;

	gs_make_scaling(image.Width, image.Height, &imat);
	gs_make_translation(origin.x, origin.y + v_state->StartLine, &dmat);
	gs_matrix_scale(&dmat, image.Width, image.Height, &dmat);
	/* The ImageMatrix is dmat' * imat. */
	gs_matrix_invert(&dmat, &dmat);
	gs_matrix_multiply(&dmat, &imat, &image.ImageMatrix);
    }
    image.CombineWithColor = true;
    image.Interpolate = pxs->interpolate;
    code = pl_begin_image(pxs->pgs, &image, &v_state->info);
    if (code < 0)
	return code;
    return 0;
}
Esempio n. 6
0
/* Initialize for writing a path using the default implementation. */
void
gdev_vector_dopath_init(gdev_vector_dopath_state_t *state,
                        gx_device_vector *vdev, gx_path_type_t type,
                        const gs_matrix *pmat)
{
    state->vdev = vdev;
    state->type = type;
    if (pmat) {
        state->scale_mat = *pmat;
        /*
         * The path element writing procedures all divide the coordinates
         * by the scale, so we must compensate for that here.
         */
        gs_matrix_scale(&state->scale_mat, 1.0 / vdev->scale.x,
                        1.0 / vdev->scale.y, &state->scale_mat);
    } else {
        gs_make_scaling(vdev->scale.x, vdev->scale.y, &state->scale_mat);
    }
    state->first = true;
}
Esempio n. 7
0
/* Compute the FontDescriptor metrics for a font. */
int
pdf_compute_font_descriptor(gx_device_pdf *pdev, pdf_font_descriptor_t *pfd)
{
    gs_font_base *bfont = pdf_base_font_font(pfd->base_font, false);
    gs_glyph glyph, notdef;
    int index;
    int wmode = bfont->WMode;
    int members = (GLYPH_INFO_WIDTH0 << wmode) |
        GLYPH_INFO_BBOX | GLYPH_INFO_NUM_PIECES;
    pdf_font_descriptor_values_t desc;
    gs_matrix smat;
    gs_matrix *pmat = NULL;
    int fixed_width = 0;
    int small_descent = 0, small_height = 0;
    bool small_present = false;
    int x_height = 0;
    int cap_height = 0;
    gs_rect bbox_colon, bbox_period, bbox_I;
    bool is_cid = (bfont->FontType == ft_CID_encrypted ||
                   bfont->FontType == ft_CID_TrueType);
    bool have_colon = false, have_period = false, have_I = false;
    int code;

    memset(&bbox_colon, 0, sizeof(bbox_colon)); /* quiet gcc warnings. */
    memset(&bbox_period, 0, sizeof(bbox_period)); /* quiet gcc warnings. */
    memset(&bbox_I, 0, sizeof(bbox_I)); /* quiet gcc warnings. */
    memset(&desc, 0, sizeof(desc));
    if (is_cid && bfont->FontBBox.p.x != bfont->FontBBox.q.x &&
                  bfont->FontBBox.p.y != bfont->FontBBox.q.y) {
        int scale = (bfont->FontType == ft_TrueType || bfont->FontType == ft_CID_TrueType ? 1000 : 1);

        desc.FontBBox.p.x = (int)(bfont->FontBBox.p.x * scale);
        desc.FontBBox.p.y = (int)(bfont->FontBBox.p.y * scale);
        desc.FontBBox.q.x = (int)(bfont->FontBBox.q.x * scale);
        desc.FontBBox.q.y = (int)(bfont->FontBBox.q.y * scale);
        desc.Ascent = desc.FontBBox.q.y;
        members &= ~GLYPH_INFO_BBOX;
    } else {
        desc.FontBBox.p.x = desc.FontBBox.p.y = max_int;
        desc.FontBBox.q.x = desc.FontBBox.q.y = min_int;
    }
    /*
     * Embedded TrueType fonts use a 1000-unit character space, but the
     * font itself uses a 1-unit space.  Compensate for this here.
     */
    switch (bfont->FontType) {
    case ft_TrueType:
    case ft_CID_TrueType:
        gs_make_scaling(1000.0, 1000.0, &smat);
        pmat = &smat;
        /* Type 3 fonts may use a FontMatrix in PDF, so we don't
         * need to deal with non-standard matrices
         */
    case ft_GL2_531:
    case ft_PCL_user_defined:
    case ft_GL2_stick_user_defined:
    case ft_MicroType:
    case ft_user_defined:
        break;
        /* Other font types may use a non-standard (not 1000x1000) design grid
         * The FontMatrix is used to map to the unit square. However PDF files
         * don't allow FontMatrix entries, all fonts are nominally 1000x1000.
         * If we have a font with a non-standard matrix we must account for that
         * here by scaling the font outline.
         */
    default:
        gs_matrix_scale(&bfont->FontMatrix, 1000.0, 1000.0, &smat);
        pmat = &smat;
        break;
    }

    /*
     * Scan the entire glyph space to compute Ascent, Descent, FontBBox, and
     * the fixed width if any.  For non-symbolic fonts, also note the
     * bounding boxes for Latin letters and a couple of other characters,
     * for computing the remaining descriptor values (CapHeight,
     * ItalicAngle, StemV, XHeight, and flags SERIF, SCRIPT, ITALIC,
     * ALL_CAPS, and SMALL_CAPS).  (The algorithms are pretty crude.)
     */
    notdef = GS_NO_GLYPH;
    for (index = 0;
         (bfont->procs.enumerate_glyph((gs_font *)bfont, &index,
                (is_cid ? GLYPH_SPACE_INDEX : GLYPH_SPACE_NAME), &glyph)) >= 0 &&
             index != 0;
         ) {
        gs_glyph_info_t info;
        gs_const_string gname;
        gs_glyph glyph_known_enc;
        gs_char position=0;

        code = bfont->procs.glyph_info((gs_font *)bfont, glyph, pmat, members, &info);
        if (code == gs_error_VMerror)
            return code;
        if (code < 0) {
            /*
             * Since this function may be indirtectly called from gx_device_finalize,
             * we are unable to propagate error code to the interpreter.
             * Therefore we skip it here hoping that few errors can be
             * recovered by the integration through entire glyph set.
             */
            continue;
        }
        if (members & GLYPH_INFO_BBOX) {
            /* rect_merge(desc.FontBBox, info.bbox); Expanding due to type cast :*/
            if (info.bbox.p.x < desc.FontBBox.p.x) desc.FontBBox.p.x = (int)info.bbox.p.x;
            if (info.bbox.q.x > desc.FontBBox.q.x) desc.FontBBox.q.x = (int)info.bbox.q.x;
            if (info.bbox.p.y < desc.FontBBox.p.y) desc.FontBBox.p.y = (int)info.bbox.p.y;
            if (info.bbox.q.y > desc.FontBBox.q.y) desc.FontBBox.q.y = (int)info.bbox.q.y;
            if (!info.num_pieces)
                desc.Ascent = max(desc.Ascent, (int)info.bbox.q.y);
        }
        if (notdef == GS_NO_GLYPH && gs_font_glyph_is_notdef(bfont, glyph)) {
            notdef = glyph;
            desc.MissingWidth = (int)info.width[wmode].x;
        }
        if (info.width[wmode].y != 0)
            fixed_width = min_int;
        else if (fixed_width == 0)
            fixed_width = (int)info.width[wmode].x;
        else if (info.width[wmode].x != fixed_width)
            fixed_width = min_int;
        if (desc.Flags & FONT_IS_SYMBOLIC)
            continue;		/* skip Roman-only computation */
        if (is_cid)
            continue;
        code = bfont->procs.glyph_name((gs_font *)bfont, glyph, &gname);
        if (code < 0) {
            /* If we fail to get the glyph name, best assume this is a symbolic font */
            desc.Flags |= FONT_IS_SYMBOLIC;
            continue;
        }
        /* See if the glyph name is in any of the known encodings */
        glyph_known_enc = gs_c_name_glyph(gname.data, gname.size);
        if (glyph_known_enc == gs_no_glyph) {
            desc.Flags |= FONT_IS_SYMBOLIC;
            continue;
        }
        /* Finally check if the encoded glyph is in Standard Encoding */
        /* gs_c_decode always fails to find .notdef, its always present so
         * don't worry about it
         */
        if(strncmp(".notdef", (const char *)gname.data, gname.size)) {
            position = gs_c_decode(glyph_known_enc, 0);
            if (position == GS_NO_CHAR) {
                desc.Flags |= FONT_IS_SYMBOLIC;
                continue;
            }
        }
        switch (gname.size) {
        case 5:
            if (!memcmp(gname.data, "colon", 5))
                bbox_colon = info.bbox, have_colon = true;
            continue;
        case 6:
            if (!memcmp(gname.data, "period", 6))
                bbox_period = info.bbox, have_period = true;
            continue;
        case 1:
            break;
        default:
            continue;
        }

        if (gname.data[0] >= 'A' && gname.data[0] <= 'Z') {
            cap_height = max(cap_height, (int)info.bbox.q.y);
            if (gname.data[0] == 'I')
                bbox_I = info.bbox, have_I = true;
        } else if (gname.data[0] >= 'a' && gname.data[0] <= 'z') {
            int y0 = (int)(info.bbox.p.y), y1 = (int)(info.bbox.q.y);

            small_present = true;
            switch (gname.data[0]) {
            case 'b': case 'd': case 'f': case 'h':
            case 'k': case 'l': case 't': /* ascender */
                small_height = max(small_height, y1);
            case 'i':		/* anomalous ascent */
                break;
            case 'j':		/* descender with anomalous ascent */
                small_descent = min(small_descent, y0);
                break;
            case 'g': case 'p': case 'q': case 'y': /* descender */
                small_descent = min(small_descent, y0);
            default:		/* no ascender or descender */
                x_height = max(x_height, y1);
            }
        }
    }
    if (!(desc.Flags & FONT_IS_SYMBOLIC)) {
        desc.Flags |= FONT_IS_ADOBE_ROMAN; /* required if not symbolic */
        desc.XHeight = (int)x_height;
        if (!small_present && (!pdev->PDFA != 0 || bfont->FontType != ft_TrueType))
            desc.Flags |= FONT_IS_ALL_CAPS;
        desc.CapHeight = cap_height;
        /*
         * Look at various glyphs to determine ItalicAngle, StemV,
         * SERIF, SCRIPT, and ITALIC.
         */
        if (have_colon && have_period) {
            /* Calculate the dominant angle. */
            int angle =
                (int)(atan2((bbox_colon.q.y - bbox_colon.p.y) -
                              (bbox_period.q.y - bbox_period.p.y),
                            (bbox_colon.q.x - bbox_colon.p.x) -
                              (bbox_period.q.x - bbox_period.p.x)) *
                      radians_to_degrees) - 90;

            /* Normalize to [-90..90]. */
            while (angle > 90)
                angle -= 180;
            while (angle < -90)
                angle += 180;
            if (angle < -30)
                angle = -30;
            else if (angle > 30)
                angle = 30;
            /*
             * For script or embellished fonts, we can get an angle that is
             * slightly off from zero even for non-italic fonts.
             * Compensate for this now.
             */
            if (angle <= 2 && angle >= -2)
                angle = 0;
            desc.ItalicAngle = angle;
        }
        if (desc.ItalicAngle)
            desc.Flags |= FONT_IS_ITALIC;
        if (have_I) {
            double wdot = bbox_period.q.x - bbox_period.p.x;
            double wcolon = bbox_I.q.x - bbox_I.p.x;
            double wI = bbox_period.q.x - bbox_period.p.x;

            desc.StemV = (int)wdot;
            if (wI > wcolon * 2.5 || wI > (bbox_period.q.y - bbox_period.p.y) * 0.25)
                desc.Flags |= FONT_IS_SERIF;
        }
    }
    if (desc.Ascent == 0)
        desc.Ascent = desc.FontBBox.q.y;
    desc.Descent = desc.FontBBox.p.y;
    if (!(desc.Flags & (FONT_IS_SYMBOLIC | FONT_IS_ALL_CAPS)) &&
        (small_descent > desc.Descent / 3 || desc.XHeight > small_height * 0.9) &&
        (!pdev->PDFA != 0 || bfont->FontType != ft_TrueType)
        )
        desc.Flags |= FONT_IS_SMALL_CAPS;
    if (fixed_width > 0 && (!pdev->PDFA != 0 || bfont->FontType != ft_TrueType)) {
        desc.Flags |= FONT_IS_FIXED_WIDTH;
        desc.AvgWidth = desc.MaxWidth = desc.MissingWidth = fixed_width;
    }
    if (desc.CapHeight == 0)
        desc.CapHeight = desc.Ascent;
    if (desc.StemV == 0)
        desc.StemV = (int)(desc.FontBBox.q.x * 0.15);
    pfd->common.values = desc;
    return 0;
}