Example #1
0
/* Returns exec_cont - a function, which must be called by caller after this function. */
static int
type1exec_bbox(i_ctx_t *i_ctx_p, gs_text_enum_t *penum, gs_type1exec_state * pcxs,
               gs_font * pfont, op_proc_t *exec_cont)
{
    os_ptr op = osp;
    gs_type1_state *const pcis = &pcxs->cis;
    gs_font_base *const pbfont = (gs_font_base *) pfont;
    op_proc_t cont = (pbfont->PaintType == 0 && penum->orig_font->PaintType == 0
                        ? bbox_finish_fill : bbox_finish_stroke);
    ref *pcdevproc;

    /*
     * We appear to have a valid bounding box.  If we don't have Metrics for
     * this character, start interpreting the CharString; do the
     * setcachedevice as soon as we know the (side bearing and) width.
     */
    if ((pcxs->present == metricsNone && !pcxs->use_FontBBox_as_Metrics2) ||
         (penum->orig_font->WMode && zchar_get_CDevProc(pbfont, &pcdevproc))) {
        /* Get the width from the CharString,
         * then set the cache device. */
        /* We pass here when WMode==1 and the font has CDevProc,
         * because we do need sbw as CDevProc's argument.
         * A more natural way would be not setting pcxs->use_FontBBox_as_Metrics2
         * when the font has CDevProc, except for missing sbw in the glyph.
         * We prefer to pass here because we've got examples
         * of Tyoe 1 fonts with empty glyphs, i.e. with no sbw,
         * so we don't want to assume that they'll never appear in a CID font.
         * In that case penum->FontBBox_as_Metrics2 will go here to zchar_set_cache. */
        ref cnref;
        ref other_subr;
        int code;

        /* Since an OtherSubr callout might change osp, */
        /* save the character name now. */
        ref_assign(&cnref, op - 1);
        code = type1_continue_dispatch(i_ctx_p, pcxs, op, &other_subr, 4);
        op = osp;		/* OtherSubrs might change it */
        switch (code) {
            default:		/* code < 0 or done, error */
                return ((code < 0 ? code :
                         gs_note_error(e_invalidfont)));
            case type1_result_callothersubr:	/* unknown OtherSubr */
                return type1_call_OtherSubr(i_ctx_p, pcxs,
                                            bbox_getsbw_continue,
                                            &other_subr);
            case type1_result_sbw:	/* [h]sbw, done */
                break;
        }
        type1_cis_get_metrics(pcis, pcxs->sbw);
        return zchar_set_cache(i_ctx_p, pbfont, &cnref,
                               NULL, pcxs->sbw + 2,
                               &pcxs->char_bbox,
                               cont, exec_cont, NULL);
    } else {
        /* We have the width and bounding box: */
        /* set up the cache device now. */
        return zchar_set_cache(i_ctx_p, pbfont, op - 1,
                               (pcxs->present == metricsSideBearingAndWidth
                                && !pcxs->use_FontBBox_as_Metrics2 ?
                                pcxs->sbw : NULL),
                               pcxs->sbw + 2,
                               &pcxs->char_bbox,
                               cont, exec_cont,
                               (pcxs->use_FontBBox_as_Metrics2 ? pcxs->sbw : NULL));
    }
}
Example #2
0
/*
 * Consult Metrics2 and CDevProc, and call setcachedevice[2].  Return
 * o_push_estack if we had to call a CDevProc, or if we are skipping the
 * rendering process (only getting the metrics).
 * Returns exec_cont - a function, which must be called by caller after this function.
 */
int
zchar_set_cache(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
                const ref * pcnref, const double psb[2],
                const double pwidth[2], const gs_rect * pbbox,
                op_proc_t cont, op_proc_t *exec_cont,
                const double Metrics2_sbw_default[4])
{
    os_ptr op = osp;
    ref *pcdevproc, *valueref;
    int have_cdevproc;
    ref rpop;
    ref cid, *cidptr;
    bool metrics2;
    bool metrics2_use_default = false;
    double w2[10];
    gs_text_enum_t *penum = op_show_find(i_ctx_p);

    w2[0] = pwidth[0], w2[1] = pwidth[1];

    /* Adjust the bounding box for stroking if needed. */

    w2[2] = pbbox->p.x, w2[3] = pbbox->p.y;
    w2[4] = pbbox->q.x, w2[5] = pbbox->q.y;
    if (pbfont->PaintType != 0) {
        double expand = max(1.415, gs_currentmiterlimit(igs)) *
        gs_currentlinewidth(igs) / 2;

        w2[2] -= expand, w2[3] -= expand;
        w2[4] += expand, w2[5] += expand;
    }

    /* Check for Metrics2. */

    {
        int code = zchar_get_metrics2(pbfont, pcnref, w2 + 6);

        if (code < 0)
            return code;
        metrics2 = code > 0;
    }

    /*
     * For FontType 9 and 11, if Metrics2 is missing, the caller provides
     * default Metrics2 values derived from the FontBBox.
     */
    if (!metrics2 && Metrics2_sbw_default != NULL) {
        w2[6] = Metrics2_sbw_default[2];
        w2[7] = Metrics2_sbw_default[3];
        w2[8] = Metrics2_sbw_default[0];
        w2[9] = Metrics2_sbw_default[1];
        metrics2 = true;
        metrics2_use_default = true;
    }

    /* Check for CDevProc or "short-circuiting". */

    have_cdevproc = zchar_get_CDevProc(pbfont, &pcdevproc);

    /* Obscure test. The CDevProc is supposed to be called with the original CID but what we get passed
     * here is the TT GID. So the CDevProc won't do the right thing. We need to extract the CID from the
     * enumerator, and use that instead.
     */
    cidptr = (ref *)pcnref;
    if (pbfont->FontType == ft_CID_TrueType && dict_find_string(&pfont_data(gs_font_parent(pbfont))->dict, "File", &valueref) > 0) {
        if (pbfont->key_name.size != pbfont->font_name.size ||
            strncmp((const char *)pbfont->key_name.chars, (const char *)pbfont->font_name.chars, pbfont->key_name.size)) {

            if (penum->returned.current_glyph >= GS_MIN_CID_GLYPH) {
                make_int(&cid, penum->returned.current_glyph - GS_MIN_CID_GLYPH);
            }
            else {
                make_int(&cid, penum->returned.current_glyph);
            }
            cidptr = &cid;
        }
    }
    if (have_cdevproc || zchar_show_width_only(penum)) {
        int i;
        op_proc_t zsetc;
        int nparams;

        if (have_cdevproc) {
            check_proc_only(*pcdevproc);
            zsetc = zsetcachedevice2;

            /* If we have cdevproc and the font type is CID type 0,
               we'll throw away Metrics2_sbw_default that is calculated
               from FontBBox. */
            if (!metrics2
                || (penum->current_font->FontType == ft_CID_encrypted
                    && metrics2_use_default)) {
                w2[6] = w2[0], w2[7] = w2[1];
                w2[8] = w2[9] = 0;
            }
            nparams = 10;
        } else {
            make_oper(&rpop, 0, zpop);
            pcdevproc = &rpop;
            if (metrics2)
                zsetc = zsetcachedevice2, nparams = 10;
            else
                zsetc = zsetcachedevice, nparams = 6;
        }
        check_estack(3);
        /* Push the l.s.b. for .type1addpath if necessary. */
        if (psb != 0) {
            push(nparams + 3);
            make_real(op - (nparams + 2), psb[0]);
            make_real(op - (nparams + 1), psb[1]);
        } else {
            push(nparams + 1);
        }
        for (i = 0; i < nparams; ++i)
            make_real(op - nparams + i, w2[i]);
        ref_assign(op, cidptr);
        push_op_estack(cont);
        push_op_estack(zsetc);
        ++esp;
        ref_assign(esp, pcdevproc);
        return o_push_estack;
    } {
        int code =
            (metrics2 ? gs_text_setcachedevice2(penum, w2) :
             gs_text_setcachedevice(penum, w2));

        if (code < 0)
            return code;
    }

    /* No metrics modification, do the stroke or fill now. */

    /* Push the l.s.b. for .type1addpath if necessary. */
    if (psb != 0) {
        push(2);
        make_real(op - 1, psb[0]);
        make_real(op, psb[1]);
    }
    *exec_cont = cont;
    return 0;
}
Example #3
0
/*
 * Consult Metrics2 and CDevProc, and call setcachedevice[2].  Return
 * o_push_estack if we had to call a CDevProc, or if we are skipping the
 * rendering process (only getting the metrics).
 * Returns exec_cont - a function, which must be called by caller after this function.
 */
int
zchar_set_cache(i_ctx_t *i_ctx_p, const gs_font_base * pbfont,
		const ref * pcnref, const double psb[2],
		const double pwidth[2], const gs_rect * pbbox,
		op_proc_t cont, op_proc_t *exec_cont,
		const double Metrics2_sbw_default[4])
{
    os_ptr op = osp;
    ref *pcdevproc;
    int have_cdevproc;
    ref rpop;
    bool metrics2;
    bool metrics2_use_default = false;
    double w2[10];
    gs_text_enum_t *penum = op_show_find(i_ctx_p);

    w2[0] = pwidth[0], w2[1] = pwidth[1];

    /* Adjust the bounding box for stroking if needed. */

    w2[2] = pbbox->p.x, w2[3] = pbbox->p.y;
    w2[4] = pbbox->q.x, w2[5] = pbbox->q.y;
    if (pbfont->PaintType != 0) {
	double expand = max(1.415, gs_currentmiterlimit(igs)) *
	gs_currentlinewidth(igs) / 2;

	w2[2] -= expand, w2[3] -= expand;
	w2[4] += expand, w2[5] += expand;
    }

    /* Check for Metrics2. */

    {
	int code = zchar_get_metrics2(pbfont, pcnref, w2 + 6);

	if (code < 0)
	    return code;
	metrics2 = code > 0;
    }

    /*
     * For FontType 9 and 11, if Metrics2 is missing, the caller provides
     * default Metrics2 values derived from the FontBBox.
     */
    if (!metrics2 && Metrics2_sbw_default != NULL) {
        w2[6] = Metrics2_sbw_default[2];
        w2[7] = Metrics2_sbw_default[3];
        w2[8] = Metrics2_sbw_default[0];
        w2[9] = Metrics2_sbw_default[1];
	metrics2 = true;
	metrics2_use_default = true;
    }

    /* Check for CDevProc or "short-circuiting". */

    have_cdevproc = zchar_get_CDevProc(pbfont, &pcdevproc);
    if (have_cdevproc || zchar_show_width_only(penum)) {
	int i;
	op_proc_t zsetc;
	int nparams;

	if (have_cdevproc) {
	    check_proc_only(*pcdevproc);
	    zsetc = zsetcachedevice2;
	    
	    /* If we have cdevproc and the font type is CID type 0,
	       we'll throw away Metrics2_sbw_default that is calculated 
	       from FontBBox. */
	    if (!metrics2 
		|| (penum->current_font->FontType == ft_CID_encrypted
		    && metrics2_use_default)) {
		w2[6] = w2[0], w2[7] = w2[1];
		w2[8] = w2[9] = 0;
	    }
	    nparams = 10;
	} else {
	    make_oper(&rpop, 0, zpop);
	    pcdevproc = &rpop;
	    if (metrics2)
		zsetc = zsetcachedevice2, nparams = 10;
	    else
		zsetc = zsetcachedevice, nparams = 6;
	}
	check_estack(3);
	/* Push the l.s.b. for .type1addpath if necessary. */
	if (psb != 0) {
	    push(nparams + 3);
	    make_real(op - (nparams + 2), psb[0]);
	    make_real(op - (nparams + 1), psb[1]);
	} else {
	    push(nparams + 1);
	}
	for (i = 0; i < nparams; ++i)
	    make_real(op - nparams + i, w2[i]);
	ref_assign(op, pcnref);
	push_op_estack(cont);
	push_op_estack(zsetc);
	++esp;
	ref_assign(esp, pcdevproc);
	return o_push_estack;
    } {
	int code =
	    (metrics2 ? gs_text_setcachedevice2(penum, w2) :
	     gs_text_setcachedevice(penum, w2));

	if (code < 0)
	    return code;
    }

    /* No metrics modification, do the stroke or fill now. */

    /* Push the l.s.b. for .type1addpath if necessary. */
    if (psb != 0) {
	push(2);
	make_real(op - 1, psb[0]);
	make_real(op, psb[1]);
    }
    *exec_cont = cont;
    return 0;
}