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

Revisions

View the latest version of libsvgbird/Layer.vala.
Click to object matrix transformation
1 /* 2 Copyright (C) 2015 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 bool update_boundaries (Context cr) { 36 if (objects.size == 0) { 37 return false; 38 } 39 40 top = CANVAS_MAX; 41 bottom = CANVAS_MIN; 42 left = CANVAS_MAX; 43 right = CANVAS_MIN; 44 45 cr.save (); 46 47 foreach (Object object in objects) { 48 bool has_size = false; 49 50 cr.save (); 51 52 if (object is Layer) { 53 Layer sublayer = (Layer) object; 54 sublayer.apply_transform (cr); 55 object.view_matrix = cr.get_matrix (); 56 has_size = sublayer.update_boundaries (cr); 57 } else { 58 object.apply_transform (cr); 59 object.view_matrix = cr.get_matrix (); 60 has_size = object.update_boundaries (cr); 61 } 62 63 if (has_size) { 64 left = fmin (left, object.left); 65 right = fmax (right, object.right); 66 top = fmin (top, object.top); 67 bottom = fmax (bottom, object.bottom); 68 } 69 70 cr.restore (); 71 } 72 73 cr.restore (); 74 75 return boundaries_width != 0; 76 } 77 78 public void draw (Context cr) { 79 draw_layer (cr, true); 80 } 81 82 public override void draw_outline (Context cr) { 83 draw_layer (cr, false); 84 } 85 86 private void draw_layer (Context cr, bool paint) { 87 cr.save (); 88 89 if (clip_path != null) { 90 ClipPath clipping = (!) clip_path; 91 clipping.apply (cr); 92 } 93 94 foreach (Object object in objects) { 95 cr.save (); 96 97 if (object.clip_path != null) { 98 ClipPath clipping = (!) object.clip_path; 99 clipping.apply (cr); 100 } 101 102 if (object is Layer) { 103 Layer sublayer = (Layer) object; 104 sublayer.apply_transform (cr); 105 106 if (paint) { 107 sublayer.draw (cr); 108 } else { 109 sublayer.draw_outline (cr); 110 } 111 } else if (object.visible) { 112 object.apply_transform (cr); 113 object.draw_outline (cr); 114 115 if (paint) { 116 object.paint (cr); 117 } 118 } 119 cr.restore (); 120 } 121 122 cr.restore (); 123 } 124 125 public int index_of (Layer sublayer) { 126 return objects.index_of (sublayer); 127 } 128 129 public void add_layer (Layer layer) { 130 objects.add (layer); 131 update_boundaries_for_object (); 132 } 133 134 public void add_object (Object object) { 135 objects.add (object); 136 update_boundaries_for_object (); 137 } 138 139 public void remove (Object o) { 140 objects.remove (o); 141 142 foreach (Object object in objects) { 143 if (object is Layer) { 144 Layer sublayer = (Layer) object; 145 sublayer.remove (o);; 146 } 147 } 148 149 update_boundaries_for_object (); 150 } 151 152 public void remove_layer (Layer layer) { 153 objects.remove (layer); 154 155 foreach (Object object in objects) { 156 if (object is Layer) { 157 Layer sublayer = (Layer) object; 158 sublayer.remove_layer (layer); 159 } 160 } 161 162 update_boundaries_for_object (); 163 } 164 165 public static void copy_layer (Layer from, Layer to) { 166 to.name = from.name; 167 to.objects = from.objects.copy (); 168 } 169 170 public override Object copy () { 171 Layer layer = new Layer (); 172 copy_layer (this, layer); 173 Object.copy_attributes (this, layer); 174 return layer; 175 } 176 177 public Gee.ArrayList<Layer> get_sublayers () { 178 Gee.ArrayList<Layer> sublayers = new Gee.ArrayList<Layer> (); 179 180 foreach (Object object in objects) { 181 if (likely (object is Layer)) { 182 Layer sublayer = (Layer) object; 183 sublayers.add (sublayer); 184 } else { 185 warning ("An object in the group " + name + " is not a layer."); 186 } 187 } 188 189 return sublayers; 190 } 191 192 public void print (int indent = 0) { 193 stdout.printf (@"Layer: $(name)"); 194 195 if (!visible) { 196 stdout.printf (" hidden"); 197 } 198 199 stdout.printf (@" $(transforms) $(style)"); 200 stdout.printf (@"\n"); 201 202 foreach (Object object in objects) { 203 stdout.printf (@"$(object.to_string ()) $(object.transforms) $(object.style)"); 204 205 if (!object.visible) { 206 stdout.printf (" hidden"); 207 } 208 209 stdout.printf ("\n"); 210 211 for (int i = 0; i < indent; i++) { 212 stdout.printf ("\t"); 213 } 214 215 if (object is Layer) { 216 Layer sublayer = (Layer) object; 217 sublayer.print (indent + 1); 218 } 219 } 220 } 221 222 public override bool is_over (double x, double y) { 223 return false; 224 } 225 226 public override void move (double dx, double dy) { 227 } 228 229 public override bool is_empty () { 230 return false; 231 } 232 233 public override string to_string () { 234 return "Layer: " + name; 235 } 236 } 237 238 } 239