The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Layer.vala in /libsvgbird

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) 2015 2016 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using Cairo; 16 using Math; 17 18 namespace SvgBird { 19 20 public class Layer : Object { 21 public ObjectGroup objects; 22 public string name = "Layer"; 23 24 public Layer () { 25 objects = new ObjectGroup (); 26 transforms = new SvgTransforms (); 27 } 28 29 public Layer.with_name (string name) { 30 this.name = name; 31 objects = new ObjectGroup (); 32 transforms = new SvgTransforms (); 33 } 34 35 public override void move (double dx, double dy) { 36 left += dx; 37 right += dx; 38 top += dy; 39 bottom += dy; 40 41 foreach (Object object in objects.objects) { 42 object.move (dx, dy); 43 } 44 45 update_view_matrix (); 46 } 47 48 public override bool update_boundaries (Context cr) { 49 if (objects.size == 0) { 50 return false; 51 } 52 53 top = CANVAS_MAX; 54 bottom = CANVAS_MIN; 55 left = CANVAS_MAX; 56 right = CANVAS_MIN; 57 58 cr.save (); 59 parent_matrix = copy_matrix (cr.get_matrix ()); 60 apply_transform (cr); 61 view_matrix = copy_matrix (cr.get_matrix ()); 62 63 foreach (Object object in objects) { 64 bool has_size = false; 65 66 if (object is Layer) { 67 Layer sublayer = (Layer) object; 68 has_size = sublayer.update_boundaries (cr); 69 } else { 70 has_size = object.update_boundaries (cr); 71 } 72 73 if (has_size) { 74 left = fmin (left, object.left); 75 right = fmax (right, object.right); 76 top = fmin (top, object.top); 77 bottom = fmax (bottom, object.bottom); 78 } 79 } 80 81 cr.restore (); 82 83 return boundaries_width != 0; 84 } 85 86 public void draw (Context cr) { 87 draw_layer (cr, true); 88 } 89 90 public override void draw_outline (Context cr) { 91 draw_layer (cr, false); 92 } 93 94 private void draw_layer (Context cr, bool paint) { 95 cr.save (); 96 97 apply_transform (cr); 98 99 if (clip_path != null) { 100 ClipPath clipping = (!) clip_path; 101 clipping.apply (cr); 102 } 103 104 foreach (Object object in objects) { 105 cr.save (); 106 107 if (object.clip_path != null) { 108 ClipPath clipping = (!) object.clip_path; 109 clipping.apply (cr); 110 } 111 112 if (object is Layer) { 113 Layer sublayer = (Layer) object; 114 115 if (paint) { 116 sublayer.draw (cr); 117 } else { 118 sublayer.draw_outline (cr); 119 } 120 } else if (object.visible) { 121 object.apply_transform (cr); 122 object.draw_outline (cr); 123 124 if (paint) { 125 object.paint (cr); 126 } 127 } 128 cr.restore (); 129 } 130 131 cr.restore (); 132 } 133 134 public int index_of (Layer sublayer) { 135 return objects.index_of (sublayer); 136 } 137 138 public void add_layer (Layer layer) { 139 objects.add (layer); 140 update_boundaries_for_object (); 141 } 142 143 public void add_object (Object object) { 144 objects.add (object); 145 update_boundaries_for_object (); 146 } 147 148 public void remove (Object o) { 149 objects.remove (o); 150 151 foreach (Object object in objects) { 152 if (object is Layer) { 153 Layer sublayer = (Layer) object; 154 sublayer.remove (o); 155 } 156 } 157 158 update_boundaries_for_object (); 159 } 160 161 public void remove_layer (Layer layer) { 162 objects.remove (layer); 163 164 foreach (Object object in objects) { 165 if (object is Layer) { 166 Layer sublayer = (Layer) object; 167 sublayer.remove_layer (layer); 168 } 169 } 170 171 update_boundaries_for_object (); 172 } 173 174 public static void copy_layer (Layer from, Layer to) { 175 to.name = from.name; 176 to.objects = from.objects.copy (); 177 } 178 179 public override Object copy () { 180 Layer layer = new Layer (); 181 copy_layer (this, layer); 182 Object.copy_attributes (this, layer); 183 return layer; 184 } 185 186 public Gee.ArrayList<Layer> get_sublayers () { 187 Gee.ArrayList<Layer> sublayers = new Gee.ArrayList<Layer> (); 188 189 foreach (Object object in objects) { 190 if (likely (object is Layer)) { 191 Layer sublayer = (Layer) object; 192 sublayers.add (sublayer); 193 } else { 194 warning ("An object in the group " + name + " is not a layer."); 195 } 196 } 197 198 return sublayers; 199 } 200 201 public void print (int indent = 0) { 202 stdout.printf (@"Layer: $(name)"); 203 204 if (!visible) { 205 stdout.printf (" hidden"); 206 } 207 208 stdout.printf (@" $(transforms) $(style)"); 209 stdout.printf (@"\n"); 210 211 foreach (Object object in objects) { 212 stdout.printf (@"$(object.to_string ()) $(object.transforms) $(object.style)"); 213 214 if (!object.visible) { 215 stdout.printf (" hidden"); 216 } 217 218 stdout.printf ("\n"); 219 220 for (int i = 0; i < indent; i++) { 221 stdout.printf ("\t"); 222 } 223 224 if (object is Layer) { 225 Layer sublayer = (Layer) object; 226 sublayer.print (indent + 1); 227 } 228 } 229 } 230 231 public override bool is_over (double x, double y) { 232 return false; 233 } 234 235 public override bool is_empty () { 236 return false; 237 } 238 239 public override string to_string () { 240 return "Layer: " + name; 241 } 242 } 243 244 } 245