The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Object.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/Object.vala.
Store boundaries in SVG coordinates
1 /* 2 Copyright (C) 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 abstract class Object : GLib.Object { 21 bool open = false; 22 23 public bool visible = true; 24 public SvgStyle style = new SvgStyle (); 25 public SvgTransforms transforms = new SvgTransforms (); 26 public ClipPath? clip_path = null; 27 public string id = ""; 28 public string css_class = ""; 29 30 public virtual Color? color { get; set; } // FIXME: keep this in svg style 31 public virtual Color? stroke_color { get; set; } 32 public virtual Gradient? gradient { get; set; } 33 34 /** Path boundaries */ 35 public virtual double xmax { get; set; } 36 public virtual double xmin { get; set; } 37 public virtual double ymax { get; set; } 38 public virtual double ymin { get; set; } 39 40 public virtual double rotation { get; set; } 41 public virtual double stroke { get; set; } 42 public virtual LineCap line_cap { get; set; default = LineCap.BUTT; } 43 public virtual bool fill { get; set; } 44 45 public Object () { 46 } 47 48 public Object.create_copy (Object o) { 49 open = o.open; 50 } 51 52 public void set_open (bool open) { 53 this.open = open; 54 } 55 56 public bool is_open () { 57 return open; 58 } 59 60 public abstract void update_region_boundaries (); 61 public abstract bool is_over (double x, double y); 62 public abstract void draw_outline (Context cr); 63 64 public abstract Object copy (); 65 public abstract void move (double dx, double dy); 66 public abstract void rotate (double theta, double xc, double yc); 67 public abstract bool is_empty (); 68 public abstract void resize (double ratio_x, double ratio_y); 69 70 public static void copy_attributes (Object from, Object to) { 71 to.open = from.open; 72 73 if (from.color != null) { 74 to.color = ((!) from.color).copy (); 75 } else { 76 to.color = null; 77 } 78 79 if (from.stroke_color != null) { 80 to.stroke_color = ((!) from.stroke_color).copy (); 81 } else { 82 to.stroke_color = null; 83 } 84 85 if (to.gradient != null) { 86 to.gradient = ((!) from.gradient).copy (); 87 } else { 88 to.gradient = null; 89 } 90 91 to.xmax = from.xmax; 92 to.xmin = from.xmin; 93 to.ymax = from.ymax; 94 to.ymin = from.ymin; 95 96 to.rotation = from.rotation; 97 to.stroke = from.stroke; 98 to.line_cap = from.line_cap; 99 to.fill = from.fill; 100 101 to.style = from.style.copy (); 102 to.transforms = from.transforms.copy (); 103 104 if (from.clip_path != null) { 105 to.clip_path = ((!) from.clip_path).copy (); 106 } 107 } 108 109 public virtual string to_string () { 110 return "Object"; 111 } 112 113 public void paint (Context cr) { 114 Color fill, stroke; 115 bool need_fill = style.fill_gradient != null || style.fill != null; 116 bool need_stroke = style.stroke_gradient != null || style.stroke != null; 117 118 cr.set_line_width (style.stroke_width); 119 120 if (style.fill_gradient != null) { 121 apply_gradient (cr, (!) style.fill_gradient); 122 } else if (style.fill != null) { 123 fill = (!) style.fill; 124 cr.set_source_rgba (fill.r, fill.g, fill.b, fill.a); 125 } 126 127 if (need_fill) { 128 if (need_stroke) { 129 cr.fill_preserve (); 130 } else { 131 cr.fill (); 132 } 133 } 134 135 if (style.stroke_gradient != null) { 136 apply_gradient (cr, (!) style.stroke_gradient); 137 } else if (style.stroke != null) { 138 stroke = (!) style.stroke; 139 cr.set_source_rgba (stroke.r, stroke.g, stroke.b, stroke.a); 140 } 141 142 if (need_stroke) { 143 cr.stroke (); 144 } 145 } 146 147 public void apply_gradient (Context cr, Gradient? gradient) { 148 Cairo.Pattern pattern; 149 Gradient g; 150 151 if (gradient != null) { 152 g = (!) gradient; 153 154 pattern = new Cairo.Pattern.linear (g.x1, g.y1, g.x2, g.y2); 155 156 Matrix gradient_matrix = g.get_matrix (); 157 gradient_matrix.invert (); 158 pattern.set_matrix (gradient_matrix); 159 160 foreach (Stop s in g.stops) { 161 Color c = s.color; 162 pattern.add_color_stop_rgba (s.offset, c.r, c.g, c.b, c.a); 163 } 164 165 cr.set_source (pattern); 166 } 167 } 168 169 public void apply_transform (Context cr) { 170 Matrix view_matrix = cr.get_matrix (); 171 Matrix object_matrix = transforms.get_matrix (); 172 173 object_matrix.multiply (object_matrix, view_matrix); 174 cr.set_matrix (object_matrix); 175 } 176 177 } 178 179 } 180