Пример #1
0
struct MATH *MathTableNew(SplineFont *sf) {
    struct MATH *math = gcalloc(1,sizeof(struct MATH));	/* Too big for chunkalloc */
    int emsize = sf->ascent+sf->descent;
    DBounds b;
    SplineChar *sc;

    math->ScriptPercentScaleDown	= 80;
    math->ScriptScriptPercentScaleDown	= 60;
    math->DelimitedSubFormulaMinHeight	= emsize*1.5;
    /* No default given for math->DisplayOperatorMinHeight */
    /* No default given for math->AxisHeight */
    sc = SFGetChar(sf,'x',NULL);
    if ( sc!=NULL ) {
	SplineCharFindBounds(sc,&b);
	math->AccentBaseHeight = b.maxy;
    }
    sc = SFGetChar(sf,'I',NULL);
    if ( sc!=NULL ) {
	SplineCharFindBounds(sc,&b);
	math->FlattenedAccentBaseHeight = b.maxy;
    }
    if ( sf->pfminfo.subsuper_set )
	math->SubscriptShiftDown = sf->pfminfo.os2_subyoff;
    math->SubscriptTopMax = math->AccentBaseHeight;		/* X-height */
    /* No default given for math->SubscriptBaselineDropMin */
    if ( sf->pfminfo.subsuper_set )
	math->SuperscriptShiftUp = sf->pfminfo.os2_supyoff;
    /* No default given for math->SuperscriptShiftUpCramped */
    math->SuperscriptBottomMin = math->AccentBaseHeight;	/* X-height */
    /* No default given for math->SuperscriptBaselineDropMax */
    math->SubSuperscriptGapMin = 4*sf->uwidth;			/* 4* default rule thickness */
    math->SuperscriptBottomMaxWithSubscript = math->AccentBaseHeight;	/* X-height */
    math->SpaceAfterScript = emsize/24;				/* .5pt at 12pt */
    math->StackGapMin = 3*sf->uwidth;				/* 3* default rule thickness */
    math->StackDisplayStyleGapMin = 7*sf->uwidth;
    math->StretchStackGapAboveMin = math->UpperLimitGapMin;
    math->StretchStackGapBelowMin = math->LowerLimitGapMin;
    math->FractionNumeratorDisplayStyleShiftUp = math->StackTopDisplayStyleShiftUp;
    math->FractionDenominatorDisplayStyleShiftDown = math->StackBottomDisplayStyleShiftDown;
    math->FractionNumeratorGapMin = sf->uwidth;
    math->FractionNumeratorDisplayStyleGapMin = 3*sf->uwidth;
    math->FractionRuleThickness = sf->uwidth;
    math->FractionDenominatorGapMin = sf->uwidth;
    math->FractionDenominatorDisplayStyleGapMin = 3*sf->uwidth;
    math->OverbarVerticalGap = 3*sf->uwidth;
    math->OverbarRuleThickness = sf->uwidth;
    math->OverbarExtraAscender = sf->uwidth;
    math->UnderbarVerticalGap = 3*sf->uwidth;
    math->UnderbarRuleThickness = sf->uwidth;
    math->UnderbarExtraDescender = sf->uwidth;
    math->RadicalVerticalGap = sf->uwidth;
    math->RadicalExtraAscender = sf->uwidth;
    math->RadicalKernBeforeDegree = 5*emsize/18;
    math->RadicalKernAfterDegree = -10*emsize/18;
    math->RadicalDegreeBottomRaisePercent = 60;

    math->MinConnectorOverlap = emsize/50;
return( math );
}
Пример #2
0
real SFGuessItalicAngle(SplineFont *sf) {
    static const char *easyserif = "IBDEFHKLNPR";
    int i,si;
    real as, topx, bottomx;
    DBounds bb;
    double angle;

    for ( i=0; easyserif[i]!='\0'; ++i )
	if ( (si=SFFindExistingSlot(sf,easyserif[i],NULL))!=-1 && sf->glyphs[si]!=NULL )
    break;
    if ( easyserif[i]=='\0' )		/* can't guess */
return( 0 );

    SplineCharFindBounds(sf->glyphs[si],&bb);
    as = bb.maxy-bb.miny;

    topx = SCFindMinXAtY(sf->glyphs[si],ly_fore,2*as/3+bb.miny);
    bottomx = SCFindMinXAtY(sf->glyphs[si],ly_fore,as/3+bb.miny);
    if ( topx==bottomx )
return( 0 );

    angle = atan2(as/3,topx-bottomx)*180/3.1415926535897932-90;
    if ( angle<1 && angle>-1 ) angle = 0;
return( angle );
}
Пример #3
0
static void SCDefWidthVal(char *buf,SplineChar *sc, enum widthtype wtype) {
    DBounds bb;

    if ( wtype==wt_width )
	sprintf( buf, "%d", sc->width );
    else if ( wtype==wt_vwidth )
	sprintf( buf, "%d", sc->vwidth );
    else {
	SplineCharFindBounds(sc,&bb);
	if ( wtype==wt_lbearing )
	    sprintf( buf, "%.4g", (double) bb.minx );
	else if ( wtype==wt_rbearing )
	    sprintf( buf, "%.4g", sc->width-(double) bb.maxx );
	else
	    sprintf( buf, "%.4g", rint( (sc->width-(double) bb.maxx + (double) bb.minx)/2 ) );
    }
}
Пример #4
0
static void BaseLang_FinishEdit(GGadget *g, int r, int c, int wasnew) {

    if ( wasnew && c==0 ) {
        BaseLangDlg *b = GDrawGetUserData(GGadgetGetWindow(g));
        int rows, cols = GMatrixEditGetColCnt(g);
        struct matrix_data *md = GMatrixEditGet(g,&rows);
        uint32 lang = TagFromString(md[r*cols+0].u.md_str);
        int gid;
        SplineChar *sc;
        DBounds bnd, scb;

        memset(&bnd,0,sizeof(bnd));
        for ( gid=0; gid<b->sf->glyphcnt; ++gid ) if ( (sc=b->sf->glyphs[gid])!=NULL ) {
                if ( lang==CHR('E','N','G',' ') && (sc->unicodeenc<0 || sc->unicodeenc>127))
                    /* English just uses ASCII */;
                else if ( b->script==CHR('l','a','t','n') &&
                          (sc->unicodeenc<0 || sc->unicodeenc>255) &&
                          lang!=CHR('V','I','T',' ') )
                    /* Most languages in latin script only use one accent per */
                    /*  letter. So latin1 should provide a reasonable bounding */
                    /*  box. Vietnamese is an exception. */;
                else if ( SCScriptFromUnicode(sc)!=b->script )
                    /* Not interesting */;
                else {
                    SplineCharFindBounds(sc,&scb);
                    if ( bnd.minx==bnd.maxx )
                        bnd = scb;
                    else {
                        if ( scb.minx<bnd.minx ) bnd.minx = scb.minx;
                        if ( scb.miny<bnd.miny ) bnd.miny = scb.miny;
                        if ( scb.maxx>bnd.maxx ) bnd.maxx = scb.maxx;
                        if ( scb.maxy>bnd.maxy ) bnd.maxy = scb.maxy;
                    }
                }
            }
        if ( b->vertical ) {
            md[r*cols+1].u.md_ival = floor(bnd.minx);
            md[r*cols+2].u.md_ival = ceil(bnd.maxx);
        } else {
            md[r*cols+1].u.md_ival = floor(bnd.miny);
            md[r*cols+2].u.md_ival = ceil(bnd.maxy);
        }
    }
}
Пример #5
0
static void DoChar(SplineChar *sc,CreateWidthData *wd, FontViewBase *fv,
	BDFChar *bc) {
    real transform[6];
    DBounds bb;
    IBounds ib;
    int width=0;
    BVTFunc bvts[2];
    BDFFont *bdf;
    RefChar *r = HasUseMyMetrics(sc,fv->active_layer);

    /* Can't change the horizontal or vertical advance if there's a "use my metrics" bit set */
    if ( r!=NULL && wd->wtype != wt_lbearing )
return;

    if ( wd->wtype == wt_width ) {
	if ( wd->type==st_set )
	    width = wd->setto;
	else if ( wd->type == st_incr )
	    width = sc->width + wd->increment;
	else
	    width = sc->width * wd->scale/100;
	sc->widthset = true;
	if ( width!=sc->width ) {
	    SCPreserveWidth(sc);
	    SCSynchronizeWidth(sc,width,sc->width,fv);
	}
    } else if ( wd->wtype == wt_lbearing ) {
	transform[0] = transform[3] = 1.0;
	transform[1] = transform[2] = transform[5] = 0;
	bvts[1].func = bvt_none;
	bvts[0].func = bvt_transmove; bvts[0].y = 0;
	if ( bc==NULL ) {
	    SplineCharFindBounds(sc,&bb);
	    if ( wd->type==st_set )
		transform[4] = wd->setto-bb.minx;
	    else if ( wd->type == st_incr )
		transform[4] = wd->increment;
	    else
		transform[4] = bb.minx*wd->scale/100 - bb.minx;
	} else {
	    double scale = (fv->sf->ascent+fv->sf->descent)/(double) (fv->active_bitmap->pixelsize);
	    BDFCharFindBounds(bc,&ib);
	    if ( wd->type==st_set )
		transform[4] = wd->setto-ib.minx*scale;
	    else if ( wd->type == st_incr )
		transform[4] = wd->increment;
	    else
		transform[4] = scale*ib.minx*wd->scale/100 - ib.minx;
	}
	if ( transform[4]!=0 ) {
	    FVTrans(fv,sc,transform,NULL,fvt_dontmovewidth);
	    bvts[0].x = transform[4];
	    for ( bdf = fv->sf->bitmaps; bdf!=NULL; bdf=bdf->next ) if ( bdf->glyphs[sc->orig_pos]!=NULL )
		BCTrans(bdf,bdf->glyphs[sc->orig_pos],bvts,fv);
	}
return;
    } else if ( wd->wtype == wt_rbearing ) {
	if ( bc==NULL ) {
	    SplineCharFindBounds(sc,&bb);
	    if ( wd->type==st_set )
		width = bb.maxx + wd->setto;
	    else if ( wd->type == st_incr )
		width = sc->width+wd->increment;
	    else
		width = (sc->width-bb.maxx) * wd->scale/100 + bb.maxx;
	} else {
	    double scale = (fv->sf->ascent+fv->sf->descent)/(double) (fv->active_bitmap->pixelsize);
	    BDFCharFindBounds(bc,&ib);
	    ++ib.maxx;
	    if ( wd->type==st_set )
		width = rint(ib.maxx*scale + wd->setto);
	    else if ( wd->type == st_incr )
		width = rint(sc->width+wd->increment);
	    else
		width = rint(scale * (bc->width-ib.maxx) * wd->scale/100 + ib.maxx*scale);
	}
	if ( width!=sc->width ) {
	    SCPreserveWidth(sc);
	    SCSynchronizeWidth(sc,width,sc->width,fv);
	}
    } else if ( wd->wtype == wt_bearings ) {
	transform[0] = transform[3] = 1.0;
	transform[1] = transform[2] = transform[5] = 0;
	bvts[1].func = bvt_none;
	bvts[0].func = bvt_transmove; bvts[0].y = 0;
	if ( bc==NULL ) {
	    SplineCharFindBounds(sc,&bb);
	    if ( wd->type==st_set ) {
		transform[4] = wd->setto-bb.minx;
		width = bb.maxx-bb.minx + 2*wd->setto;
	    } else if ( wd->type == st_incr ) {
		transform[4] = wd->increment;
		width += 2*wd->increment;
	    } else {
		transform[4] = bb.minx*wd->scale/100 - bb.minx;
		width = bb.maxx-bb.minx +
			(bb.minx + (sc->width-bb.maxx))*wd->scale/100;
	    }
	} else {
	    double scale = (fv->sf->ascent+fv->sf->descent)/(double) (fv->active_bitmap->pixelsize);
	    BDFCharFindBounds(bc,&ib);
	    ++ib.maxx;
	    if ( wd->type==st_set ) {
		transform[4] = wd->setto-ib.minx;
		width = (ib.maxx-ib.minx + 2*wd->setto);
	    } else if ( wd->type == st_incr ) {
		transform[4] = wd->increment;
		width += 2*wd->increment;
	    } else {
		transform[4] = ib.minx*wd->scale/100 - ib.minx;
		width = ib.maxx-ib.minx +
			(ib.minx + (bc->width-ib.maxx))*wd->scale/100;
	    }
	    transform[4] *= scale;
	    width = rint(width*scale);
	}
	if ( width!=sc->width ) {
	    SCPreserveWidth(sc);
	    SCSynchronizeWidth(sc,width,sc->width,fv);
	}
	if ( transform[4]!=0 ) {
	    FVTrans(fv,sc,transform,NULL,fvt_dontmovewidth);
	    bvts[0].x = transform[4];
	    for ( bdf = fv->sf->bitmaps; bdf!=NULL; bdf=bdf->next ) if ( bdf->glyphs[sc->orig_pos]!=NULL )
		BCTrans(bdf,bdf->glyphs[sc->orig_pos],bvts,fv);
	}
return;
    } else {
	if ( wd->type==st_set )
	    width = wd->setto;
	else if ( wd->type == st_incr )
	    width = sc->vwidth + wd->increment;
	else
	    width = sc->vwidth * wd->scale/100;
	if ( width!=sc->vwidth ) {
	    SCPreserveVWidth(sc);
	    sc->vwidth = width;
	}
    }
    SCCharChangedUpdate(sc,fv->active_layer);
}