Fill out the stroke shape computation section.
--- a/master/definitions.xml Sun May 20 19:08:09 2012 +1000
+++ b/master/definitions.xml Mon May 21 19:01:33 2012 +1000
@@ -1639,6 +1639,9 @@
<term name='inherit' href='http://www.w3.org/TR/2008/REC-CSS2-20080411/cascade.html#value-def-inherit'/>
<term name='object bounding box units' href='coords.html#ObjectBoundingBoxUnits'/>
<term name='simple alpha compositing' href='masking.html#SimpleAlphaBlending'/>
+ <term name='dash positions' href='painting.html#TermDashPositions'/>
+ <term name='cap shape' href='painting.html#TermCapShape'/>
+ <term name='line join shape' href='painting.html#TermLineJoinShape'/>
<!-- === defined in other specifications ================================ -->
Binary file master/images/painting/linejoin-construction.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/master/images/painting/linejoin-construction.svg Mon May 21 19:01:33 2012 +1000
@@ -0,0 +1,37 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="200">
+ <defs>
+ <g id="dot">
+ <rect x="-3" y="-3" width="6" height="6" fill="white"/>
+ <rect x="-2" y="-2" width="4" height="4" fill="black"/>
+ </g>
+ </defs>
+ <g transform="translate(100,0)">
+ <g stroke-width="40" stroke="#444">
+ <path d="M 50,150 L 150,50"/>
+ <path d="M 150,50 L 250,150"/>
+ </g>
+ <path fill="deeppink" d="M 135.86,35.86 L 150,50 164.14,35.86 A 20,20 0 0 0 135.86,35.86"/>
+ <g stroke="#6a9100" xstroke-dasharray="4" fill="none">
+ <path transform="translate(-14.14, -14.14)" d="M -50,250 L 200,0"/>
+ <path transform="translate(14.14, 14.14)" d="M -50,250 L 250,-50"/>
+ <path transform="translate(-14.14, 14.14)" d="M 50,-50 350,250"/>
+ <path transform="translate(14.14, -14.14)" d="M 50,-50 350,250"/>
+ </g>
+ <path d="M 50,150 L 150,50 250,150" stroke-width="2" stroke="#ccc" fill="none"/>
+ <use xlink:href="#dot" x="150" y="50"/>
+ <use xlink:href="#dot" x="135.86" y="35.86"/>
+ <use xlink:href="#dot" x="164.14" y="35.86"/>
+ <use xlink:href="#dot" x="150" y="21.72"/>
+ <g font-family="sans-serif" font-size="12px">
+ <text x="150" y="67" text-anchor="middle" fill="#ccc">P</text>
+ <text x="130" y="37" text-anchor="end" fill="#444">P1</text>
+ <text x="170" y="37" fill="#444">P2</text>
+ <text x="150" y="13" text-anchor="middle">P3</text>
+
+ <text x="-30" y="193" text-anchor="end">A<tspan dy="2" font-size="10px">left</tspan></text>
+ <text x="52" y="193">A<tspan dy="2" font-size="10px">right</tspan></text>
+ <text x="230" y="193">B<tspan dy="2" font-size="10px">left</tspan></text>
+ <text x="357" y="193" text-anchor="end">B<tspan dy="2" font-size="10px">right</tspan></text>
+ </g>
+ </g>
+</svg>
--- a/master/painting.html Sun May 20 19:08:09 2012 +1000
+++ b/master/painting.html Mon May 21 19:01:33 2012 +1000
@@ -977,8 +977,179 @@
<a>graphics element</a>'s stroke is, taking into account the
stroking properties above:</p>
-<p class="issue">Here will be steps that describe how exactly to handle
-dashing, line caps, line joins and stroke width.</p>
+<ol>
+ <li>Let <var>shape</var> be an empty shape.</li>
+ <li>Let <var>path</var> be the <a>equivalent path</a> of the <a>graphics element</a>.</li>
+ <!--
+ <li>Let <var>length</var> be the total length of <var>path</var>.</li>
+ -->
+ <li>Let <var>dashes</var> be the list of values of <a>'stroke-dasharray'</a> on the <a>graphics element</a>,
+ converted to user units, repeated if necessary so that it has an even number of elements; if the property
+ has the value <span class="prop-value">none</span>, then the list has a single value 0.</li>
+ <li>Let <var>dashcount</var> be the number of values in <var>dashes</var>.</li>
+ <li>Let <var>dashsum</var> be the sum of the values in <var>dashes</var>.</li>
+ <li>Let <var>dashing</var> be true if <var>dashsum</var> > 0 and false otherwise.</li>
+ <!--
+ <li>Let <var>offset</var>, <var>width</var>, <var>cap</var> and <var>join</var> be the values of the <a>'stroke-dashoffset'</a>, <a>'stroke-width'</a>, <a>'stroke-linecap'</a> and <a>'stroke-linejoin'</a> properties on the <a>graphics element</a>.</li>
+ -->
+ <li>Let <var>offset</var> be the value of the <a>'stroke-dashoffset'</a> property on the <a>graphics element</a>.</li>
+ <li>If <var>offset</var> is negative, then set <var>offset</var> to <var>dashsum</var> − abs(<var>offset</var>).</li>
+ <li>Set <var>offset</var> to <var>offset</var> mod <var>dashsum</var>.</li>
+ <li>For each subpath of <var>path</var>:
+ <ol>
+ <li>Let <var>positions</var> be the <a>dash positions</a> for the subpath.</li>
+ <li>For each pair <<var>startpos</var>, <var>endpos</var>> in <var>positions</var>:
+ <ol>
+ <li>Let <var>dash</var> be the shape that includes, for all distances
+ between <var>startpos</var> and <var>endpos</var>
+ along the subpath, all points that lie on the line perpendicular to the subpath
+ at that distance and which are within distance <a>'stroke-width'</a> of the
+ point on the subpath at that position.</li>
+ <li>Set <var>dash</var> to be the union of <var>dash</var> and the starting <a>cap shape</a> for the subpath at position <var>startpos</var>.</li>
+ <li>Set <var>dash</var> to be the union of <var>dash</var> and the ending <a>cap shape</a> for the subpath at position <var>endpos</var>.</li>
+ <li>Let <var>loseg</var> be the index of the path segment in the subpath at distance <var>position</var> along the subpath.</li>
+ <li>Let <var>hiseg</var> be the index of the path segment in the subpath at distance <var>endposition</var> along the subpath.
+ <p class="note">It does not matter whether any zero length segments are
+ included when choosing <var>loseg</var> and <var>hiseg</var>.</p>
+ </li>
+ <li>Let <var>segindex</var> be <var>loseg</var>.</li>
+ <li>While <var>segindex</var> < <var>hiseg</var>:
+ <ol>
+ <li>Set <var>dash</var> to be the union of <var>dash</var> and the
+ <a>line join shape</a> for the subpath at segment index <var>segindex</var>.</li>
+ <li>Set <var>segindex</var> to <var>segindex</var> + 1.</li>
+ </ol>
+ </li>
+ <li>Set <var>shape</var> to be the union of <var>shape</var> and <var>stroke</var>.</li>
+ </ol>
+ </li>
+ </ol>
+ </li>
+ <li>Return <var>shape</var>.</li>
+</ol>
+
+<p>The <dfn id="TermDashPositions">dash positions</dfn> for a given subpath of a <a>graphics element</a>'s
+<a>equivalent path</a> is a sequence of pairs of "starting distance along the subpath" and "ending distance
+along the subpath". It is determined as follows:</p>
+
+<ol>
+ <li>Let <var>length</var> be the length of the subpath.</li>
+
+ <li>Let <var>dashes</var> be the list of values of <a>'stroke-dasharray'</a> on the <a>graphics element</a>,
+ converted to user units, repeated if necessary so that it has an even number of elements; if the property
+ has the value <span class="prop-value">none</span>, then the list has a single value 0.</li>
+ <li>Let <var>dashcount</var> be the number of values in <var>dashes</var>.</li>
+ <li>Let <var>dashsum</var> be the sum of the values in <var>dashes</var>.</li>
+ <li>If <var>dashsum</var> = 0, then return a sequence with the single pair <0, <var>length</var>>.</li>
+
+ <li>Let <var>positions</var> be an empty sequence.</li>
+ <li>Let <var>offset</var> be the value of the <a>'stroke-dashoffset'</a> property on the <a>graphics element</a>.</li>
+ <li>If <var>offset</var> is negative, then set <var>offset</var> to <var>dashsum</var> − abs(<var>offset</var>).</li>
+ <li>Set <var>offset</var> to <var>offset</var> mod <var>dashsum</var>.</li>
+
+ <li>Let <var>dashindex</var> be the smallest integer such that sum(<var>dashes<sub>i</sub></var>, 0 ≤ <var>i</var> ≤ <var>dashindex</var>) ≥ <var>offset</var>.</li>
+ <li>Let <var>dashlength</var> be min(sum(<var>dashes<sub>i</sub></var>, 0 ≤ <var>i</var> ≤ <var>dashindex</var>) − <var>offset</var>, <var>length</var>).</li>
+ <li>If <var>dashindex</var> mod 2 = 0, then append to <var>positions</var> the pair <0, <var>dashlength</var>>.</li>
+ <li>Let <var>position</var> be <var>dashlength</var>.</li>
+ <li>Set <var>dashindex</var> to (<var>dashindex</var> + 1) mod <var>dashcount</var>.</li>
+
+ <li>While <var>position</var> < <var>length</var>:
+ <ol>
+ <li>Let <var>dashlength</var> be min(<var>dashes</var><sub><var>dashindex</var></sub>, <var>length</var> − <var>position</var>).</li>
+ <li>If <var>dashindex</var> mod 2 = 0, then append to <var>positions</var> the pair <<var>position</var>, <var>position</var> + <var>dashlength</var>>.</li>
+ <li>Set <var>dashindex</var> to (<var>dashindex</var> + 1) mod <var>dashcount</var>.</li>
+ <li>Set <var>position</var> to <var>position</var> + <var>dashlength</var>.</li>
+ </ol>
+ </li>
+
+ <li>Return <var>positions</var>.</li>
+</ol>
+
+<p>The starting and ending <dfn id="TermCapShape">cap shapes</dfn> at a given <var>position</var> along a subpath is determined as follows:</p>
+
+<ol>
+ <li>If <a>'stroke-linecap'</a> is <span class="prop-value">butt</span>, then return an empty shape.</li>
+ <li>Otherwise, if <a>'stroke-linecap'</a> is <span class="prop-value">round</span>, then:
+ <ol>
+ <li>If this is a starting cap, then return a semicircle of radius <a>'stroke-width'</a> positioned such that:
+ <ul>
+ <li>Its straight edge is parallel to the line perpendicular to the subpath at distance <var>position</var> along it.</li>
+ <li>The midpoint of its straight edge is at the point that is along the subpath at distance <var>position</var>.</li>
+ <li>The direction from the midpoint of its arc to the midpoint of its straight edge is the same as the direction of the subpath at distance <var>position</var> along it.</li>
+ </ul>
+ </li>
+ <li>Otherwise, this is an ending cap. Return a semicircle of radius <a>'stroke-width'</a> positioned such that:
+ <ul>
+ <li>Its straight edge is parallel to the line perpendicular to the subpath at distance <var>position</var> along it.</li>
+ <li>The midpoint of its straight edge is at the point that is along the subpath at distance <var>position</var>.</li>
+ <li>The direction from the midpoint of its straight edge to the midpoint of its arc is the same as the direction of the subpath at distance <var>position</var> along it.</li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+ <li>Otherwise, <a>'stroke-linecap'</a> is <span class="prop-value">square</span>:
+ <ol>
+ <li>If this is a starting cap, then return a rectangle with side lengths <a>'stroke-width'</a> and <a>'stroke-width'</a> / 2 positioned such that:
+ <ul>
+ <li>Its longer edges, <var>A</var> and <var>B</var>, are parallel to the line perpendicular to the subpath at distance <var>position</var> along it.</li>
+ <li>The midpoint of <var>A</var> is at <var>start</var>.</li>
+ <li>The direction from the midpoint of <var>B</var> to the midpoint of <var>A</var> is the same as the direction of the subpath at distance <var>position</var> along it.</li>
+ </ul>
+ </li>
+ <li>Otherwise, this is an ending cap. Return a rectangle with side lengths <a>'stroke-width'</a> and <a>'stroke-width'</a> / 2 positioned such that:
+ <ul>
+ <li>Its longer edges, <var>A</var> and <var>B</var>, are parallel to the line perpendicular to the subpath at distance <var>endposition</var> along it.</li>
+ <li>The midpoint of <var>A</var> is at <var>end</var>.</li>
+ <li>The direction from the midpoint of <var>A</var> to the midpoint of <var>B</var> is the same as the direction of the subpath at distance <var>endposition</var> along it.</li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+</ol>
+
+<p>The <dfn id="TermLineJoinShape">line join shape</dfn> for a given segment of a subpath is determined as follows:</p>
+
+<ol>
+ <li>Let <var>P</var> be the point at the end of the segment.</li>
+ <li>Let <var>A</var> be the line parallel to the tangent at the end of the segment.</li>
+ <li>Let <var>B</var> be the line parallel to the tangent at the start of the following segment.</li>
+
+ <li>If <var>A</var> and <var>B</var> are the same line, then return an empty shape.</li>
+
+ <li>Let <var>A<sub>left</sub></var> and <var>A<sub>right</sub></var> be lines parallel to <var>A</var> at a distance of <a>'stroke-width'</a> / 2 to the left and to the right of <var>A</var>, respectively.</li>
+ <li>Let <var>B<sub>left</sub></var> and <var>B<sub>right</sub></var> be lines parallel to <var>B</var> at a distance of <a>'stroke-width'</a> / 2 to the left and to the right of <var>B</var>, respectively.</li>
+
+ <li>Let <var>P</var><sub>1</sub>, <var>P</var><sub>2</sub> and <var>P</var><sub>3</sub> be points determined as follows:
+ <ol>
+ <li>If the acute angle between <var>A</var> and <var>B</var> is on the right of these lines, considering the direction of the subpath, then
+ <var>P</var><sub>1</sub> and <var>P</var><sub>2</sub> are the points on
+ <var>A<sub>left</sub></var> and <var>B<sub>left</sub></var> closest to <var>P</var>,
+ and <var>P</var><sub>3</sub> is the intersection of <var>A<sub>left</sub></var> and <var>B<sub>left</sub></var>.</li>
+ <li>Otherwise,
+ <var>P</var><sub>1</sub> and <var>P</var><sub>2</sub> are the points on
+ <var>A<sub>right</sub></var> and <var>B<sub>right</sub></var> closest to <var>P</var>,
+ and <var>P</var><sub>3</sub> is the intersection of <var>A<sub>right</sub></var> and <var>B<sub>right</sub></var>.</li>
+ </ol>
+ </li>
+
+ <li>Let <var>bevel</var> be the triangle formed from the three points <var>P</var>, <var>P</var><sub>1</sub> and <var>P</var><sub>2</sub>.</li>
+
+ <li>If <a>'stroke-linejoin'</a> is <span class="prop-value">round</span>, then return the union
+ of <var>bevel</var> and a circular sector of radius <a>'stroke-width'</a>, centered on <var>P</var>,
+ and which has <var>P</var><sub>1</sub> and <var>P</var><sub>2</sub> as the two endpoints of the arc.</li>
+
+ <li>Let <var>angle</var> be the angle between <var>A</var> and <var>B</var>.</li>
+ <li>Let <var>miterlength</var> be <a>'stroke-width'</a> / sin(<var>angle</var> / 2).</li>
+ <li>If <a>'stroke-linejoin'</a> is <span class="prop-value">miter</span> and 1 / sin(<var>angle</var> / 2) ≤ <a>'stroke-miterlimit'</a>, then
+ return the union of <var>bevel</var> and the triangle formed from the three points <var>P</var><sub>1</sub>, <var>P</var><sub>2</sub> and <var>P</var><sub>3</sub>.</li>
+
+ <li>Return <var>bevel</var>.</li>
+</ol>
+
+<div class="figure">
+ <img src="images/painting/linejoin-construction.svg" style="border: 1px solid #888"/>
+ <p class="caption">Construction of a round line join shape.</p>
+</div>
<h2 id="VisibilityControl">Controlling visibility</h2>
--- a/master/style/default_svg.css Sun May 20 19:08:09 2012 +1000
+++ b/master/style/default_svg.css Mon May 21 19:01:33 2012 +1000
@@ -152,7 +152,7 @@
}
sub {
- font-size: 67%;
+ font-size: 80%;
}
dl.definitions > dt,