The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

SvgTransforms.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) 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 17 namespace SvgBird { 18 19 public class SvgTransforms : GLib.Object { 20 public Matrix rotation_matrix; 21 public Matrix size_matrix; 22 public Gee.ArrayList<SvgTransform> transforms; 23 24 public double rotation = 0; 25 public double total_rotation = 0; 26 public double translate_x = 0; 27 public double translate_y = 0; 28 29 public SvgTransforms () { 30 transforms = new Gee.ArrayList<SvgTransform> (); 31 rotation_matrix = Matrix.identity (); 32 size_matrix = Matrix.identity (); 33 } 34 35 public void clear_rotation () { 36 rotation = 0; 37 total_rotation = 0; 38 rotation_matrix = Matrix.identity (); 39 } 40 41 public double get_rotation () { 42 Matrix m = get_matrix (); 43 double w = 1; 44 double h = 1; 45 m.transform_distance (ref w, ref h); 46 return Math.atan2 (h, w); 47 } 48 49 public void collapse_transforms () { 50 Matrix collapsed = get_matrix (); 51 52 translate_x = 0; 53 translate_y = 0; 54 55 rotation_matrix = Matrix.identity (); 56 rotation = 0; 57 58 size_matrix = Matrix.identity (); 59 60 clear (); 61 62 SvgTransform collapsed_transform = new SvgTransform.for_matrix (collapsed); 63 add (collapsed_transform); 64 } 65 66 public void clear () { 67 transforms.clear (); 68 69 rotation_matrix = Matrix.identity (); 70 rotation = 0; 71 72 size_matrix = Matrix.identity (); 73 74 translate_x = 0; 75 translate_y = 0; 76 } 77 78 public void translate (double x, double y) { 79 translate_x += x; 80 translate_y += y; 81 } 82 83 public void rotate (double theta, double x, double y) { 84 rotation += theta; 85 total_rotation += theta; 86 87 while (rotation > 2 * Math.PI) { 88 rotation -= 2 * Math.PI; 89 } 90 91 while (rotation < -2 * Math.PI) { 92 rotation += 2 * Math.PI; 93 } 94 95 while (total_rotation > 2 * Math.PI) { 96 total_rotation -= 2 * Math.PI; 97 } 98 99 while (total_rotation < -2 * Math.PI) { 100 total_rotation += 2 * Math.PI; 101 } 102 103 rotation_matrix = Matrix.identity (); 104 rotation_matrix.translate (x, y); 105 rotation_matrix.rotate (rotation); 106 rotation_matrix.translate (-x, -y); 107 } 108 109 public void resize (double scale_x, double scale_y, double x, double y) { 110 if (scale_x <= 0 || scale_y <= 0) { 111 return; 112 } 113 114 double x2 = x; 115 double y2 = y; 116 117 size_matrix = Matrix.identity (); 118 size_matrix.scale (scale_x, scale_y); 119 size_matrix.transform_point (ref x2, ref y2); 120 121 double dx = x - x2; 122 double dy = y - y2; 123 124 size_matrix.translate (dx / scale_x, dy / scale_y); 125 } 126 127 public SvgTransforms copy () { 128 SvgTransforms copy_transforms = new SvgTransforms (); 129 130 foreach (SvgTransform t in transforms) { 131 copy_transforms.add (t.copy ()); 132 } 133 134 return copy_transforms; 135 } 136 137 public void insert (int position, SvgTransform transform) { 138 transforms.insert (position, transform); 139 } 140 141 public void add (SvgTransform transform) { 142 transforms.add (transform); 143 } 144 145 public Matrix get_matrix () { 146 Matrix transformation_matrix = Matrix.identity (); 147 148 for (int i = 0; i < transforms.size; i++) { 149 Matrix part = transforms.get (i).get_matrix (); 150 transformation_matrix.multiply (transformation_matrix, part); 151 } 152 153 transformation_matrix.translate (translate_x, translate_y); 154 155 transformation_matrix.multiply (transformation_matrix, rotation_matrix); 156 transformation_matrix.multiply (transformation_matrix, size_matrix); 157 158 return transformation_matrix; 159 } 160 161 public string to_string () { 162 StringBuilder sb = new StringBuilder (); 163 164 foreach (SvgTransform t in transforms) { 165 sb.append (t.to_string ()); 166 sb.append (" "); 167 } 168 169 return sb.str; 170 } 171 172 public string get_xml () { 173 StringBuilder svg = new StringBuilder (); 174 bool first = true; 175 176 foreach (SvgTransform transform in transforms) { 177 if (!first) { 178 svg.append (" "); 179 } 180 181 svg.append (transform.get_xml ()); 182 first = false; 183 } 184 185 return svg.str; 186 } 187 } 188 189 } 190