예제 #1
0
/* <font> setfont - */
int
zsetfont(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_font *pfont;
    int code = font_param(op, &pfont);

    if (code < 0 || (code = gs_setfont(igs, pfont)) < 0)
        return code;
    pop(1);
    return code;
}
예제 #2
0
/* - .wrapfont - */
static int
zwrapfont(i_ctx_t *i_ctx_p)
{
    gs_font *font = gs_currentfont(igs);
    gs_font_type0 *font0;
    int wmode = 0;
    int code;

    switch (font->FontType) {
    case ft_TrueType:
	code = gs_font_type0_from_type42(&font0, (gs_font_type42 *)font, wmode,
					 true, font->memory);
	if (code < 0)
	    return code;
	/*
	 * Patch up BuildChar and CIDMap.  This isn't necessary for
	 * TrueType fonts in general, only for Type 42 fonts whose
	 * BuildChar is implemented in PostScript code.
	 */
	{
	    font_data *pdata = pfont_data(font);
	    const char *bgstr = "%Type11BuildGlyph";
	    ref temp;

	    make_int(&temp, 0);
	    ref_assign(&pdata->u.type42.CIDMap, &temp);
	    code = name_ref((const byte *)bgstr, strlen(bgstr), &temp, 1);
	    if (code < 0)
		return code;
	    r_set_attrs(&temp, a_executable);
	    ref_assign(&pdata->BuildGlyph, &temp);
	}
	break;
    case ft_CID_encrypted:
    case ft_CID_user_defined:
    case ft_CID_TrueType:
	code = gs_font_type0_from_cidfont(&font0, font, wmode, NULL,
					  font->memory);
	break;
    default:
	return_error(e_rangecheck);
    }
    if (code < 0)
	return code;
    gs_setfont(igs, (gs_font *)font0);
    return 0;
}
예제 #3
0
int
gslt_render_font_glyph(gs_state *pgs, gslt_font_t *xf, gs_matrix *tm, int gid, gslt_glyph_bitmap_t *slot)
{
    gs_fixed_point subpixel = {0, 0}; /* we don't use subpixel accurate device metrics */
    gs_log2_scale_point oversampling = {0, 0}; /* we don't use oversampling */
    gs_text_params_t params;
    gs_text_enum_t *textenum;
    gs_matrix matrix;
    cached_fm_pair *ppair;
    cached_char *cc;
    int code;

    /* get the real font matrix (this is a little dance) */
    gs_setfont(pgs, xf->font); /* set pgs->font and invalidate existing charmatrix */
    gs_setcharmatrix(pgs, tm); /* set the charmatrix to ctm * tm */
    gs_currentcharmatrix(pgs, &matrix, true); /* extract charmatrix (and multiply by FontMatrix) */

    // dprintf4("tm = [%g %g %g %g]\n", matrix.xx, matrix.xy, matrix.yx, matrix.yy);

    /* find the font/matrix pair (or add it) */
    code = gx_lookup_fm_pair(xf->font, &matrix, &oversampling, false, &ppair);
    if (code != 0)
        return gs_throw(-1, "cannot gx_lookup_fm_pair()");

    cc = gx_lookup_cached_char(xf->font, ppair, gid, 0, 1, &subpixel);
    if (!cc)
    {
        /* No luck ... now we need to get it into the cache somehow.
         *
         * We do this by rendering one glyph (that's why we need a device and pgs).
         * The renderer always renders the bitmap into the cache, and draws
         * from out of the cache when blitting to the device.
         *
         * Things don't get evicted from the cache until there is a collision,
         * so we have a safe window to snarf it back out of the cache
         * after it's been drawn to the device.
         */

        // dprintf1("cache miss for glyph %d\n", gid);

        params.operation = TEXT_FROM_SINGLE_GLYPH | TEXT_DO_DRAW | TEXT_RETURN_WIDTH;
        params.data.d_glyph = gid;
        params.size = 1;

	gs_moveto(pgs, 100.0, 100.0); // why?

        code = gs_text_begin(pgs, &params, xf->font->memory, &textenum);
	if (code != 0)
            return gs_throw1(-1, "cannot gs_text_begin() (%d)", code);

        code = gs_text_process(textenum);
	if (code != 0)
            return gs_throw1(-1, "cannot gs_text_process() (%d)", code);

        gs_text_release(textenum, "gslt font render");

        cc = gx_lookup_cached_char(xf->font, ppair, gid, 0, 1, &subpixel);
        if (!cc)
        {
            /* merde! it rendered but was not placed in the cache. */
            return gs_throw(-2, "cannot render from cache");
        }
    }

    /* copy values from the cache into the client struct */
    slot->w = cc->width;
    slot->h = cc->height;
    slot->stride = cc_raster(cc);
    slot->lsb = fixed2int(cc->offset.x);
    slot->top = fixed2int(cc->offset.y);

    slot->cc = cc;
    slot->data = cc_bits(cc);
    gx_retain_cached_char(cc);

#define XXX
#ifndef XXX
    static int xxx = 0; /* declaration out in the wild not allowed in ansi c */
    dprintf1("glyph %d\n", xxx);
    debug_dump_bitmap(cc_bits(cc), cc_raster(cc), cc->height, "");
    {
        char fn[32];
        sprintf(fn, "glyph%d.pbm", xxx);
        FILE *fo = fopen(fn, "wb");
        if (!fo)
            return -1;
        fprintf(fo, "P4\n%d %d\n", cc->width, cc->height);
        int y;
        int s = (cc->width + 7) / 8;
        for (y = 0; y < cc->height; y++)
            fwrite(cc_bits(cc) + y * cc_raster(cc), 1, s, fo);
        fclose(fo);
    }
    xxx ++;
#endif

    return 0;
}
예제 #4
0
int
gslt_outline_font_glyph(gs_state *pgs, gslt_font_t *xf, int gid, gslt_outline_walker_t *walk)
{
    gs_text_params_t params;
    gs_text_enum_t *textenum;
    gs_matrix matrix;
    segment *seg;
    curve_segment *cseg;

    gs_gsave(pgs);
    gs_make_identity(&matrix);
    gs_setmatrix(pgs, &matrix);
    gs_scale(pgs, 1000.0, 1000.0); /* otherwise we hit serious precision problems with fixpoint math */

    /* set gstate params */
    gs_setfont(pgs, xf->font); /* set pgs->font and invalidate existing charmatrix */
    gs_make_identity(&matrix);
    gs_setcharmatrix(pgs, &matrix); /* set the charmatrix to identity */

    /* reset the path */
    gs_newpath(pgs);
    gs_moveto(pgs, 0.0, 0.0);

    /* draw the glyph, in charpath mode */
    params.operation = TEXT_FROM_SINGLE_GLYPH | TEXT_DO_FALSE_CHARPATH | TEXT_RETURN_WIDTH;
    params.data.d_glyph = gid;
    params.size = 1;

    if (gs_text_begin(pgs, &params, xf->font->memory, &textenum) != 0)
        return gs_throw(-1, "cannot gs_text_begin()");
    if (gs_text_process(textenum) != 0)
        return gs_throw(-1, "cannot gs_text_process()");
    gs_text_release(textenum, "gslt font outline");

    /* walk the resulting path */
    seg = (segment*)pgs->path->first_subpath;
    while (seg)
    {
        switch (seg->type)
        {
        case s_start:
            walk->moveto(walk->user,
                    fixed2float(seg->pt.x) * 0.001,
                    fixed2float(seg->pt.y) * 0.001);
            break;
        case s_line:
            walk->lineto(walk->user,
                    fixed2float(seg->pt.x) * 0.001,
                    fixed2float(seg->pt.y) * 0.001);
            break;
        case s_line_close:
            walk->closepath(walk->user);
            break;
        case s_curve:
            cseg = (curve_segment*)seg;
            walk->curveto(walk->user,
                    fixed2float(cseg->p1.x) * 0.001,
                    fixed2float(cseg->p1.y) * 0.001,
                    fixed2float(cseg->p2.x) * 0.001,
                    fixed2float(cseg->p2.y) * 0.001,
                    fixed2float(seg->pt.x) * 0.001,
                    fixed2float(seg->pt.y) * 0.001);
            break;
        }
        seg = seg->next;
    }

    /* and toss it away... */
    gs_newpath(pgs);

    gs_grestore(pgs);
    return 0;
}
예제 #5
0
파일: plfapi.c 프로젝트: hackqiang/gs
static int
pl_fapi_char_metrics(const pl_font_t * plfont, const void *vpgs,
                     gs_char char_code, float metrics[4])
{
    int code = 0;
    gs_text_enum_t penum1;
    gs_font *pfont = plfont->pfont;
    gs_font_base *pbfont = (gs_font_base *) pfont;
    gs_text_params_t text;
    gs_char buf[2];
    gs_state *rpgs = (gs_state *) vpgs;
    /* NAFF: undefined glyph would be better handled inside FAPI */
    gs_char chr = char_code;
    gs_glyph unused_glyph = gs_no_glyph;
    gs_glyph glyph;
    gs_matrix mat = {72.0, 0.0, 0.0, 72.0, 0.0, 0.0};
    gs_matrix fmat;
    gs_fapi_font tmp_ff;

    if (pfont->FontType == ft_MicroType) {
        glyph = char_code;
    } else {
        glyph = pl_tt_encode_char(pfont, chr, unused_glyph);
    }

    if (pfont->WMode & 1) {
        gs_glyph vertical = pl_font_vertical_glyph(glyph, plfont);

        if (vertical != gs_no_glyph)
            glyph = vertical;
    }

    /* undefined character */
    if (glyph == 0xffff || glyph == gs_no_glyph) {
        metrics[0] = metrics[1] = metrics[2] = metrics[3] = 0;
        code = 1;
    } else {
        gs_fapi_server *I = pbfont->FAPI;
        gs_state lpgs;
        gs_state *pgs = &lpgs;

        /* This is kind of naff, but it's *much* cheaper to copy
         * the parts of the gstate we need, than gsave/grestore
         */
        memset(pgs, 0x00, sizeof(lpgs));
        pgs->is_gstate = rpgs->is_gstate;
        pgs->memory = rpgs->memory;
        pgs->ctm = rpgs->ctm;
        pgs->in_cachedevice = CACHE_DEVICE_NOT_CACHING;
        pgs->device = rpgs->device;
        pgs->log_op = rpgs->log_op;
        *(pgs->color) = *(rpgs->color);

        tmp_ff.fapi_set_cache = I->ff.fapi_set_cache;
        I->ff.fapi_set_cache = pl_fapi_set_cache_metrics;

        gs_setmatrix(pgs, &mat);
        fmat = pfont->FontMatrix;
        pfont->FontMatrix = pfont->orig_FontMatrix;
        (void)gs_setfont(pgs, pfont);

        I->ff.is_mtx_skipped = plfont->is_xl_format;

        buf[0] = char_code;
        buf[1] = '\0';

        text.operation = TEXT_FROM_CHARS | TEXT_DO_NONE | TEXT_RETURN_WIDTH;
        text.data.chars = buf;
        text.size = 1;

        if ((code = gs_text_enum_init(&penum1, &null_text_procs,
                             NULL, NULL, &text, pfont,
                             NULL, NULL, NULL, pfont->memory)) >= 0) {

            penum1.pis = (gs_imager_state *)pgs;

            code = gs_fapi_do_char(pfont, pgs, &penum1, plfont->font_file, false,
                        NULL, NULL, char_code, glyph, 0);

            if (code >= 0 || code == gs_error_unknownerror) {
                metrics[0] = metrics[1] = 0;
                metrics[2] = penum1.returned.total_width.x;
                metrics[3] = penum1.returned.total_width.y;
                if (code < 0)
                    code = 0;
            }
        }
        pfont->FontMatrix = fmat;

        I->ff.fapi_set_cache = tmp_ff.fapi_set_cache;
    }
    return (code);
}
예제 #6
0
int
pxpcl_selectfont(px_args_t * par, px_state_t * pxs)
{
    int code;
    stream_cursor_read r;
    const px_value_t *pstr = par->pv[3];
    const byte *str = (const byte *)pstr->value.array.data;
    uint len = pstr->value.array.size;
    px_gstate_t *pxgs = pxs->pxgs;
    pcl_font_selection_t *pfp;

    if (!global_pcs)
        pxPassthrough_init(pxs);

    /* this is the first passthrough on this page */
    if (global_pass_first) {
        pxPassthrough_setpagestate(pxs);
        pxPassthrough_pcl_state_nonpage_exceptions(pxs);
        global_pass_first = false;
    } else {
        /* there was a previous passthrough check if there were
           any intervening XL commands */
        if (global_this_pass_contiguous == false)
            pxPassthrough_pcl_state_nonpage_exceptions(pxs);
    }
    r.ptr = str - 1;
    r.limit = str + len - 1;

    code = pcl_process(&global_pcl_parser_state, global_pcs, &r);
    if (code < 0)
        return code;

    code = pcl_recompute_font(global_pcs, false);       /* select font */
    if (code < 0)
        return code;

    code = gs_setfont(pxs->pgs, global_pcs->font->pfont);
    if (code < 0)
        return code;

    pfp = &global_pcs->font_selection[global_pcs->font_selected];

    {
#define CP_PER_INCH         (7200.0)
#define CP_PER_MM           (7200.0/25.4)
#define CP_PER_10ths_of_MM  (CP_PER_MM/10.0)

        static const double centipoints_per_measure[4] = {
            CP_PER_INCH,        /* eInch */
            CP_PER_MM,          /* eMillimeter */
            CP_PER_10ths_of_MM, /* eTenthsOfAMillimeter */
            1                   /* pxeMeasure_next, won't reach */
        };

        gs_point sz;

        pcl_font_scale(global_pcs, &sz);
        pxgs->char_size = sz.x /
            centipoints_per_measure[pxs->measure] * pxs->units_per_measure.x;
    }
    pxgs->symbol_set = pfp->params.symbol_set;

    if (pcl_downloaded_and_bound(global_pcs->font)) {
        pxgs->symbol_map = 0;
    } else {
        px_set_symbol_map(pxs, global_pcs->font->font_type == plft_16bit);
    }

    {
        pl_font_t *plf = global_pcs->font;

        /* unfortunately the storage identifier is inconsistent
           between PCL and PCL XL, NB we should use the pxfont.h
           enumerations pxfsInternal and pxfsDownloaded but there is a
           foolish type redefinition in that header that need to be
           fixed. */

        if (plf->storage == 4)
            plf->storage = 1;
        else
            plf->storage = 0;

        pxgs->base_font = (px_font_t *) plf;
    }
    pxgs->char_matrix_set = false;
    return 0;
}