Example #1
0
/* Get a Type 42 character metrics and set the cache device. */
int
zchar42_set_cache(i_ctx_t *i_ctx_p, gs_font_base *pbfont, ref *cnref, 
	    uint glyph_index, op_proc_t cont, op_proc_t *exec_cont, bool put_lsb)
{   double sbw[4];
    double w[2];
    int present;
    int code = zchar_get_metrics(pbfont, cnref, sbw);

    if (code < 0)
	return code;
    present = code;
    if (present == metricsNone) {
	float sbw42[4];
	int i;

	code = gs_type42_wmode_metrics((gs_font_type42 *)pbfont,
				       glyph_index, false, sbw42);
	if (code < 0)
	    return code;
	present = metricsSideBearingAndWidth;
	for (i = 0; i < 4; ++i)
	    sbw[i] = sbw42[i];
	w[0] = sbw[2];
	w[1] = sbw[3];
	if (gs_rootfont(igs)->WMode) { /* for vertically-oriented metrics */
	    code = gs_type42_wmode_metrics((gs_font_type42 *)pbfont,
					   glyph_index,
					   true, sbw42);
	    if (code < 0) { /* no vertical metrics */
		if (pbfont->FontType == ft_CID_TrueType) {
		    sbw[0] = sbw[2] / 2;
		    sbw[1] = pbfont->FontBBox.q.y;
		    sbw[2] = 0;
		    sbw[3] = pbfont->FontBBox.p.y - pbfont->FontBBox.q.y;
		}
	    } else {
		sbw[0] = sbw[2] / 2;
		sbw[1] = (pbfont->FontBBox.q.y + pbfont->FontBBox.p.y - sbw42[3]) / 2;
		sbw[2] = sbw42[2];
		sbw[3] = sbw42[3];
	    }
	}
    } else {
        w[0] = sbw[2];
        w[1] = sbw[3];
    }
    return zchar_set_cache(i_ctx_p, pbfont, cnref,
			   (put_lsb && present == metricsSideBearingAndWidth ?
			    sbw : NULL),
			   w, &pbfont->FontBBox,
			   cont, exec_cont,
			   gs_rootfont(igs)->WMode ? sbw : NULL);
}
Example #2
0
/* Continue from an OtherSubr callout while getting metrics. */
static int
bbox_getsbw_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    ref other_subr;
    gs_type1exec_state *pcxs = r_ptr(esp, gs_type1exec_state);
    gs_type1_state *const pcis = &pcxs->cis;
    int code;

    code = type1_continue_dispatch(i_ctx_p, pcxs, NULL, &other_subr, 4);
    op = osp;			/* in case z1_push/pop_proc was called */
    switch (code) {
        default:		/* code < 0 or done, error */
            op_type1_free(i_ctx_p);
            return ((code < 0 ? code : gs_note_error(e_invalidfont)));
        case type1_result_callothersubr:	/* unknown OtherSubr */
            return type1_push_OtherSubr(i_ctx_p, pcxs, bbox_getsbw_continue,
                                        &other_subr);
        case type1_result_sbw: {	/* [h]sbw, done */
            double sbw[4];
            const gs_font_base *const pbfont =
                (const gs_font_base *)pcis->pfont;
            gs_rect bbox;
            op_proc_t cont = (pbfont->PaintType == 0 ? bbox_finish_fill : bbox_finish_stroke), exec_cont = 0;

            /* Get the metrics before freeing the state. */
            type1_cis_get_metrics(pcis, sbw);
            bbox = pcxs->char_bbox;
            op_type1_free(i_ctx_p);
            code = zchar_set_cache(i_ctx_p, pbfont, op - 1, sbw, sbw + 2, &bbox,
                                   cont, &exec_cont, NULL);
            if (code >= 0 && exec_cont != 0)
                code = (*exec_cont)(i_ctx_p);
            return code;
        }
    }
}
Example #3
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));
    }
}