UNPKG

4.97 kBJavaScriptView Raw
1const { inchMM, ptMM, pcMM, svgColors } = require('./constants')
2
3// Calculate the CAG length/size from the given SVG value (float)
4const svg2cagX = (v, svgUnitsPmm) => (v / svgUnitsPmm[0])
5
6const svg2cagY = (v, svgUnitsPmm) => 0 - (v / svgUnitsPmm[1])
7
8// Calculate the CAG length/size from the given CSS value (string)
9const cagLengthX = (css, svgUnitsPmm, svgUnitsX) => {
10 if (css.indexOf('%') < 0) {
11 return css2cag(css, svgUnitsPmm[0])
12 }
13 // calculate the units as a percentage of the width
14 let v = parseFloat(css) // number part
15 if (isNaN(v)) { return 0.0 }
16 if (v === 0) return v
17 v = (v / 100) * svgUnitsX
18 // convert the units to mm
19 v = v / svgUnitsPmm[0]
20 return Math.round(v * 100000) / 100000
21}
22
23const cagLengthY = (css, svgUnitsPmm, svgUnitsY) => {
24 if (css.indexOf('%') < 0) {
25 return css2cag(css, svgUnitsPmm[1])
26 }
27 // calculate the units as a percentage of the width
28 let v = parseFloat(css) // number part
29 if (isNaN(v)) { return 0.0 }
30 if (v === 0) return v
31 v = (v / 100) * svgUnitsY
32 // convert the units to mm
33 v = v / svgUnitsPmm[1]
34 return Math.round(v * 100000) / 100000
35}
36
37const cagLengthP = (css, svgUnitsPmm, svgUnitsV) => {
38 if (css.indexOf('%') < 0) {
39 return css2cag(css, svgUnitsPmm[1])
40 }
41 // calculate the units as a percentage of the viewport
42 let v = parseFloat(css) // number part
43 if (isNaN(v)) { return 0.0 }
44 if (v === 0) return v
45 v = (v / 100) * svgUnitsV
46 // convert the units to mm
47 v = v / svgUnitsPmm[0] // FIXME should this use X units?
48 return v
49}
50
51const css2cag = (css, unit) => {
52 let v = parseFloat(css) // number part
53 if (isNaN(v)) { return 0.0 }
54 if (v === 0) return v
55 if (css.search(/EM/i) > 0) { // FIXME self assignment , useless ?
56 // v = v // font size
57 } else
58 if (css.search(/EX/i) > 0) { // FIXME self assignment , useless ?
59 // v = v // x-height of font
60 } else
61 if (css.search(/MM/i) > 0) { // FIXME self assignment , useless ?
62 // v = v // absolute millimeters
63 } else
64 if (css.search(/CM/i) > 0) {
65 v = (v * 10) // absolute centimeters > millimeters
66 } else
67 if (css.search(/IN/i) > 0) {
68 v = (v / inchMM) // absolute inches > millimeters
69 } else
70 if (css.search(/PT/i) > 0) {
71 v = (v / ptMM) // absolute points > millimeters
72 } else
73 if (css.search(/PC/i) > 0) {
74 v = (v / pcMM) // absolute picas > millimeters
75 } else {
76 v = (v / unit) // absolute pixels(units) > millimeters
77 }
78 return v
79}
80
81// convert the SVG color specification to CAG RGB
82const cagColor = (value) => {
83 // let rgb = [0,0,0]; // default is black
84 let rgb
85 value = value.toLowerCase()
86 if (value in svgColors) {
87 rgb = svgColors[value]
88 rgb = [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255] // converted to 0.0-1.0 values
89 } else {
90 if (value[0] === '#') {
91 if (value.length === 4) {
92 // short HEX specification
93 value = '#' + value[1] + value[1] + value[2] + value[2] + value[3] + value[3]
94 }
95 if (value.length === 7) {
96 // HEX specification
97 rgb = [
98 parseInt('0x' + value.slice(1, 3)) / 255,
99 parseInt('0x' + value.slice(3, 5)) / 255,
100 parseInt('0x' + value.slice(5, 7)) / 255
101 ]
102 }
103 } else {
104 const pat = /rgb\(.+,.+,.+\)/
105 let s = pat.exec(value)
106 if (s !== null) {
107 // RGB specification
108 s = s[0]
109 s = s.slice(s.indexOf('(') + 1, s.indexOf(')'))
110 rgb = s.split(',')
111 if (s.indexOf('%') > 0) {
112 // rgb(#%,#%,#%)
113 rgb = [parseInt(rgb[0]), parseInt(rgb[1]), parseInt(rgb[2])]
114 rgb = [rgb[0] / 100, rgb[1] / 100, rgb[2] / 100] // converted to 0.0-1.0 values
115 } else {
116 // rgb(#,#,#)
117 rgb = [parseInt(rgb[0]), parseInt(rgb[1]), parseInt(rgb[2])]
118 rgb = [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255] // converted to 0.0-1.0 values
119 }
120 }
121 }
122 }
123 return rgb
124}
125
126const cssStyle = (element, name) => {
127 if ('STYLE' in element) {
128 const list = element.STYLE + ';'
129 const pat = name + '\\s*:\\s*(\\S+);'
130 const exp = new RegExp(pat, 'i')
131 let v = exp.exec(list)
132 if (v !== null) {
133 v = v[0] // name plus value
134 let i = v.indexOf(':') + 1 // skip past the ':'
135 while (v[i] === ' ') i++
136 v = v.slice(i, v.indexOf(';'))
137 return v
138 }
139 }
140 return undefined
141}
142
143const reflect = (x, y, px, py) => {
144 const ox = x - px
145 const oy = y - py
146 if (x === px && y === px) return [x, y]
147 if (x === px) return [x, py + (-oy)]
148 if (y === py) return [px + (-ox), y]
149 return [px + (-ox), py + (-oy)]
150}
151
152// Return the value for the given attribute from the group hiearchy
153const groupValue = (svgGroups, name) => {
154 let i = svgGroups.length
155 while (i > 0) {
156 const g = svgGroups[i - 1]
157 if (name in g) {
158 return g[name]
159 }
160 i--
161 }
162 return undefined
163}
164
165module.exports = {
166 svg2cagX,
167 svg2cagY,
168 cagLengthX,
169 cagLengthY,
170 cagLengthP,
171 css2cag,
172 cagColor,
173 cssStyle,
174 reflect,
175 groupValue
176}