Commit 176c0b1
restore things after the revert
Changed files (7)
deletedlibbirdfont/Context.valamodifiedlibbirdfont/Font.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/GlyphSequence.valaaddedlibbirdfont/KerningDisplay.valamodifiedlibbirdfont/MenuTab.valamodifiedlibbirdfont/SvgFont.vala
Diff
deleted file mode 100644@@ -1,335 +0,0 @@-/*- Copyright (C) 2012 Johan Mattsson-- This program is free software: you can redistribute it and/or modify- it under the terms of the GNU General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- This program is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU General Public License for more details.-- You should have received a copy of the GNU General Public License- along with this program. If not, see <http://www.gnu.org/licenses/>.-*/--using Cairo;--namespace BirdFont {--/** Kerning context. */-public class ContextDisplay : FontDisplay {-- List <GlyphSequence> row;- int active_handle = -1;- int selected_handle = -1;- - double begin_handle_x = 0;- double begin_handle_y = 0;- - double last_handle_x = 0;-/*-<<<<<<< HEAD- public KerningDisplay () {- GlyphSequence w = new GlyphSequence ();- row = new List <GlyphSequence> ();-=======-*/- public ContextDisplay () {- GlyphSequence w = new GlyphSequence ();- row = new List <GlyphSequence> ();-//>>>>>>> parent of a76d9a8... parse ligatures from svg font- row.append (w);- }-- public override string get_name () {- return "Kerning";- }- - public override void draw (Allocation allocation, Context cr) {- Glyph glyph;- double x, y, w, kern, alpha;- double x2;- int i, wi;- Glyph? prev;- Font font = BirdFont.get_current_font ();- GlyphSequence word_with_ligatures;- - i = 0;- - // bg color- cr.save ();- cr.set_source_rgba (1, 1, 1, 1);- cr.rectangle (0, 0, allocation.width, allocation.height);- cr.fill ();- cr.restore ();- - alpha = 1;- y = 100;- x = 20;- w = 0;- prev = null;- - foreach (GlyphSequence word in row) {- wi = 0;- word_with_ligatures = word.process_ligatures ();- foreach (Glyph? g in word_with_ligatures.glyph) {- if (g == null) {- continue;- }- - if (prev == null) {- kern = 0;- } else {- kern = font.get_kerning_by_name (((!)prev).get_name (), ((!)g).get_name ());- }- - // draw glyph - if (g == null) {- w = 50;- alpha = 1;- } else {- alpha = 0;- glyph = (!) g;- Svg.draw_svg_path (cr, glyph.get_svg_data (), x + kern, y);- w = glyph.get_width ();- }-- // handle- if (active_handle == i) {- //x2 = x + kern;- x2 = x + kern / 2.0;- - cr.save ();- cr.set_source_rgba (153/255.0, 153/255.0, 173/255.0, 1);- cr.move_to (x2 - 5, y + 20);- cr.line_to (x2 + 0, y + 20 - 5);- cr.line_to (x2 + 5, y + 20);- cr.fill ();- - cr.set_font_size (10);- cr.show_text (((!)g).get_name ());- cr.restore ();- } - - x += w + kern;- - // caption- if (g == null || ((!)g).is_empty ()) {- cr.save ();- cr.set_source_rgba (153/255.0, 153/255.0, 153/255.0, alpha);- cr.move_to (x - w / 2.0 - 5, y + 20);- cr.set_font_size (10);- cr.show_text ("?"); // ?- cr.restore ();- }- - prev = g;- - wi++;- i++;- }- - if (y > allocation.height && i > 10) {- row.remove (word);- }- - y += MainWindow.get_current_glyph ().get_height () + 20;- x = 20; - }- }- - private void set_kerning (int handle, double val) {- string a, b;- Font font;- int wi = 0;- double kern;- GlyphSequence word_with_ligatures;- - font = BirdFont.get_current_font ();-- font.touch ();-- a = "";- b = "";-- foreach (GlyphSequence word in row) {- word_with_ligatures = word.process_ligatures ();- foreach (Glyph? g in word_with_ligatures.glyph) {- - if (g == null) {- continue;- }- - b = ((!) g).get_name ();- - if (handle == wi) {- kern = font.get_kerning_by_name (a, b) + val;- font.set_kerning_by_name (a, b, kern);- }- - wi++;- - a = b;- }- }- - - }-- public override void selected_canvas () {- Glyph g;- GlyphSequence w;- unowned List<GlyphSequence>? r;- StringBuilder s = new StringBuilder ();- bool append_char = false;- Font font = BirdFont.get_current_font ();- - KeyBindings.singleton.set_require_modifier (true);- - g = MainWindow.get_current_glyph ();- s.append_unichar (g.get_unichar ());-- r = row;- return_if_fail (r != null);-- if (row.length () == 0) {- append_char = true;- }- - if (append_char) {- w = new GlyphSequence ();- row.append (w);- w.glyph.prepend (font.get_glyph (s.str));- } - }- - public override void key_press (uint keyval) {- unichar c = (unichar) keyval;- Glyph? g;- Font f = BirdFont.get_current_font ();- string name;- - if (KeyBindings.modifier == NONE || KeyBindings.modifier == SHIFT) {- - if (keyval == Key.BACK_SPACE && row.length () > 0) { - row.first ().data.glyph.remove_link (row.first ().data.glyph.last ());- }- - if (row.length () == 0 || c == Key.ENTER) {- row.prepend (new GlyphSequence ());- }- - if (!is_modifier_key (c) && c.validate ()) {- name = f.get_name_for_character (c);- g = f.get_glyph_by_name (name);- row.first ().data.glyph.append (g);- }- }- - MainWindow.get_glyph_canvas ().redraw ();- }- - public override void motion_notify (double ex, double ey) {- double k, y;- - if (selected_handle == -1) {- set_active_handle (ex, ey);- } else {- y = 1;- - if (Math.fabs (ey - begin_handle_y) > 20) {- y = ((Math.fabs (ey - begin_handle_y) / 100) + 1);- }- - k = (ex - last_handle_x) / y; // y-axis is variable precision- set_kerning (selected_handle, k);- MainWindow.get_glyph_canvas ().redraw ();- }- - last_handle_x = ex;- }- - public void set_active_handle (double ex, double ey) {- double y = 100;- double x = 20;- double w = 0;- double d, kern;- double min = double.MAX;- int i = 0;- int row_index = 0;- int col_index = 0;- Glyph glyph = new Glyph.no_lines ("");- Font font = BirdFont.get_current_font ();- - Glyph? prev = null;- string gl_name = "";- GlyphSequence word_with_ligatures;- - foreach (GlyphSequence word in row) {- col_index = 0;- - word_with_ligatures = word.process_ligatures ();- foreach (Glyph? g in word_with_ligatures.glyph) {- // draw glyph-- if (g == null) {- w = 50; - } else {- glyph = (!) g;- w = glyph.get_width ();- }- - gl_name = glyph.get_name ();- - if (prev == null) {- kern = 0;- } else {- kern = font.get_kerning_by_name (((!)prev).get_name (), gl_name);- }- - d = Math.pow (x + kern - ex, 2) + Math.pow (y - ey, 2);- - if (d < min) {- min = d;- - if (active_handle != i - row_index) {- active_handle = i - row_index;- MainWindow.get_glyph_canvas ().redraw ();- }-- if (col_index == word.glyph.length () || col_index == 0) {- active_handle = -1;- }- }- - prev = g;- x += w + kern;- i++;- col_index++;- }- - row_index++;- y += MainWindow.get_current_glyph ().get_height () + 20;- x = 20;- }- }- - public override void button_release (int button, double ex, double ey) {- set_active_handle (ex, ey);- selected_handle = -1;- }- - public override void button_press (uint button, double ex, double ey) {- set_active_handle (ex, ey);- selected_handle = active_handle;- begin_handle_x = ex;- begin_handle_y = ey;- last_handle_x = ex;- }--}--}@@ -34,6 +34,9 @@ public class Font : GLib.Object { /** Table with glyphs sorted by their name. */ GlyphTable glyph_name = new GlyphTable (); + /** Table with ligatures. */+ GlyphTable ligature = new GlyphTable ();+ /** Last unassigned index */ int next_unindexed = 0; @@ -345,17 +348,12 @@ public class Font : GLib.Object { public void delete_glyph (GlyphCollection glyph) { glyph_cache.remove (glyph.get_unicode ()); glyph_name.remove (glyph.get_name ());-/*-<<<<<<< HEAD+ ligature.remove (glyph.get_current ().get_ligature_string ()); } - // FIXME: order if ligature substitution is important+ // FIXME: order of ligature substitutions is important public GlyphCollection? get_ligature (uint indice) { return ligature.nth (indice);-=======-*/- // FIXME: DELETE: glyph_cache.remove (glyph);-//>>>>>>> parent of a76d9a8... parse ligatures from svg font } /** Obtain all versions and alterntes for this glyph. */@@ -387,7 +385,7 @@ public class Font : GLib.Object { public GlyphCollection? get_glyph_collection_by_name (string glyph) { // TODO: load from disk here if needed. GlyphCollection? gc = null;- gc = glyph_name.get (glyph);+ gc = glyph_name.get (glyph); return gc; } @@ -404,12 +402,8 @@ public class Font : GLib.Object { public Glyph? get_glyph (string unicode) { GlyphCollection? gc = null;-//<<<<<<< HEAD-// gc = glyph_unicode.get (unicode);-//=======- gc = glyph_cache.get (name);-//>>>>>>> parent of a76d9a8... parse ligatures from svg font- + gc = glyph_cache.get (unicode);+ if (gc == null) { return null; }@@ -828,6 +822,7 @@ public class Font : GLib.Object { glyph_cache.remove_all (); glyph_name.remove_all ();+ ligature.remove_all (); if (path.has_suffix (".svg")) { font_file = path;@@ -954,35 +949,25 @@ public class Font : GLib.Object { if (gcl != null) { warning (@"glyph \"$(g.get_name ())\" does already exist"); }- +/*+ if (g.name == "") { // FIXME: DELETE?+ warning ("refusing to insert glyph without name");+ g.name = @"($(++next_unindexed))";+ return;+ }+*/ if (g.is_unassigned ()) { gc = new GlyphCollection (g);- -/* -<<<<<<< HEAD+ }+ gc = new GlyphCollection (g); add_glyph_collection (gc); if (g.is_ligature ()) { liga = g.get_ligature_string (); ligature.insert (liga, gc);-=======-*/- if (g.name == "") {- warning ("refusing to insert glyph without name");- g.name = @"($(++next_unindexed))";- return;- }- - add_glyph_collection ((!) gc);- } else if (gcl == null) {- gc = new GlyphCollection (g);- add_glyph_collection ((!) gc);- } else {- stderr.printf (@"Glyph collection does already have an entry for $(g.get_name ()) char $((uint64) g.unichar_code).\n");-//>>>>>>> parent of a76d9a8... parse ligatures from svg font }- + // take xheight from appropriate lower case letter // xheight_position = estimate_xheight (); }@@ -84,14 +84,10 @@ public class Glyph : FontDisplay { string glyph_sequence = ""; bool open = true;-/*-<<<<<<< HEAD+ bool ligature = false; string substitution = ""; -=======->>>>>>> parent of a76d9a8... parse ligatures from svg font-*/ public Glyph (string name, unichar unichar_code = 0) { this.name = name; this.unichar_code = unichar_code;@@ -110,8 +106,6 @@ public class Glyph : FontDisplay { path_list.append (new Path ()); }-/*-<<<<<<< HEAD public string get_ligature_string () { return substitution;@@ -148,9 +142,7 @@ public class Glyph : FontDisplay { public bool is_ligature () { return ligature; }-=======->>>>>>> parent of a76d9a8... parse ligatures from svg font-*/+ public void select_all_paths () { clear_active_paths (); @@ -214,7 +206,9 @@ public class Glyph : FontDisplay { return 0; }- + + // It looks like this can be remove but firefox refuses to load+ // the generated font if it is removed. See the revert 6bbf and a76d. public void set_unassigned (bool u) { unassigned = u; }@@ -1492,14 +1486,10 @@ public class Glyph : FontDisplay { if (background_image != null) { g.background_image = ((!) background_image).copy (); }- /* -<<<<<<< HEAD+ g.ligature = ligature; g.substitution = substitution; -=======->>>>>>> parent of a76d9a8... parse ligatures from svg font-*/ return g; } @@ -30,7 +30,7 @@ public class GlyphSequence { */ public GlyphSequence process_ligatures () { GlyphSequence ligatures = new GlyphSequence ();-/* // FIXME Font font = BirdFont.get_current_font ();+ Font font = BirdFont.get_current_font (); Glyph liga; GlyphCollection? gc; @@ -45,13 +45,14 @@ public class GlyphSequence { break; } + // FIXME: DELETE print (@"LIGA: $(((!) gc).get_current ().get_ligature_string ())\n"); liga = ((!) gc).get_current (); ligatures.replace (liga.get_ligature (), liga); i++; }- */+ return ligatures; } new file mode 100644@@ -0,0 +1,328 @@+/*+ Copyright (C) 2012 Johan Mattsson++ This program is free software: you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation, either version 3 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program. If not, see <http://www.gnu.org/licenses/>.+*/++using Cairo;++namespace BirdFont {++/** Kerning context. */+public class KerningDisplay : FontDisplay {++ List <GlyphSequence> row;+ int active_handle = -1;+ int selected_handle = -1;+ + double begin_handle_x = 0;+ double begin_handle_y = 0;+ + double last_handle_x = 0;++ public KerningDisplay () {+ GlyphSequence w = new GlyphSequence ();+ row = new List <GlyphSequence> ();+ row.append (w);+ }++ public override string get_name () {+ return "Kerning";+ }+ + public override void draw (Allocation allocation, Context cr) {+ Glyph glyph;+ double x, y, w, kern, alpha;+ double x2;+ int i, wi;+ Glyph? prev;+ Font font = BirdFont.get_current_font ();+ GlyphSequence word_with_ligatures;+ + i = 0;+ + // bg color+ cr.save ();+ cr.set_source_rgba (1, 1, 1, 1);+ cr.rectangle (0, 0, allocation.width, allocation.height);+ cr.fill ();+ cr.restore ();+ + alpha = 1;+ y = 100;+ x = 20;+ w = 0;+ prev = null;+ + foreach (GlyphSequence word in row) {+ wi = 0;+ word_with_ligatures = word.process_ligatures ();+ foreach (Glyph? g in word_with_ligatures.glyph) {+ if (g == null) {+ continue;+ }+ + if (prev == null) {+ kern = 0;+ } else {+ kern = font.get_kerning_by_name (((!)prev).get_name (), ((!)g).get_name ());+ }+ + // draw glyph + if (g == null) {+ w = 50;+ alpha = 1;+ } else {+ alpha = 0;+ glyph = (!) g;+ Svg.draw_svg_path (cr, glyph.get_svg_data (), x + kern, y);+ w = glyph.get_width ();+ }++ // handle+ if (active_handle == i) {+ //x2 = x + kern;+ x2 = x + kern / 2.0;+ + cr.save ();+ cr.set_source_rgba (153/255.0, 153/255.0, 173/255.0, 1);+ cr.move_to (x2 - 5, y + 20);+ cr.line_to (x2 + 0, y + 20 - 5);+ cr.line_to (x2 + 5, y + 20);+ cr.fill ();+ + cr.set_font_size (10);+ cr.show_text (((!)g).get_name ());+ cr.restore ();+ } + + x += w + kern;+ + // caption+ if (g == null || ((!)g).is_empty ()) {+ cr.save ();+ cr.set_source_rgba (153/255.0, 153/255.0, 153/255.0, alpha);+ cr.move_to (x - w / 2.0 - 5, y + 20);+ cr.set_font_size (10);+ cr.show_text ("?"); // ?+ cr.restore ();+ }+ + prev = g;+ + wi++;+ i++;+ }+ + if (y > allocation.height && i > 10) {+ row.remove (word);+ }+ + y += MainWindow.get_current_glyph ().get_height () + 20;+ x = 20; + }+ }+ + private void set_kerning (int handle, double val) {+ string a, b;+ Font font;+ int wi = 0;+ double kern;+ GlyphSequence word_with_ligatures;+ + font = BirdFont.get_current_font ();++ font.touch ();++ a = "";+ b = "";++ foreach (GlyphSequence word in row) {+ word_with_ligatures = word.process_ligatures ();+ foreach (Glyph? g in word_with_ligatures.glyph) {+ + if (g == null) {+ continue;+ }+ + b = ((!) g).get_name ();+ + if (handle == wi) {+ kern = font.get_kerning_by_name (a, b) + val;+ font.set_kerning_by_name (a, b, kern);+ }+ + wi++;+ + a = b;+ }+ }+ + + }++ public override void selected_canvas () {+ Glyph g;+ GlyphSequence w;+ unowned List<GlyphSequence>? r;+ StringBuilder s = new StringBuilder ();+ bool append_char = false;+ Font font = BirdFont.get_current_font ();+ + KeyBindings.singleton.set_require_modifier (true);+ + g = MainWindow.get_current_glyph ();+ s.append_unichar (g.get_unichar ());++ r = row;+ return_if_fail (r != null);++ if (row.length () == 0) {+ append_char = true;+ }+ + if (append_char) {+ w = new GlyphSequence ();+ row.append (w);+ w.glyph.prepend (font.get_glyph (s.str));+ } + }+ + public override void key_press (uint keyval) {+ unichar c = (unichar) keyval;+ Glyph? g;+ Font f = BirdFont.get_current_font ();+ string name;+ + if (KeyBindings.modifier == NONE || KeyBindings.modifier == SHIFT) {+ + if (keyval == Key.BACK_SPACE && row.length () > 0) { + row.first ().data.glyph.remove_link (row.first ().data.glyph.last ());+ }+ + if (row.length () == 0 || c == Key.ENTER) {+ row.prepend (new GlyphSequence ());+ }+ + if (!is_modifier_key (c) && c.validate ()) {+ name = f.get_name_for_character (c);+ g = f.get_glyph_by_name (name);+ row.first ().data.glyph.append (g);+ }+ }+ + MainWindow.get_glyph_canvas ().redraw ();+ }+ + public override void motion_notify (double ex, double ey) {+ double k, y;+ + if (selected_handle == -1) {+ set_active_handle (ex, ey);+ } else {+ y = 1;+ + if (Math.fabs (ey - begin_handle_y) > 20) {+ y = ((Math.fabs (ey - begin_handle_y) / 100) + 1);+ }+ + k = (ex - last_handle_x) / y; // y-axis is variable precision+ set_kerning (selected_handle, k);+ MainWindow.get_glyph_canvas ().redraw ();+ }+ + last_handle_x = ex;+ }+ + public void set_active_handle (double ex, double ey) {+ double y = 100;+ double x = 20;+ double w = 0;+ double d, kern;+ double min = double.MAX;+ int i = 0;+ int row_index = 0;+ int col_index = 0;+ Glyph glyph = new Glyph.no_lines ("");+ Font font = BirdFont.get_current_font ();+ + Glyph? prev = null;+ string gl_name = "";+ GlyphSequence word_with_ligatures;+ + foreach (GlyphSequence word in row) {+ col_index = 0;+ + word_with_ligatures = word.process_ligatures ();+ foreach (Glyph? g in word_with_ligatures.glyph) {+ // draw glyph++ if (g == null) {+ w = 50; + } else {+ glyph = (!) g;+ w = glyph.get_width ();+ }+ + gl_name = glyph.get_name ();+ + if (prev == null) {+ kern = 0;+ } else {+ kern = font.get_kerning_by_name (((!)prev).get_name (), gl_name);+ }+ + d = Math.pow (x + kern - ex, 2) + Math.pow (y - ey, 2);+ + if (d < min) {+ min = d;+ + if (active_handle != i - row_index) {+ active_handle = i - row_index;+ MainWindow.get_glyph_canvas ().redraw ();+ }++ if (col_index == word.glyph.length () || col_index == 0) {+ active_handle = -1;+ }+ }+ + prev = g;+ x += w + kern;+ i++;+ col_index++;+ }+ + row_index++;+ y += MainWindow.get_current_glyph ().get_height () + 20;+ x = 20;+ }+ }+ + public override void button_release (int button, double ex, double ey) {+ set_active_handle (ex, ey);+ selected_handle = -1;+ }+ + public override void button_press (uint button, double ex, double ey) {+ set_active_handle (ex, ey);+ selected_handle = active_handle;+ begin_handle_x = ex;+ begin_handle_y = ey;+ last_handle_x = ex;+ }++}++}@@ -408,7 +408,7 @@ c.append (""" } public static void show_kerning_context () {- MainWindow.get_tab_bar ().add_unique_tab (new ContextDisplay (), 85, false);+ MainWindow.get_tab_bar ().add_unique_tab (new KerningDisplay (), 85, false); } public static void preview () {@@ -225,6 +225,14 @@ class SvgFont : GLib.Object { return unicode_value; } + bool is_ligature (string v) {+ if (v.has_prefix ("&")) {+ return false;+ }+ + return v.char_count () > 1;+ }+ void parse_glyph (Xml.Node* node) { string attr_name = ""; string attr_content;@@ -233,6 +241,7 @@ class SvgFont : GLib.Object { string svg = ""; Glyph glyph; double advance = font_advance;+ string ligature = ""; for (Xml.Attr* prop = node->properties; prop != null; prop = prop->next) { attr_name = prop->name;@@ -244,6 +253,10 @@ class SvgFont : GLib.Object { if (glyph_name == "") { glyph_name = attr_content; }+ + if (is_ligature (attr_content)) {+ ligature = attr_content;+ } } // svg data@@ -260,26 +273,15 @@ class SvgFont : GLib.Object { } } -/* -<<<<<<< HEAD glyph = new Glyph (glyph_name, unicode_value); ImportSvg.parse_svg_data (svg, glyph, true, units); glyph.right_limit = glyph.left_limit + advance * units; if (ligature != "") { glyph.set_ligature_substitution (ligature);-=======-*/- // FIXME: this code will ignore characters that are mapped several glyphs- if (unicode_value != '\0') {- glyph = new Glyph (glyph_name, unicode_value);- ImportSvg.parse_svg_data (svg, glyph, true, units); - glyph.right_limit = glyph.left_limit + advance * units;- font.add_glyph_callback (glyph);- } else {- warning ("ignoring glyph");-//>>>>>>> parent of a76d9a8... parse ligatures from svg font }+ + font.add_glyph_callback (glyph); } }