summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Williams <pfaedit@users.sourceforge.net>2011-02-21 18:54:36 -0800
committerGeorge Williams <pfaedit@users.sourceforge.net>2011-02-21 18:54:36 -0800
commit838258c27615b1d094115d19b0300b2396e34add (patch)
treec0f818f2a7cea0154139ed005c5b5f61c8322e76
parent102cb313bb296ae43595cc899c4f8d3b625fce69 (diff)
Alexey doesn't like autokerning, so add a flag to turn that off in the kerning class dlg.
Also I seem to have gotten some old files mixed in the repository in the last couple of days. Fix that up and get back to what should be there.
-rw-r--r--fontforge/autowidth2.c14
-rw-r--r--fontforge/baseviews.h1
-rw-r--r--fontforge/fontinfo.c53
-rw-r--r--fontforge/kernclass.c45
-rw-r--r--fontforge/libffstamp.h4
-rw-r--r--fontforge/lookupui.c97
-rw-r--r--fontforge/python.c126
-rw-r--r--fontforge/sfd.c7
-rw-r--r--fontforge/splinefont.h3
-rw-r--r--fontforge/splineutil2.c2
-rw-r--r--fontforge/stamp.c4
-rw-r--r--htdocs/python.html6
-rw-r--r--htdocs/sfdformat.html9
13 files changed, 219 insertions, 152 deletions
diff --git a/fontforge/autowidth2.c b/fontforge/autowidth2.c
index 67821d8a..e746f311 100644
--- a/fontforge/autowidth2.c
+++ b/fontforge/autowidth2.c
@@ -824,6 +824,7 @@ void AutoKern2BuildClasses(SplineFont *sf,int layer,
SplineChar **leftglyphs,SplineChar **rightglyphs,
struct lookup_subtable *sub,
int separation, int min_kern, int touching, int only_closer,
+ int autokern,
real good_enough) {
AW_Data all;
AW_Glyph *glyphs, *me, *other;
@@ -847,22 +848,26 @@ return;
good_enough = (sf->ascent+sf->descent)/100.0;
if ( separation==0 && !touching ) {
+ /* Use default values. Generate them if they don't exist */
if ( sub->separation==0 && !sub->kerning_by_touch ) {
sub->separation = sf->width_separation;
if ( sf->width_separation==0 )
sub->separation = 15*(sf->ascent+sf->descent)/100;
separation = sub->separation;
+ autokern = true;
} else {
separation = sub->separation;
touching = sub->kerning_by_touch;
min_kern = sub->minkern;
only_closer = sub->onlyCloser;
+ autokern = !sub->dontautokern;
}
}
sub->separation = separation;
sub->minkern = min_kern;
sub->kerning_by_touch = touching;
sub->onlyCloser = only_closer;
+ sub->dontautokern = !autokern;
chunk_height = (sf->ascent + sf->descent)/200;
memset(&all,0,sizeof(all));
@@ -1006,10 +1011,11 @@ return;
kc->adjusts = gcalloc(lclasscnt*rclasscnt,sizeof(DeviceTable));
#endif
- AutoKern2NewClass(sf,layer,kc->firsts, kc->seconds,
- kc->first_cnt, kc->second_cnt,
- kc2AddOffset, kc,
- separation,min_kern,touching,only_closer,chunk_height);
+ if ( autokern )
+ AutoKern2NewClass(sf,layer,kc->firsts, kc->seconds,
+ kc->first_cnt, kc->second_cnt,
+ kc2AddOffset, kc,
+ separation,min_kern,touching,only_closer,chunk_height);
if ( sub->lookup->lookup_flags & pst_r2l ) {
char **temp = kc->seconds;
diff --git a/fontforge/baseviews.h b/fontforge/baseviews.h
index caf67c44..0bc2b11b 100644
--- a/fontforge/baseviews.h
+++ b/fontforge/baseviews.h
@@ -610,6 +610,7 @@ extern void AutoKern2BuildClasses(SplineFont *sf,int layer,
SplineChar **leftglyphs,SplineChar **rightglyphs,
struct lookup_subtable *sub,
int separation, int min_kern, int touching, int only_closer,
+ int autokern,
real good_enough);
#endif
diff --git a/fontforge/fontinfo.c b/fontforge/fontinfo.c
index 62fe90fa..56490e1a 100644
--- a/fontforge/fontinfo.c
+++ b/fontforge/fontinfo.c
@@ -24,7 +24,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "pfaeditui.h"
+#include "fontforgeui.h"
#include "ofl.h"
#include <ustring.h>
#include <chardata.h>
@@ -2013,7 +2013,7 @@ static struct psdict *GFI_ParsePrivate(struct gfi_data *d) {
struct psdict *ret = gcalloc(1,sizeof(struct psdict));
GGadget *private = GWidgetGetControl(d->gw,CID_Private);
int rows, cols = GMatrixEditGetColCnt(private);
- struct matrix_data *strings = _GMatrixEditGet(private, &rows);
+ struct matrix_data *strings = GMatrixEditGet(private, &rows);
int i,j;
ret->cnt = rows;
@@ -3497,6 +3497,20 @@ static int GFI_AddOFL(GGadget *g, GEvent *e) {
return( true );
}
+static int ss_cmp(const void *_md1, const void *_md2) {
+ const struct matrix_data *md1 = _md1, *md2 = _md2;
+
+ char buf1[20], buf2[20];
+ const char *l1, *l2;
+
+ if ( md1[1].u.md_ival == md2[1].u.md_ival ) {
+ l1 = langname(md1[0].u.md_ival,buf1);
+ l2 = langname(md2[0].u.md_ival,buf2);
+return( strcoll(l1,l2));
+ }
+return( md1[1].u.md_ival - md2[1].u.md_ival );
+}
+
static void SSMatrixInit(struct matrixinit *mi,struct gfi_data *d) {
SplineFont *sf = d->sf;
struct matrix_data *md;
@@ -3519,6 +3533,7 @@ static void SSMatrixInit(struct matrixinit *mi,struct gfi_data *d) {
md[3*cnt+2].u.md_str = copy(on->name);
}
}
+ qsort( md, cnt, 3*sizeof(struct matrix_data), ss_cmp );
mi->matrix_data = md;
mi->initial_row_cnt = cnt;
}
@@ -3945,7 +3960,8 @@ static void StoreSSNames(struct gfi_data *d) {
OtfFeatNameListFree(sf->feat_names);
sf->feat_names = NULL;
- for ( i=0; i<rows; ++i ) {
+ qsort( strings, rows, 3*sizeof(struct matrix_data), ss_cmp );
+ for ( i=rows-1; i>=0; --i ) {
if ( strings[3*i+2].u.md_str == NULL )
continue;
tag = strings[3*i+1].u.md_ival;
@@ -4142,6 +4158,7 @@ static int GFI_OK(GGadget *g, GEvent *e) {
int32 len;
GTextInfo **ti;
int subs[4], super[4], strike[2];
+ struct otfname *fontstyle_name;
int design_size, size_top, size_bottom, styleid;
int strokedfont = false;
real strokewidth;
@@ -4212,7 +4229,7 @@ return( true );
}
if ( layer_cnt>=BACK_LAYER_MAX-2 ) {
ff_post_error(_("Too many layers"),_("FontForge supports at most %d layers"),BACK_LAYER_MAX-2);
- /* This can be increased in configure-pfaedit.h */
+ /* This can be increased in configure-fontforge.h */
return( true );
}
if ( !CheckNames(d))
@@ -4252,6 +4269,34 @@ return(true);
size_bottom = rint(10*GetReal8(gw,CID_DesignBottom,_("_Bottom"),&err));
size_top = rint(10*GetReal8(gw,CID_DesignTop,_("_Top"),&err));
styleid = GetInt8(gw,CID_StyleID,_("Style _ID:"),&err);
+ fontstyle_name = OtfNameFromStyleNames(GWidgetGetControl(gw,CID_StyleName));
+ OtfNameListFree(fontstyle_name);
+ if ( design_size==0 && ( size_bottom!=0 || size_top!=0 || styleid!=0 || fontstyle_name!=NULL )) {
+ ff_post_error(_("Bad Design Size Info"),_("If the design size is 0, then all other fields on that pane must be zero (or unspecified) too."));
+return( true );
+ } else if ( styleid!=0 && fontstyle_name==NULL ) {
+ ff_post_error(_("Bad Design Size Info"),_("If you specify a style id for the design size, then you must specify a style name"));
+return( true );
+ } else if ( fontstyle_name==NULL && styleid!=0 ) {
+ ff_post_error(_("Bad Design Size Info"),_("If you specify a style name for the design size, then you must specify a style id"));
+return( true );
+ } else if ( design_size<0 ) {
+ ff_post_error(_("Bad Design Size Info"),_("If you specify a design size, it must be positive"));
+return( true );
+ } else if ( size_bottom!=0 && size_bottom>design_size ) {
+ ff_post_error(_("Bad Design Size Info"),_("In the design size range, the bottom field must be less than the design size."));
+return( true );
+ } else if ( size_top!=0 && size_top<design_size ) {
+ ff_post_error(_("Bad Design Size Info"),_("In the design size range, the bottom top must be more than the design size."));
+return( true );
+ } else if ( styleid!=0 && size_top==0 ) {
+ ff_post_error(_("Bad Design Size Info"),_("If you specify a style id for the design size, then you must specify a size range"));
+return( true );
+ } else if ( size_top!=0 && styleid==0 ) {
+ ff_post_notice(_("Bad Design Size Info"),_("If you specify a design size range, then you are supposed to specify a style id and style name too. FontForge will allow you to leave those fields blank, but other applications may not."));
+ /* no return, this is just a warning */
+ }
+
if ( *_GGadgetGetTitle(GWidgetGetControl(gw,CID_Revision))!='\0' )
sfntRevision = rint(65536.*GetReal8(gw,CID_Revision,_("sfnt Revision:"),&err));
if ( *_GGadgetGetTitle(GWidgetGetControl(gw,CID_WoffMajor))!='\0' ) {
diff --git a/fontforge/kernclass.c b/fontforge/kernclass.c
index 485e6c8b..5411cbac 100644
--- a/fontforge/kernclass.c
+++ b/fontforge/kernclass.c
@@ -119,6 +119,7 @@ typedef struct kernclasslistdlg {
#define CID_MinKern 2009
#define CID_Touched 2010
#define CID_OnlyCloser 2011
+#define CID_Autokern 2012
#define CID_SizeLabel 3000
#define CID_MagLabel 3001
@@ -1157,7 +1158,7 @@ static int KC_OK(GGadget *g, GEvent *e) {
int i;
int len;
struct matrix_data *classes;
- int err, touch=0, separation=0, minkern=0, onlyCloser;
+ int err, touch=0, separation=0, minkern=0, onlyCloser, autokern;
sf = kcd->sf;
if ( sf->cidmaster!=NULL ) sf = sf->cidmaster;
@@ -1168,6 +1169,7 @@ static int KC_OK(GGadget *g, GEvent *e) {
separation = GetInt8(kcd->gw,CID_Separation,_("Separation"),&err);
minkern = GetInt8(kcd->gw,CID_MinKern,_("Min Kern"),&err);
onlyCloser = GGadgetIsChecked(GWidgetGetControl(kcd->gw,CID_OnlyCloser));
+ autokern = GGadgetIsChecked(GWidgetGetControl(kcd->gw,CID_Autokern));
if ( err )
return( true );
KCD_Finalize(kcd);
@@ -1188,6 +1190,7 @@ return( true );
kc->subtable->minkern = minkern;
kc->subtable->kerning_by_touch = touch;
kc->subtable->onlyCloser = onlyCloser;
+ kc->subtable->dontautokern = !autokern;
kc->first_cnt = kcd->first_cnt;
kc->second_cnt = kcd->second_cnt;
@@ -1983,11 +1986,12 @@ void ME_ClassCheckUnique(GGadget *g,int r, int c, SplineFont *sf) {
static void KCD_FinishEdit(GGadget *g,int r, int c, int wasnew) {
KernClassDlg *kcd = GDrawGetUserData(GGadgetGetWindow(g));
int is_first = GGadgetGetCid(g) == CID_ClassList;
- int i;
+ int i, autokern;
ME_ClassCheckUnique(g, r, c, kcd->sf);
if ( wasnew ) {
+ autokern = GGadgetIsChecked(GWidgetGetControl(kcd->gw,CID_Autokern));
if ( is_first ) {
kcd->offsets = grealloc(kcd->offsets,(kcd->first_cnt+1)*kcd->second_cnt*sizeof(int16));
memset(kcd->offsets+kcd->first_cnt*kcd->second_cnt,
@@ -1998,7 +2002,8 @@ static void KCD_FinishEdit(GGadget *g,int r, int c, int wasnew) {
0, kcd->second_cnt*sizeof(DeviceTable));
#endif
++kcd->first_cnt;
- KCD_AutoKernAClass(kcd,kcd->first_cnt-1,true);
+ if ( autokern )
+ KCD_AutoKernAClass(kcd,kcd->first_cnt-1,true);
} else {
int16 *new = galloc(kcd->first_cnt*(kcd->second_cnt+1)*sizeof(int16));
for ( i=0; i<kcd->first_cnt; ++i ) {
@@ -2021,7 +2026,8 @@ static void KCD_FinishEdit(GGadget *g,int r, int c, int wasnew) {
}
#endif
++kcd->second_cnt;
- KCD_AutoKernAClass(kcd,kcd->second_cnt-1,false);
+ if ( autokern )
+ KCD_AutoKernAClass(kcd,kcd->second_cnt-1,false);
}
KCD_SBReset(kcd);
GDrawRequestExpose(kcd->gw,NULL,false);
@@ -2524,10 +2530,10 @@ static void FillShowKerningWindow(KernClassDlg *kcd, GGadgetCreateData *left,
void KernClassD(KernClass *kc, SplineFont *sf, int layer, int isv) {
GRect pos;
GWindowAttrs wattrs;
- GGadgetCreateData gcd[53], sepbox, classbox, hvbox, buttonbox, mainbox[2], topbox[2], titbox;
+ GGadgetCreateData gcd[54], sepbox, classbox, hvbox, buttonbox, mainbox[2], topbox[2], titbox, hbox;
GGadgetCreateData *harray1[17], *harray2[17], *varray1[5], *varray2[5];
- GGadgetCreateData *hvarray[13], *buttonarray[8], *varray[19], *h4array[8], *harrayclasses[6], *titlist[4];
- GTextInfo label[53];
+ GGadgetCreateData *hvarray[13], *buttonarray[8], *varray[19], *h4array[8], *harrayclasses[6], *titlist[4], *h5array[3];
+ GTextInfo label[54];
KernClassDlg *kcd;
int i, j, kc_width, vi;
int as, ds, ld, sbsize;
@@ -2574,6 +2580,7 @@ return;
memset(&wattrs,0,sizeof(wattrs));
memset(&gcd,0,sizeof(gcd));
memset(&classbox,0,sizeof(classbox));
+ memset(&hbox,0,sizeof(hbox));
memset(&hvbox,0,sizeof(hvbox));
memset(&buttonbox,0,sizeof(buttonbox));
memset(&mainbox,0,sizeof(mainbox));
@@ -2725,7 +2732,6 @@ return;
label[i].text_is_1byte = true;
label[i].text_in_resource = true;
gcd[i].gd.label = &label[i];
- gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = 5+4;
gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
if ( kc->subtable->onlyCloser )
gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
@@ -2734,7 +2740,28 @@ return;
"so the kerning offset will be negative.");
gcd[i].gd.cid = CID_OnlyCloser;
gcd[i].creator = GCheckBoxCreate;
- varray[j++] = &gcd[i++]; varray[j++] = NULL;
+ h5array[0] = &gcd[i++];
+
+ label[i].text = (unichar_t *) _("Autokern new entries");
+ label[i].text_is_1byte = true;
+ label[i].text_in_resource = true;
+ gcd[i].gd.label = &label[i];
+ gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
+ if ( !kc->subtable->dontautokern )
+ gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
+ gcd[i].gd.popup_msg = (unichar_t *) _(
+ "When adding a new class provide default kerning values\n"
+ "Between it and every class with which it interacts.");
+ gcd[i].gd.cid = CID_Autokern;
+ gcd[i].creator = GCheckBoxCreate;
+ h5array[1] = &gcd[i++]; h5array[2] = NULL;
+
+ memset(&hbox,0,sizeof(hbox));
+ hbox.gd.flags = gg_enabled|gg_visible;
+ hbox.gd.u.boxelements = h5array;
+ hbox.creator = GHBoxCreate;
+
+ varray[j++] = &hbox; varray[j++] = NULL;
gcd[i].gd.pos.x = 10; gcd[i].gd.pos.y = GDrawPointsToPixels(gw,gcd[i-1].gd.pos.y+17);
gcd[i].gd.pos.width = pos.width-20;
diff --git a/fontforge/libffstamp.h b/fontforge/libffstamp.h
index a29b549b..c691f9f5 100644
--- a/fontforge/libffstamp.h
+++ b/fontforge/libffstamp.h
@@ -1,3 +1,3 @@
-#define LibFF_ModTime 1298320590L /* Seconds since 1970 (standard unix time) */
-#define LibFF_ModTime_Str "20:36 GMT 21-Feb-2011"
+#define LibFF_ModTime 1298329534L /* Seconds since 1970 (standard unix time) */
+#define LibFF_ModTime_Str "23:05 GMT 21-Feb-2011"
#define LibFF_VersionDate 20110221 /* Year, month, day */
diff --git a/fontforge/lookupui.c b/fontforge/lookupui.c
index 1fc1da61..8c0e0f19 100644
--- a/fontforge/lookupui.c
+++ b/fontforge/lookupui.c
@@ -2011,6 +2011,7 @@ typedef struct anchorclassdlg {
#define CID_MinKern 2009
#define CID_Touched 2010
#define CID_OnlyCloser 2011
+#define CID_Autokern 2012
#define CID_KernDisplay 2022
#define CID_PixelSize 2023
@@ -3493,6 +3494,9 @@ return( true );
static int PSTKD_DoAutoKern(PSTKernDlg *pstkd,SplineChar **glyphlist) {
int err, touch, separation, minkern, onlyCloser;
+ if ( !GGadgetIsChecked(GWidgetGetControl(pstkd->gw,CID_Autokern)) )
+return( false );
+
err = false;
touch = GGadgetIsChecked(GWidgetGetControl(pstkd->gw,CID_Touched));
separation = GetInt8(pstkd->gw,CID_Separation,_("Separation"),&err);
@@ -3670,7 +3674,7 @@ static int PSTKD_Ok(GGadget *g, GEvent *e) {
char *buts[3];
KernPair *kp, *kpprev, *kpnext;
PST *pst, *pstprev, *pstnext;
- int err, touch=0, separation=0, minkern=0, onlyCloser=0;
+ int err, touch=0, separation=0, minkern=0, onlyCloser=0, autokern=0;
int _t = lookup_type == gpos_single ? pst_position
: lookup_type == gpos_pair ? pst_pair
: lookup_type == gsub_single ? pst_substitution
@@ -3686,6 +3690,7 @@ static int PSTKD_Ok(GGadget *g, GEvent *e) {
separation = GetInt8(pstkd->gw,CID_Separation,_("Separation"),&err);
minkern = GetInt8(pstkd->gw,CID_MinKern,_("Min Kern"),&err);
onlyCloser = GGadgetIsChecked(GWidgetGetControl(pstkd->gw,CID_OnlyCloser));
+ autokern = GGadgetIsChecked(GWidgetGetControl(pstkd->gw,CID_Autokern));
if ( err )
return( true );
}
@@ -3879,6 +3884,7 @@ return( true );
pstkd->sub->minkern = minkern;
pstkd->sub->kerning_by_touch = touch;
pstkd->sub->onlyCloser = onlyCloser;
+ pstkd->sub->dontautokern = !autokern;
}
pstkd->done = true;
}
@@ -4159,9 +4165,9 @@ static void PSTKernD(SplineFont *sf, struct lookup_subtable *sub, int def_layer)
GWindowAttrs wattrs;
char title[300];
struct matrixinit mi;
- GGadgetCreateData gcd[22], buttongcd[6], box[6];
- GGadgetCreateData *h1array[8], *h2array[7], *h3array[7], *varray[20], *h4array[8];
- GTextInfo label[22], buttonlabel[6];
+ GGadgetCreateData gcd[23], buttongcd[6], box[6], hbox;
+ GGadgetCreateData *h1array[8], *h2array[7], *h3array[7], *varray[20], *h4array[8], *h5array[4];
+ GTextInfo label[23], buttonlabel[6];
int i,k,mi_pos, mi_k;
enum otlookup_type lookup_type = sub->lookup->lookup_type;
char sepbuf[40], mkbuf[40];
@@ -4470,7 +4476,6 @@ static void PSTKernD(SplineFont *sf, struct lookup_subtable *sub, int def_layer)
label[i].text_is_1byte = true;
label[i].text_in_resource = true;
gcd[i].gd.label = &label[i];
- gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = 5+4;
gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
if ( sub->onlyCloser )
gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
@@ -4479,7 +4484,26 @@ static void PSTKernD(SplineFont *sf, struct lookup_subtable *sub, int def_layer)
"so the kerning offset will be negative.");
gcd[i].gd.cid = CID_OnlyCloser;
gcd[i].creator = GCheckBoxCreate;
- varray[k++] = &gcd[i++]; varray[k++] = NULL;
+ h5array[0] = &gcd[i++];
+
+ label[i].text = (unichar_t *) _("Autokern new entries");
+ label[i].text_is_1byte = true;
+ label[i].text_in_resource = true;
+ gcd[i].gd.label = &label[i];
+ gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
+ if ( !sub->dontautokern )
+ gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
+ gcd[i].gd.popup_msg = (unichar_t *) _(
+ "When adding new entries provide default kerning values.");
+ gcd[i].gd.cid = CID_Autokern;
+ gcd[i].creator = GCheckBoxCreate;
+ h5array[1] = &gcd[i++]; h5array[2] = NULL;
+
+ memset(&hbox,0,sizeof(hbox));
+ hbox.gd.flags = gg_enabled|gg_visible;
+ hbox.gd.u.boxelements = h5array;
+ hbox.creator = GHBoxCreate;
+ varray[k++] = &hbox; varray[k++] = NULL;
label[i].text = (unichar_t *) _("Size:");
label[i].text_is_1byte = true;
@@ -5011,6 +5035,7 @@ return( true );
#undef CID_MinKern
#undef CID_Touched
#undef CID_OnlyCloser
+#undef CID_Autokern
#define CID_KPairs 1000
#define CID_KClasses 1001
#define CID_KCBuild 1002
@@ -5018,9 +5043,9 @@ return( true );
#define CID_MinKern 1004
#define CID_Touched 1005
#define CID_ClassDistance 1006
-#define CID_KPAuto 1007
#define CID_Guts 1008
#define CID_OnlyCloser 1009
+#define CID_Autokern 1010
struct kf_results {
int asked;
@@ -5039,12 +5064,10 @@ static int KF_FormatChange(GGadget *g, GEvent *e) {
kf = GDrawGetUserData(GGadgetGetWindow(g));
if ( GGadgetIsChecked(GWidgetGetControl(kf->gw,CID_KPairs)) ) {
GGadgetSetEnabled(GWidgetGetControl(kf->gw,CID_KCBuild),0);
- GGadgetSetEnabled(GWidgetGetControl(kf->gw,CID_KPAuto),1);
sprintf(mkbuf,"%d",15*(kf->sf->ascent+kf->sf->descent)/1000 );
GGadgetSetTitle8(GWidgetGetControl(kf->gw,CID_MinKern),mkbuf);
} else {
GGadgetSetEnabled(GWidgetGetControl(kf->gw,CID_KCBuild),1);
- GGadgetSetEnabled(GWidgetGetControl(kf->gw,CID_KPAuto),0);
GGadgetSetTitle8(GWidgetGetControl(kf->gw,CID_MinKern),"0");
}
}
@@ -5087,9 +5110,9 @@ static int KF_OK(GGadget *g, GEvent *e) {
if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
struct kf_dlg *kf = GDrawGetUserData(GGadgetGetWindow(g));
- int touch, separation, minkern, err, onlyCloser;
+ int touch, separation, minkern, err, onlyCloser, autokern;
real good_enough=0;
- int isclass, autobuild=0, autokern=0;
+ int isclass, autobuild=0;
struct kf_results *results = kf->results;
err = false;
@@ -5097,6 +5120,7 @@ static int KF_OK(GGadget *g, GEvent *e) {
separation = GetInt8(kf->gw,CID_Separation,_("Separation"),&err);
minkern = GetInt8(kf->gw,CID_MinKern,_("Min Kern"),&err);
onlyCloser = GGadgetIsChecked(GWidgetGetControl(kf->gw,CID_OnlyCloser));
+ autokern = GGadgetIsChecked(GWidgetGetControl(kf->gw,CID_Autokern));
if ( err )
return( true );
@@ -5106,8 +5130,7 @@ return( true );
good_enough = GetReal8(kf->gw,CID_ClassDistance,_("Intra Class Distance"),&err);
if ( err )
return( true );
- } else
- autokern = GGadgetIsChecked(GWidgetGetControl(kf->gw,CID_KPAuto));
+ }
if ( autobuild || autokern ) {
results->firstglyphs = SelectedGlyphs(kf->first_fv);
if ( results->firstglyphs == NULL )
@@ -5122,6 +5145,7 @@ return( true );
kf->sub->minkern = minkern;
kf->sub->kerning_by_touch = touch;
kf->sub->onlyCloser = onlyCloser;
+ kf->sub->dontautokern = !autokern;
results->good_enough = good_enough;
if ( !isclass )
results->asked = 0;
@@ -5162,8 +5186,8 @@ static int kern_format_dlg( SplineFont *sf, int def_layer,
struct lookup_subtable *sub, struct kf_results *results ) {
GRect pos;
GWindowAttrs wattrs;
- GGadgetCreateData gcd[15], boxes[7];
- GGadgetCreateData *varray[21], *h1array[5], *h2array[6], *h3array[6], *h4array[8], *buttonarray[8];
+ GGadgetCreateData gcd[16], boxes[7], hbox;
+ GGadgetCreateData *varray[21], *h2array[6], *h3array[6], *h4array[8], *buttonarray[8], *h5array[4];
GTextInfo label[15];
char sepbuf[40], mkbuf[40], distancebuf[40];
struct kf_dlg kf;
@@ -5236,22 +5260,6 @@ static int kern_format_dlg( SplineFont *sf, int def_layer,
gcd[i].creator = GRadioCreate;
varray[j++] = &gcd[i++]; varray[j++] = NULL;
- label[i].text = (unichar_t *) _("FontForge will auto kern the selected glyphs");
- label[i].text_is_1byte = true;
- label[i].text_in_resource = true;
- gcd[i].gd.label = &label[i];
- gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
- gcd[i].gd.popup_msg = (unichar_t *) _(
- "FontForge will look at the glyphs selected in the font view\n"
- "and guess at good kerning values for them" );
- gcd[i].gd.cid = CID_KPAuto;
- gcd[i].creator = GCheckBoxCreate;
- h1array[0] = GCD_HPad10; h1array[1] = &gcd[i++]; h1array[2] = GCD_Glue; h1array[3] = NULL;
- boxes[2].gd.flags = gg_enabled|gg_visible;
- boxes[2].gd.u.boxelements = h1array;
- boxes[2].creator = GHBoxCreate;
- varray[j++] = &boxes[2]; varray[j++] = NULL;
-
label[i].text = (unichar_t *) _("Use a matrix of kerning classes");
label[i].text_is_1byte = true;
label[i].text_in_resource = true;
@@ -5396,7 +5404,6 @@ static int kern_format_dlg( SplineFont *sf, int def_layer,
label[i].text_is_1byte = true;
label[i].text_in_resource = true;
gcd[i].gd.label = &label[i];
- gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = 5+4;
gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
if ( sub->onlyCloser )
gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
@@ -5405,7 +5412,26 @@ static int kern_format_dlg( SplineFont *sf, int def_layer,
"so the kerning offset will be negative.");
gcd[i].gd.cid = CID_OnlyCloser;
gcd[i].creator = GCheckBoxCreate;
- varray[j++] = &gcd[i++]; varray[j++] = NULL;
+ h5array[0] = &gcd[i++];
+
+ label[i].text = (unichar_t *) _("Autokern new entries");
+ label[i].text_is_1byte = true;
+ label[i].text_in_resource = true;
+ gcd[i].gd.label = &label[i];
+ gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
+ if ( !sub->dontautokern )
+ gcd[i].gd.flags = gg_enabled|gg_visible|gg_utf8_popup|gg_cb_on;
+ gcd[i].gd.popup_msg = (unichar_t *) _(
+ "When adding new entries provide default kerning values.");
+ gcd[i].gd.cid = CID_Autokern;
+ gcd[i].creator = GCheckBoxCreate;
+ h5array[1] = &gcd[i++]; h5array[2] = NULL;
+
+ memset(&hbox,0,sizeof(hbox));
+ hbox.gd.flags = gg_enabled|gg_visible;
+ hbox.gd.u.boxelements = h5array;
+ hbox.creator = GHBoxCreate;
+ varray[j++] = &hbox; varray[j++] = NULL;
guts_row = j/2;
gcd[i].gd.flags = gg_enabled|gg_visible;
@@ -5446,7 +5472,6 @@ static int kern_format_dlg( SplineFont *sf, int def_layer,
GGadgetsCreate(kf.gw,boxes);
GHVBoxSetExpandableRow(boxes[0].ret,guts_row);
- GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
GHVBoxSetExpandableCol(boxes[4].ret,gb_expandglue);
GHVBoxSetExpandableCol(boxes[5].ret,gb_expandglue);
@@ -5545,6 +5570,7 @@ return;
}
AutoKern2(sf, def_layer,lefts,rights,
sub,
+ /* If separation==0 and !touch then use default values */
0,0,0,0, 0, NULL, NULL);
}
} else {
@@ -5566,8 +5592,9 @@ return;
#endif
/* Need to fix for Hebrew !!!! */
if ( results.autobuild )
+ /* Specifying separation==0 and !touching means use default values */
AutoKern2BuildClasses(sf,def_layer,results.firstglyphs,
- results.secondglyphs,sub,0,0,0,0,results.good_enough);
+ results.secondglyphs,sub,0,0,0,0,0,results.good_enough);
}
free(results.firstglyphs);
free(results.secondglyphs);
diff --git a/fontforge/python.c b/fontforge/python.c
index 39e50f5c..72c203a3 100644
--- a/fontforge/python.c
+++ b/fontforge/python.c
@@ -5734,75 +5734,6 @@ return( -1 );
return( 0 );
}
-static PyObject *PyFF_Glyph_get_lcarets(PyFF_Glyph *self,void *closure) {
-
- SplineChar *sc = ((PyFF_Glyph *) self)->sc;
- int cnt=0, i;
- PST *pst, *lcar = NULL;
- PyObject *tuple;
-
- for ( pst = sc->possub; pst!=NULL; pst=pst->next ) {
- if ( pst->type==pst_lcaret ) {
- lcar = pst;
- cnt = lcar->u.lcaret.cnt;
- break;
- }
- }
- tuple = PyTuple_New(cnt);
-
- if ( lcar != NULL ) {
- for ( i=0; i<cnt; ++i ) {
- PyTuple_SetItem( tuple,i,Py_BuildValue("i",lcar->u.lcaret.carets[i]) );
- }
- }
-return( tuple );
-}
-
-static int PyFF_Glyph_set_lcarets(PyFF_Glyph *self,PyObject *value,void *closure) {
- SplineChar *sc = self->sc;
- int i, cnt, lig_comp_max = 0, lc;
- char *pt;
- int16 *carets;
- PST *pst, *lcar = NULL;
-
- cnt = PySequence_Size(value);
- if ( cnt==-1 )
-return( -1 );
-
- if ( cnt > 0 )
- carets = galloc( cnt*sizeof(int16) );
- for ( i=0; i<cnt; ++i ) {
- carets[i] = PyInt_AsLong( PySequence_GetItem(value,i) );
- if ( PyErr_Occurred())
-return( -1 );
- }
-
- for ( pst = sc->possub; pst!=NULL; pst=pst->next ) {
- if ( pst->type==pst_lcaret ) {
- lcar = pst;
- free( lcar->u.lcaret.carets );
- } else if ( pst->type==pst_ligature ) {
- for ( lc=0, pt=pst->u.lig.components; *pt; ++pt )
- if ( *pt==' ' ) ++lc;
- if ( lc>lig_comp_max )
- lig_comp_max = lc;
- }
- }
-
- if ( lcar == NULL && cnt > 0 ) {
- lcar = chunkalloc(sizeof(PST));
- lcar->type = pst_lcaret;
- lcar->next = sc->possub;
- sc->possub = lcar;
- }
- if ( lcar != NULL ) {
- lcar->u.lcaret.cnt = cnt;
- lcar->u.lcaret.carets = cnt > 0 ? carets : NULL;
- sc->lig_caret_cnt_fixed = ( cnt != lig_comp_max ) ? true : false;
- }
-return( 0 );
-}
-
static PyObject *PyFF_Glyph_get_font(PyFF_Glyph *self,void *closure) {
return( PyFV_From_FV_I(self->sc->parent->fv));
@@ -6683,9 +6614,6 @@ static PyGetSetDef PyFF_Glyph_getset[] = {
{"manualHints",
(getter)PyFF_Glyph_get_manualhints, (setter)PyFF_Glyph_set_manualhints,
"The hints have been set manually, and the glyph should not be autohinted by default" },
- {"lcarets",
- (getter)PyFF_Glyph_get_lcarets, (setter)PyFF_Glyph_set_lcarets,
- "The ligature caret locations, defined for this glyph, as a tuple.", NULL},
{"validation_state",
(getter)PyFF_Glyph_get_validation_state, (setter)PyFF_cant_set,
"glyph's validation state (readonly)", NULL},
@@ -12760,6 +12688,7 @@ return( false );
return( false );
AutoKern2BuildClasses(fv->sf,fv->active_layer,first,second,sub,
sub->separation,0,sub->kerning_by_touch, sub->onlyCloser,
+ !sub->dontautokern,
good_enough);
free(first);
if ( first!=second )
@@ -12806,13 +12735,15 @@ static PyObject *PyFFFont_addKerningClass(PyObject *self, PyObject *args) {
char **class1_strs, **class2_strs;
int cnt1, cnt2, acnt;
int16 *offs=NULL;
- int separation= -1, touch=0, do_autokern=false, only_closer=0;
+ int separation= -1, touch=0, do_autokern=false, only_closer=0, autokern=true;
double class_error_distance;
/* arguments:
* (char *lookupname, char *newsubtabname, char ***classes1, char ***classes2, int *offsets [,char *after_sub_name])
- * (char *lookupname, char *newsubtabname, int separation, char ***classes1, char ***classes2 [, int only_closer, char *after_sub_name])
- * (char *lookupname, char *newsubtabname, int separation, double err, char **list1, char **list2 [, int only_closer, char *after_sub_name])
- * (char *lookupname, char *newsubtabname, int separation, double err [, int only_closer, char *after_sub_name])
+ * (char *lookupname, char *newsubtabname, int separation, char ***classes1, char ***classes2 [, int only_closer, int autokern, char *after_sub_name])
+ * (char *lookupname, char *newsubtabname, int separation, double err, char **list1, char **list2 [, int only_closer, int autokern, char *after_sub_name])
+ * (char *lookupname, char *newsubtabname, int separation, double err [, int only_closer, int autokern, char *after_sub_name])
+ * Also support arguments where [,int autokern] is absent as we used not to
+ * allow the user to specify it
* First is fully specified set of classes with offsets cnt=5/6
* Second fully specified set of classes, to be autokerned cnt=5/7
* Third two lists of glyphs to be turned into classes and then autokerned cnt=6/8
@@ -12831,21 +12762,45 @@ return( NULL );
return( NULL );
do_autokern = false;
} else if ( !PyInt_Check(arg4) && !PyLong_Check(arg4) && !PyFloat_Check(arg4)) {
- if ( !PyArg_ParseTuple(args,"ssiOO|is", &lookup, &subtable,
- &separation, &class1s, &class2s,
- &only_closer, &after_str ))
+ PyObject *arg7 = acnt>=7 ? PySequence_GetItem(args,6) : NULL;
+ if ( arg7!=NULL && (PyInt_Check(arg7) || PyLong_Check(arg7))) {
+ if ( !PyArg_ParseTuple(args,"ssiOO|iis", &lookup, &subtable,
+ &separation, &class1s, &class2s,
+ &only_closer, &autokern, &after_str ))
+return( NULL );
+ } else {
+ if ( !PyArg_ParseTuple(args,"ssiOO|is", &lookup, &subtable,
+ &separation, &class1s, &class2s,
+ &only_closer, &after_str ))
return( NULL );
+ }
} else if ( acnt>5 &&
(arg5=PySequence_GetItem(args,4)) && PySequence_Check(arg5) ) {
- if ( !PyArg_ParseTuple(args,"ssidOO|is", &lookup, &subtable,
- &separation, &class_error_distance, &list1, &list2,
- &only_closer, &after_str ))
+ PyObject *arg8 = acnt>=8 ? PySequence_GetItem(args,7) : NULL;
+ if ( arg8!=NULL && (PyInt_Check(arg8) || PyLong_Check(arg8))) {
+ if ( !PyArg_ParseTuple(args,"ssidOO|iis", &lookup, &subtable,
+ &separation, &class_error_distance, &list1, &list2,
+ &only_closer, &autokern, &after_str ))
return( NULL );
+ } else {
+ if ( !PyArg_ParseTuple(args,"ssidOO|is", &lookup, &subtable,
+ &separation, &class_error_distance, &list1, &list2,
+ &only_closer, &after_str ))
+return( NULL );
+ }
} else {
- if ( !PyArg_ParseTuple(args,"ssid|is", &lookup, &subtable,
- &separation, &class_error_distance,
- &only_closer, &after_str ))
+ PyObject *arg6 = acnt>=6 ? PySequence_GetItem(args,5) : NULL;
+ if ( arg6!=NULL && (PyInt_Check(arg6) || PyLong_Check(arg6))) {
+ if ( !PyArg_ParseTuple(args,"ssid|iis", &lookup, &subtable,
+ &separation, &class_error_distance,
+ &only_closer, &autokern, &after_str ))
return( NULL );
+ } else {
+ if ( !PyArg_ParseTuple(args,"ssid|is", &lookup, &subtable,
+ &separation, &class_error_distance,
+ &only_closer, &after_str ))
+return( NULL );
+ }
}
if ( separation==0 )
touch=1;
@@ -12880,6 +12835,7 @@ return( NULL );
sub->separation = separation;
sub->kerning_by_touch = touch;
sub->onlyCloser = only_closer;
+ sub->dontautokern = !autokern;
}
sub->kc = chunkalloc(sizeof(KernClass));
sub->kc->subtable = sub;
diff --git a/fontforge/sfd.c b/fontforge/sfd.c
index 25c15d72..b31f0d82 100644
--- a/fontforge/sfd.c
+++ b/fontforge/sfd.c
@@ -1626,10 +1626,10 @@ static void SFDDumpOtfFeatNames(FILE *sfd, SplineFont *sf) {
fprintf( sfd, "OtfFeatName: '%c%c%c%c' ",
fn->tag>>24, fn->tag>>16, fn->tag>>8, fn->tag );
for ( on=fn->names; on!=NULL; on=on->next ) {
- fprintf( sfd, "%d ", on->lang );
+ fprintf( sfd, " %d ", on->lang );
SFDDumpUTF7Str(sfd, on->name);
+ putc('\n',sfd);
}
- putc('\n',sfd);
}
}
@@ -1961,7 +1961,7 @@ static int SFD_Dump(FILE *sfd,SplineFont *sf,EncMap *map,EncMap *normal,
} else if ( otl->lookup_type==gpos_pair && sub->vertical_kerning )
fprintf(sfd,"(1)");
if ( otl->lookup_type==gpos_pair && (sub->separation!=0 || sub->kerning_by_touch))
- fprintf(sfd,"[%d,%d,%d]", sub->separation, sub->minkern, sub->kerning_by_touch+2*sub->onlyCloser );
+ fprintf(sfd,"[%d,%d,%d]", sub->separation, sub->minkern, sub->kerning_by_touch+2*sub->onlyCloser+4*sub->dontautokern );
putc(' ',sfd);
}
fprintf( sfd, "} [" );
@@ -5979,6 +5979,7 @@ static void SFDParseLookup(FILE *sfd,SplineFont *sf,OTLookup *otl) {
ch = nlgetc(sfd);
sub->kerning_by_touch = ((ch-'0')&1)?1:0;
sub->onlyCloser = ((ch-'0')&2)?1:0;
+ sub->dontautokern = ((ch-'0')&4)?1:0;
nlgetc(sfd); /* slurp final bracket */
} else {
ungetc(ch,sfd);
diff --git a/fontforge/splinefont.h b/fontforge/splinefont.h
index 15d35fb2..7da111bd 100644
--- a/fontforge/splinefont.h
+++ b/fontforge/splinefont.h
@@ -428,7 +428,8 @@ typedef struct otlookup {
unsigned int vertical_kerning: 1;
unsigned int ticked: 1;
unsigned int kerning_by_touch: 1; /* for gpos_pair, calculate kerning so that glyphs will touch */
- unsigned int onlyCloser: 1;
+ unsigned int onlyCloser: 1; /* for kerning classes */
+ unsigned int dontautokern: 1; /* for kerning classes */
struct kernclass *kc;
struct generic_fpst *fpst;
struct generic_asm *sm;
diff --git a/fontforge/splineutil2.c b/fontforge/splineutil2.c
index 9e718a4f..9e3a3437 100644
--- a/fontforge/splineutil2.c
+++ b/fontforge/splineutil2.c
@@ -24,7 +24,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "pfaedit.h"
+#include "fontforge.h"
#include <math.h>
#include "ustring.h"
#include "chardata.h"
diff --git a/fontforge/stamp.c b/fontforge/stamp.c
index 3c000b36..d32791dc 100644
--- a/fontforge/stamp.c
+++ b/fontforge/stamp.c
@@ -1,5 +1,5 @@
#include <time.h>
-const time_t source_modtime = 1298320590L;
-const char *source_modtime_str = "20:36 GMT 21-Feb-2011";
+const time_t source_modtime = 1298329534L;
+const char *source_modtime_str = "23:05 GMT 21-Feb-2011";
const char *source_version_str = "20110221";
diff --git a/htdocs/python.html b/htdocs/python.html
index eec8bdde..75b417ba 100644
--- a/htdocs/python.html
+++ b/htdocs/python.html
@@ -3684,7 +3684,7 @@ pen = None; # Finalize the pen. This tells FontForge
&nbsp;separation,<BR>
&nbsp;first-classes,<BR>
&nbsp;second-classes<BR>
- &nbsp;[,onlyCloser,after])</CODE>
+ &nbsp;[,onlyCloser,autokern,after])</CODE>
<P ALIGN=Center>
<STRONG>or</STRONG>
<P>
@@ -3692,13 +3692,13 @@ pen = None; # Finalize the pen. This tells FontForge
&nbsp;separation,class-distance,<BR>
&nbsp;,first-glyph-list,<BR>
&nbsp;second-glyph-list,<BR>
- &nbsp;[,onlyCloser,after])</CODE>
+ &nbsp;[,onlyCloser,autokern,after])</CODE>
<P ALIGN=Center>
<STRONG>or</STRONG>
<P>
<CODE>(lookup-name,new-subtable-name,<BR>
&nbsp;separation,class-distance,<BR>
- &nbsp;[,onlyCloser,after])</CODE></TD>
+ &nbsp;[,onlyCloser,autokern,after])</CODE></TD>
<TD>Creates a new subtable and a new kerning class in the named lookup. The
classes arguments are tuples of tuples of glyph names (each sub-tuble of
glyph names is a kerning class). The offsets argument is a tuple of kerning
diff --git a/htdocs/sfdformat.html b/htdocs/sfdformat.html
index d1cdb1e3..c864f6f5 100644
--- a/htdocs/sfdformat.html
+++ b/htdocs/sfdformat.html
@@ -430,9 +430,12 @@ Lookup: 258 0 0 "'kern' Horizontal Kerning in Latin lookup 0" {"'kern' Horizont
represent default values for autokerning in this subtable, the first is the
desired separation between glyphs, the next is the minimum (absolute) value
that will generate a kerning pair (kerning by 1 em unit isn't interesting
- and if that's what autokern comes up with, there is really no point to it),
- and the last is an indication if separation is based on closest approach
- (touching).
+ and if that's what autokern comes up with, there is really no point to it
+ and it wastes time), and the last is a set of bit flags: if the number is
+ odd then it means separation is based on closest approach (touching), if
+ the number has bit 2 set, then only negative (closer) kerning values will
+ be generated by autokerning and if the number has bit 4 set then no auto-
+ kerning will happen at all.
<P>
The order in which lookups are applied is the order listed here. The order
in which subtables are applied is the order listed here.