The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

AutoTrace.vala in /birdfont-autotrace

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
Circle boundaries heads/master
1 /* 2 Copyright (C) 2014 Johan Mattsson 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation, either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 using Cairo; 19 using Gee; 20 21 namespace BirdFont { 22 23 class AutoTrace { 24 25 ArrayList<string> files; 26 27 bool help; 28 bool quadratic_control_points; 29 double cutoff; 30 double details; 31 double simplification; 32 33 public AutoTrace (string[] arg) { 34 files = new ArrayList<string> (); 35 help = false; 36 quadratic_control_points = false; 37 cutoff = 1; 38 details = 1; 39 simplification = 0.5; 40 41 for (int i = 1; i < arg.length; i++) { 42 if (arg[i] == "-q" || arg[i] == "--quadratic") { 43 quadratic_control_points = true; 44 } else if (arg[i] == "-c" || arg[i] == "--cutoff" && i + 1 < arg.length) { 45 cutoff = double.parse (arg[i + 1]); 46 i++; 47 } else if (arg[i] == "-d" || arg[i] == "--details" && i + 1 < arg.length) { 48 details = double.parse (arg[i + 1]); 49 i++; 50 } else if (arg[i] == "-s" || arg[i] == "--simplification" && i + 1 < arg.length) { 51 simplification = double.parse (arg[i + 1]); 52 i++; 53 } else if (arg[i] == "-h" || arg[i] == "--help") { 54 help = true; 55 } else { 56 files.add (arg[i]); 57 } 58 } 59 } 60 61 public bool has_help_flag () { 62 return help; 63 } 64 65 public static void print_help (string[] arg) { 66 stdout.printf (t_("Usage:")); 67 stdout.printf (arg[0]); 68 stdout.printf (" [" + t_("OPTION") + " ...] " + t_("FILE") + " ..." + "\n"); 69 stdout.printf ("-c, --cutoff " + t_("brighness cutoff, from 0.001 to 2, the default value is 1") + "\n"); 70 stdout.printf ("-d, --details " + t_("details, from 0.001 to 9.999, the default value is 1") + "\n"); 71 stdout.printf ("-h, --help " + t_("print this message") + "\n"); 72 stdout.printf ("-q, --quadratic " + t_("use quadratic control points") + "\n"); 73 stdout.printf ("-s, --simplification " + t_("simplification, from 0.001 to 1, the default value is 0.5") + "\n"); 74 stdout.printf ("\n"); 75 } 76 77 public int trace () { 78 BackgroundImage bg; 79 File file; 80 PathList pl; 81 Glyph g; 82 double w, h; 83 Font font; 84 string svg; 85 string file_name; 86 DataOutputStream data_stream; 87 88 foreach (string f in files) { 89 file = File.new_for_path (f); 90 if (!file.query_exists ()) { 91 stdout.printf (@"$f\n"); 92 stdout.printf (t_("File does not exist.") + "\n"); 93 return 1; 94 } 95 96 if (((!) file.get_basename ()).index_of (".") == -1) { 97 stdout.printf (@"$f\n"); 98 stdout.printf (t_("Unknown file format.") + "\n"); 99 return 2; 100 } 101 } 102 103 if (quadratic_control_points) { 104 DrawingTools.point_type = PointType.QUADRATIC; 105 } else { 106 DrawingTools.point_type = PointType.CUBIC; 107 } 108 109 foreach (string f in files) { 110 file_name = f; 111 file_name = file_name.substring (0, file_name.last_index_of (".")); 112 file_name = @"$file_name.svg"; 113 114 stdout.printf (t_("Writing") + " " + file_name + "\n"); 115 116 font = BirdFont.new_font (); 117 bg = new BackgroundImage (f); 118 119 DrawingTools.auto_trace_resolution.set_value_round (details); 120 DrawingTools.background_threshold.set_value_round (details); 121 DrawingTools.auto_trace_simplify.set_value_round (simplification); 122 bg.set_high_contrast (true); 123 124 g = new Glyph.no_lines (""); 125 126 GlyphCanvas.current_display = g; 127 BirdFont.current_glyph_collection = new GlyphCollection.with_glyph ('\0', ""); 128 129 h = bg.get_img ().get_height (); 130 131 font.top_limit = h / 2; 132 font.bottom_limit = -h / 2; 133 font.top_position = h / 2; 134 font.bottom_position = -h / 2; 135 136 w = bg.get_img ().get_width (); 137 g.left_limit = -w / 2.0; 138 g.right_limit = w / 2.0; 139 140 bg.center_in_glyph (); 141 142 pl = bg.autotrace (); 143 144 foreach (Path p in pl.paths) { 145 g.add_path (p); 146 } 147 148 svg = ExportTool.export_to_string (g, false); 149 150 file = File.new_for_path (file_name); 151 152 try { 153 if (file.query_exists ()) { 154 file.delete (); 155 } 156 157 data_stream = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION)); 158 data_stream.put_string (svg); 159 } catch (GLib.Error e) { 160 warning(e.message); 161 return 1; 162 } 163 } 164 165 return 0; 166 } 167 } 168 169 public static int main (string[] arg) { 170 AutoTrace autotrace; 171 Preferences p; 172 173 BirdFont.current_font = new Font (); 174 175 p = new Preferences (); 176 177 BirdFont.init_gettext (); 178 Theme.set_default_colors (); 179 180 DrawingTools.background_threshold = new SpinButton (); 181 DrawingTools.background_scale = new SpinButton (); 182 DrawingTools.auto_trace_resolution = new SpinButton (); 183 DrawingTools.auto_trace_simplify = new SpinButton (); 184 185 autotrace = new AutoTrace (arg); 186 187 if (autotrace.has_help_flag () || arg.length <= 1) { 188 AutoTrace.print_help (arg); 189 return 0; 190 } 191 192 return autotrace.trace (); 193 } 194 195 } 196