-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend Canvas TextMetrics for editing and text styling #11000
base: main
Are you sure you want to change the base?
Changes from all commits
20e36f8
370fb3c
1f94348
1b9e735
9cab38c
85c06f1
b6a2c7a
6e08c93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4165,6 +4165,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute | |
<dfn data-x="DOMPointInit-x" data-xref="https://drafts.fxtf.org/geometry/#dom-dompointinit-x">x</dfn> and | ||
<dfn data-x="DOMPointInit-y" data-xref="https://drafts.fxtf.org/geometry/#dom-dompointinit-y">y</dfn> members</li> | ||
<li><dfn data-x-href="https://drafts.fxtf.org/geometry/#matrix-multiply">Matrix multiplication</dfn></li> | ||
<li><dfn data-x-href="https://www.w3.org/TR/geometry-1/#DOMRect">DOMRectReadOnly and DOMRect</dfn></li> | ||
</ul> | ||
|
||
<p>The following terms are defined in the <cite>CSS Scoping</cite>: <ref>CSSSCOPING</ref></p> | ||
|
@@ -65501,10 +65502,20 @@ interface mixin <dfn interface>CanvasUserInterface</dfn> { | |
undefined <span data-x="dom-context-2d-drawFocusIfNeeded-path-element">drawFocusIfNeeded</span>(<span>Path2D</span> path, <span>Element</span> element); | ||
}; | ||
|
||
|
||
dictionary <dfn dictionary>TextClusterOptions</dfn> { | ||
<span>CanvasTextAlign</span> align; | ||
<span>CanvasTextBaseline</span> baseline; | ||
double x; | ||
double y; | ||
}; | ||
|
||
interface mixin <dfn interface>CanvasText</dfn> { | ||
// text (see also the <span>CanvasPathDrawingStyles</span> and <span>CanvasTextDrawingStyles</span> interfaces) | ||
undefined <span data-x="dom-context-2d-fillText">fillText</span>(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth); | ||
undefined <span data-x="dom-context-2d-strokeText">strokeText</span>(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth); | ||
undefined <span data-x="dom-context-2d-fillTextCluster">fillTextCluster</span>(<span>TextCluster</span> cluster, double x, double y, optional <span>TextClusterOptions</span> options); | ||
undefined <span data-x="dom-context-2d-strokeTextCluster">strokeTextCluster</span>(<span>TextCluster</span> cluster, double x, double y, optional <span>TextClusterOptions</span> options); | ||
AndresRPerez12 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<span>TextMetrics</span> <span data-x="dom-context-2d-measureText">measureText</span>(DOMString text); | ||
}; | ||
|
||
|
@@ -65604,6 +65615,22 @@ interface <dfn interface>TextMetrics</dfn> { | |
readonly attribute double <span data-x="dom-textmetrics-hangingBaseline">hangingBaseline</span>; | ||
readonly attribute double <span data-x="dom-textmetrics-alphabeticBaseline">alphabeticBaseline</span>; | ||
readonly attribute double <span data-x="dom-textmetrics-ideographicBaseline">ideographicBaseline</span>; | ||
|
||
sequence<<span data-x="DOMRectReadOnly and DOMRect">DOMRectReadOnly</span>> <span data-x="dom-textmetrics-getSelectionRects">getSelectionRects</span>(unsigned long start, unsigned long end); | ||
<span data-x="DOMRectReadOnly and DOMRect">DOMRectReadOnly</span> <span data-x="dom-textmetrics-getActualBoundingBox">getActualBoundingBox</span>(unsigned long start, unsigned long end); | ||
unsigned long <span data-x="dom-textmetrics-getIndexFromOffset">getIndexFromOffset</span>(double offset); | ||
sequence<<span>TextCluster</span>> <span data-x="dom-textmetrics-getTextClusters">getTextClusters</span>(unsigned long start, unsigned long end, optional <span>TextClusterOptions</span> options); | ||
}; | ||
|
||
[Exposed=(Window,Worker)] | ||
interface <dfn interface>TextCluster</dfn> { | ||
// opaque object | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what this comment buys us. |
||
readonly attribute double <span data-x="dom-TextCluster-x">x</span>; | ||
readonly attribute double <span data-x="dom-TextCluster-y">y</span>; | ||
readonly attribute unsigned long <span data-x="dom-TextCluster-begin">begin</span>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sometimes you use "begin" and sometimes "start". That should be made consistent. |
||
readonly attribute unsigned long <span data-x="dom-TextCluster-end">end</span>; | ||
readonly attribute <span>CanvasTextAlign</span> <span data-x="dom-TextCluster-align">align</span>; | ||
readonly attribute <span>CanvasTextBaseline</span> <span data-x="dom-TextCluster-baseline">baseline</span>; | ||
}; | ||
AndresRPerez12 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
dictionary <dfn dictionary>ImageDataSettings</dfn> { | ||
|
@@ -69122,6 +69149,16 @@ try { | |
provided, the text will be scaled to fit that width if necessary.</p> | ||
</dd> | ||
|
||
<dt><code data-x=""><var>context</var>.<span subdfn data-x="dom-context-2d-fillTextCluster">fillTextCluster</span>(<var>cluster</var>, <var>x</var>, <var>y</var> [, <var>options</var> ])</code></dt> | ||
<dt><code data-x=""><var>context</var>.<span subdfn data-x="dom-context-2d-strokeTextCluster">strokeTextCluster</span>(<var>cluster</var>, <var>x</var>, <var>y</var> [, <var>options</var> ])</code></dt> | ||
|
||
<dd> | ||
<p>Fills or strokes (respectively) the given text cluster as it would be positioned if the text | ||
as a whole was rendered at the given position. The align and baseline used to render, as well as | ||
the position of the cluster in relation to the anchor point of the while text, can be modified | ||
with the options dictionary.</p> | ||
</dd> | ||
|
||
<dt><code data-x=""><var>metrics</var> = <var>context</var>.<span subdfn data-x="dom-context-2d-measureText">measureText</span>(<var>text</var>)</code></dt> | ||
|
||
<dd> | ||
|
@@ -69143,6 +69180,27 @@ try { | |
<dt><code data-x=""><var>metrics</var>.<span subdfn data-x="dom-textmetrics-ideographicBaseline">ideographicBaseline</span></code></dt> | ||
|
||
<dd><p>Returns the measurement described below.</p></dd> | ||
|
||
AndresRPerez12 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<dt><code data-x=""><var>metrics</var>.<span subdfn data-x="dom-textmetrics-getSelectionRects">getSelectionRects</span>(<var>start</var>, <var>end</var>)</code></dt> | ||
|
||
<dd><p>Returns a list of <code data-x="DOMRectReadOnly and DOMRect">DOMRectReadOnly</code> objects corresponding to the selection | ||
rectangles for the given range in the string.</p></dd> | ||
|
||
<dt><code data-x=""><var>metrics</var>.<span subdfn data-x="dom-textmetrics-getActualBoundingBox">getActualBoundingBox</span>(<var>start</var>, <var>end</var>)</code></dt> | ||
|
||
<dd><p>Returns a <code data-x="DOMRectReadOnly and DOMRect">DOMRectReadOnly</code> that corresponds to the bounding rectangle for the | ||
given range in the string.</p></dd> | ||
|
||
<dt><code data-x=""><var>metrics</var>.<span subdfn data-x="dom-textmetrics-getIndexFromOffset">getIndexFromOffset</span>(<var>offset</var>)</code></dt> | ||
|
||
<dd><p>Returns the index for the character at the given offset from the start of the text.</p></dd> | ||
|
||
<dt><code data-x=""><var>metrics</var>.<span subdfn data-x="dom-textmetrics-getTextClusters">getTextClusters</span>(<var>start</var>, <var>end</var> [, <var>options</var> ])</code></dt> | ||
|
||
<dd><p>Returns a list of <code>TextCluster</code> objects, with positional data for each one. | ||
They correspond to splitting the text into the minimal rendering units possible. The options | ||
dictionary enables selecting a specific point to be returned for each cluster be specifying align | ||
and baseline values.</p></dd> | ||
</dl> | ||
|
||
<div w-nodev> | ||
|
@@ -69196,6 +69254,77 @@ try { | |
</li> | ||
</ol> | ||
|
||
<p>The <dfn method for="CanvasText"><code | ||
data-x="dom-context-2d-fillTextCluster">fillTextCluster(<var>cluster</var>, <var>x</var>, | ||
<var>y</var>, <var>options</var>)</code></dfn> and <dfn method for="CanvasText"><code | ||
data-x="dom-context-2d-strokeTextCluster">strokeTextCluster(<var>cluster</var>, <var>x</var>, | ||
<var>y</var>, <var>options</var>)</code></dfn> methods render a <code>TextCluster</code> object. | ||
The cluster is rendered where it would be if the whole text that was passed to <code | ||
data-x="dom-context-2d-measureText">measureText()</code> to obtain the cluster was rendered at | ||
position (<var>x</var>,<var>y</var>), unless the positioning is modified with the options | ||
argument. Specifically, when the method is invoked, the user agent must run these steps:</p> | ||
Comment on lines
+69257
to
+69265
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These need to be rephrased to use the modern way of defining methods. "The X method steps are ..." |
||
|
||
<ol> | ||
<li><p>If any of the arguments are infinite or NaN, then return.</p></li> | ||
Comment on lines
+69267
to
+69268
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation and formatting here doesn't appear to follow the guidelines. |
||
|
||
<li><p>Run the <span>text preparation algorithm</span>, passing it the complete text and the | ||
<code>CanvasTextDrawingStyles</code> from the opaque <code>TextCluster</code> | ||
<var>cluster</var>, with the exception of <code | ||
data-x="dom-context-2d-textAlign">textAlign</code> and <code | ||
data-x="dom-context-2d-textBaseline">textBaseline</code>, which are taken from the <code | ||
data-x="dom-TextCluster-align">align</code> and <code | ||
data-x="dom-TextCluster-baseline">baseline</code> attributes of <var>cluster</var>. Let | ||
<var>glyphs</var> be the result.</p></li> | ||
|
||
<li><p>Filter <var>glyphs</var> to include only the glyphs that contain <span | ||
data-x="code point">code points</span> within the range <code | ||
data-x="dom-TextCluster-begin">cluster["begin"]</code> to <code | ||
data-x="dom-TextCluster-end">cluster["end"]</code>.</p></li> | ||
|
||
<li><p>Move all the shapes in <var>glyphs</var> to the right by <var>x</var> | ||
<span data-x="'px'">CSS pixels</span> and down by <var>y</var> <span data-x="'px'">CSS | ||
pixels</span>.</p></li> | ||
|
||
<li> | ||
<p>If a <code>TextClusterOptions</code> options dictionary is passed and it has an <code | ||
data-x="">options["x"]</code> value, move all the shapes in <var>glyphs</var> to the right by | ||
<code data-x="">options["x"] − cluster["x"]</code>.</p> | ||
|
||
<p>If a <code>TextClusterOptions</code> options dictionary is passed and it has an <code | ||
data-x="">options["y"]</code> value, move all the shapes in <var>glyphs</var> down by <code | ||
data-x="">options["y"] − cluster["y"]</code>.</p> | ||
</li> | ||
|
||
<li> | ||
<p>Paint the shapes given in <var>glyphs</var>, as transformed by the <span | ||
data-x="dom-context-2d-transformation">current transformation matrix</span>, with each <span | ||
data-x="'px'">CSS pixel</span> in the coordinate space of <var>glyphs</var> mapped to one | ||
coordinate space unit.</p> | ||
|
||
<p>For <code data-x="dom-context-2d-fillTextCluster">fillTextCluster()</code>, | ||
<span>this</span>'s <span data-x="concept-CanvasFillStrokeStyles-fill-style">fill style</span> | ||
must be applied to the shapes and <span>this</span>'s <span | ||
data-x="concept-CanvasFillStrokeStyles-stroke-style">stroke style</span> must be ignored. For | ||
<code data-x="dom-context-2d-strokeTextCluster">strokeTextCluster()</code>, the reverse holds: | ||
<span>this</span>'s <span data-x="concept-CanvasFillStrokeStyles-stroke-style">stroke | ||
style</span> must be applied to the result of <span data-x="trace a path">tracing</span> the | ||
shapes using the object implementing the <code>CanvasText</code> interface for the line | ||
styles, and <span>this</span>'s <span data-x="concept-CanvasFillStrokeStyles-fill-style">fill | ||
style</span> must be ignored.</p> | ||
|
||
<p>These shapes are painted without affecting the current path, and are subject to <span | ||
data-x="shadows">shadow effects</span>, <span data-x="concept-canvas-global-alpha">global | ||
alpha</span>, the <span>clipping region</span>, and the <span>current compositing and blending | ||
operator</span>.</p> | ||
</li> | ||
</ol> | ||
|
||
<p class="note">By setting <code data-x="">options["x"]</code> and <code | ||
data-x="">options["y"]</code> to 0, the cluster will be rendered exactly at the position | ||
(<var>x</var>,<var>y</var>) passed to <code | ||
data-x="dom-context-2d-fillTextCluster">fillTextCluster()</code> and <code | ||
data-x="dom-context-2d-strokeTextCluster">strokeTextCluster()</code>.</p> | ||
|
||
<p> | ||
<!--INSERT TRACKING--> | ||
The <dfn method for="CanvasText"><code | ||
|
@@ -69327,6 +69456,125 @@ try { | |
positive numbers indicating that the given baseline is below the <span>ideographic-under | ||
baseline</span>. (Zero if the given baseline is the <span>ideographic-under | ||
baseline</span>.)</p></dd> | ||
|
||
<dt><dfn method for="TextMetrics"><code data-x="dom-textmetrics-getSelectionRects">getSelectionRects(<var>start</var>, <var>end</var>)</code></dfn> method</dt> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not follow the bad precedent set of the current set of attributes. Please define these as modern methods. |
||
|
||
<dd><p>Returns the set of rectangles, in <span data-x="'px'">CSS pixels</span>, that the user | ||
agent would render as a selection to select the characters within the specified range. The | ||
range includes the character at the <var>start</var> index but stops before the <var>end</var> | ||
index. The positions are returned relative to the alignment point given by the | ||
<code data-x="dom-context-2d-textAlign">textAlign</code> and <code | ||
data-x="dom-context-2d-textBaseline">textBaseline</code> attributes.</p></dd> | ||
|
||
<dt><dfn method for="TextMetrics"><code data-x="dom-textmetrics-getActualBoundingBox">getActualBoundingBox(<var>start</var>, <var>end</var>)</code></dfn> method</dt> | ||
|
||
<dd> | ||
<p>Returns the rectangle equivalent to the box described by <code | ||
data-x="dom-textmetrics-actualBoundingBoxLeft">actualBoundingBoxLeft</code>, <code | ||
data-x="dom-textmetrics-actualBoundingBoxRight">actualBoundingBoxRight</code>, <code | ||
data-x="dom-textmetrics-actualBoundingBoxAscent">actualBoundingBoxAscent</code>, <code | ||
data-x="dom-textmetrics-actualBoundingBoxDescent">actualBoundingBoxDescent</code>, for the given | ||
range. The range includes the character at the <var>start</var> index but stops before the | ||
<var>end</var> index. The positions are returned relative to the alignment point given by the | ||
<code data-x="dom-context-2d-textAlign">textAlign</code> and <code | ||
data-x="dom-context-2d-textBaseline">textBaseline</code> attributes.</p> | ||
|
||
<p class="note">The bounding box can be (and usually is) different from the selection | ||
rectangles, which are based on the advance of the text. A font that is particularly slanted or | ||
with accents that go beyond the flow of text will have a different paint bounding box.</p> | ||
</dd> | ||
|
||
<dt><dfn method for="TextMetrics"><code data-x="dom-textmetrics-getIndexFromOffset">getIndexFromOffset(<var>offset</var>)</code></dfn> method</dt> | ||
|
||
<dd><p>Returns the string index for the character at the given offset distance from the start | ||
position of the text run, relative to the alignment point given by the <code | ||
data-x="dom-context-2d-textAlign">textAlign</code> attribute, with offset always increasing left | ||
to right (negative offsets are valid). Values to the left or right of the text bounds will return | ||
0 or the length of the text, depending on the writing direction.</p></dd> | ||
|
||
<dt><dfn method for="TextMetrics"><code data-x="dom-textmetrics-getTextClusters">getTextClusters(<var>start</var>, <var>end</var>, <var>options</var>)</code></dfn> method</dt> | ||
|
||
AndresRPerez12 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<dd> | ||
<p>Splits the given range of the text into clusters and returns the positional data for each | ||
cluster. The range includes the character at the <var>start</var> index but stops before the | ||
<var>end</var> index. Each cluster represents a minimal group of characters such that their | ||
corresponding glyphs cannot be broken down any further, and each character in the range is part | ||
of only one cluster. If a cluster is only partially contained by the given character range, it | ||
should still be included in the returned list.</p> | ||
|
||
<p>The result is a list of new <code>TextCluster</code> objects. These objects are opaque as | ||
they encapsulate the complete text that was segmented, along with the | ||
<code>CanvasTextDrawingStyles</code> values that were active at the time <code | ||
data-x="dom-context-2d-measureText">measureText()</code> was called. Note that <code | ||
data-x="dom-context-2d-textAlign">textAlign</code> and <code | ||
data-x="dom-context-2d-textBaseline">textBaseline</code> are exceptions, as they are explicitly | ||
set attributes and are handled separately. Each <code>TextCluster</code> object has members | ||
AndresRPerez12 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
behaving as described in the following list:</p> | ||
|
||
<dl> | ||
<dt><dfn attribute for="TextCluster"><code data-x="dom-TextCluster-x">x</code></dfn> attribute</dt> | ||
|
||
<dd> | ||
<p>The x coordinate of the cluster, on a coordinate space using <span | ||
data-x="'px'">CSS pixels</span>, with its origin at the anchor point defined by the <code | ||
data-x="dom-context-2d-textAlign">textAlign</code> attribute (at the time <code | ||
data-x="dom-context-2d-measureText">measureText()</code> was called) in relation to the text | ||
as a whole.</p> | ||
|
||
<p>The x position specified for each cluster corresponds to the alignment point given by the | ||
<code data-x="dom-TextCluster-align">align</code> attribute of the cluster (e.g. if | ||
this attribute is set to "<code data-x="">left</code>", the calculated position corresponds | ||
to the <code data-x="dom-context-2d-textAlign-left">left</code> of each cluster). The | ||
selection criteria for this alignment point is explained in the section for this attribute | ||
of the cluster.</p> | ||
</dd> | ||
|
||
<dt><dfn attribute for="TextCluster"><code data-x="dom-TextCluster-y">y</code></dfn> attribute</dt> | ||
|
||
<dd> | ||
<p>The y coordinate of the cluster, on a coordinate space using <span | ||
data-x="'px'">CSS pixels</span>, with its origin at the anchor point defined by the <code | ||
data-x="dom-context-2d-textBaseline">textBaseline</code> attribute (at the time <code | ||
data-x="dom-context-2d-measureText">measureText()</code> was called) in relation to the text | ||
as a whole.</p> | ||
|
||
<p>The y position specified for each cluster corresponds to the alignment point given by the | ||
<code data-x="dom-TextCluster-baseline">baseline</code> attribute of the cluster (e.g. if | ||
this attribute is set to "<code data-x="">top</code>", the calculated position corresponds | ||
to the <code data-x="dom-context-2d-textBaseline-top">top</code> of each cluster). The | ||
selection criteria for this alignment point is explained in the section for this attribute | ||
of the cluster.</p> | ||
</dd> | ||
|
||
<dt><dfn attribute for="TextCluster"><code data-x="dom-TextCluster-begin">begin</code></dfn> attribute</dt> | ||
|
||
<dd><p>The starting index for the range of <span data-x="code point">code points</span> that are | ||
rendered as this cluster.</p></dd> | ||
|
||
<dt><dfn attribute for="TextCluster"><code data-x="dom-TextCluster-end">end</code></dfn> attribute</dt> | ||
|
||
<dd><p>The index immediately after the last included index for the range of <span | ||
data-x="code point">code points</span> that are rendered as this cluster.</p></dd> | ||
|
||
<dt><dfn attribute for="TextCluster"><code data-x="dom-TextCluster-align">align</code></dfn> attribute</dt> | ||
|
||
<dd><p>The align for the specific point returned for the cluster. If a | ||
<code>TextClusterOptions</code> options dictionary is passed, and it has a value for | ||
<code data-x="">options["align"]</code>, this will be the assigned value. Otherwise, it will be | ||
set as the <code data-x="dom-context-2d-textAlign">textAlign</code> attribute. Note that this | ||
doesn't change the origin of the coordinate system, just which point is specified for each | ||
cluster.</p></dd> | ||
|
||
<dt><dfn attribute for="TextCluster"><code data-x="dom-TextCluster-baseline">baseline</code></dfn> attribute</dt> | ||
|
||
<dd><p>The baseline for the specific point returned for the cluster. If a | ||
<code>TextClusterOptions</code> options dictionary is passed, and it has a value for | ||
<code data-x="">options["baseline"]</code>, this will be the assigned value. Otherwise, it will | ||
be set as the <code data-x="dom-context-2d-textBaseline">textBaseline</code> attribute. Note | ||
that this doesn't change the origin of the coordinate system, just which point is specified | ||
for each cluster.</p></dd> | ||
</dl> | ||
</dd> | ||
</dl> | ||
|
||
<p class="note">Glyphs rendered using <code data-x="dom-context-2d-fillText">fillText()</code> and | ||
|
@@ -69339,8 +69587,6 @@ try { | |
documents, rendered using CSS, straight to the canvas. This would be provided in preference to a | ||
dedicated way of doing multiline layout.</p> | ||
|
||
|
||
|
||
<h6>Drawing paths to the canvas</h6> | ||
|
||
<p>Objects that implement the <code>CanvasDrawPath</code> interface have a <dfn>current default | ||
|
@@ -146080,6 +146326,7 @@ INSERT INTERFACES HERE | |
Andreas Kling, | ||
Andrei Popescu, | ||
Andres Gomez, | ||
Andrés Ricardo Pérez Rojas, | ||
Andres Rios, | ||
Andreu Botella, | ||
Andrew Barfield, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each needs its own reference.