Commit fceb592
Merge branch 'master' of gitorious.org:supplement/birdfont Conflicts: src/OpenFontFormatWriter.vala
Changed files (5)
modifiedREADMEmodifiedsrc/Font.valamodifiedsrc/MenuTab.valamodifiedsrc/OpenFontFormatWriter.valamodifiedsrc/wscript
Diff
@@ -12,13 +12,12 @@ Building from source Install vala and all required libraries, they are most likely in packages with a -dev or -devel affix. You can run this as root if you are using Debian: -apt-get install valac libglib-2.0-dev libgtk+2.0-dev libxml2-dev libwebkitgtk-dev+sudo apt-get install valac libglib2.0-dev libgtk2.0-dev libxml2-dev libwebkitgtk-dev Configure, build and install with waf: ./waf configure ./waf build-su-./waf install+sudo ./waf install ------------------------@@ -228,7 +228,7 @@ class Font : GLib.Object { } ret = new Glyph ("nonmarkingreturn", '\r');- ret.set_unassigned (true);+ ret.set_unassigned (false); ret.left_limit = 0; ret.right_limit = 0; ret.remove_empty_paths ();@@ -246,7 +246,7 @@ class Font : GLib.Object { } n = new Glyph ("null", '\0');- n.set_unassigned (true);+ n.set_unassigned (false); n.left_limit = 0; n.right_limit = 0; n.remove_empty_paths ();@@ -142,21 +142,30 @@ class MenuTab : FontDisplay { <div class="content"> <form> """);+ +c.append ("""+ <h3>Name</h3>+ <input class="text" type="text" id="fontname" value=""" + "\"" + f.get_name () + "\"" + """ onchange="update_export_settings ();"/><br />+ + <input class="button" type="button" value="Export" id="export_button" onclick="call ('export:fonts');"/>+ <input class="button" type="button" value="Preview" id="preview_button" onclick="call ('preview:fonts');"/><br />+"""); -if (Supplement.experimental) {+ if (!Supplement.experimental) {+ c.append ("""<div style="visibility:hidden;">""");+ }+ c.append (""" <h3>Formats</h3> <input class="checkbox" type="checkbox" id="svg" checked="checked" onchange="update_export_settings ();"/> SVG<br /> <input class="checkbox" type="checkbox" id="ttf" checked="checked" onchange="update_export_settings ();"/> TTF<br /> """);-} + if (!Supplement.experimental) {+ c.append ("</div>");+ }+ c.append ("""- <h3>Name</h3>- <input class="text" type="text" id="fontname" value=""" + "\"" + f.get_name () + "\"" + """ onchange="update_export_settings ();"/><br />- - <input class="button" type="button" value="Export" id="export_button" onclick="call ('export:fonts');"/>- <input class="button" type="button" value="Preview" id="preview_button" onclick="call ('preview:fonts');"/><br /> </form> </div> </div>@@ -680,7 +680,8 @@ class LocaTable : Table { if (!(glyf_table.location_offsets.length () == glyf_table.glyphs.length () + 1)) { warning (@"(glyf_table.location_offsets.length () == glyf_table.glyphs.length () + 1) ($(glyf_table.location_offsets.length ()) == $(glyf_table.glyphs.length () + 1))"); } - + + fd.pad (); font_data = fd; } } @@ -734,29 +735,36 @@ class GlyfTable : Table { glyphs = new List<Glyph> (); } - public int get_gid (string name) { - int i = 0; + public double get_xheight () { + return get_capheight (); // FIXME + } + + public double get_capheight () { + double x1, x2, y1, y2; + Font f = Supplement.get_current_font (); + double max = double.MIN; + foreach (Glyph g in glyphs) { - if (g.name == name) { - return i; + g.boundries (out x1, out y1, out x2, out y2); + if (y2 > max) { + max = y2; } - - i++; } - return -1; + return max - f.base_line; } - public int16 get_space_gid () { - int16 i = 0; + public int get_gid (string name) { + int i = 0; foreach (Glyph g in glyphs) { - if (g.unichar_code == ' ') { + if (g.name == name) { return i; } + i++; } - return 0; + return -1; } public int16 get_average_width () { @@ -772,15 +780,7 @@ class GlyfTable : Table { } public uint16 get_first_char () { - foreach (Glyph g in glyphs) { - if (g.is_unassigned ()) { - continue; - } - - return (uint16)g.unichar_code; - } - - return 0; + return 32; // space } public uint16 get_last_char () { @@ -877,12 +877,6 @@ class GlyfTable : Table { glyph.left_limit = xmin - hmtx_table.get_lsb (index); glyph.left_limit = 0; glyph.right_limit = glyph.left_limit + hmtx_table.get_advance (index); - - if (xmin > glyph.right_limit || xmax < glyph.left_limit) { - warning (@"Glyph $(name) is outside of it's box."); - glyph.left_limit = xmin; - glyph.right_limit = xmax; - } } else { // add empty glyph glyph = new Glyph (name, character); @@ -1008,12 +1002,17 @@ class GlyfTable : Table { int npoints = 0; int16 ncontours; - int16 ixmin; + int16 ixmin; // set boundries int16 iymin; int16 ixmax; int16 iymax; uint16 ninstructions; - + + int16 rxmin = int16.MAX; // real xmin + int16 rymin = int16.MAX;; + int16 rxmax = int16.MIN; + int16 rymax = int16.MIN; + int nflags; Error? error = null; @@ -1073,7 +1072,6 @@ class GlyfTable : Table { return_val_if_fail (npoints < len, new Glyph.no_lines ("")); - // FIXA: implement instructions (maybe) ninstructions = dis.read_ushort (); return_val_if_fail (ninstructions < len, new Glyph.no_lines ("")); @@ -1139,13 +1137,16 @@ class GlyfTable : Table { last = xcoordinates[i]; + if (last > rxmax) rxmax = last; + if (last < rxmin) rxmin = last; + if (!(ixmin <= last <= ixmax)) { stderr.printf (@"x is out of bounds in glyph $(name.str). ($ixmin <= $last <= $ixmax) char $((uint)character)\n"); } if (!(head_table.xmin <= last <= head_table.xmax)) { stderr.printf (@"x is outside of of font bounding box in glyph $(name.str). ($(head_table.xmin) <= $last <= $(head_table.xmax)) char $((uint)character)\n"); - } + } } last = 0; @@ -1166,6 +1167,9 @@ class GlyfTable : Table { } last = ycoordinates[i]; + + if (last > rymax) rymax = last; + if (last < rymin) rymin = last; if (!(iymin <= last <= iymax)) { stderr.printf (@"y is out of bounds in glyph $(name.str). ($iymin <= $last <= $iymax) char $((uint)character)\n"); @@ -1176,6 +1180,14 @@ class GlyfTable : Table { } } + if (rymin != iymin || rxmin != ixmin || rxmax != ixmax || rymax != iymax) { + warning (@"Warning real boundry for glyph does not match boundry set in glyph header for glyph $(name.str)."); + stderr.printf (@"ymin: $rymin header: $iymin\n"); + stderr.printf (@"xmin: $rxmin header: $ixmin\n"); + stderr.printf (@"ymax: $rymax header: $iymax\n"); + stderr.printf (@"xmax: $rxmax header: $ixmax\n"); + } + int j = 0; int first_point; int last_point = 0; @@ -1362,7 +1374,7 @@ class GlyfTable : Table { txmax = int16.MIN; tymax = int16.MIN; - // will be set again after coordinate arrays have been parsed + // bounding box will be set again after coordinate arrays have been created fd.add_16 (10); fd.add_16 (20); fd.add_16 (30); @@ -1410,14 +1422,17 @@ class GlyfTable : Table { // flags nflags = 0; + List<uint8> flags = new List<uint8> (); foreach (Path p in g.path_list) { p = p.get_quadratic_points (); foreach (EditPoint e in p.points) { fd.add_byte (Coordinate.ON_PATH); + flags.append (Coordinate.ON_PATH); nflags++; if (e.get_right_handle ().type == PointType.CURVE) { fd.add_byte (Coordinate.NONE); + flags.append (Coordinate.NONE); nflags++; } } @@ -1431,27 +1446,26 @@ class GlyfTable : Table { printd (@"flags: $(nflags)\n"); // x coordinates + List<int16> coordinate_x = new List<int16> (); + List<int16> coordinate_y = new List<int16> (); double prev = 0; foreach (Path p in g.path_list) { p = p.get_quadratic_points (); foreach (EditPoint e in p.points) { - x = e.x * UNITS - prev + g.left_limit * UNITS; + x = e.x * UNITS - prev - g.left_limit * UNITS; fd.add_16 ((int16) x); - - if (x + prev <= txmin) txmin = (int16) x + (int16) prev; - if (x + prev >= txmax) txmax = (int16) x + (int16) prev; - - prev = e.x * UNITS + g.left_limit * UNITS; - + coordinate_x.append ((int16) x); + + prev = e.x * UNITS - g.left_limit * UNITS; + if (e.get_right_handle ().type == PointType.CURVE) { - x = e.get_right_handle ().x () * UNITS - prev + g.left_limit * UNITS; + x = e.get_right_handle ().x () * UNITS - prev - g.left_limit * UNITS; fd.add_16 ((int16) x); - - // Only on curve points are good for calculating bounding box - - prev = e.get_right_handle ().x () * UNITS + g.left_limit * UNITS; + coordinate_x.append ((int16) x); + + prev = e.get_right_handle ().x () * UNITS - g.left_limit * UNITS; } } } @@ -1463,28 +1477,61 @@ class GlyfTable : Table { foreach (EditPoint e in p.points) { y = e.y * UNITS - prev + font.base_line * UNITS; fd.add_16 ((int16) y); - - if (y + prev <= tymin) tymin = (int16) y + (int16) prev; - if (y + prev >= tymax) tymax = (int16) y + (int16) prev; - - prev = e.y * UNITS + font.base_line * UNITS; + + coordinate_y.append ((int16) y); + prev = e.y * UNITS + font.base_line * UNITS; + if (e.get_right_handle ().type == PointType.CURVE) { y = e.get_right_handle ().y () * UNITS - prev + font.base_line * UNITS; fd.add_16 ((int16) y); + coordinate_y.append ((int16) y); prev = e.get_right_handle ().y () * UNITS + font.base_line * UNITS; } } } + len = fd.length (); printd (@"fd.length (): $(fd.length ())\n"); coordinate_length = fd.length () - nflags - glyph_header; printd (@"coordinate_length: $(coordinate_length)\n"); assert (fd.length () > nflags + glyph_header); + + // bounding box + int16 last = 0; + int16 coordinate; + + int i = 0; + foreach (int16 c in coordinate_x) { + c += last; + + // Only on curve points are good for calculating bounding box + if ((flags.nth (i).data & Coordinate.ON_PATH) > 0) { + if (c < txmin) txmin = c; + if (c > txmax) txmax = c; + } + + last = c; + i++; + } + + last = 0; + i = 0; + foreach (int16 c in coordinate_y) { + c += last; + + if ((flags.nth (i).data & Coordinate.ON_PATH) > 0) { + if (c < tymin) tymin = c; + if (c > tymax) tymax = c; + } + + last = c; + i++; + } - len = fd.length (); + fd.seek_end (); printd (@"glyph_offset: $(glyph_offset)\n"); printd (@"len: $(len)\n"); @@ -1541,8 +1588,8 @@ class GlyfTable : Table { // add notdef. character at index zero + other special chars first glyphs.append (font.get_not_def_character ()); - //glyphs.append (font.get_null_character ()); - //glyphs.append (font.get_nonmarking_return ()); + glyphs.append (font.get_null_character ()); + glyphs.append (font.get_nonmarking_return ()); glyphs.append (font.get_space ()); List<Glyph> unassigned_glyphs = new List<Glyph> (); @@ -1551,7 +1598,7 @@ class GlyfTable : Table { for (indice = 0; (gl = font.get_glyph_indice (indice)) != null; indice++) { g = (!) gl; - if (g.name == ".notdef" || g.unichar_code == 0 || g.name == "space" || g.unichar_code == 0x0020) { + if (g.name == ".notdef" || g.unichar_code == '\0' || g.unichar_code == '\r' || g.name == "space" || g.unichar_code == 0x0020 || g.name == "" || g.name == ".null" || g.unichar_code == 0 || g.name == "nonmarkingreturn") { continue; } @@ -1618,7 +1665,7 @@ class CmapSubtable : Table { s = new StringBuilder (); c = get_char (i); s.append_unichar (c); - print (@"Char: $(s.str) val ($((uint32)c))\tindice: $(i)\n"); + printd (@"Char: $(s.str) val ($((uint32)c))\tindice: $(i)\n"); } } } @@ -1827,7 +1874,7 @@ class CmapSubtableWindowsUnicode : CmapSubtable { seg_count = (uint16) ranges.length () + 1; seg_count_2 = seg_count * 2; search_range = 2 * largest_pow2 (seg_count); - entry_selector = (uint16) (Math.log (search_range / 2) / Math.log (2)); + entry_selector = largest_pow2_exponent (seg_count); range_shift = seg_count_2 - search_range; // format @@ -2008,7 +2055,7 @@ class CmapTable : Table { } if (encoding == 3) { - stderr.printf ("Font contains a cmap table with the obsolete encoding 3."); + stderr.printf ("Font contains a cmap table with the obsolete encoding 3.\n"); } } @@ -2018,7 +2065,7 @@ class CmapTable : Table { foreach (CmapSubtable t in subtables) { t.parse (dis); - // t.print_cmap (); + t.print_cmap (); } } @@ -2066,7 +2113,7 @@ class HeadTable : Table { uint16 lowest_PPEM; int16 font_direction_hint; - public int16 loca_offset_size = 1; + public int16 loca_offset_size = 0; // 0 for int16 1 for int32 int16 glyph_data_format; Fixed version; @@ -2365,7 +2412,11 @@ class HmtxTable : Table { } public double get_advance (uint32 i) { - return_val_if_fail (i < nmetrics, 0.0); + if (i >= nmetrics) { + warning (@"i >= nmetrics $i >= $nmetrics"); + return 0; + } + return_val_if_fail (advance_width != null, 0.0); return advance_width[i] * 1000 / head_table.get_units_per_em (); @@ -2384,7 +2435,24 @@ class HmtxTable : Table { requires (i < nmonospaced && left_side_bearing_monospaced != null) { return left_side_bearing_monospaced[i] * 1000 / head_table.get_units_per_em (); } + + public void print_all () { + return_if_fail (advance_width != null); + return_if_fail (left_side_bearing != null); + for (int i = 0; i < nmetrics; i++) { + print (@"get_lsb ($i): $(get_lsb(i))\n"); + print (@"get_advance ($i): $(get_advance(i))\n"); + } + + if (left_side_bearing_monospaced != null) { + for (int i = 0; i < nmonospaced; i++) { + print (@"get_lsb_mono ($i): $(get_lsb_mono(i))\n"); + } + } + + } + public void parse (FontData dis, HheaTable hhea_table, LocaTable loca_table) { nmetrics = hhea_table.num_horizontal_metrics; nmonospaced = loca_table.size - nmetrics; @@ -2396,6 +2464,9 @@ class HmtxTable : Table { return; } + printd (@"nmetrics: $nmetrics\n"); + printd (@"loca_table.size: $(loca_table.size)\n"); + advance_width = new uint16[nmetrics]; left_side_bearing = new uint16[nmetrics]; left_side_bearing_monospaced = new uint16[nmonospaced]; @@ -2403,13 +2474,13 @@ class HmtxTable : Table { for (int i = 0; i < nmetrics; i++) { advance_width[i] = dis.read_ushort (); left_side_bearing[i] = dis.read_short (); - - // Delete: print (@"advance_width[i] $(advance_width[i]) $(left_side_bearing[i]) \n"); } for (int i = 0; i < nmonospaced; i++) { left_side_bearing_monospaced[i] = dis.read_short (); } + + print_all (); } public void process () { @@ -2795,6 +2866,9 @@ class Os2Table : Table { FontData fd = new FontData (); Font font = Supplement.get_current_font (); + int16 ascender; + int16 descender; + fd.add_u16 (0x0002); // USHORT Version 0x0000, 0x0001, 0x0002, 0x0003, 0x0004 fd.add_16 (glyf_table.get_average_width ()); // SHORT xAvgCharWidth @@ -2803,17 +2877,17 @@ class Os2Table : Table { fd.add_u16 (5); // USHORT usWidthClass (5 is normal) fd.add_u16 (0); // USHORT fsType - fd.add_16 (0); // SHORT ySubscriptXSize - fd.add_16 (0); // SHORT ySubscriptYSize - fd.add_16 (0); // SHORT ySubscriptXOffset - fd.add_16 (0); // SHORT ySubscriptYOffset - fd.add_16 (0); // SHORT ySuperscriptXSize - fd.add_16 (0); // SHORT ySuperscriptYSize - fd.add_16 (0); // SHORT ySuperscriptXOffset - fd.add_16 (0); // SHORT ySuperscriptYOffset - fd.add_16 (0); // SHORT yStrikeoutSize - fd.add_16 (0); // SHORT yStrikeoutPosition - fd.add_16 (0); // SHORT sFamilyClass + fd.add_16 (40); // SHORT ySubscriptXSize + fd.add_16 (40); // SHORT ySubscriptYSize + fd.add_16 (40); // SHORT ySubscriptXOffset + fd.add_16 (40); // SHORT ySubscriptYOffset + fd.add_16 (40); // SHORT ySuperscriptXSize + fd.add_16 (40); // SHORT ySuperscriptYSize + fd.add_16 (40); // SHORT ySuperscriptXOffset + fd.add_16 (40); // SHORT ySuperscriptYOffset + fd.add_16 (40); // SHORT yStrikeoutSize + fd.add_16 (200); // SHORT yStrikeoutPosition + fd.add_16 (40); // SHORT sFamilyClass // PANOSE fd.add (0); @@ -2839,22 +2913,31 @@ class Os2Table : Table { fd.add_u16 (glyf_table.get_first_char ()); // USHORT usFirstCharIndex fd.add_u16 (glyf_table.get_last_char ()); // USHORT usLastCharIndex - fd.add_16 ((int16) (-1 * (font.top_position - font.base_line))); // SHORT sTypoAscender - fd.add_16 ((int16) (-1 * font.bottom_position)); // SHORT sTypoDescender + // DELETE + //ascender = (int16) (-1 * (font.top_position - font.base_line)* UNITS); + //descender = (int16) (-font.bottom_position * UNITS); + + ascender = (int16) (-font.top_position * UNITS); + descender = (int16) (-font.bottom_position * UNITS); + + fd.add_16 (ascender); // SHORT sTypoAscender + fd.add_16 (descender); // SHORT sTypoDescender fd.add_16 (3); // SHORT sTypoLineGap - fd.add_u16 (0); // USHORT usWinAscent - fd.add_u16 (0); // USHORT usWinDescent + fd.add_u16 (ascender); // USHORT usWinAscent + fd.add_u16 (descender); // USHORT usWinDescent fd.add_u32 (0); // ULONG ulCodePageRange1 Bits 0-31 fd.add_u32 (0); // ULONG ulCodePageRange2 Bits 32-63 - fd.add_16 (0); // SHORT sxHeight version 0x0002 and later - fd.add_16 (0); // SHORT sCapHeight version 0x0002 and later + fd.add_16 (ascender); // SHORT sxHeight version 0x0002 and later + fd.add_16 (ascender); // SHORT sCapHeight version 0x0002 and later fd.add_16 (0); // USHORT usDefaultChar version 0x0002 and later fd.add_16 (0x0020); // USHORT usBreakChar version 0x0002 and later, also known as space - fd.add_16 (0); // USHORT usMaxContext version 0x0002 and later + + // FIXA: calculate these values + fd.add_16 (1); // USHORT usMaxContext version 0x0002 and later // padding fd.pad (); @@ -66,7 +66,7 @@ TEST = [ def build (bld): bld.program ( target = 'birdfont', - param = '--disable-warnings --enable-experimental --enable-experimental-non-null --vapidir=../../', + param = ['--disable-warnings', '--enable-experimental', '--enable-experimental-non-null', '--vapidir=../../'], packages = 'gtk+-2.0 libxml-2.0', uselib = 'GTK GLIB GIO XML WEB', source = SUPPLEMENT_MAIN