1/*
2 * Copyright (c) 2014 Kurt Jung (Gmail: kurt.w.jung)
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17package gofpdf
18
19// SVGBasicWrite renders the paths encoded in the basic SVG image specified by
20// sb. The scale value is used to convert the coordinates in the path to the
21// unit of measure specified in New(). The current position (as set with a call
22// to SetXY()) is used as the origin of the image. The current line cap style
23// (as set with SetLineCapStyle()), line width (as set with SetLineWidth()),
24// and draw color (as set with SetDrawColor()) are used in drawing the image
25// paths.
26func (f *Fpdf) SVGBasicWrite(sb *SVGBasicType, scale float64) {
27	originX, originY := f.GetXY()
28	var x, y, newX, newY float64
29	var cx0, cy0, cx1, cy1 float64
30	var path []SVGBasicSegmentType
31	var seg SVGBasicSegmentType
32	var startX, startY float64
33	sval := func(origin float64, arg int) float64 {
34		return origin + scale*seg.Arg[arg]
35	}
36	xval := func(arg int) float64 {
37		return sval(originX, arg)
38	}
39	yval := func(arg int) float64 {
40		return sval(originY, arg)
41	}
42	val := func(arg int) (float64, float64) {
43		return xval(arg), yval(arg + 1)
44	}
45	for j := 0; j < len(sb.Segments) && f.Ok(); j++ {
46		path = sb.Segments[j]
47		for k := 0; k < len(path) && f.Ok(); k++ {
48			seg = path[k]
49			switch seg.Cmd {
50			case 'M':
51				x, y = val(0)
52				startX, startY = x, y
53				f.SetXY(x, y)
54			case 'L':
55				newX, newY = val(0)
56				f.Line(x, y, newX, newY)
57				x, y = newX, newY
58			case 'C':
59				cx0, cy0 = val(0)
60				cx1, cy1 = val(2)
61				newX, newY = val(4)
62				f.CurveCubic(x, y, cx0, cy0, newX, newY, cx1, cy1, "D")
63				x, y = newX, newY
64			case 'Q':
65				cx0, cy0 = val(0)
66				newX, newY = val(2)
67				f.Curve(x, y, cx0, cy0, newX, newY, "D")
68				x, y = newX, newY
69			case 'H':
70				newX = xval(0)
71				f.Line(x, y, newX, y)
72				x = newX
73			case 'V':
74				newY = yval(0)
75				f.Line(x, y, x, newY)
76				y = newY
77			case 'Z':
78				f.Line(x, y, startX, startY)
79				x, y = startX, startY
80			default:
81				f.SetErrorf("Unexpected path command '%c'", seg.Cmd)
82			}
83		}
84	}
85}
86