summaryrefslogtreecommitdiff
path: root/fontforge
diff options
context:
space:
mode:
authorGeorge Williams <pfaedit@users.sourceforge.net>2011-03-14 19:32:58 -0700
committerGeorge Williams <pfaedit@users.sourceforge.net>2011-03-14 19:32:58 -0700
commit1f400288e4b456da9f817f871fa9486ff95645a1 (patch)
treedef9320b389d67dc93863dc7557fd1610c277369 /fontforge
parent27d43b11b065636f612df584d070fdf2a986ad28 (diff)
Barry wants a python entry to the "Change Glyph" dlg.
Diffstat (limited to 'fontforge')
-rw-r--r--fontforge/python.c218
1 files changed, 216 insertions, 2 deletions
diff --git a/fontforge/python.c b/fontforge/python.c
index 37ba263b..5ce08b78 100644
--- a/fontforge/python.c
+++ b/fontforge/python.c
@@ -1043,7 +1043,7 @@ return( NULL );
return( NULL );
}
for ( i=0; i<cnt; ++i ) {
- PyObject *utf8_name = PYBYTES_UTF8(PyTuple_GetItem(answero,i));
+ PyObject *utf8_name = PYBYTES_UTF8(PySequence_GetItem(answero,i));
if ( utf8_name==NULL )
return( NULL );
answers[i] = copy(PyBytes_AsString(utf8_name));
@@ -14748,7 +14748,7 @@ static PyObject *PyFFFont_addSmallCaps(PyObject *self, PyObject *args, PyObject
memset(&genchange,0,sizeof(genchange));
SmallCapsFindConstants(&small,fv->sf,fv->active_layer);
genchange.small = &small;
- genchange.gc = gc_subsuper;
+ genchange.gc = gc_smallcaps;
genchange.extension_for_letters = "sc";
genchange.extension_for_symbols = "taboldstyle";
if ( !PyArg_ParseTupleAndKeywords(args,keywds,"|ddddissddd",smallcaps_keywords,
@@ -14788,6 +14788,219 @@ return( NULL );
Py_RETURN( self );
}
+static char *genchange_keywords[] = {
+/* Stem info */
+ "stemType",
+ "thickThreshold",
+ "stemScale", "stemAdd",
+ "stemHeightScale", "thinStemScale",
+ "stemHeightAdd", "thinStemAdd",
+ "stemWidthScale", "thickStemScale",
+ "stemWidthAdd", "thickStemAdd",
+ "processDiagonalStems",
+/* Horizontal counter info */
+ "hCounterType",
+ "hCounterScale", "hCounterAdd",
+ "lsbScale", "lsbAdd",
+ "rsbScale", "rsbAdd",
+/* Vertical counter info */
+ "vCounterType",
+ "vCounterScale", "vCounterAdd",
+ "vScale",
+ "vMap",
+ NULL};
+
+static PyObject *PyFFFont_genericGlyphChange(PyObject *self, PyObject *args, PyObject *keywds) {
+ FontViewBase *fv = ((PyFF_Font *) self)->fv;
+ struct smallcaps small;
+ struct genericchange genchange;
+ char *stemtype = "uniform", *hcountertype="uniform", *vCounterType="mapped";
+ double thickthreshold=0,
+ stemscale=0, stemadd=0,
+ stemheightscale=0, thinstemscale=0,
+ stemheightadd=0, thinstemadd=0,
+ stemwidthscale=0, thickstemscale=0,
+ stemwidthadd=0, thickstemadd=0;
+ int processdiagonalstems=1;
+ double counterScale=0, counterAdd=0,
+ lsbScale=0, lsbAdd=0,
+ rsbScale=0, rsbAdd=0;
+ double vCounterScale=0, vCounterAdd=0,
+ vScale=1.0;
+ PyObject *vMap=NULL;
+
+ memset(&genchange,0,sizeof(genchange));
+ SmallCapsFindConstants(&small,fv->sf,fv->active_layer);
+ genchange.small = &small;
+ genchange.gc = gc_generic;
+ if ( !PyArg_ParseTupleAndKeywords(args,keywds,"|sdddddddddddisddddddsdddO",genchange_keywords,
+/* Stem info */
+ &stemtype,
+ &thickthreshold,
+ &stemscale, &stemadd,
+ &stemheightscale,&thinstemscale,
+ &stemheightadd, &thinstemadd,
+ &stemwidthscale, &thickstemscale,
+ &stemwidthadd, &thickstemadd,
+ &processdiagonalstems,
+/* Horizontal counter info */
+ &hcountertype,
+ &counterScale, &counterAdd,
+ &lsbScale, &lsbAdd,
+ &rsbScale, &rsbAdd,
+/* Vertical counter info */
+ &vCounterType,
+ &vCounterScale, vCounterAdd,
+ &vScale,
+ &vMap
+ ))
+return( NULL );
+
+/* Stem info */
+ if ( strcasecmp(stemtype,"uniform")==0 ) {
+ if ( stemscale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for stemScale: %g.", stemscale );
+return( NULL );
+ }
+ genchange.stem_width_scale = genchange.stem_height_scale = stemscale;
+ genchange.stem_width_add = genchange.stem_height_add = stemadd;
+ } else if ( strcasecmp( stemtype, "thickThin" )==0 ) {
+ if ( thinstemscale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for thinStemScale: %g.", thinstemscale );
+return( NULL );
+ }
+ if ( thickstemscale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for thickStemScale: %g.", thickstemscale );
+return( NULL );
+ }
+ if ( thickthreshold<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for thickThreshold: %g.", thickthreshold );
+return( NULL );
+ }
+ genchange.stem_width_scale = thickstemscale;
+ genchange.stem_width_add = thickstemadd;
+ genchange.stem_height_scale = thinstemscale;
+ genchange.stem_height_add = thinstemadd;
+ genchange.stem_threshold = thickthreshold;
+ } else if ( strcasecmp( stemtype, "horizontalVertical" )==0 ) {
+ if ( stemheightscale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for stemHeightScale: %g.", stemheightscale );
+return( NULL );
+ }
+ if ( stemwidthscale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for stemWidthScale: %g.", stemwidthscale );
+return( NULL );
+ }
+ genchange.stem_width_scale = stemwidthscale;
+ genchange.stem_width_add = stemwidthadd;
+ genchange.stem_height_scale = stemheightscale;
+ genchange.stem_height_add = stemheightadd;
+ } else {
+ PyErr_Format(PyExc_TypeError, "Unexpected value for stemType: %s\n (Try: 'uniform', 'thickThin', or 'horizontalVertical')", stemtype );
+return( NULL );
+ }
+ genchange.dstem_control = processdiagonalstems;
+ if ( genchange.stem_height_add!=genchange.stem_width_add ) {
+ if (( genchange.stem_height_add==0 && genchange.stem_width_add!=0 ) ||
+ ( genchange.stem_height_add!=0 && genchange.stem_width_add==0 )) {
+ PyErr_Format(PyExc_TypeError, _("The horizontal and vertical stem add amounts must either both be zero, or neither may be 0"));
+return( NULL );
+ }
+ /* if width_add has a different sign than height_add that's also */
+ /* a problem, but this test will catch that too */
+ if (( genchange.stem_height_add/genchange.stem_width_add>4 ) ||
+ ( genchange.stem_height_add/genchange.stem_width_add<.25 )) {
+ PyErr_Format(PyExc_TypeError, _("The horizontal and vertical stem add amounts may not differ by more than a factor of 4"));
+return( NULL );
+ }
+ }
+
+/* Horizontal counter info */
+ if ( strcasecmp(hcountertype,"uniform")==0 ) {
+ if ( counterScale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for hCounterScale: %g.", counterScale );
+return( NULL );
+ }
+ genchange.hcounter_scale = genchange.lsb_scale = genchange.rsb_scale = counterScale;
+ genchange.hcounter_add = genchange.lsb_add = genchange.rsb_add = counterAdd;
+ } else if ( strcasecmp(hcountertype,"nonUniform")==0 ) {
+ if ( counterScale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for hCounterScale: %g.", counterScale );
+return( NULL );
+ }
+ if ( lsbScale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for lsbScale: %g.", lsbScale );
+return( NULL );
+ }
+ if ( rsbScale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for rsbScale: %g.", rsbScale );
+return( NULL );
+ }
+ genchange.hcounter_scale = counterScale;
+ genchange.lsb_scale = lsbScale;
+ genchange.rsb_scale = rsbScale;
+ genchange.hcounter_add = counterAdd;
+ genchange.lsb_add = lsbAdd;
+ genchange.rsb_add = rsbAdd;
+ } else if ( strcasecmp(hcountertype,"center")==0 ) {
+ genchange.center_in_hor_advance = 1;
+ } else if ( strcasecmp(hcountertype,"retainScale")==0 ) {
+ genchange.center_in_hor_advance = 2;
+ } else {
+ PyErr_Format(PyExc_TypeError, "Unexpected value for hCounterType: %s\n (Try: 'uniform', 'nonUniform', 'retain', or 'scale')", hcountertype );
+return( NULL );
+ }
+
+/* Vertical counter info */
+ if ( strcasecmp(vCounterType,"scaled")==0 ) {
+ if ( vCounterScale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for vCounterScale: %g.", vCounterScale );
+return( NULL );
+ }
+ genchange.vcounter_scale = vCounterScale;
+ genchange.vcounter_add = vCounterAdd;
+ genchange.use_vert_mapping = false;
+ } else if ( strcasecmp(vCounterType,"mapped")==0 ) {
+ int cnt,i;
+ genchange.use_vert_mapping = true;
+ if ( vScale<=0 ) {
+ PyErr_Format(PyExc_TypeError, "Unexpected (or unspecified) value for vScale: %g.", vScale );
+return( NULL );
+ }
+ genchange.v_scale = vScale;
+ if ( vMap==NULL || !PySequence_Check(vMap) || STRING_CHECK(vMap)) {
+ PyErr_Format(PyExc_TypeError, "vMap should be a tuple (or some other sequence type)." );
+return( NULL );
+ }
+ cnt = PySequence_Size(vMap);
+ genchange.m.cnt = cnt;
+ genchange.m.maps = galloc(cnt*sizeof(struct position_maps));
+ for ( i=0; i<cnt; ++i ) {
+ PyObject *subTuple = PySequence_GetItem(vMap,i);
+ if ( subTuple==NULL || !PySequence_Check(subTuple) || STRING_CHECK(subTuple) || PySequence_Size(subTuple)!=3 ) {
+ PyErr_Format(PyExc_TypeError, "vMap should be a tuple of 3-tuples." );
+ free(genchange.m.maps);
+return( NULL );
+ }
+ if ( !PyArg_ParseTuple(subTuple,"ddd",
+ &genchange.m.maps[i].current,
+ &genchange.m.maps[i].desired,
+ &genchange.m.maps[i].cur_width) ) {
+ free(genchange.m.maps);
+return( NULL );
+ }
+ }
+ } else {
+ PyErr_Format(PyExc_TypeError, "Unexpected value for vCounterType: %s\n (Try: 'scaled', or 'mapped')", vCounterType );
+return( NULL );
+ }
+
+ FVGenericChange( fv, &genchange );
+ free(genchange.m.maps);
+
+Py_RETURN( self );
+}
+
static PyObject *PyFFFont_autoHint(PyObject *self, PyObject *args) {
FontViewBase *fv = ((PyFF_Font *) self)->fv;
@@ -15107,6 +15320,7 @@ static PyMethodDef PyFF_Font_methods[] = {
/*{ "compareGlyphs", (PyCFunction) PyFFFont_compareGlyphs, METH_VARARGS, "Compares two sets of glyphs"},*/
/* compareGlyphs assumes an old scripting context */
{ "correctDirection", (PyCFunction) PyFFFont_Correct, METH_NOARGS, "Orient a layer so that external contours are clockwise and internal counter clockwise." },
+ { "genericGlyphChange", (PyCFunction) PyFFFont_genericGlyphChange, METH_VARARGS | METH_KEYWORDS, "Rather like changeWeight or condenseExtend but with more options."},
{ "italicize", (PyCFunction) PyFFFont_italicize, METH_VARARGS | METH_KEYWORDS, "Italicize the selected glyphs"},
{ "intersect", (PyCFunction) PyFFFont_Intersect, METH_NOARGS, "Leaves the areas where the contours of a glyph overlap."},
{ "removeOverlap", (PyCFunction) PyFFFont_RemoveOverlap, METH_NOARGS, "Remove overlapping areas from a glyph"},