See this demo on jsFiddle (or hosted here):
- I have an svg path that is rougly (99.99%) circular
- Along this path, I place text, using a 'textpath' svg element
- I want the end of the text to meet with the beginning as accurately as possible (ideally pixel-perfectly) so as to make a continuous text loop
Here's an excerpt of the code (stripped down of all text values):
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" viewBox="0 0 480 480" preserveAspectRatio="xMidYMid" height="100%"
width="100%">
<defs>
<style type="text/css">
/* for some reason, SVG font import doesn't work in Chrome or Firefox! */
@font-face {
font-family: Libertine;
src: url(LinLibertine_R.svg#LinLibertineO);
}
@font-face {
font-family: Libertine2;
src: url(LinLibertine_Rah.ttf);
}
/* Chrome seems to round to the nearest 0.5 em; also, does not display em-widths consistently with Firefox (though px-widths are consistent) */
.ex1 {
font: 0.85em Libertine2;
}
.measurement {
font: 1.0em monospace;
}
</style>
<text id="day1">...</text>
<text id="day2">...</text>
<text id="day3">...</text>
<text id="day4">...</text>
<text id="day5">...</text>
<text id="day6">...</text>
<text id="day7">...</text>
</defs>
<g transform="translate(240,240)">
<g transform="translate(-240,-240)">
<circle r="1" cx="240" cy="27" fill="black" />
<path id="circle" d="M 240,20 a 220,220, 0 1,1 -0.0001,0.0000 Z"
fill="none" stroke="red" stroke-width="0" />
<path id="inner-circle" d="M 240,40 a 200,200, 0 1,1 -0.0001,0.0000 Z"
fill="none" stroke="red" stroke-width="0" />
<text class="ex1" fill="black">
<!-- this RTL text-along-path is displayed backwards (ie sdrawkcab) in
Chrome; manual CSS overrides (e.g. unicode-bidi) cause blank/white screen
-->
<textPath xlink:href="#circle" method="stretch">...</textPath>
</text>
<text class="measurement" fill="grey">
<textPath xlink:href="#inner-circle" method="stretch">A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 G0 G1 G2 G3 G4 G5 G6 G8 G9</textPath>
</text>
</g>
</g>
</svg>
So far, the best I can do is import a font via CSS, which roughly standardizes the width across browsers.
Note that Chrome does not read fine-tuned font-size values (e.g. it seems to round 0.87em to 0.85em), and seems to have a different text-rendering engine than Firefox, even when the font-sizes are consistent. For example, a font-size of 1em renders the inner 'measurement circle' in the above example to the F in tick 'F9' in Firefox, where Chrome renders nearly to the beginning of tick 'F4', a problem which is reduced to a single-character-width-difference when px units are used in font-size.
You'll also notice that Chrome renders Right-to-Left (RTL) text incorrectly, and manual CSS overrides (using 'unicode-bidi' and 'direction' directives) have caused complete failure (no SVG rendering at all).
It goes without saying — there are lots of problems. So far, this has been a fun experiment, but any help in standardization would be greatly appreciated.
As far as my own solutions; I am thinking of specifying the location of each character manually using the font specifications in the LinuxLibertine svg-font, which is a very tacky alternative to figuring out the root of the rendering inconsistencies.