Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add support for glyphs with encodings in PUA when in BMP but with pro…

…per encodings in another plane.

Add support for AMS reencoding of glyphs into PUA.
Add Build Duplicate (element menu & scripting) command.
Recovery files should now preserve unicode interp.
  • Loading branch information...
commit 205e065453b15ed80fd0b5a29d943c60cecffba4 1 parent d5a6453
George Williams authored
View
2  fontforge/Makefile.dynamic.in
@@ -38,7 +38,7 @@ fontforge_OBJECTS = autohint.o autosave.o autowidth.o bitmapdlg.o \
cvdebug.o showatt.o kernclass.o nonlineartrans.o effects.o \
histograms.o ttfspecial.o svg.o parsettfatt.o contextchain.o \
macenc.o statemachine.o typofeatures.o splinerefigure.o mm.o \
- parsettfvar.o tottfvar.o
+ parsettfvar.o tottfvar.o pua.o
DIFFOBJS = sfddiff.o sfd.o diffstubs.o stamp.o
ACORNOBJS = acorn2sfd.o sfd.o diffstubs.o psunicodenames.o stamp.o
View
2  fontforge/Makefile.in
@@ -38,7 +38,7 @@ fontforge_OBJECTS = autohint.o autosave.o autowidth.o bitmapdlg.o \
cvdebug.o showatt.o kernclass.o nonlineartrans.o effects.o \
histograms.o ttfspecial.o svg.o parsettfatt.o contextchain.o \
macenc.o statemachine.o typofeatures.o splinerefigure.o mm.o \
- parsettfvar.o tottfvar.o
+ parsettfvar.o tottfvar.o pua.o
DIFFOBJS = sfddiff.o sfd.o diffstubs.o stamp.o
ACORNOBJS = acorn2sfd.o sfd.o diffstubs.o psunicodenames.o stamp.o
View
2  fontforge/Makefile.static.in
@@ -33,7 +33,7 @@ fontforge_OBJECTS = autohint.o autosave.o autowidth.o bitmapdlg.o \
cvdebug.o showatt.o kernclass.o nonlineartrans.o effects.o \
histograms.o ttfspecial.o svg.o parsettfatt.o contextchain.o \
macenc.o statemachine.o typofeatures.o splinerefigure.o mm.o \
- parsettfvar.o tottfvar.o
+ parsettfvar.o tottfvar.o pua.o
DIFFOBJS = sfddiff.o sfd.o diffstubs.o stamp.o
ACORNOBJS = acorn2sfd.o sfd.o diffstubs.o psunicodenames.o stamp.o
View
26 fontforge/charinfo.c
@@ -4511,7 +4511,7 @@ static void psinitnames(void) {
psnamesinited = true;
}
-int UniFromName(const char *name) {
+int UniFromName(const char *name,enum uni_interp interp,int encname) {
int i = -1;
char *end;
struct psbucket *buck;
@@ -4524,6 +4524,16 @@ int UniFromName(const char *name) {
i = strtol(name+1,&end,16);
if ( *end )
i = -1;
+ else if ( encname!=em_unicode4 && (interp==ui_ams || interp==ui_trad_chinese)) {
+ int j;
+ extern const int cns14pua[], amspua[];
+ const int *pua = interp==ui_ams ? amspua : cns14pua;
+ for ( j=0xf8ff-0xe000; j>=0; --j )
+ if ( pua[j]==i ) {
+ i = j+0xe000;
+ break;
+ }
+ }
} else if ( name[0]=='U' && name[1]=='+' && strlen(name)==6 ) {
/* Unifont uses this convention */
i = strtol(name+2,&end,16);
@@ -4542,7 +4552,7 @@ int UniFromName(const char *name) {
return( i );
}
-int uUniFromName(const unichar_t *name) {
+int uUniFromName(const unichar_t *name,enum uni_interp interp,int encname) {
int i = -1;
unichar_t *end;
@@ -4554,6 +4564,16 @@ int uUniFromName(const unichar_t *name) {
i = u_strtol(name+1,&end,16);
if ( *end )
i = -1;
+ else if ( encname!=em_unicode4 && (interp==ui_ams || interp==ui_trad_chinese)) {
+ int j;
+ extern const int cns14pua[], amspua[];
+ const int *pua = interp==ui_ams ? amspua : cns14pua;
+ for ( j=0xf8ff-0xe000; j>=0; --j )
+ if ( pua[j]==i ) {
+ i = j+0xe000;
+ break;
+ }
+ }
} else if ( name[0]=='U' && name[1]=='+' && u_strlen(name)==6 ) {
/* Unifont uses this convention */
i = u_strtol(name+2,&end,16);
@@ -5146,7 +5166,7 @@ static int CI_SName(GGadget *g, GEvent *e) { /* Set From Name */
const unichar_t *ret = _GGadgetGetTitle(GWidgetGetControl(ci->gw,CID_UName));
int i;
char buf[40]; unichar_t ubuf[2], *temp;
- i = uUniFromName(ret);
+ i = uUniFromName(ret,ui_none,em_custom);
if ( i==-1 ) {
/* Adobe says names like uni00410042 represent a ligature (A&B) */
/* (that is "uni" followed by two 4-digit codes). */
View
2  fontforge/descrip.mms
@@ -22,7 +22,7 @@ fontforge_OBJECTS2=displayfonts.obj,combinations.obj,sftextfield.obj,ikarus.obj,
cvdebug.obj,showatt.obj,kernclass.obj,nonlineartrans.obj,effects.obj,\
histograms.obj,ttfspecial.obj,svg.obj,parsettfatt.obj,contextchain.obj,\
macenc.obj,statemachine.obj,typofeatures.obj,splinerefigure.obj,mm.obj,\
- parsettfvar.obj,tottfvar.obj
+ parsettfvar.obj,tottfvar.obj,pua.obj
fontforge.exe : nomen.h $(fontforge_OBJECTS) $(fontforge_OBJECTS2) xlib.opt
library/create tmp.olb $(fontforge_OBJECTS)
View
80 fontforge/fontinfo.c
@@ -1729,6 +1729,72 @@ void SFRestoreNearTop(SplineFont *sf) {
#endif /* FONTFORGE_CONFIG_NO_WINDOWING_UI */
}
+static void SFToPUA(SplineFont *sf) {
+ int i, j;
+ extern const int cns14pua[], amspua[];
+ const int *pua;
+ int low, high;
+ BDFFont *bdf;
+
+ if ( sf->uni_interp==ui_trad_chinese ) {
+ pua = cns14pua;
+ low = 0x20000;
+ high = 0x2ffff;
+ } else {
+ pua = amspua;
+ low = 0x1d400;
+ high = 0x1d7ff;
+ }
+
+ for ( i=low; i<sf->charcnt && i<=high; ++i ) {
+ if ( sf->chars[i]!=NULL ) {
+ for ( j=0xf8ff-0xe000; j>=0; --j )
+ if ( pua[j] == i )
+ break;
+ if ( j>=0 ) {
+ j += 0xe000;
+ if ( sf->chars[j]!=NULL ) {
+ sf->chars[j] = sf->chars[i];
+ sf->chars[i] = NULL;
+ sf->chars[j]->unicodeenc = j;
+ sf->chars[j]->enc = j;
+ for ( bdf=sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
+ if ( j<bdf->charcnt && bdf->chars[j]==NULL && bdf->chars[i]!=NULL ) {
+ bdf->chars[j] = bdf->chars[i];
+ bdf->chars[i] = NULL;
+ bdf->chars[j]->enc = j;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static void SFFromPUA(SplineFont *sf) {
+ int i, j;
+ extern const int cns14pua[], amspua[];
+ const int *pua = sf->uni_interp==ui_trad_chinese ? cns14pua : amspua;
+ BDFFont *bdf;
+
+ for ( i=0xe000; i<sf->charcnt && i<=0xf8ff; ++i ) {
+ if ( sf->chars[i]!=NULL && (j=pua[i-0xe000])>0x10000 && j<sf->charcnt &&
+ sf->chars[j]==NULL ) {
+ sf->chars[j] = sf->chars[i];
+ sf->chars[i] = NULL;
+ sf->chars[j]->unicodeenc = j;
+ sf->chars[j]->enc = j;
+ for ( bdf=sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
+ if ( j<bdf->charcnt && bdf->chars[j]==NULL && bdf->chars[i]!=NULL ) {
+ bdf->chars[j] = bdf->chars[i];
+ bdf->chars[i] = NULL;
+ bdf->chars[j]->enc = j;
+ }
+ }
+ }
+ }
+}
+
/* see also SplineFontNew in splineutil2.c */
static int __SFReencodeFont(SplineFont *sf,enum charset new_map,
SplineFont *target) {
@@ -1748,6 +1814,8 @@ static int __SFReencodeFont(SplineFont *sf,enum charset new_map,
if ( target==NULL ) {
if ( sf->encoding_name==new_map )
return(false);
+ if ( sf->encoding_name==em_unicode4 && (sf->uni_interp==ui_ams || sf->uni_interp==ui_trad_chinese))
+ SFToPUA(sf);
if ( new_map==em_custom ) {
sf->encoding_name=em_custom; /* Custom, it's whatever's there */
return(false);
@@ -1897,11 +1965,6 @@ return( false );
sf->chars = chars;
sf->charcnt = enc_cnt+extras;
sf->encoding_name = new_map;
- for ( i=0; i<sf->charcnt; ++i ) if ( sf->chars[i]!=NULL ) {
- for ( refs=sf->chars[i]->layers[ly_fore].refs; refs!=NULL; refs = refs->next )
- refs->local_enc = refs->sc->enc;
- }
-
for ( bdf=sf->bitmaps; bdf!=NULL; bdf = bdf->next ) {
free(bdf->chars);
bdf->chars = bdf->temp;
@@ -1909,6 +1972,13 @@ return( false );
bdf->charcnt = enc_cnt+extras;
bdf->encoding_name = new_map;
}
+ if ( sf->encoding_name==em_unicode4 && (sf->uni_interp==ui_ams || sf->uni_interp==ui_trad_chinese))
+ SFFromPUA(sf);
+ for ( i=0; i<sf->charcnt; ++i ) if ( sf->chars[i]!=NULL ) {
+ for ( refs=sf->chars[i]->layers[ly_fore].refs; refs!=NULL; refs = refs->next )
+ refs->local_enc = refs->sc->enc;
+ }
+
free(sf->remap);
sf->remap = NULL;
sf->encodingchanged = true;
View
253 fontforge/fontview.c
@@ -1394,6 +1394,7 @@ void FontViewMenu_MetaFont(GtkMenuItem *menuitem, gpointer user_data) {
#define MID_ShowDependentSubs 2234
#define MID_DefaultATT 2235
#define MID_POV 2236
+#define MID_BuildDuplicates 2237
#define MID_Center 2600
#define MID_Thirds 2601
#define MID_SetWidth 2602
@@ -3265,6 +3266,97 @@ void FontViewMenu_Transform(GtkMenuItem *menuitem, gpointer user_data) {
}
#endif
+static int SFIsDuplicatable(SplineFont *sf, SplineChar *sc) {
+ extern const int cns14pua[], amspua[];
+ const int *pua = sf->uni_interp==ui_trad_chinese ? cns14pua : sf->uni_interp==ui_ams ? amspua : NULL;
+ int baseuni = 0;
+ const unichar_t *pt;
+
+ if ( pua!=NULL && sc->unicodeenc>=0xe000 && sc->unicodeenc<=0xf8ff )
+ baseuni = pua[sc->unicodeenc-0xe000];
+ if ( baseuni==0 && ( pt = SFGetAlternate(sf,sc->unicodeenc,sc,false))!=NULL &&
+ pt[0]!='\0' && pt[1]=='\0' )
+ baseuni = pt[0];
+ if ( baseuni!=0 && SFGetCharDup(sf,baseuni,NULL)!=NULL )
+return( true );
+
+return( false );
+}
+
+void FVBuildDuplicate(FontView *fv) {
+ extern const int cns14pua[], amspua[];
+ const int *pua = fv->sf->uni_interp==ui_trad_chinese ? cns14pua : fv->sf->uni_interp==ui_ams ? amspua : NULL;
+ int i, cnt=0;
+ SplineChar dummy;
+ const unichar_t *pt;
+ RefChar *ref;
+
+ for ( i=0; i<fv->sf->charcnt; ++i ) if ( fv->selected[i] )
+ ++cnt;
+# ifdef FONTFORGE_CONFIG_GDRAW
+ GProgressStartIndicatorR(10,_STR_BuildingDuplicates,_STR_BuildingDuplicates,_STR_NULL,cnt,1);
+# elif defined(FONTFORGE_CONFIG_GTK)
+ gwwv_progress_start_indicator(10,_("Building duplicate encodings"),_("Building duplicate encodings"),NULL,cnt,1);
+# endif
+
+ for ( i=0; i<fv->sf->charcnt; ++i ) if ( fv->selected[i] ) {
+ SplineChar *sc = fv->sf->chars[i], *basesc;
+ int baseuni = 0;
+ if ( sc==NULL )
+ sc = SCBuildDummy(&dummy,fv->sf,i);
+ if ( pua!=NULL && sc->unicodeenc>=0xe000 && sc->unicodeenc<=0xf8ff )
+ baseuni = pua[sc->unicodeenc-0xe000];
+ if ( baseuni==0 && ( pt = SFGetAlternate(fv->sf,sc->unicodeenc,sc,false))!=NULL &&
+ pt[0]!='\0' && pt[1]=='\0' )
+ baseuni = pt[0];
+ if ( baseuni!=0 && (basesc = SFGetCharDup(fv->sf,baseuni,NULL))!=NULL ) {
+ if ( fv->sf->chars[i]==NULL )
+ fv->sf->chars[i] = MakeDupRef(basesc,i,sc->unicodeenc);
+ else {
+ SCPreserveState(sc,2);
+ SCClearContents(sc);
+ free(sc->name);
+ sc->name = basesc->name;
+ sc->width = basesc->width; sc->vwidth = basesc->vwidth;
+ ref = RefCharCreate();
+ sc->layers[ly_fore].refs = ref;
+ ref->sc = basesc;
+ ref->local_enc = basesc->enc;
+ ref->unicode_enc = basesc->unicodeenc;
+ ref->adobe_enc = getAdobeEnc(basesc->name);
+ ref->transform[0] = ref->transform[3] = 1;
+ SCReinstanciateRefChar(sc,ref);
+ SCMakeDependent(sc,basesc);
+ }
+ SCCharChangedUpdate(fv->sf->chars[i]);
+ }
+#ifndef FONTFORGE_CONFIG_NO_WINDOWING_UI
+# ifdef FONTFORGE_CONFIG_GDRAW
+ if ( !GProgressNext())
+# elif defined(FONTFORGE_CONFIG_GTK)
+ if ( !gwwv_progress_next())
+# endif
+ break;
+#endif /* FONTFORGE_CONFIG_NO_WINDOWING_UI */
+ }
+# ifdef FONTFORGE_CONFIG_GDRAW
+ GProgressEndIndicator();
+# elif defined(FONTFORGE_CONFIG_GTK)
+ gwwv_progress_end_indicator();
+# endif
+}
+
+#ifndef FONTFORGE_CONFIG_NO_WINDOWING_UI
+# if defined(FONTFORGE_CONFIG_GDRAW)
+static void FVMenuBuildDuplicate(GWindow gw,struct gmenuitem *mi,GEvent *e) {
+ FVBuildDuplicate( (FontView *) GDrawGetUserData(gw));
+# elif defined(FONTFORGE_CONFIG_GTK)
+void FontViewMenu_Transform(GtkMenuItem *menuitem, gpointer user_data) {
+ FVBuildDuplicate( (FontView *) FV_From_MI(menuitem));
+# endif
+}
+#endif
+
int ScriptLangMatch(struct script_record *sr,uint32 script,uint32 lang) {
int i, j;
@@ -5058,7 +5150,8 @@ static void ellistcheck(GWindow gw,struct gmenuitem *mi,GEvent *e) {
sc = fv->sf->chars[i];
if ( sc==NULL )
sc = SCBuildDummy(&dummy,fv->sf,i);
- if ( SFIsSomethingBuildable(fv->sf,sc,false)) {
+ if ( SFIsSomethingBuildable(fv->sf,sc,false) ||
+ SFIsDuplicatable(fv->sf,sc)) {
anybuildable = true;
break;
}
@@ -5149,6 +5242,20 @@ static void balistcheck(GWindow gw,struct gmenuitem *mi,GEvent *e) {
}
}
mi->ti.disabled = !anybuildable;
+ } else if ( mi->mid==MID_BuildDuplicates ) {
+ int anybuildable = false;
+ int i;
+ for ( i=0; i<fv->sf->charcnt; ++i ) if ( fv->selected[i] ) {
+ SplineChar *sc, dummy;
+ sc = fv->sf->chars[i];
+ if ( sc==NULL )
+ sc = SCBuildDummy(&dummy,fv->sf,i);
+ if ( SFIsDuplicatable(fv->sf,sc)) {
+ anybuildable = true;
+ break;
+ }
+ }
+ mi->ti.disabled = !anybuildable;
}
}
}
@@ -5349,6 +5456,7 @@ static GMenuItem eflist[] = {
static GMenuItem balist[] = {
{ { (unichar_t *) _STR_Buildaccent, NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 'B' }, 'A', ksm_control|ksm_shift, NULL, NULL, FVMenuBuildAccent, MID_BuildAccent },
{ { (unichar_t *) _STR_Buildcomposit, NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 'B' }, '\0', ksm_control|ksm_shift, NULL, NULL, FVMenuBuildComposite, MID_BuildComposite },
+ { { (unichar_t *) _STR_BuildDuplicates, NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 1, 0, 'B' }, '\0', ksm_control|ksm_shift, NULL, NULL, FVMenuBuildDuplicate, MID_BuildDuplicates },
{ NULL }
};
@@ -6756,6 +6864,66 @@ return( i );
return( -1 );
}
+char *StdGlyphName(char *buffer, int uni,enum uni_interp interp) {
+ char *name = NULL;
+ int j;
+
+ if ( (uni>=0 && uni<' ') ||
+ (uni>=0x7f && uni<0xa0) )
+ /* standard controls */;
+ else if ( uni!=-1 ) {
+ if ( uni>=0xe000 && uni<=0xf8ff &&
+ (interp==ui_trad_chinese || interp==ui_ams)) {
+ extern const int cns14pua[], amspua[];
+ const int *pua = interp==ui_trad_chinese ? cns14pua : amspua;
+ if ( pua[uni-0xe000]!=0 )
+ uni = pua[uni-0xe000];
+ }
+ if ( uni<psunicodenames_cnt )
+ name = (char *) psunicodenames[uni];
+ if ( name==NULL &&
+ (interp==ui_adobe || interp==ui_ams) &&
+ ((uni>=0xe000 && uni<=0xf7ff ) ||
+ (uni>=0xfb00 && uni<=0xfb06 ))) {
+ int provenance = interp==ui_adobe ? 1 : 2;
+ /* If we are using Adobe's interpretation of the private use */
+ /* area (which means small caps, etc. Then look for those */
+ /* names (also include the names for ligatures) */
+ for ( j=0; psaltuninames[j].name!=NULL; ++j ) {
+ if ( psaltuninames[j].unicode == uni &&
+ psaltuninames[j].provenance == provenance ) {
+ name = psaltuninames[j].name;
+ break;
+ }
+ }
+ }
+ if ( name==NULL ) {
+ if ( uni==0x2d )
+ name = "hyphen-minus";
+ else if ( uni==0xad )
+ name = "softhyphen";
+ else if ( uni==0x00 )
+ name = ".notdef";
+ else if ( uni==0xa0 )
+ name = "nonbreakingspace";
+ else if ( uni==0x03bc && interp==ui_greek )
+ name = "mu.greek";
+ else if ( uni==0x0394 && interp==ui_greek )
+ name = "Delta.greek";
+ else if ( uni==0x03a9 && interp==ui_greek )
+ name = "Omega.greek";
+ else {
+ if ( uni>=0x10000 )
+ sprintf( buffer, "u%04X", uni);
+ else
+ sprintf( buffer, "uni%04X", uni);
+ name = buffer;
+ }
+ }
+ }
+return( name );
+}
+
SplineChar *SCBuildDummy(SplineChar *dummy,SplineFont *sf,int i) {
static char namebuf[100];
#ifdef FONTFORGE_CONFIG_TYPE3
@@ -6792,53 +6960,10 @@ SplineChar *SCBuildDummy(SplineChar *dummy,SplineFont *sf,int i) {
if ( sf->cidmaster!=NULL )
dummy->name = namebuf;
- else if ( (dummy->unicodeenc>=0 && dummy->unicodeenc<' ') ||
- (dummy->unicodeenc>=0x7f && dummy->unicodeenc<0xa0) )
- /* standard controls */;
- else if ( dummy->unicodeenc!=-1 ) {
- if ( dummy->unicodeenc<psunicodenames_cnt )
- dummy->name = (char *) psunicodenames[dummy->unicodeenc];
- if ( dummy->name==NULL &&
- (sf->uni_interp==ui_adobe || sf->uni_interp==ui_ams) &&
- ((dummy->unicodeenc>=0xe000 && dummy->unicodeenc<=0xf7ff ) ||
- (dummy->unicodeenc>=0xfb00 && dummy->unicodeenc<=0xfb06 ))) {
- int provenance = sf->uni_interp==ui_adobe ? 1 : 2;
- /* If we are using Adobe's interpretation of the private use */
- /* area (which means small caps, etc. Then look for those */
- /* names (also include the names for ligatures) */
- for ( j=0; psaltuninames[j].name!=NULL; ++j ) {
- if ( psaltuninames[j].unicode == dummy->unicodeenc &&
- psaltuninames[j].provenance == provenance ) {
- dummy->name = psaltuninames[j].name;
- break;
- }
- }
- }
- if ( dummy->name==NULL ) {
- if ( dummy->unicodeenc==0x2d )
- dummy->name = "hyphen-minus";
- else if ( dummy->unicodeenc==0xad )
- dummy->name = "softhyphen";
- else if ( dummy->unicodeenc==0x00 )
- dummy->name = ".notdef";
- else if ( dummy->unicodeenc==0xa0 )
- dummy->name = "nonbreakingspace";
- else if ( dummy->unicodeenc==0x03bc && sf->uni_interp==ui_greek )
- dummy->name = "mu.greek";
- else if ( dummy->unicodeenc==0x0394 && sf->uni_interp==ui_greek )
- dummy->name = "Delta.greek";
- else if ( dummy->unicodeenc==0x03a9 && sf->uni_interp==ui_greek )
- dummy->name = "Omega.greek";
- else {
- if ( dummy->unicodeenc>=0x10000 )
- sprintf( namebuf, "u%04X", dummy->unicodeenc);
- else
- sprintf( namebuf, "uni%04X", dummy->unicodeenc);
- dummy->name = namebuf;
- }
- }
- } else if ( item!=NULL && item->psnames!=NULL )
+ else if ( item!=NULL && item->psnames!=NULL )
dummy->name = item->psnames[i];
+ else
+ dummy->name = StdGlyphName(namebuf,dummy->unicodeenc,sf->uni_interp);
if ( dummy->name==NULL ) {
if ( dummy->unicodeenc!=-1 || i<256 )
dummy->name = ".notdef";
@@ -6863,10 +6988,11 @@ return( dummy );
static SplineChar *_SFMakeChar(SplineFont *sf,int i) {
SplineChar dummy, *sc;
SplineFont *ssf;
- int j;
+ int j, real_uni;
#ifdef FONTFORGE_CONFIG_TYPE3
Layer *l;
#endif
+ extern const int cns14pua[], amspua[];
if ( sf->subfontcnt!=0 ) {
ssf = NULL;
@@ -6881,6 +7007,19 @@ return( ssf->chars[i] );
}
if ( (sc = sf->chars[i])==NULL ) {
+ if (( sf->encoding_name == em_unicode || sf->encoding_name == em_unicode4 ) &&
+ ( i>=0xe000 && i<=0xf8ff ) &&
+ ( sf->uni_interp==ui_ams || sf->uni_interp==ui_trad_chinese ) &&
+ ( real_uni = (sf->uni_interp==ui_ams ? amspua : cns14pua)[i-0xe000])!=0 ) {
+ if ( real_uni<sf->charcnt ) {
+ /* if necessary, create the real unicode code point */
+ /* and then make us be a duplicate of it */
+ sf->chars[i] = MakeDupRef(_SFMakeChar(sf,real_uni),i,i);
+ SCCharChangedUpdate(sf->chars[i]);
+return( sf->chars[i] );
+ }
+ }
+
SCBuildDummy(&dummy,sf,i);
sf->chars[i] = sc = SplineCharCreate();
#ifdef FONTFORGE_CONFIG_TYPE3
@@ -7330,19 +7469,25 @@ static void FVExpose(FontView *fv,GWindow pixmap,GEvent *event) {
Color fg = 0;
FontMods *mods=NULL;
static FontMods for_charset;
+ extern const int amspua[];
+ int uni;
if ( sc==NULL )
sc = SCBuildDummy(&dummy,fv->sf,index);
- if ( sc->unicodeenc==0xad )
+ uni = sc->unicodeenc;
+ if ( fv->sf->uni_interp==ui_ams && uni>=0xe000 && uni<=0xf8ff &&
+ amspua[uni-0xe000]!=0 )
+ uni = amspua[uni-0xe000];
+ if ( uni==0xad )
buf[0] = '-';
else if ( Use2ByteEnc(fv,sc,buf,&for_charset))
mods = &for_charset;
- else if ( sc->unicodeenc!=-1 && sc->unicodeenc<65536 )
- buf[0] = sc->unicodeenc;
- else if ( sc->unicodeenc>=0x1d400 && sc->unicodeenc<=0x1d7ff ) {
+ else if ( uni!=-1 && uni<65536 )
+ buf[0] = uni;
+ else if ( uni>=0x1d400 && uni<=0x1d7ff ) {
int i;
for ( i=0; mathmap[i].start!=0; ++i ) {
- if ( sc->unicodeenc<=mathmap[i].last ) {
- buf[0] = maps[mathmap[i].charset][sc->unicodeenc-mathmap[i].start];
+ if ( uni<=mathmap[i].last ) {
+ buf[0] = maps[mathmap[i].charset][uni-mathmap[i].start];
styles = mathmap[i].styles;
break;
}
View
4 fontforge/fvimportbdf.c
@@ -150,7 +150,7 @@ static void MakeEncChar(SplineFont *sf,int enc,char *name) {
free(sf->chars[enc]->name);
sf->chars[enc]->name = cleancopy(name);
- uni = UniFromName(name);
+ uni = UniFromName(name,sf->uni_interp,sf->encoding_name);
if ( uni!=-1 )
sf->chars[enc]->unicodeenc = uni;
sf->chars[enc]->enc = enc;
@@ -183,7 +183,7 @@ static int figureProperEncoding(SplineFont *sf,BDFFont *b, int enc,char *name,
} else {
int32 uni = UniFromEnc(enc,encname);
if ( uni==-1 )
- uni = UniFromName(name);
+ uni = UniFromName(name,sf->uni_interp,sf->encoding_name);
i = EncFromSF(uni,sf);
if ( uni!=-1 && i>=sf->charcnt &&
(sf->encoding_name==em_iso8859_1 || sf->encoding_name==em_unicode))
View
2  fontforge/gotodlg.c
@@ -395,7 +395,7 @@ return( enc );
}
} else {
if ( enc==-1 ) {
- uni = UniFromName(name);
+ uni = UniFromName(name,sf->uni_interp,sf->encoding_name);
#ifndef FONTFORGE_CONFIG_NO_WINDOWING_UI
if ( uni<0 ) {
for ( i=0; specialnames[i].name!=NULL; ++i )
View
3  fontforge/nomen-en.c
@@ -310,6 +310,8 @@ static char str_Buildaccent[] = "Build Accented Char";
static unichar_t mnemonic_Buildaccent[] = 'B';
static char str_Buildcomposit[] = "Build Composite Char";
static unichar_t mnemonic_Buildcomposit[] = 'C';
+static char str_BuildDuplicates[] = "Build Duplicate Char";
+static unichar_t mnemonic_BuildDuplicates[] = 'D';
static char str_Clockwise[] = "Clockwise";
static unichar_t mnemonic_Clockwise[] = 'o';
static char str_Cclockwise[] = "Counter Clockwise";
@@ -1310,6 +1312,7 @@ static char *str_KerningLoadFailed = "Load of Kerning Metrics Failed";
static char *str_KerningLoadFailedLong = "Failed to load kern data from %hs";
/* Messages from accented characters */
static char str_Buildingaccented[] = "Building accented letters";
+static char str_BuildingDuplicates[] = "Building duplicate encodings";
static char str_Replacearing[] = "Replace Å";
static char str_Areyousurearing[] = "Are you sure you want to replace Å?\012The ring will not join to the A.";
static char str_Yes[] = "Yes";
View
47 fontforge/parsettf.c
@@ -2441,7 +2441,7 @@ return;
for ( i=0; i<info->glyph_cnt; ++i ) {
if ( info->chars[i]->unicodeenc==-1 )
- info->chars[i]->unicodeenc = UniFromName(info->chars[i]->name);
+ info->chars[i]->unicodeenc = UniFromName(info->chars[i]->name,info->uni_interp,info->encoding_name);
}
if ( dict->encodingoff==0 || dict->encodingoff==1 ) {
@@ -3227,7 +3227,23 @@ static int SubtableIsntSupported(FILE *ttf,uint32 offset,int platform,int specif
fseek(ttf,here,SEEK_SET);
return( ret );
}
-
+
+static enum uni_interp amscheck(struct dup *dups) {
+ int cnt = 0;
+ /* Try to guess if the font uses the AMS math PUA assignments */
+
+ while ( dups!=NULL ) {
+ if (( dups->sc->unicodeenc == 'b' && dups->uni==0xe668 ) ||
+ ( dups->sc->unicodeenc == 0x00b7 && dups->uni==0xe626 ) ||
+ ( dups->sc->unicodeenc == 0x29e1 && dups->uni==0xe3c8 ) ||
+ ( dups->sc->unicodeenc == 0x2A7C && dups->uni==0xE32A ) ||
+ ( dups->sc->unicodeenc == 0x2920 && dups->uni==0xE221 ))
+ ++cnt;
+ dups = dups->prev;
+ }
+return( cnt>=2 ? ui_ams : ui_none );
+}
+
static void readttfencodings(FILE *ttf,struct ttfinfo *info, int justinuse) {
int i,j;
int nencs, version;
@@ -3605,6 +3621,8 @@ static void readttfencodings(FILE *ttf,struct ttfinfo *info, int justinuse) {
}
}
}
+ if ( interp==ui_none )
+ interp = amscheck(info->dups);
if ( info->chars!=NULL && info->chars[0]!=NULL && info->chars[0]->unicodeenc==0xffff &&
info->chars[0]->name!=NULL && strcmp(info->chars[0]->name,".notdef")==0 )
info->chars[0]->unicodeenc = -1;
@@ -3612,9 +3630,9 @@ static void readttfencodings(FILE *ttf,struct ttfinfo *info, int justinuse) {
info->uni_interp = interp;
}
-static int EncFromName(const char *name) {
+static int EncFromName(const char *name,enum uni_interp interp,int encname) {
int i;
- i = UniFromName(name);
+ i = UniFromName(name,interp,encname);
if ( i==-1 && strlen(name)==4 ) {
/* MS says use this kind of name, Adobe says use the one above */
char *end;
@@ -3680,7 +3698,7 @@ static void readttfos2metrics(FILE *ttf,struct ttfinfo *info) {
}
static int cmapEncFromName(struct ttfinfo *info,const char *nm, int glyphid) {
- int uni = EncFromName(nm);
+ int uni = EncFromName(nm,info->uni_interp,info->encoding_name);
int i;
if ( uni==-1 )
@@ -3790,16 +3808,8 @@ static void readttfpostnames(FILE *ttf,struct ttfinfo *info) {
else if ( info->chars[i]->unicodeenc==-1 ) {
/* Do this later */;
name = NULL;
- } else if ( info->chars[i]->unicodeenc<psunicodenames_cnt &&
- psunicodenames[info->chars[i]->unicodeenc]!=NULL )
- name = psunicodenames[info->chars[i]->unicodeenc];
- else {
- if ( info->chars[i]->unicodeenc<0x10000 )
- sprintf( buffer, "uni%04X", info->chars[i]->unicodeenc );
- else
- sprintf( buffer, "u%04X", info->chars[i]->unicodeenc );
- name = buffer;
- }
+ } else
+ name = StdGlyphName(buffer,info->chars[i]->unicodeenc,info->uni_interp);
#if defined(FONTFORGE_CONFIG_GDRAW)
GProgressNext();
#elif defined(FONTFORGE_CONFIG_GTK)
@@ -3808,12 +3818,12 @@ static void readttfpostnames(FILE *ttf,struct ttfinfo *info) {
info->chars[i]->name = copy(name);
}
- /* If we have a GSUB table we can give some unencoded glyphs name */
+ /* If we have a GSUB table we can give some unencoded glyphs names */
/* for example if we have a vrt2 substitution of A to <unencoded> */
/* we could name the unencoded "A.vrt2" (though in this case we might */
/* try A.vert instead */ /* Werner suggested this */
/* We could try this from morx too, except that apple features don't */
- /* meaningful ids. That is A.15,3 isn't very readable */
+ /* use meaningful ids. That is A.15,3 isn't very readable */
for ( i=info->glyph_cnt-1; i>=0 ; --i )
if ( info->chars[i]!=NULL && info->chars[i]->name==NULL )
break;
@@ -4162,7 +4172,7 @@ return;
for ( i=0; i<256; ++i ) if ( (sc = hi[i])!=NULL )
chars[sc->enc] = sc;
for ( i=0; i<256+extras; ++i ) if ( (sc=chars[i])!=NULL ) {
- uenc = UniFromName(sc->name);
+ uenc = UniFromName(sc->name,info->uni_interp,info->encoding_name);
if ( uenc!=-1 )
sc->unicodeenc = uenc;
}
@@ -4654,6 +4664,7 @@ SplineFont *_SFReadTTF(FILE *ttf, int flags,char *filename) {
memset(&info,'\0',sizeof(struct ttfinfo));
info.onlystrikes = (flags&ttf_onlystrikes)?1:0;
info.onlyonestrike = (flags&ttf_onlyonestrike)?1:0;
+ info.uni_interp = ui_unset;
ret = readttf(ttf,&info,filename);
if ( !ret )
return( NULL );
View
2  fontforge/psread.c
@@ -2702,7 +2702,7 @@ return( head );
encs[i] = 0;
if ( i<32 || (i>=0x7f && i<0xa0))
encs[i] = i;
- } else if ( (enc=UniFromName(tokbuf))!=-1 )
+ } else if ( (enc=UniFromName(tokbuf,ui_none,em_custom))!=-1 )
encs[i] = enc;
else {
names[i] = copy(tokbuf);
View
1,612 fontforge/pua.c
1,612 additions, 0 deletions not shown
View
9 fontforge/scripting.c
@@ -616,7 +616,7 @@ static void bUnicodeFromName(Context *c) {
else if ( c->a.vals[1].type!=v_str )
error( c, "Bad type for argument" );
c->return_val.type = v_int;
- c->return_val.u.ival = UniFromName(c->a.vals[1].u.sval);
+ c->return_val.u.ival = UniFromName(c->a.vals[1].u.sval,ui_none,em_custom);
}
static void bChr(Context *c) {
@@ -2668,6 +2668,12 @@ static void bBuildAccented(Context *c) {
FVBuildAccent(c->curfv,true);
}
+static void bBuildDuplicate(Context *c) {
+ if ( c->a.argc!=1 )
+ error( c, "Wrong number of arguments");
+ FVBuildDuplicate(c->curfv);
+}
+
static void bMergeFonts(Context *c) {
SplineFont *sf;
int openflags=0;
@@ -3982,6 +3988,7 @@ static struct builtins { char *name; void (*func)(Context *); int nofontok; } bu
{ "BuildComposit", bBuildComposit },
{ "BuildComposite", bBuildComposit },
{ "BuildAccented", bBuildAccented },
+ { "BuildDuplicate", bBuildDuplicate },
{ "ReplaceWithReference", bReplaceOutlineWithReference },
{ "InterpolateFonts", bInterpolateFonts },
{ "MergeFonts", bMergeFonts },
View
12 fontforge/sfd.c
@@ -45,7 +45,7 @@ static const char *charset_names[] = {
"unicode", "unicode4", "sjis", "wansung", "gb2312pk", NULL};
static const char *unicode_interp_names[] = { "none", "adobe", "greek",
- "japanese", "tradchinese", "simpchinese", "korean", NULL };
+ "japanese", "tradchinese", "simpchinese", "korean", "ams", NULL };
signed char inbase64[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -4140,10 +4140,15 @@ static int ModSF(FILE *asfd,SplineFont *sf) {
if ( getname(asfd,tok)!=1 || strcmp(tok,"Encoding:")!=0 )
return(false);
getint(asfd,&newmap);
- if ( sf->encoding_name!=newmap )
- SFReencodeFont(sf,newmap);
if ( getname(asfd,tok)!=1 )
return( false );
+ if ( strcmp(tok,"UnicodeInterp:")==0 ) {
+ sf->uni_interp = SFDGetUniInterp(asfd,tok,sf);
+ if ( getname(asfd,tok)!=1 )
+return( false );
+ }
+ if ( sf->encoding_name!=newmap )
+ SFReencodeFont(sf,newmap);
if ( strcmp(tok,"Order2:")==0 ) {
getint(asfd,&order2);
if ( getname(asfd,tok)!=1 )
@@ -4274,6 +4279,7 @@ return;
if ( !sf->new && sf->origname!=NULL ) /* might be a new file */
fprintf( asfd, "Base: %s\n", sf->origname );
fprintf( asfd, "Encoding: %d\n", sf->encoding_name );
+ fprintf( asfd, "UnicodeInterp: %s\n", unicode_interp_names[sf->uni_interp]);
if ( sf->order2 )
fprintf( asfd, "Order2: %d\n", sf->order2 );
fprintf( asfd, "BeginChars: %d\n", max );
View
2  fontforge/splineutil.c
@@ -1854,7 +1854,7 @@ static void _SplineFontFromType1(SplineFont *sf, FontDict *fd, struct pscontext
sf->chars[i]->orig_pos = k;
sf->chars[i]->vwidth = sf->ascent+sf->descent;
sf->chars[i]->enc = i;
- sf->chars[i]->unicodeenc = UniFromName(encoding[i]);
+ sf->chars[i]->unicodeenc = UniFromName(encoding[i],sf->uni_interp,sf->encoding_name);
sf->chars[i]->parent = sf;
SCLigDefault(sf->chars[i]); /* Also reads from AFM file, but it probably doesn't exist */
#if defined(FONTFORGE_CONFIG_GDRAW)
View
6 fontforge/stamp.c
@@ -1,5 +1,5 @@
#include <time.h>
-const time_t source_modtime = 1096420624;
-const char *source_modtime_str = "18:17 28-Sep-2004";
-const char *source_version_str = "20040928";
+const time_t source_modtime = 1096516171;
+const char *source_modtime_str = "20:49 29-Sep-2004";
+const char *source_version_str = "20040929";
View
2  fontforge/start.c
@@ -53,7 +53,7 @@ static void initadobeenc(void) {
if ( strcmp(AdobeStandardEncoding[i],".notdef")==0 )
unicode_from_adobestd[i] = 0xfffd;
else {
- j = UniFromName(AdobeStandardEncoding[i]);
+ j = UniFromName(AdobeStandardEncoding[i],ui_none,em_custom);
if ( j==-1 ) j = 0xfffd;
unicode_from_adobestd[i] = j;
}
View
2  fontforge/svg.c
@@ -1968,7 +1968,7 @@ static SplineChar *SVGParseGlyphArgs(xmlNodePtr glyph,int defh, int defv) {
}
if ( glyphname!=NULL ) {
if ( sc->unicodeenc==-1 )
- sc->unicodeenc = UniFromName((char *) glyphname);
+ sc->unicodeenc = UniFromName((char *) glyphname,ui_none,em_custom);
sc->name = copy((char *) glyphname);
_xmlFree(glyphname);
} else if ( orientation!=NULL && *orientation=='v' && sc->unicodeenc!=-1 ) {
View
3  fontforge/tottfgpos.c
@@ -213,6 +213,7 @@ uint32 SCScriptFromUnicode(SplineChar *sc) {
if ( sc==NULL )
return( DEFAULT_SCRIPT );
+ sc = SCDuplicate(sc);
sf = sc->parent;
if ( sc->unicodeenc!=-1 )
@@ -221,7 +222,7 @@ return( ScriptFromUnicode( sc->unicodeenc,sf ));
for ( pt=sc->name; *pt!='\0' && *pt!='_' && *pt!='.'; ++pt );
if ( *pt!='\0' ) {
char *str = copyn(sc->name,pt-sc->name);
- int uni = UniFromName(str);
+ int uni = UniFromName(str,sf->uni_interp,sf->encoding_name);
free(str);
if ( uni!=-1 )
return( ScriptFromUnicode( uni,sf ));
View
1  fontforge/views.h
@@ -628,6 +628,7 @@ extern void NonLinearDlg(FontView *fv,struct charview *cv);
extern void FVPointOfView(FontView *fv,struct pov_data *);
extern void CVYPerspective(CharView *cv,double x_vanish, double y_vanish);
extern void FVBuildAccent(FontView *fv,int onlyaccents);
+extern void FVBuildDuplicate(FontView *fv);
extern void FVChangeChar(FontView *fv,int encoding);
extern void SCClearContents(SplineChar *sc);
extern void SCClearAll(SplineChar *sc);
Please sign in to comment.
Something went wrong with that request. Please try again.