Skip to content

Commit

Permalink
[giow] (0) Make the addText() methods on Path not create overlapping …
Browse files Browse the repository at this point in the history
…subpaths.

Affected topics: Canvas

git-svn-id: http://svn.whatwg.org/webapps@8538 340c8d12-0b0e-0410-8428-c7bf67bfef74
  • Loading branch information
Hixie committed Mar 12, 2014
1 parent cc6dc1f commit a8de4c1
Show file tree
Hide file tree
Showing 5 changed files with 279 additions and 43 deletions.
106 changes: 92 additions & 14 deletions complete.html
Expand Up @@ -298,7 +298,7 @@

<header class=head id=head><p><a href=http://www.whatwg.org/ class=logo><img width=101 src=/images/logo alt=WHATWG height=101></a></p>
<hgroup><h1 class=allcaps>HTML</h1>
<h2 class="no-num no-toc">Living Standard &mdash; Last Updated 10 March 2014</h2>
<h2 class="no-num no-toc">Living Standard &mdash; Last Updated 12 March 2014</h2>
</hgroup><dl><dt><strong>Web developer edition:</strong></dt>
<dd><strong><a href=http://developers.whatwg.org/>http://developers.whatwg.org/</a></strong></dd>
<dt>Multiple-page version:</dt>
Expand Down Expand Up @@ -56740,23 +56740,76 @@ <h6 id=path-objects><span class=secno>4.12.4.2.7 </span><code><a href=#path>Path
<li><p>Move all the shapes in <var title="">glyphs</var> to the right by <var title="">x</var>
CSS pixels and down by <var title="">y</var> CSS pixels.</li>

<li><p>Let <var title="">glyph subpaths</var> be a <a href=#concept-path title=concept-path>path</a> describing the shapes given
in <var title="">glyphs</var>, with each CSS pixel in the coordinate space of <var title="">glyphs</var> mapped to one coordinate space unit in <var title="">glyph subpaths</var>.
Subpaths in <var title="">glyph subpaths</var> must wind clockwise, regardless of how the user
<!--CLEANUP-->
<li><p>Let <var title="">glyph paths</var> be a list of <a href=#concept-path title=concept-path>paths</a> describing the shapes given
in <var title="">glyphs</var>, with each CSS pixel in the coordinate space of <var title="">glyphs</var> mapped to one coordinate space unit in <var title="">glyph paths</var>.
Subpaths in <var title="">glyph paths</var> must wind clockwise, regardless of how the user
agent's font subsystem renders fonts and regardless of how the fonts themselves are defined.</p>

<li><p>Transform all the coordinates and lines in <var title="">glyph subpaths</var> by the
<li><p>Transform all the coordinates and lines in <var title="">glyph paths</var> by the
transformation matrix <var title="">transform</var>, if it is not null.</li>

<li><p>If the method is <code title=dom-path-addPathByStrokingText><a href=#dom-path-addpathbystrokingtext>addPathByStrokingText()</a></code>, replace <var title="">glyph subpaths</var> by the result of <a href=#trace-a-path title="trace a path">tracing</a> <var title="">glyph subpaths</var>, using the <code><a href=#canvasdrawingstyles>CanvasDrawingStyles</a></code> object argument for the
<!--CLEANUP-->
<li><p>If the method is <code title=dom-path-addPathByStrokingText><a href=#dom-path-addpathbystrokingtext>addPathByStrokingText()</a></code>, replace <var title="">glyph paths</var> by the result of <a href=#trace-a-path title="trace a path">tracing</a> each <a href=#concept-path title=concept-path>path</a> in <var title="">glyph paths</var>, using the <code><a href=#canvasdrawingstyles>CanvasDrawingStyles</a></code> object argument for the
line styles.</p>

<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">glyph
subpaths</var>.</li>
<li id=mergeGlyphs>

<p>Let <var title="">merged path</var> be a <a href=#concept-path title=concept-path>path</a> that
consists of a set of non-overlapping subpaths that exactly outline the points from which, in any
of the <a href=#concept-path title=concept-path>paths</a> in <var title="">glyph paths</var>, the number
of times a half-infinite straight line drawn from that point crosses that path is even.</p>

<p>The subpaths in <var title="">merged path</var> must be oriented such that for any point in
the path, the number of times a half-infinite straight line drawn from that point crosses a
subpath is even if and only if number of times a half-infinite straight line drawn from that
same point crosses a subpath going in one direction is equal to the number of times it crosses a
subpath going in the other direction.</p>

<div class=example>

<p>For example, suppose <var title="">text</var> consists of two overlapping glyphs "Q" and
"p" (maybe the "Q" has a flourish that crosses into the tail of the "p"). The <var title="">glyph paths</var> therefore consist of two paths, each with two subpaths: one for the
outside of the letter shape, and one for the inside of the letter shape. There are points that,
according to the even-odd fill rule, are filled in both shapes simultaneously: where they
overlap. As such, the subpaths from the two glyphs actually cross each other.</p>

<p><img src=http://images.whatwg.org/Qp-overlap.png alt=""></p> <!-- this image repeats the previous paragraph,
so alternative text would be redundant -->
<!--
c.clearRect(0, 0, 640, 480);
c.save();
try {
c.font = '100px Zapfino';
c.fillStyle = 'blue';
c.fillText('Q', 200, 200);
c.fillStyle = 'fuchsia';
c.fillText('p', 337, 200);
} finally {
c.restore();
}
-->

<p>The resulting <var title="">merged path</var> in such a situation would have just one path
for these two letters, with a total of just three subpaths (one big outer outline, one for the
inside of the "Q", and one for inside of the "p"). This single path would have no subpaths that
cross each other.</p>

<p><img src=http://images.whatwg.org/Qp-overlap-outline.png alt=""></p> <!-- this image again repeats the
previous paragraph, so alternative text would be redundant -->
<!-- this is just an edge-detected version of the previous image -->

</div>

</li>

<li><p>Add all the subpaths in <var title="">glyph subpaths</var> to the <code><a href=#path>Path</a></code>
<!--CLEANUP-->
<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">merged path</var>.</li>

<li><p>Add all the subpaths in <var title="">merged path</var> to the <code><a href=#path>Path</a></code>
object.</li>

<!--CLEANUP-->
<li><p>Create a new subpath in the <code><a href=#path>Path</a></code> object with (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) as the only point in
the subpath.</li>

Expand Down Expand Up @@ -56797,6 +56850,8 @@ <h6 id=path-objects><span class=secno>4.12.4.2.7 </span><code><a href=#path>Path

<li><p>Move all the shapes in <var title="">glyphs</var> to the right by <var title="">offset</var> CSS pixels.</li>

<li><p>Let <var title="">transformed path list</var> be an empty list of paths.</li>

<li>

<p>For each glyph <var title="">glyph</var> in the <var title="">glyphs</var> array, run these
Expand Down Expand Up @@ -56839,14 +56894,37 @@ <h6 id=path-objects><span class=secno>4.12.4.2.7 </span><code><a href=#path>Path
<li><p>If the method is <code title=dom-path-addPathByStrokingText><a href=#dom-path-addpathbystrokingtext>addPathByStrokingText()</a></code>, replace <var title="">glyph subpaths</var> by the result of <a href=#trace-a-path title="trace a path">tracing</a> <var title="">glyph subpaths</var>, using the <code><a href=#canvasdrawingstyles>CanvasDrawingStyles</a></code> object argument for
the line styles.</p>

<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">glyph
subpaths</var>. (This coordinate is only used if this is the last glyph processed.)</li>

<li><p>Add all the subpaths in <var title="">glyph subpaths</var> to <var title="">target</var>.</li>
<li><p>Add all the subpaths in <var title="">glyph subpaths</var> to <var title="">transformed path list</var>.</li>

</ol></li>

<li><p>Create a new subpath in the <code><a href=#path>Path</a></code> object with (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) as the only point in
<li>

<p>Let <var title="">merged path</var> be a <a href=#concept-path title=concept-path>path</a> that
consists of a set of non-overlapping subpaths that exactly outline the points from which, in any
of the <a href=#concept-path title=concept-path>paths</a> in <var title="">transformed path list</var>,
the number of times a half-infinite straight line drawn from that point crosses that path is
even.</p>

<p>The subpaths in <var title="">merged path</var> must be oriented such that for any point in
the path, the number of times a half-infinite straight line drawn from that point crosses a
subpath is even if and only if number of times a half-infinite straight line drawn from that
same point crosses a subpath going in one direction is equal to the number of times it crosses a
subpath going in the other direction.</p>

<p class=note>See <a href=#mergeGlyphs>the equivalent step in the earlier algorithm</a> for
an example of this step. It's even more likely that there will be overlap with this method,
since neighboring glyphs are likely to be rotated relative to each other.</p>

</li>

<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">merged
path</var>.</li>

<li><p>Add all the subpaths in <var title="">merged path</var> to <var title="">target</var>.</li>

<!--CLEANUP-->
<li><p>Create a new subpath in <var title="">target</var> with (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) as the only point in
the subpath.</li>

</ol></div>
Expand Down
Binary file added images/Qp-overlap-outline.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Qp-overlap.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
106 changes: 92 additions & 14 deletions index
Expand Up @@ -298,7 +298,7 @@

<header class=head id=head><p><a href=http://www.whatwg.org/ class=logo><img width=101 src=/images/logo alt=WHATWG height=101></a></p>
<hgroup><h1 class=allcaps>HTML</h1>
<h2 class="no-num no-toc">Living Standard &mdash; Last Updated 10 March 2014</h2>
<h2 class="no-num no-toc">Living Standard &mdash; Last Updated 12 March 2014</h2>
</hgroup><dl><dt><strong>Web developer edition:</strong></dt>
<dd><strong><a href=http://developers.whatwg.org/>http://developers.whatwg.org/</a></strong></dd>
<dt>Multiple-page version:</dt>
Expand Down Expand Up @@ -56740,23 +56740,76 @@ try {
<li><p>Move all the shapes in <var title="">glyphs</var> to the right by <var title="">x</var>
CSS pixels and down by <var title="">y</var> CSS pixels.</li>

<li><p>Let <var title="">glyph subpaths</var> be a <a href=#concept-path title=concept-path>path</a> describing the shapes given
in <var title="">glyphs</var>, with each CSS pixel in the coordinate space of <var title="">glyphs</var> mapped to one coordinate space unit in <var title="">glyph subpaths</var>.
Subpaths in <var title="">glyph subpaths</var> must wind clockwise, regardless of how the user
<!--CLEANUP-->
<li><p>Let <var title="">glyph paths</var> be a list of <a href=#concept-path title=concept-path>paths</a> describing the shapes given
in <var title="">glyphs</var>, with each CSS pixel in the coordinate space of <var title="">glyphs</var> mapped to one coordinate space unit in <var title="">glyph paths</var>.
Subpaths in <var title="">glyph paths</var> must wind clockwise, regardless of how the user
agent's font subsystem renders fonts and regardless of how the fonts themselves are defined.</p>

<li><p>Transform all the coordinates and lines in <var title="">glyph subpaths</var> by the
<li><p>Transform all the coordinates and lines in <var title="">glyph paths</var> by the
transformation matrix <var title="">transform</var>, if it is not null.</li>

<li><p>If the method is <code title=dom-path-addPathByStrokingText><a href=#dom-path-addpathbystrokingtext>addPathByStrokingText()</a></code>, replace <var title="">glyph subpaths</var> by the result of <a href=#trace-a-path title="trace a path">tracing</a> <var title="">glyph subpaths</var>, using the <code><a href=#canvasdrawingstyles>CanvasDrawingStyles</a></code> object argument for the
<!--CLEANUP-->
<li><p>If the method is <code title=dom-path-addPathByStrokingText><a href=#dom-path-addpathbystrokingtext>addPathByStrokingText()</a></code>, replace <var title="">glyph paths</var> by the result of <a href=#trace-a-path title="trace a path">tracing</a> each <a href=#concept-path title=concept-path>path</a> in <var title="">glyph paths</var>, using the <code><a href=#canvasdrawingstyles>CanvasDrawingStyles</a></code> object argument for the
line styles.</p>

<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">glyph
subpaths</var>.</li>
<li id=mergeGlyphs>

<p>Let <var title="">merged path</var> be a <a href=#concept-path title=concept-path>path</a> that
consists of a set of non-overlapping subpaths that exactly outline the points from which, in any
of the <a href=#concept-path title=concept-path>paths</a> in <var title="">glyph paths</var>, the number
of times a half-infinite straight line drawn from that point crosses that path is even.</p>

<p>The subpaths in <var title="">merged path</var> must be oriented such that for any point in
the path, the number of times a half-infinite straight line drawn from that point crosses a
subpath is even if and only if number of times a half-infinite straight line drawn from that
same point crosses a subpath going in one direction is equal to the number of times it crosses a
subpath going in the other direction.</p>

<div class=example>

<p>For example, suppose <var title="">text</var> consists of two overlapping glyphs "Q" and
"p" (maybe the "Q" has a flourish that crosses into the tail of the "p"). The <var title="">glyph paths</var> therefore consist of two paths, each with two subpaths: one for the
outside of the letter shape, and one for the inside of the letter shape. There are points that,
according to the even-odd fill rule, are filled in both shapes simultaneously: where they
overlap. As such, the subpaths from the two glyphs actually cross each other.</p>

<p><img src=http://images.whatwg.org/Qp-overlap.png alt=""></p> <!-- this image repeats the previous paragraph,
so alternative text would be redundant -->
<!--
c.clearRect(0, 0, 640, 480);
c.save();
try {
c.font = '100px Zapfino';
c.fillStyle = 'blue';
c.fillText('Q', 200, 200);
c.fillStyle = 'fuchsia';
c.fillText('p', 337, 200);
} finally {
c.restore();
}
-->

<p>The resulting <var title="">merged path</var> in such a situation would have just one path
for these two letters, with a total of just three subpaths (one big outer outline, one for the
inside of the "Q", and one for inside of the "p"). This single path would have no subpaths that
cross each other.</p>

<p><img src=http://images.whatwg.org/Qp-overlap-outline.png alt=""></p> <!-- this image again repeats the
previous paragraph, so alternative text would be redundant -->
<!-- this is just an edge-detected version of the previous image -->

</div>

</li>

<li><p>Add all the subpaths in <var title="">glyph subpaths</var> to the <code><a href=#path>Path</a></code>
<!--CLEANUP-->
<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">merged path</var>.</li>

<li><p>Add all the subpaths in <var title="">merged path</var> to the <code><a href=#path>Path</a></code>
object.</li>

<!--CLEANUP-->
<li><p>Create a new subpath in the <code><a href=#path>Path</a></code> object with (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) as the only point in
the subpath.</li>

Expand Down Expand Up @@ -56797,6 +56850,8 @@ try {

<li><p>Move all the shapes in <var title="">glyphs</var> to the right by <var title="">offset</var> CSS pixels.</li>

<li><p>Let <var title="">transformed path list</var> be an empty list of paths.</li>

<li>

<p>For each glyph <var title="">glyph</var> in the <var title="">glyphs</var> array, run these
Expand Down Expand Up @@ -56839,14 +56894,37 @@ try {
<li><p>If the method is <code title=dom-path-addPathByStrokingText><a href=#dom-path-addpathbystrokingtext>addPathByStrokingText()</a></code>, replace <var title="">glyph subpaths</var> by the result of <a href=#trace-a-path title="trace a path">tracing</a> <var title="">glyph subpaths</var>, using the <code><a href=#canvasdrawingstyles>CanvasDrawingStyles</a></code> object argument for
the line styles.</p>

<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">glyph
subpaths</var>. (This coordinate is only used if this is the last glyph processed.)</li>

<li><p>Add all the subpaths in <var title="">glyph subpaths</var> to <var title="">target</var>.</li>
<li><p>Add all the subpaths in <var title="">glyph subpaths</var> to <var title="">transformed path list</var>.</li>

</ol></li>

<li><p>Create a new subpath in the <code><a href=#path>Path</a></code> object with (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) as the only point in
<li>

<p>Let <var title="">merged path</var> be a <a href=#concept-path title=concept-path>path</a> that
consists of a set of non-overlapping subpaths that exactly outline the points from which, in any
of the <a href=#concept-path title=concept-path>paths</a> in <var title="">transformed path list</var>,
the number of times a half-infinite straight line drawn from that point crosses that path is
even.</p>

<p>The subpaths in <var title="">merged path</var> must be oriented such that for any point in
the path, the number of times a half-infinite straight line drawn from that point crosses a
subpath is even if and only if number of times a half-infinite straight line drawn from that
same point crosses a subpath going in one direction is equal to the number of times it crosses a
subpath going in the other direction.</p>

<p class=note>See <a href=#mergeGlyphs>the equivalent step in the earlier algorithm</a> for
an example of this step. It's even more likely that there will be overlap with this method,
since neighboring glyphs are likely to be rotated relative to each other.</p>

</li>

<li><p>Let (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) be the last point in the last subpath of <var title="">merged
path</var>.</li>

<li><p>Add all the subpaths in <var title="">merged path</var> to <var title="">target</var>.</li>

<!--CLEANUP-->
<li><p>Create a new subpath in <var title="">target</var> with (<var title="">x<sub title="">final</sub></var>, <var title="">y<sub title="">final</sub></var>) as the only point in
the subpath.</li>

</ol></div>
Expand Down

0 comments on commit a8de4c1

Please sign in to comment.