Пример #1
0
int MMFXFill(hotCtx g) {
    MMFXCtx h = g->ctx.MMFX;
    int i;
    Offset offset;

    if (!IS_MM(g)) {
        return 0;
    }

    /* Fill header */
    h->tbl.version  = VERSION(1, 0);
    h->tbl.nMetrics = (unsigned short)h->metrics.cnt;
    h->tbl.offSize  =
        (HEADER_SIZE + uint16 * h->metrics.cnt +
         h->metrics.array[h->metrics.cnt - 1].index > 65535) ? 4 : 2;

    /* Sort metrics by id */
    qsort(h->metrics.array, h->metrics.cnt, sizeof(Metric), cmpIds);

    /* Check if all named metrics present */
    for (i = 0; i < h->metrics.cnt; i++) {
        if (h->metrics.array[i].id >= MMFXNamedMetricCnt) {
            break;
        }
    }
    if (i < MMFXNamedMetricCnt) {
        hotMsg(g, hotFATAL, "Missing named metrics");
    }
    else if (i > MMFXNamedMetricCnt) {
        hotMsg(g, hotFATAL, "Duplicate named metrics");
    }

    /* Allocate and fill offset array */
    offset = (unsigned short)(HEADER_SIZE + h->tbl.offSize * h->metrics.cnt);
    h->tbl.offset = MEM_NEW(g, sizeof(long) * h->metrics.cnt);
    for (i = 0; i < h->metrics.cnt; i++) {
        h->tbl.offset[i] = offset + h->metrics.array[i].index;
    }

    return 1;
}
Пример #2
0
int MMSDFill(hotCtx g) {
    int i;
    Offset offset;
    MMSDCtx h = g->ctx.MMSD;

    if (!IS_MM(g)) {
        return 0;
    }

    h->tbl.version = VERSION(1, 0);
    h->tbl.flags = 0;
    if (g->font.flags & HOT_USE_FOR_SUBST) {
        h->tbl.flags |= MMSD_USE_FOR_SUBST;
    }
    if (g->font.flags & HOT_CANT_INSTANCE) {
        h->tbl.flags |= MMSD_CANT_INSTANCE;
    }

    /* Fill axis table */
    h->tbl.axis_.nAxes = (unsigned short)g->font.mm.axis.cnt;
    h->tbl.axis_.axisSize = AXIS_SIZE;
    h->tbl.axis_.axis_ = MEM_NEW(g, sizeof(AxisRec) * h->tbl.axis_.nAxes);
    for (i = 0; i < h->tbl.axis_.nAxes; i++) {
        AxisRec *dst = &h->tbl.axis_.axis_[i];
        MMAxis *src = &g->font.mm.axis.array[i];
        dst->longLabel_ = src->longLabel;
        dst->shortLabel_ = src->shortLabel;
    }

    if (g->font.mm.instance.cnt != 0) {
        /* Fill instance table */
        h->tbl.instance_.nInstances = (unsigned short)g->font.mm.instance.cnt;
        h->tbl.instance_.instanceSize = INSTANCE_SIZE;
        h->tbl.instance_.instance_ =
            MEM_NEW(g, sizeof(InstanceRec) * h->tbl.instance_.nInstances);
        for (i = 0; i < h->tbl.instance_.nInstances; i++) {
            h->tbl.instance_.instance_[i].nameSuffix_ =
                g->font.mm.instance.array[i].suffix;
        }
    } else {
        h->tbl.instance_.nInstances = 0;
    }

    if (g->font.mm.style.cnt != 0) {
        /* Fill style table */
        h->tbl.style_.nStyles = (unsigned short)g->font.mm.style.cnt;
        h->tbl.style_.styleSize = STYLE_SIZE;
        h->tbl.style_.style_ =
            MEM_NEW(g, sizeof(StyleRec) * h->tbl.style_.nStyles);
        for (i = 0; i < h->tbl.style_.nStyles; i++) {
            StyleRec *dst = &h->tbl.style_.style_[i];
            MMStyle *src = &g->font.mm.style.array[i];

            dst->axis = (unsigned char)src->axis;
            dst->flags = (unsigned char)src->flags;
            dst->action[0].point = src->action[0].point;
            dst->action[0].delta = src->action[0].delta;
            dst->action[1].point = src->action[1].point;
            dst->action[1].delta = src->action[1].delta;
        }
    } else {
        h->tbl.style_.nStyles = 0;
    }

    /* Fill offsets */
    h->tbl.axis = offset = HEADER_SIZE;
    offset += AXIS_TBL_SIZE(h);

    if (h->tbl.instance_.nInstances != 0) {
        h->tbl.instance = offset;
        offset += INSTANCE_TBL_SIZE(h);
    } else {
        h->tbl.instance = 0;
    }

    if (h->tbl.style_.nStyles != 0) {
        h->tbl.style = offset;
        offset += STYLE_TBL_SIZE(h);
    } else {
        h->tbl.style = 0;
    }

    /* Calculate string offsets */
    for (i = 0; i < h->tbl.axis_.nAxes; i++) {
        AxisRec *axis = &h->tbl.axis_.axis_[i];

        axis->longLabel = offset;
        offset += strlen(axis->longLabel_) + 1;
        axis->shortLabel = offset;
        offset += strlen(axis->shortLabel_) + 1;
    }
    if (h->tbl.instance != 0) {
        for (i = 0; i < h->tbl.instance_.nInstances; i++) {
            InstanceRec *instance = &h->tbl.instance_.instance_[i];

            instance->nameSuffix = offset;
            offset += strlen(instance->nameSuffix_) + 1;
        }
    }

    return 1;
}
Пример #3
0
/* Print proofs at the current UDV */
static void printCaretOffset(hotCtx g, short caretoff, int iMaster)
	{
#define IN2PIX(a) ((a)*72)
#define MARGIN 	  IN2PIX(.25)
#define PTSIZE    (60)
#define YTOP      IN2PIX(11.4)
#define LINEGAP   IN2PIX(1.3)
#define SCALE     ((double)PTSIZE/1000)
#define GAP (.15)

	hheaCtx h = g->ctx.hhea;
	int xLine;
	char msg[1024];
	static int caretPrint = 0;
	static double xCurr = MARGIN;
	static double yCurr = YTOP;

	if (caretPrint == 0)
		{
		printf("%%!\n"
			   "/_MT{moveto}bind def\n"
			   "/_NP{newpath}bind def\n"
			   "/_LT{lineto}bind def\n"
			   "/_CT{curveto}bind def\n"
			   "/_CP{closepath}bind def\n");
		printf("/Times-Roman findfont 9 scalefont setfont\n\n");
		caretPrint = 1;
		}

	printf("/caret {_NP "
		   "%hd %f mul %hd _MT "
		   "%hd %f mul %hd _LT\n"
		   " .1 setlinewidth stroke 0 0 _MT}bind def\n\n",
		   g->font.TypoAscender, h->caretoff.tangent, g->font.TypoAscender,
		   g->font.TypoDescender, h->caretoff.tangent, g->font.TypoDescender);

	/* Set up for a line */
	printf("gsave\n");
	yCurr -= LINEGAP;
	if (yCurr < MARGIN + IN2PIX(.3))
		{
		printf("showpage\n");
		yCurr = YTOP - LINEGAP;
		}

	printf("%f %f translate\n", xCurr, yCurr);

	/* Draw baselines */
	printf("0 0 _MT %d 0 _LT ", IN2PIX(5));
	printf("%f 0 _MT %f 0 _LT\n", IN2PIX(5 + GAP), (double)IN2PIX(8));
	printf(".1 setlinewidth stroke\n");

	/* Prepare message */
	sprintf(msg, "%d %s", caretoff, g->font.FontName.array);
	if (IS_MM(g))
		{
		if (iMaster == -1)
			sprintf(&msg[strlen(msg)], "[dflt]");
		else
			sprintf(&msg[strlen(msg)], "[%d/%d]",
					iMaster, g->font.mm.nMasters);
		}
	
	printf("0 -20 _MT (%s) show\n", msg);
	fprintf(stderr, "%s\n", msg);

	printf("%.3f %.3f scale\n", SCALE, SCALE);

	/* Print glyphs with offset */
	xLine = 0;
	printGlyphRun(g, &xLine, (int)(IN2PIX(5)/SCALE), caretoff, 1);

	/* Print some glyphs without the offset, for contrast */
	printf("%f 0 translate\n", IN2PIX(5 + GAP)/SCALE - xLine);
	xLine = (int)(IN2PIX(5 + GAP)/SCALE);
	printGlyphRun(g, &xLine, (int)(IN2PIX(8)/SCALE), caretoff, 0);

	printf("grestore\n");
	}
Пример #4
0
/* Calculate caret offset for an italic font. Shear heuristic glyph upright,
   calculate its left (a) and right (b) sidebearings. Return a-(a+b)/2 */
static short calcCaretOffset(hotCtx g)
	{
	hheaCtx h = g->ctx.hhea;
	unsigned int i;
	double a;
	double b;
	FWord hAdv;
	short caretoff;
	GID gid = GID_UNDEF;
	static cffPathCallbacks pathcb =
		{
		NULL,
		caretoffMoveto,
		caretoffLineto,
		caretoffCurveto,
		NULL,
		NULL,
		NULL,
		NULL,
		};
	UV uv[] =
		{
		UV_CARET_OFFSET_1,
		UV_CARET_OFFSET_2,
		UV_CARET_OFFSET_3,
		};

	/* Determine heuristic glyph */
	for (i = 0; i < ARRAY_LEN(uv); i++)
		if ((gid = mapUV2GID(g, uv[i])) != GID_UNDEF)
			break;
	if (gid == GID_UNDEF)
		return 0;

	h->caretoff.tangent = tan(FIX2DBL(-g->font.ItalicAngle) / RAD_DEG);
	h->caretoff.bboxLeft = DBL_MAX;
	h->caretoff.bboxRight = 0;

	if (IS_MM(g))
		cffSetUDV(g->ctx.cff, g->font.mm.axis.cnt, g->font.mm.UDV);
	hAdv = cffGetGlyphInfo(g->ctx.cff, gid, &pathcb)->hAdv;

	if (h->caretoff.bboxLeft == DBL_MAX)
		return 0;

	a = h->caretoff.bboxLeft;
	b = hAdv - h->caretoff.bboxRight;
	caretoff = (short)RND(a - (a + b) / 2);

#if HOT_DEBUG
#if 0
	printCaretOffset(g, caretoff, -1);
	if (IS_MM(g))
		{
		Fixed WV[TX_MAX_MASTERS];
		int i;
		for (i = 0; i < g->font.mm.nMasters; i++)
			WV[i] = 0;

		for (i = 0; i < g->font.mm.nMasters; i++)
			{
			WV[i] = INT2FIX(1);
			cffSetWV(g->ctx.cff, g->font.mm.nMasters, WV);
			printCaretOffset(g, caretoff, i);
			WV[i] = 0;
			}
		}
#endif
#endif

	return caretoff;
	}