Commit 9d22b27
TTF grid Use 1000 units per em
Changed files (7)
modifiedlibbirdfont/BirdFont.valamodifiedlibbirdfont/DrawingTools.valamodifiedlibbirdfont/GridTool.valamodifiedlibbirdfont/MoveTool.valamodifiedlibbirdfont/OpenFontFormat/GlyfData.valamodifiedlibbirdfont/OpenFontFormat/HeadTable.valamodifiedlibbirdfont/PenTool.vala
Diff
@@ -272,6 +272,7 @@ public class BirdFont { DefaultCharacterSet.create_default_character_sets (); DefaultCharacterSet.get_characters_for_prefered_language (); + HeadTable.init (); } public static void set_bundle_path (string path) {@@ -641,9 +641,13 @@ public class DrawingTools : ToolCollection { g.redraw_area (0, 0, g.allocation.width, g.allocation.height); }); style_tools.add_tool (fill_open_path);- - // FIXME transparency on windows + Tool ttf_units = new Tool ("ttf_units", _("Use TTF units."));+ ttf_units.select_action.connect((self) => {+ GridTool.ttf_units = !GridTool.ttf_units;+ });+ style_tools.add_tool (ttf_units);+ draw_tools.set_open (true); draw_tool_modifiers.set_open (true); edit_point_modifiers.set_open (true);@@ -23,6 +23,7 @@ class GridTool : Tool { static List<Line> vertical; static bool visible = false;+ public static bool ttf_units = true; public static double size_x; public static double size_y;@@ -73,12 +74,34 @@ class GridTool : Tool { } public static void set_grid_width (double w) {+ double t = 0;+ + if (ttf_units) {+ ttf_grid_coordinate (ref w, ref t); + }+ size_x = w; size_y = w; update_lines (); } + public static void ttf_grid (ref int pixel_x, ref int pixel_y) {+ double coordinate_x = Glyph.path_coordinate_x (pixel_x);+ double coordinate_y = Glyph.path_coordinate_y (pixel_y);+ + coordinate_x = GlyfData.tie_to_ttf_grid_x (MainWindow.get_current_glyph (), coordinate_x);+ coordinate_y = GlyfData.tie_to_ttf_grid_y (BirdFont.get_current_font (), coordinate_y);+ + pixel_x = Glyph.reverse_path_coordinate_x (coordinate_x);+ pixel_y = Glyph.reverse_path_coordinate_y (coordinate_y);+ }++ public static void ttf_grid_coordinate (ref double x, ref double y) {+ x = GlyfData.tie_to_ttf_grid_x (MainWindow.get_current_glyph (), x);+ y = GlyfData.tie_to_ttf_grid_y (BirdFont.get_current_font (), y);+ }+ private static void update_lines () { Glyph g = MainWindow.get_current_glyph (); double step = size_y;@@ -243,6 +266,10 @@ class GridTool : Tool { return y; } + public static bool has_ttf_grid () {+ return ttf_units;+ }+ public static bool is_visible () { return visible; }@@ -95,7 +95,11 @@ class MoveTool : Tool { foreach (Path p in glyph.active_paths) { tie_path_to_grid (p, x, y); }- }+ } else if (GridTool.has_ttf_grid ()) {+ foreach (Path p in glyph.active_paths) {+ tie_path_to_ttf_grid (p, x, y);+ }+ } if (group_selection) { select_group ();@@ -298,7 +302,11 @@ class MoveTool : Tool { glyph.redraw_area (0, 0, glyph.allocation.width, glyph.allocation.height); } - void tie_path_to_grid (Path p, double x, double y) {+ void tie_path_to_ttf_grid (Path p, double x, double y) {+ tie_path_to_grid (p, x, y, true);+ } ++ void tie_path_to_grid (Path p, double x, double y, bool ttf_grid = false) { double sx, sy, qx, qy; // tie to grid@@ -307,8 +315,13 @@ class MoveTool : Tool { qx = p.xmin; qy = p.ymin; - GridTool.tie_coordinate (ref sx, ref sy);- GridTool.tie_coordinate (ref qx, ref qy);+ if (ttf_grid) {+ GridTool.ttf_grid_coordinate (ref sx, ref sy);+ GridTool.ttf_grid_coordinate (ref qx, ref qy);+ } else {+ GridTool.tie_coordinate (ref sx, ref sy);+ GridTool.tie_coordinate (ref qx, ref qy);+ } if (Math.fabs (qy - p.ymin) < Math.fabs (sy - p.ymax)) { p.move (0, qy - p.ymin);@@ -51,8 +51,10 @@ class GlyfData : GLib.Object { public int16 bounding_box_xmax = 0; public int16 bounding_box_ymax = 0; - private static double UNITS = HeadTable.UNITS;- + private static double UNITS {+ get { return HeadTable.UNITS; }+ }+ public GlyfData (Glyph g) { Path q; @@ -147,6 +149,18 @@ class GlyfData : GLib.Object { } } + public static double tie_to_ttf_grid_x (Glyph glyph, double x) {+ double ttf_x;+ ttf_x = rint (x * UNITS - glyph.left_limit * UNITS);+ return (ttf_x / UNITS) + glyph.left_limit;+ }++ public static double tie_to_ttf_grid_y (Font font, double y) {+ double ttf_y;+ ttf_y = rint (y * UNITS + font.base_line * UNITS);+ return (ttf_y / UNITS) - font.base_line;+ }+ void process_x () { double prev = 0; double x;@@ -41,8 +41,8 @@ class HeadTable : Table { uint64 modified; // public static uint16 units_per_em = 4096; FIXME: windows testing- public static uint16 units_per_em = 1000;- public static double UNITS = 10 * (units_per_em / 1000);+ public static uint16 units_per_em;+ public static double UNITS; const uint8 BASELINE_AT_ZERO = 1 << 0; const uint8 LSB_AT_ZERO = 1 << 1;@@ -52,6 +52,13 @@ class HeadTable : Table { public HeadTable (GlyfTable gt) { glyf_table = gt; id = "head";+ init ();+ }+ + /** Set default value for unit. */+ public static void init () {+ units_per_em = 1000;+ UNITS = 10 * (units_per_em / 1000); } public uint32 get_adjusted_checksum () {@@ -45,6 +45,8 @@ public class PenTool : Tool { private static bool show_selection_box = false; private static double selection_box_x = 0; private static double selection_box_y = 0;+ private static double selection_box_last_x = 0;+ private static double selection_box_last_y = 0; public static double precision = 1; private static ImageSurface? tie_icon = null;@@ -83,7 +85,7 @@ public class PenTool : Tool { move_point_on_path = false; }); - press_action.connect ((self, b, x, y) => {+ press_action.connect ((self, b, x, y) => { // retain path direction Glyph glyph = MainWindow.get_current_glyph (); clockwise = new List<Path> ();@@ -103,11 +105,13 @@ public class PenTool : Tool { last_point_y = y; press (b, x, y, false);- + if (GridTool.is_visible ()) { tie_pixels (ref x, ref y);+ } else if (GridTool.has_ttf_grid ()) {+ GridTool.ttf_grid (ref x, ref y); }- + last_point_x = x; last_point_y = y; });@@ -120,8 +124,10 @@ public class PenTool : Tool { }); release_action.connect ((self, b, ix, iy) => {- double x = ix;- double y = iy;+ double x, y;+ + x = ix;+ y = iy; join_paths (x, y); @@ -153,6 +159,9 @@ public class PenTool : Tool { }); move_action.connect ((self, x, y) => {+ selection_box_last_x = x;+ selection_box_last_y = y;+ move (x, y); }); @@ -193,10 +202,10 @@ public class PenTool : Tool { g = MainWindow.get_current_glyph (); - x1 = Glyph.path_coordinate_x (fmin (selection_box_x, last_point_x));- y1 = Glyph.path_coordinate_y (fmin (selection_box_y, last_point_y));- x2 = Glyph.path_coordinate_x (fmax (selection_box_x, last_point_x));- y2 = Glyph.path_coordinate_y (fmax (selection_box_y, last_point_y));+ x1 = Glyph.path_coordinate_x (fmin (selection_box_x, selection_box_last_x));+ y1 = Glyph.path_coordinate_y (fmin (selection_box_y, selection_box_last_y));+ x2 = Glyph.path_coordinate_x (fmax (selection_box_x, selection_box_last_x));+ y2 = Glyph.path_coordinate_y (fmax (selection_box_y, selection_box_last_y)); remove_all_selected_points (); @@ -277,11 +286,11 @@ public class PenTool : Tool { DrawingTools.precision.set_value_round (p, false, false); } - public void move (double x, double y) {+ public void move (int x, int y) { Glyph glyph = MainWindow.get_current_glyph (); double coordinate_x, coordinate_y;- double px = 0;- double py = 0;+ int px = 0;+ int py = 0; EditPoint p; control_point_event (x, y);@@ -295,10 +304,15 @@ public class PenTool : Tool { if (GridTool.is_visible ()) { coordinate_x = Glyph.path_coordinate_x (x); coordinate_y = Glyph.path_coordinate_y (y);- GridTool.tie_coordinate (ref coordinate_x, ref coordinate_y);+ GridTool.tie_coordinate (ref coordinate_x, ref coordinate_y); px = Glyph.reverse_path_coordinate_x (coordinate_x); py = Glyph.reverse_path_coordinate_y (coordinate_y); selected_handle.move_delta ((px - last_point_x), (py - last_point_y));+ } if (GridTool.has_ttf_grid ()) {+ px = x;+ py = y;+ GridTool.ttf_grid (ref px, ref py);+ selected_handle.move_delta ((px - last_point_x), (py - last_point_y)); } else { selected_handle.move_delta ((x - last_point_x) * precision, (y - last_point_y) * precision); }@@ -311,9 +325,12 @@ public class PenTool : Tool { if (GridTool.is_visible ()) { last_point_x = Glyph.precise_reverse_path_coordinate_x (selected_handle.x ()); last_point_y = Glyph.precise_reverse_path_coordinate_y (selected_handle.y ());+ } if (GridTool.has_ttf_grid ()) {+ last_point_x = Glyph.precise_reverse_path_coordinate_x (selected_handle.x ());+ last_point_y = Glyph.precise_reverse_path_coordinate_y (selected_handle.y ()); } else { last_point_x = x;- last_point_y = y; + last_point_y = y; } return;@@ -327,8 +344,13 @@ public class PenTool : Tool { coordinate_x = Glyph.path_coordinate_x (x); coordinate_y = Glyph.path_coordinate_y (y); GridTool.tie_coordinate (ref coordinate_x, ref coordinate_y);- px = Glyph.precise_reverse_path_coordinate_x (coordinate_x);- py = Glyph.precise_reverse_path_coordinate_y (coordinate_y);+ px = Glyph.reverse_path_coordinate_x (coordinate_x);+ py = Glyph.reverse_path_coordinate_y (coordinate_y);+ glyph.move_selected_edit_point_delta (p, (px - last_point_x), (py - last_point_y));+ } else if (GridTool.has_ttf_grid ()) {+ px = x;+ py = y;+ GridTool.ttf_grid (ref px, ref py); glyph.move_selected_edit_point_delta (p, (px - last_point_x), (py - last_point_y)); } else { glyph.move_selected_edit_point_delta (p, (x - last_point_x) * precision, (y - last_point_y) * precision);@@ -341,6 +363,9 @@ public class PenTool : Tool { if (GridTool.is_visible ()) { last_point_x = Glyph.precise_reverse_path_coordinate_x (selected_point.x); last_point_y = Glyph.precise_reverse_path_coordinate_y (selected_point.y);+ } else if (GridTool.has_ttf_grid ()) {+ last_point_x = Glyph.precise_reverse_path_coordinate_x (selected_point.x);+ last_point_y = Glyph.precise_reverse_path_coordinate_y (selected_point.y); } else { last_point_x = x; last_point_y = y; @@ -393,10 +418,12 @@ public class PenTool : Tool { select_active_point (x, y); } - if (selected_points.length () == 0) {+ if (selected_points.length () == 0 && !active_handle.active) { show_selection_box = true; selection_box_x = x; selection_box_y = y;+ selection_box_last_x = x;+ selection_box_last_y = y; } glyph.store_undo_state ();@@ -722,11 +749,11 @@ public class PenTool : Tool { void draw_selection_box (Context cr) { double x, y, w, h;- - x = fmin (selection_box_x, last_point_x);- y = fmin (selection_box_y, last_point_y);- w = fmax (selection_box_x, last_point_x) - x;- h = fmax (selection_box_y, last_point_y) - y;++ x = fmin (selection_box_x, selection_box_last_x);+ y = fmin (selection_box_y, selection_box_last_y);+ w = fmax (selection_box_x, selection_box_last_x) - x;+ h = fmax (selection_box_y, selection_box_last_y) - y; cr.save (); cr.set_source_rgba (0, 0, 0.3, 1);@@ -891,7 +918,8 @@ public class PenTool : Tool { double y = Glyph.path_coordinate_y (event_y); double distance; PointSelection e;- + int px, py;+ double coordinate_x, coordinate_y; set_active_edit_point (null, new Path ()); if (ep == null) {@@ -903,19 +931,32 @@ public class PenTool : Tool { if (distance < CONTACT_SURFACE) { set_active_edit_point (e.point, e.path);- + if (first_move_action && GridTool.is_visible () && move_selected) {- double coordinate_x = e.point.x;- double coordinate_y = e.point.y;+ coordinate_x = e.point.x;+ coordinate_y = e.point.y; GridTool.tie_coordinate (ref coordinate_x, ref coordinate_y);- int px = Glyph.reverse_path_coordinate_x (coordinate_x);- int py = Glyph.reverse_path_coordinate_y (coordinate_y);+ px = Glyph.reverse_path_coordinate_x (coordinate_x);+ py = Glyph.reverse_path_coordinate_y (coordinate_y); last_point_x += Glyph.reverse_path_coordinate_x (e.point.x) - px; last_point_y += Glyph.reverse_path_coordinate_y (e.point.y) - py; first_move_action = false;- }+ } else if (first_move_action && GridTool.has_ttf_grid () && move_selected) {+ coordinate_x = e.point.x;+ coordinate_y = e.point.y;+ + GridTool.ttf_grid_coordinate (ref coordinate_x, ref coordinate_y);++ px = Glyph.reverse_path_coordinate_x (coordinate_x);+ py = Glyph.reverse_path_coordinate_y (coordinate_y);+ + last_point_x += Glyph.reverse_path_coordinate_x (e.point.x) - px;+ last_point_y += Glyph.reverse_path_coordinate_y (e.point.y) - py;+ + first_move_action = false;+ } } }