Commit 4607fdc
Improved TTF generation, character width, gasp table etc.
Changed files (10)
modifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/GlyphBackgroundImage.valamodifiedlibbirdfont/OpenFontFormat/DirectoryTable.valamodifiedlibbirdfont/OpenFontFormat/GaspTable.valamodifiedlibbirdfont/OpenFontFormat/GlyfData.valamodifiedlibbirdfont/OpenFontFormat/GlyfTable.valamodifiedlibbirdfont/OpenFontFormat/GposTable.valamodifiedlibbirdfont/OpenFontFormat/HeadTable.valamodifiedlibbirdfont/OpenFontFormat/HmtxTable.valamodifiedlibbirdfont/OpenFontFormat/Os2Table.vala
Diff
@@ -79,6 +79,8 @@ public class Glyph : FontDisplay { public static Glyph? background_glyph = null; + bool empty = false;+ /** Id in the verison list. */ public int version_id = 1; @@ -128,6 +130,14 @@ public class Glyph : FontDisplay { return gs; } + public void set_empty_ttf (bool e) {+ empty = e;+ }++ public bool is_empty_ttf () {+ return empty;+ }+ public void set_ligature_substitution (string glyph_sequence) { ligature = true; substitution = glyph_sequence;@@ -203,6 +213,7 @@ public class Glyph : FontDisplay { return; } + path_list.first ().data.update_region_boundaries (); x1 = path_list.first ().data.xmin; y1 = path_list.first ().data.ymin; x2 = path_list.first ().data.xmax;@@ -1591,6 +1602,7 @@ public class Glyph : FontDisplay { g.ligature = ligature; g.substitution = substitution;+ g.empty = empty; g.open = open; @@ -173,23 +173,20 @@ public class GlyphBackgroundImage { public void create_background_folders (Font font) { File dir;- try {- dir = BirdFont.get_settings_directory ();- if (!dir.query_exists ()) {- DirUtils.create ((!) dir.get_path (), 0xFFFFFF);- }- - dir = font.get_backgrounds_folder ();- if (!dir.query_exists ()) {- DirUtils.create ((!) dir.get_path (), 0xFFFFFF);- }+ + dir = BirdFont.get_settings_directory ();+ if (!dir.query_exists ()) {+ DirUtils.create ((!) dir.get_path (), 0xFFFFFF);+ }+ + dir = font.get_backgrounds_folder ();+ if (!dir.query_exists ()) {+ DirUtils.create ((!) dir.get_path (), 0xFFFFFF);+ } - dir = font.get_backgrounds_folder ().get_child ("parts");- if (!dir.query_exists ()) {- DirUtils.create ((!) dir.get_path (), 0xFFFFFF);- }- } catch (GLib.Error e) {- warning (e.message);+ dir = font.get_backgrounds_folder ().get_child ("parts");+ if (!dir.query_exists ()) {+ DirUtils.create ((!) dir.get_path (), 0xFFFFFF); } } @@ -70,7 +70,7 @@ public class DirectoryTable : Table { hhea_table.process (); maxp_table.process (); name_table.process ();- os_2_table.process (glyf_table);+ os_2_table.process (glyf_table, hmtx_table); head_table.process (); loca_table.process (glyf_table, head_table); post_table.process ();@@ -17,10 +17,10 @@ namespace BirdFont { public class GaspTable : Table { public const uint16 NONE = 0;- public const uint16 GASP_GRIDFIT = 1 << 0;- public const uint16 GASP_DOGRAY = 1 << 1;- public const uint16 GASP_SYMMETRIC_GRIDFIT = 1 << 2;- public const uint16 GASP_SYMMETRIC_SMOOTHING = 1 << 3;+ public const uint16 GASP_GRIDFIT = 1;+ public const uint16 GASP_DOGRAY = 2;+ public const uint16 GASP_SYMMETRIC_GRIDFIT = 4;+ public const uint16 GASP_SYMMETRIC_SMOOTHING = 8; public GaspTable () { id = "gasp";@@ -246,11 +246,13 @@ class GlyfData : GLib.Object { foreach (int16 c in coordinate_x) { c += last;+ + if (c < bounding_box_xmin) {+ bounding_box_xmin = c;+ } - // Only on curve points are good for calculating bounding box- if ((flags.nth (i).data & CoordinateFlags.ON_PATH) > 0) { - if (c < bounding_box_xmin) bounding_box_xmin = c;- if (c > bounding_box_xmax) bounding_box_xmax = c;+ if (c > bounding_box_xmax) {+ bounding_box_xmax = c; } last = c;@@ -265,17 +267,15 @@ class GlyfData : GLib.Object { i = 0; foreach (int16 c in coordinate_y) { c += last;- - if ((flags.nth (i).data & CoordinateFlags.ON_PATH) > 0) {- if (c < bounding_box_ymin) {- bounding_box_ymin = c;- }- - if (c > bounding_box_ymax) {- bounding_box_ymax = c;- }+ + if (c < bounding_box_ymin) {+ bounding_box_ymin = c; } + if (c > bounding_box_ymax) {+ bounding_box_ymax = c;+ }+ last = c; i++; }@@ -49,10 +49,7 @@ public class GlyfTable : Table { uint16 max_points = 0; uint16 max_contours = 0;- - double total_width = 0;- int non_zero_glyphs = 0;- + public GlyfTable (LocaTable l) { id = "glyf"; loca_table = l;@@ -74,10 +71,6 @@ public class GlyfTable : Table { return -1; } - public int16 get_average_width () {- return (int16) Math.rint (total_width / non_zero_glyphs);- }- public uint16 get_max_contours () { return max_contours; }@@ -219,17 +212,18 @@ public class GlyfTable : Table { g.remove_empty_paths (); glyf_data = new GlyfData (g); - if (glyf_data.get_ncontours () == 0) {- warning (@"No paths in $(g.get_name ()) ($(g.get_hex ())) can be exported.");- }- - if (g.path_list.length () == 0 || glyf_data.paths.length () == 0) {+ if (g.path_list.length () == 0 || glyf_data.paths.length () == 0 || glyf_data.get_ncontours () == 0) { // location_offsets will be equal to location_offset + 1 for // all empty glyphs+ g.set_empty_ttf (true); return; } - non_zero_glyphs++;+ g.set_empty_ttf (false);++ if (glyf_data.get_ncontours () == 0) {+ warning (@"No paths in $(g.get_name ()) ($(g.get_hex ())) can be exported.");+ } ncontours = (int16) glyf_data.paths.length (); fd.add_short (ncontours);@@ -314,9 +308,6 @@ public class GlyfTable : Table { if (glyf_data.bounding_box_ymax > this.ymax) { this.ymax = glyf_data.bounding_box_ymax; }- - // part of average width calculation for OS/2 table- total_width += xmax - xmin; printd (@"length before padding: $(fd.length ())\n"); @@ -264,20 +264,6 @@ public class GposTable : Table { public uint pairs_offset_length () { return 2 * pairs.pairs.length (); }--/*-// FIXME: DELETE- public int get_pair_index (int gid) {- int i = 0;- foreach (PairFormat1 p in pairs) {- if (p.left == gid) {- return i;- }- i++;- }- return -1;- }-*/ } }@@ -1,5 +1,5 @@ /*- Copyright (C) 2012, 2013 Johan Mattsson+ Copyright (C) 2012, 2013, 2014 Johan Mattsson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -1,5 +1,5 @@ /*- Copyright (C) 2012, 2013 Johan Mattsson+ Copyright (C) 2012, 2013, 2014 Johan Mattsson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -25,8 +25,8 @@ public class HmtxTable : Table { public int16 max_advance = 0; public int16 max_extent = 0;- public int16 min_lsb = 0; - public int16 min_rsb = 0;+ public int16 min_lsb = int16.MAX; + public int16 min_rsb = int16.MAX; HeadTable head_table; GlyfTable glyf_table;@@ -38,8 +38,13 @@ public class HmtxTable : Table { } ~HmtxTable () {- if (advance_width != null) delete advance_width;- if (left_side_bearing != null) delete left_side_bearing; + if (advance_width != null) {+ delete advance_width;+ }+ + if (left_side_bearing != null) {+ delete left_side_bearing;+ } } public double get_advance (uint32 i) {@@ -96,38 +101,66 @@ public class HmtxTable : Table { int16 extent; int16 rsb; int16 lsb;++ int16 left_marker; + int16 right_marker; double xmin; double ymin; double xmax; double ymax; + if (advance_width != null) {+ warning ("advance_width is set");+ delete advance_width;+ }+ advance_width = new uint16 [glyf_table.glyphs.length ()];+ // advance and lsb+ nmetrics = 0; foreach (Glyph g in glyf_table.glyphs) {+ // FIXME: integer round off error g.boundaries (out xmin, out ymin, out xmax, out ymax);- lsb = (int16) (-1 * (g.left_limit - xmin) * HeadTable.UNITS);- advance = (int16) ((g.right_limit - g.left_limit) * HeadTable.UNITS);- extent = (int16) (lsb + (xmax - xmin) * HeadTable.UNITS);- rsb = (int16) (advance - extent);++ xmax = Math.rint (xmax * HeadTable.UNITS);+ xmin = Math.rint (xmin * HeadTable.UNITS);+ + left_marker = (int16) Math.rint (g.left_limit * HeadTable.UNITS);+ right_marker = (int16) Math.rint (g.right_limit * HeadTable.UNITS);+ + lsb = (int16) xmin - left_marker;+ advance = right_marker - left_marker;+ + extent = (int16) (lsb + xmax - xmin);+ rsb = (int16) Math.rint (advance - extent); fd.add_u16 (advance); fd.add_16 (lsb);- - if (advance > max_advance) {- max_advance = advance;- } - if (extent > max_extent) {- max_extent = extent;+ if (!g.is_empty_ttf ()) {+ if (advance > max_advance) {+ max_advance = advance;+ }+ + if (extent > max_extent) {+ max_extent = extent;+ }+ + if (rsb < min_rsb) {+ min_rsb = rsb;+ }++ if (lsb < min_lsb) {+ min_lsb = lsb;+ } } - if (rsb < min_rsb) {- min_rsb = rsb;- }-- if (lsb < min_lsb) {- min_lsb = lsb;+ if (extent < 0) {+ warning ("Negative extent."); }+ + advance_width[nmetrics] = (uint16) extent;+ nmetrics++; } // monospaced lsb ...@@ -136,6 +169,19 @@ public class HmtxTable : Table { warn_if_fail (max_advance != 0); }+ + public int16 get_average_width () {+ double total_width = 0;+ uint non_zero_glyphs = 0;+ for (int i = 0; i < nmetrics; i++) {+ if (advance_width[i] != 0) {+ total_width += advance_width[i];+ non_zero_glyphs++;+ }+ }+ print (@"$total_width / $non_zero_glyphs\n");+ return (int16) Math.rint (total_width / non_zero_glyphs);+ } } }@@ -34,7 +34,7 @@ public class Os2Table : Table { public override void parse (FontData dis) throws Error { } - public void process (GlyfTable glyf_table) {+ public void process (GlyfTable glyf_table, HmtxTable hmtx_table) { FontData fd = new FontData (); Font font = OpenFontFormatWriter.get_current_font (); int16 ascender;@@ -43,7 +43,7 @@ public class Os2Table : Table { fd.add_u16 (0x0002); // version - fd.add_16 (glyf_table.get_average_width ()); // xAvgCharWidth+ fd.add_16 (hmtx_table.get_average_width ()); // xAvgCharWidth fd.add_u16 ((uint16) font.weight); // usWeightClass (400 is normal, 700 is bold)