Showing
3 changed files
with
149 additions
and
16 deletions
| @@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
| 5 | * Fix annotations | 5 | * Fix annotations |
| 6 | * Implement default fonts bounding box | 6 | * Implement default fonts bounding box |
| 7 | * Add Bézier Curve primitive | 7 | * Add Bézier Curve primitive |
| 8 | +* Implement drawShape | ||
| 8 | 9 | ||
| 9 | # 1.0.8 | 10 | # 1.0.8 |
| 10 | * Fix monospace TTF font loading | 11 | * Fix monospace TTF font loading |
| @@ -206,26 +206,151 @@ class PdfGraphics { | @@ -206,26 +206,151 @@ class PdfGraphics { | ||
| 206 | buf.putString("$x1 $y1 $x2 $y2 $x3 $y3 c\n"); | 206 | buf.putString("$x1 $y1 $x2 $y2 $x3 $y3 c\n"); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | - void drawShape(String d) { | ||
| 210 | - var sb = StringBuffer(); | ||
| 211 | - | ||
| 212 | - RegExp exp = RegExp(r"([MmZzLlHhVvCcSsQqTtAa])|(-[\.0-9]+)|([\.0-9]+)"); | ||
| 213 | - var matches = exp.allMatches(d); | ||
| 214 | - var action; | 209 | + /// https://github.com/deeplook/svglib/blob/master/svglib/svglib.py#L911 |
| 210 | + void drawShape(String d, {stroke = true}) { | ||
| 211 | + final sb = StringBuffer(); | ||
| 212 | + final exp = RegExp(r"([MmZzLlHhVvCcSsQqTtAaE])|(-[\.0-9]+)|([\.0-9]+)"); | ||
| 213 | + final matches = exp.allMatches(d + " E"); | ||
| 214 | + String action; | ||
| 215 | + String lastAction; | ||
| 216 | + List<double> points; | ||
| 217 | + PdfPoint lastControl = PdfPoint(0.0, 0.0); | ||
| 218 | + PdfPoint lastPoint = PdfPoint(0.0, 0.0); | ||
| 215 | for (var m in matches) { | 219 | for (var m in matches) { |
| 216 | var a = m.group(1); | 220 | var a = m.group(1); |
| 217 | var b = m.group(0); | 221 | var b = m.group(0); |
| 218 | - print("$a, $b"); | ||
| 219 | - if (a != null) { | ||
| 220 | - if (action != null) { | ||
| 221 | - sb.write("$action "); | 222 | + |
| 223 | + if (a == null) { | ||
| 224 | + points.add(double.parse(b)); | ||
| 225 | + continue; | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + if (action != null) { | ||
| 229 | + switch (action) { | ||
| 230 | + case 'm': // moveto relative | ||
| 231 | + lastPoint = | ||
| 232 | + PdfPoint(lastPoint.x + points[0], lastPoint.y + points[1]); | ||
| 233 | + sb.write("${lastPoint.x} ${lastPoint.y} m "); | ||
| 234 | + break; | ||
| 235 | + case 'M': // moveto absolute | ||
| 236 | + lastPoint = PdfPoint(points[0], points[1]); | ||
| 237 | + sb.write("${lastPoint.x} ${lastPoint.y} m "); | ||
| 238 | + break; | ||
| 239 | + case 'l': // lineto relative | ||
| 240 | + lastPoint = | ||
| 241 | + PdfPoint(lastPoint.x + points[0], lastPoint.y + points[1]); | ||
| 242 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
| 243 | + break; | ||
| 244 | + case 'L': // lineto absolute | ||
| 245 | + lastPoint = PdfPoint(points[0], points[1]); | ||
| 246 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
| 247 | + break; | ||
| 248 | + case 'H': // horizontal line absolute | ||
| 249 | + lastPoint = PdfPoint(points[0], lastPoint.y); | ||
| 250 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
| 251 | + break; | ||
| 252 | + case 'V': // vertical line absolute | ||
| 253 | + lastPoint = PdfPoint(lastPoint.x, points[0]); | ||
| 254 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
| 255 | + break; | ||
| 256 | + case 'h': // horizontal line relative | ||
| 257 | + lastPoint = PdfPoint(lastPoint.x + points[0], lastPoint.y); | ||
| 258 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
| 259 | + break; | ||
| 260 | + case 'v': // vertical line relative | ||
| 261 | + lastPoint = PdfPoint(lastPoint.x, lastPoint.y + points[0]); | ||
| 262 | + sb.write("${lastPoint.x} ${lastPoint.y} l "); | ||
| 263 | + break; | ||
| 264 | + case 'C': // cubic bezier, absolute | ||
| 265 | + var len = 0; | ||
| 266 | + while ((len + 1) * 6 <= points.length) { | ||
| 267 | + sb.write( | ||
| 268 | + points.sublist(len * 6, (len + 1) * 6).join(" ") + " c "); | ||
| 269 | + len += 1; | ||
| 270 | + } | ||
| 271 | + lastPoint = | ||
| 272 | + PdfPoint(points[points.length - 2], points[points.length - 1]); | ||
| 273 | + lastControl = | ||
| 274 | + PdfPoint(points[points.length - 4], points[points.length - 3]); | ||
| 275 | + break; | ||
| 276 | + case 'S': // smooth cubic bézier, absolute | ||
| 277 | + while (points.length >= 4) { | ||
| 278 | + PdfPoint c1; | ||
| 279 | + if ('cCsS'.indexOf(lastAction) >= 0) { | ||
| 280 | + c1 = PdfPoint(lastPoint.x + (lastPoint.x - lastControl.x), | ||
| 281 | + lastPoint.y + (lastPoint.y - lastControl.y)); | ||
| 282 | + } else { | ||
| 283 | + c1 = lastPoint; | ||
| 284 | + } | ||
| 285 | + lastControl = PdfPoint(points[0], points[1]); | ||
| 286 | + lastPoint = PdfPoint(points[2], points[3]); | ||
| 287 | + sb.write( | ||
| 288 | + "${c1.x} ${c1.y} ${lastControl.x} ${lastControl.y} ${lastPoint.x} ${lastPoint.y} c "); | ||
| 289 | + points = points.sublist(4); | ||
| 290 | + lastAction = 'C'; | ||
| 291 | + } | ||
| 292 | + break; | ||
| 293 | + case 'c': // cubic bezier, relative | ||
| 294 | + var len = 0; | ||
| 295 | + while ((len + 1) * 6 <= points.length) { | ||
| 296 | + points[len + 0] += lastPoint.x; | ||
| 297 | + points[len + 1] += lastPoint.y; | ||
| 298 | + points[len + 2] += lastPoint.x; | ||
| 299 | + points[len + 3] += lastPoint.y; | ||
| 300 | + points[len + 4] += lastPoint.x; | ||
| 301 | + points[len + 5] += lastPoint.y; | ||
| 302 | + sb.write( | ||
| 303 | + points.sublist(len * 6, (len + 1) * 6).join(" ") + " c "); | ||
| 304 | + len += 1; | ||
| 305 | + } | ||
| 306 | + lastPoint = | ||
| 307 | + PdfPoint(points[points.length - 2], points[points.length - 1]); | ||
| 308 | + lastControl = | ||
| 309 | + PdfPoint(points[points.length - 4], points[points.length - 3]); | ||
| 310 | + break; | ||
| 311 | + case 's': // smooth cubic bézier, relative | ||
| 312 | + while (points.length >= 4) { | ||
| 313 | + PdfPoint c1; | ||
| 314 | + if ('cCsS'.indexOf(lastAction) >= 0) { | ||
| 315 | + c1 = PdfPoint(lastPoint.x + (lastPoint.x - lastControl.x), | ||
| 316 | + lastPoint.y + (lastPoint.y - lastControl.y)); | ||
| 317 | + } else { | ||
| 318 | + c1 = lastPoint; | ||
| 319 | + } | ||
| 320 | + lastControl = | ||
| 321 | + PdfPoint(points[0] + lastPoint.x, points[1] + lastPoint.y); | ||
| 322 | + lastPoint = | ||
| 323 | + PdfPoint(points[2] + lastPoint.x, points[3] + lastPoint.y); | ||
| 324 | + sb.write( | ||
| 325 | + "${c1.x} ${c1.y} ${lastControl.x} ${lastControl.y} ${lastPoint.x} ${lastPoint.y} c "); | ||
| 326 | + points = points.sublist(4); | ||
| 327 | + lastAction = 'c'; | ||
| 328 | + } | ||
| 329 | + break; | ||
| 330 | + // case 'Q': // quadratic bezier, absolute | ||
| 331 | + // break; | ||
| 332 | + // case 'T': // quadratic bezier, absolute | ||
| 333 | + // break; | ||
| 334 | + // case 'q': // quadratic bezier, relative | ||
| 335 | + // break; | ||
| 336 | + // case 't': // quadratic bezier, relative | ||
| 337 | + // break; | ||
| 338 | + // case 'A': // elliptical arc, absolute | ||
| 339 | + // break; | ||
| 340 | + // case 'a': // elliptical arc, relative | ||
| 341 | + // break; | ||
| 342 | + case 'Z': // close path | ||
| 343 | + case 'z': // close path | ||
| 344 | + if (stroke) sb.write("s "); | ||
| 345 | + break; | ||
| 346 | + default: | ||
| 347 | + print("Unknown path action: $action"); | ||
| 222 | } | 348 | } |
| 223 | - action = a; | ||
| 224 | - } else { | ||
| 225 | - sb.write("$b "); | ||
| 226 | } | 349 | } |
| 350 | + lastAction = action; | ||
| 351 | + action = a; | ||
| 352 | + points = List<double>(); | ||
| 227 | } | 353 | } |
| 228 | - print(sb); | ||
| 229 | buf.putString(sb.toString()); | 354 | buf.putString(sb.toString()); |
| 230 | } | 355 | } |
| 231 | 356 |
| @@ -20,12 +20,19 @@ void main() { | @@ -20,12 +20,19 @@ void main() { | ||
| 20 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); | 20 | var page = PdfPage(pdf, pageFormat: const PdfPageFormat(500.0, 300.0)); |
| 21 | 21 | ||
| 22 | var g = page.getGraphics(); | 22 | var g = page.getGraphics(); |
| 23 | + | ||
| 23 | g.saveContext(); | 24 | g.saveContext(); |
| 24 | var tm = Matrix4.identity(); | 25 | var tm = Matrix4.identity(); |
| 25 | - tm.translate(100.0, 700.0); | 26 | + tm.translate(50.0, 290.0); |
| 27 | + tm.rotateZ(pi); | ||
| 26 | g.setTransform(tm); | 28 | g.setTransform(tm); |
| 27 | -// g.drawShape("M37 0H9C6.24 0 4 2.24 4 5v38c0 2.76 2.24 5 5 5h28c2.76 0 5-2.24 5-5V5c0-2.76-2.24-5-5-5zM23 46c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm15-8H8V6h30v32z"); | 29 | + g.setColor(PdfColor(0.0, 0.0, 0.0)); |
| 30 | + g.drawShape( | ||
| 31 | + "M37 0H9C6.24 0 4 2.24 4 5v38c0 2.76 2.24 5 5 5h28c2.76 0 5-2.24 5-5V5c0-2.76-2.24-5-5-5zM23 46c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm15-8H8V6h30v32z", | ||
| 32 | + stroke: false); | ||
| 33 | + g.fillPath(); | ||
| 28 | g.restoreContext(); | 34 | g.restoreContext(); |
| 35 | + | ||
| 29 | var font1 = g.defaultFont; | 36 | var font1 = g.defaultFont; |
| 30 | 37 | ||
| 31 | var font2 = PdfTtfFont( | 38 | var font2 = PdfTtfFont( |
-
Please register or login to post a comment