I am currently implementing a simple SVG text renderer. I am puling path information out of an SVG file for the characters I need to draw.
This is all the appropriate information for font/characters stored in a JSON object:
window.font = {
horizAdvX: 487,
unitsPerEm: 2048,
ascent: 1638,
descent: -410,
glyphs: {
H: {
horizAdvX: 1382,
path: 'M147 14q64 133 244 604q-68 29 -90 80q19 14 135 37l27 66q85 217 115 327.5t81 391.5q81 -14 153 -73t126 -147q-8 -11 -17.5 -26t-22 -38.5t-23 -43.5t-27 -55.5t-27 -58.5l-31.5 -69t-32 -71t-35.5 -80.5t-36.5 -81.5q282 39 488 51q77 223 157.5 399.5t136.5 235.5 q42 -3 124.5 -47.5t101.5 -79.5q-69 -65 -143 -210.5t-140 -336.5q41 -38 41 -92q0 -39 -16 -71q-28 4 -76 8q-69 -219 -111.5 -425t-42.5 -319q0 -33 4 -53q-41 2 -65 15t-31 28.5t-18 32t-27 22.5q-26 9 -44.5 74.5t-18.5 110.5q0 160 104 510q-75 -5 -255 -24.5 t-253 -20.5q-166 -392 -231 -750q-73 18 -126 62.5t-98 117.5z'
},
u: {
horizAdvX: 1011,
path: 'M174 119q0 98 16 174q43 181 146 386.5t221 291.5q44 0 99 -16t83 -48q-18 -19 -51 -68t-93 -161t-116 -244q-24 -55 -55 -162.5t-31 -156.5q0 -22 15 -37q29 11 73.5 62.5t134.5 174.5q6 9 36 49t47 64t42.5 63t44 75.5t31.5 70.5q19 51 33 84.5t49.5 91.5t77.5 98 q53 0 114 -20.5t80 -44.5q-28 -68 -104.5 -220.5t-115 -259.5t-38.5 -204q0 -51 11.5 -92t22.5 -64.5t11 -32.5q0 -3 -2 -5t-4 -2l-2 -1q-28 0 -88 24t-106 56q-35 29 -50.5 76t-15.5 90q0 44 10 74q-10 1 -52.5 -51t-95.5 -123t-67 -88q-57 -61 -88 -64q-70 3 -138.5 47.5 t-84.5 112.5z'
},
// rest of chars ...
Using the excellent svg.js library, I have managed to get this far in the rendering process:
- Draw character using path information &
SVG.path
method - Apply a fixed height to character
- Get bounding box for character path
- Transform coordinate system so y points down (coordinate system in SVG font is 'upside down')
- Draw next character using width of previous character(s) as offset
- Repeat
This does draw text. You can see this working on this jsfiddle:
http://jsfiddle.net/dormisher/KVs7E/2/
The thing is everything is the same height, and the exact same distance apart. I need to know how to use the attributes horiz-adv-x
, unites-per-em
etc, found in the SVG font file, to get the correct horizontal and vertical positioning.
At first it seems simple, horiz-adv-x
is simply a scaling value used on the font size, so use that on the horizontal offset and hey presto! But no, doing that ends up with something looking like this:
http://jsfiddle.net/dormisher/KVs7E/3/
What I need to figure out is how the combination of the horizAdvX, and the rest of the simillar values, are used to work out horizontal advance & vertical positioning. I have read through the W3C spec but it makes little sense to me in terms of this stuff.
Be great if anyone could help me out!
The trick is, to scale the glyphs accordingly and then move them to the right position. I just realeased a text-morphing extension for svg.js which pulls its glyph from an svg-font, too.
I went this way:
Much of code. I tried to add comments to help understanding. Basically I loop through my glyphs and size and positioning them according to the scalefactor. I dont now what a
flip()
would do to a path but I am pretty sure there are some problems with that. Its better to calculate the new path points which issize()
doing for you automatically.