ACTION-3003: Add 'text-overflow' to SVG2.
authorErik Dahlström <ed@opera.com>
Mon, 28 May 2012 17:21:00 +0200
changeset 180 28b8fe41234b
parent 179 53344b6a1a0f
child 181 ccb9d9f77b5c
ACTION-3003: Add 'text-overflow' to SVG2.
master/changes.html
master/definitions.xml
master/images/text/text-overflow-ref.svg
master/images/text/text-overflow.svg
master/text.html
--- a/master/changes.html	Mon May 28 11:07:50 2012 +1000
+++ b/master/changes.html	Mon May 28 17:21:00 2012 +0200
@@ -52,6 +52,9 @@
 <ul>
   <li>Added a number of missing attributes to the element summary boxes of the
   <a>'text'</a>, <a>'textPath'</a> and <a>'tref'</a> elements.</li>
+  
+  <li>Added <a>'text/width'</a> attribute to <a>'text'</a>, and a 
+  section about <a>'text-overflow'</a> processing.</li>
 </ul>
 
 <h3 id="painting">Painting chapter</h3>
--- a/master/definitions.xml	Mon May 28 11:07:50 2012 +1000
+++ b/master/definitions.xml	Mon May 28 17:21:00 2012 +0200
@@ -984,6 +984,7 @@
     <attribute name='dy' href='text.html#TextElementDYAttribute' animatable='yes'/>
     <attribute name='rotate' href='text.html#TextElementRotateAttribute' animatable='yes'/>
     <attribute name='textLength' href='text.html#TextElementTextLengthAttribute' animatable='yes'/>
+    <attribute name='width' href='text.html#TextElementWidthAttribute' animatable='yes'/>
   </element>
 
   <element
@@ -1114,6 +1115,9 @@
   <attribute name='textLength' elements='textPath, tref, tspan' href='text.html#TSpanElementTextLengthAttribute' animatable='yes'/>
   <attribute name='lengthAdjust' elements='text, textPath, tref, tspan' href='text.html#TextElementLengthAdjustAttribute' animatable='yes'/>
 
+  <!-- attribute common to text content block elements -->
+  <!-- <attribute name='width' elements='text' href='text.html#TextElementWidthAttribute' animatable='yes'/> -->
+
   <!-- xlink:show and xlink:actuate for all elements supporting the XLink attributes, except a -->
   <attribute name='xlink:show' elements='animate, set, animateMotion, mpath, animateColor, animateTransform, color-profile, filter, feImage, font-face-uri, cursor, pattern, script, use, image, altGlyph, glyphRef' href='linking.html#XLinkShowAttribute'/>
   <attribute name='xlink:actuate' elements='animate, set, animateMotion, mpath, animateColor, animateTransform, color-profile, filter, feImage, font-face-uri, cursor, pattern, script, use, image, altGlyph, glyphRef' href='linking.html#XLinkActuateAttribute'/>
@@ -1156,7 +1160,7 @@
   <attributecategory
     name='presentation'
     href='intro.html#TermPresentationAttribute'
-    presentationattributes='alignment-baseline, baseline-shift, clip, clip-path, clip-rule, color, color-interpolation, color-interpolation-filters, color-profile, color-rendering, cursor, direction, display, dominant-baseline, enable-background, fill, fill-opacity, fill-rule, filter, flood-color, flood-opacity, font-family, font-size, font-size-adjust, font-stretch, font-style, font-variant, font-weight, glyph-orientation-horizontal, glyph-orientation-vertical, image-rendering, kerning, letter-spacing, lighting-color, marker-end, marker-mid, marker-start, mask, opacity, overflow, pointer-events, shape-rendering, solid-color, solid-opacity, stop-color, stop-opacity, stroke, stroke-dasharray, stroke-dashoffset, stroke-linecap, stroke-linejoin, stroke-miterlimit, stroke-opacity, stroke-width, text-anchor, text-decoration, text-rendering, unicode-bidi, visibility, word-spacing, writing-mode'/>
+    presentationattributes='alignment-baseline, baseline-shift, clip, clip-path, clip-rule, color, color-interpolation, color-interpolation-filters, color-profile, color-rendering, cursor, direction, display, dominant-baseline, enable-background, fill, fill-opacity, fill-rule, filter, flood-color, flood-opacity, font-family, font-size, font-size-adjust, font-stretch, font-style, font-variant, font-weight, glyph-orientation-horizontal, glyph-orientation-vertical, image-rendering, kerning, letter-spacing, lighting-color, marker-end, marker-mid, marker-start, mask, opacity, overflow, pointer-events, shape-rendering, solid-color, solid-opacity, stop-color, stop-opacity, stroke, stroke-dasharray, stroke-dashoffset, stroke-linecap, stroke-linejoin, stroke-miterlimit, stroke-opacity, stroke-width, text-anchor, text-decoration, text-overflow, text-rendering, unicode-bidi, visibility, word-spacing, writing-mode'/>
 
   <attributecategory
       name='document event'
@@ -1338,6 +1342,7 @@
 
   <property name='display' href='painting.html#VisibilityControl'/>
   <property name='visibility' href='painting.html#VisibilityControl'/>
+  <property name='text-overflow' href='text.html#TextOverflowProcessing'/>
 
   <!-- ... interfaces ..................................................... -->
 
@@ -1568,6 +1573,7 @@
   <term name='stroked' href='intro.html#TermStroke'/>
   <term name='structural elements' href='intro.html#TermStructuralElement'/>
   <term name='text content block element' href='intro.html#TermTextContentBlockElement'/>
+  <term name='text content block elements' href='intro.html#TermTextContentBlockElement'/>
   <term name='text content element' href='intro.html#TermTextContentElement'/>
   <term name='text content elements' href='intro.html#TermTextContentElement'/>
   <term name='text content child element' href='intro.html#TermTextContentChildElement'/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/master/images/text/text-overflow-ref.svg	Mon May 28 17:21:00 2012 +0200
@@ -0,0 +1,34 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="180" height="120" viewBox="0 0 180 120">
+	<style>
+	  text { font: 16px sans-serif; }
+	  rect { fill: none; stroke: black; vector-effect: non-scaling-stroke; stroke-width: 1; }
+	</style>
+
+	<g>
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<text x="20" y="2em">SVG is awesome</text>
+	</g>
+
+	<g transform="translate(0,30)">
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<text x="20" y="2em">SVG is awesome</text>
+	</g>
+
+<!--
+  This illustrates a possible way to interpret the above.
+	<g transform="translate(0,30)">
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<clipPath id="clip" clipPathUnits="userSpaceOnUse">
+			<rect x="20" y="16" height="20" width="100" style="fill:black"/>
+		</clipPath>
+		<text x="20" y="2em" width="100" text-overflow="clip" clip-path="url(#clip)">SVG is awesome</text>
+	</g>
+-->
+
+	<g transform="translate(0,60)">
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<text x="20" y="2em" width="100" text-overflow="ellipsis">SVG is aw…</text>
+	</g>
+
+</svg>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/master/images/text/text-overflow.svg	Mon May 28 17:21:00 2012 +0200
@@ -0,0 +1,34 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="180" height="120" viewBox="0 0 180 120">
+	<style>
+	  text { font: 16px sans-serif; }
+	  rect { fill: none; stroke: black; vector-effect: non-scaling-stroke; stroke-width: 1; }
+	</style>
+
+	<g>
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<text x="20" y="2em" width="100">SVG is awesome</text>
+	</g>
+
+	<g transform="translate(0,30)">
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<text x="20" y="2em" width="100" text-overflow="clip">SVG is awesome</text>
+	</g>
+
+<!--
+  This illustrates a possible way to interpret the above.
+	<g transform="translate(0,30)">
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<clipPath id="clip" clipPathUnits="userSpaceOnUse">
+			<rect x="20" y="16" height="20" width="100" style="fill:black"/>
+		</clipPath>
+		<text x="20" y="2em" width="100" text-overflow="clip" clip-path="url(#clip)">SVG is awesome</text>
+	</g>
+-->
+
+	<g transform="translate(0,60)">
+		<rect x="19.5" y="16.5" width="100" height="20"/>
+		<text x="20" y="2em" width="100" text-overflow="ellipsis">SVG is awesome</text>
+	</g>
+
+</svg>
--- a/master/text.html	Mon May 28 11:07:50 2012 +1000
+++ b/master/text.html	Mon May 28 17:21:00 2012 +0200
@@ -619,6 +619,26 @@
          <span class="anim-target"><a
         href="animate.html#Animatable">Animatable</a>:
         yes.</span></dd>
+        
+        <dl class="ready-for-wg-review">
+        <dt id="TextElementWidthAttribute"><span
+        class="adef">width</span> = "<span class="attr-value"><a
+        href="types.html#DataTypeLength">&lt;length&gt;</a></span>"</dt>
+        <dd>Indicates the maximum length that the text is allowed to have 
+        before being subject to <a>'text-overflow'</a> handling.
+        Whenever the sum of advances (including properties <a>'kerning'</a>, <a>'letter-spacing'</a> and <a>'word-spacing'</a> and 
+        adjustments due to attributes <a>'dx'</a> and <a>'dy'</a> on <a>'tspan'</a> elements) computed by the user agent exceeds 
+        the given width the <a>'text'</a> element is subject to <a>'text-overflow'</a> processing.
+        <p>The given width does not affect SVG DOM methods for measuring text, but
+        does affect the boundingbox of the element.
+        </p>
+        <br />
+        The lacuna value for <a>'width'</a> is as if the attribute wasn't specified.
+        <br />
+         <span class="anim-target"><a
+        href="animate.html#Animatable">Animatable</a>:
+        yes.</span></dd>
+        </dl>
       </dl>
     </div>
     <p id="ExampleText01"><span class="example-ref">Example text01</span> below
@@ -1957,6 +1977,76 @@
 and <a>'stroke'</a> properties) before the
 next glyph gets rendered.</p>
 
+<div class="ready-for-wg-review">
+<h3 id='TextOverflowProcessing'>Text overflow processing</h3>
+
+<p class="note">See the CSS3 UI specification for the definition
+of <a href="http://www.w3.org/TR/2012/WD-css3-ui-20120117/#text-overflow">'text-overflow'</a>.
+[<a href="refs.html#ref-CSS3UI">CSS3UI</a>]</p>
+
+<p>SVG uses the <a>'text-overflow'</a> property to control how <a>text content block elements</a>
+render when the text overflows a specified <a>'width'</a>.
+</p>
+
+<p>When applied to a <a>text content block element</a> setting <a>'text-overflow'</a> to
+<span class="attr-value">ellipsis</span> then if the text that is to be rendered
+overflows the specified <a>'width'</a> an ellipsis is rendered such that it fits
+within the given width. For the purposes of rendering the ellipsis is treated as if it replaced the characters at
+the point where it is inserted. The text positioning attributes 
+(<a>'text/x'</a>, <a>'text/y'</a>, <a>'text/dx'</a>, <a>'text/dy'</a>, <a>'text/rotate'</a>) apply to the ellipsis
+as if it was one character in the logical document order mapping to one glyph.
+In SVG <a>'text-overflow'</a> has an effect if there is a validly specified <a>'text/width'</a> attribute, regardless of the
+computed value of the <a>'overflow'</a> property on the <a>text content block element</a>.
+</p>
+
+<p>Any other value for <a>'text-overflow'</a> is treated as if it wasn't specified.</p>
+
+<p class="issue">SVG could allow the keyword 'clip' to work too. It's already possible to do clipping with clip-path, 
+but it's unconditional, where this would theoretically only clip if the text overflowed. It's mostly a convenient shorthand.</p>
+
+<p>Note that the effect of <a>'text-overflow'</a> is purely visual, the ellipsis itself does not become part of the DOM.
+For all the DOM methods it's as if <a>'text-overflow'</a> wasn't applied, and as if <a>'text/width'</a> didn't constrain the text. 
+</p>
+
+<div class="example">
+  <p>The following example shows the use of <a>'text-overflow'</a>. 
+  The top line shows text as it would normally be rendered, without any width restriction.
+  The middle line shows text with text-overflow=clip specified, and the bottom line shows
+  text with text-overflow=ellipsis.</p>
+
+  <pre><![CDATA[
+<svg xmlns="http://www.w3.org/2000/svg"
+     width="180" height="120" viewBox="0 0 180 120">
+  <style>
+    text { font: 16px sans-serif; }
+    rect { fill: none; stroke: black; vector-effect: non-scaling-stroke; stroke-width: 1; }
+  </style>
+
+  <g>
+    <rect x="19.5" y="16.5" width="100" height="20"/>
+    <text x="20" y="2em" width="100">SVG is awesome</text>
+  </g>
+
+  <g transform="translate(0,30)">
+    <rect x="19.5" y="16.5" width="100" height="20"/>
+    <text x="20" y="2em" width="100" text-overflow="clip">SVG is awesome</text>
+  </g>
+
+  <g transform="translate(0,60)">
+    <rect x="19.5" y="16.5" width="100" height="20"/>
+    <text x="20" y="2em" width="100" text-overflow="ellipsis">SVG is awesome</text>
+  </g>
+</svg>
+]]></pre>
+
+  <div class="figure">
+    <img class="bordered" src="images/text/text-overflow-ref.svg"/>
+    <p class="caption">The <a>'text-overflow'</a> property used on text elements, the bottom line showing text with an ellipsis applied.</p>
+  </div>
+</div>
+
+</div>
+
 <h2 id='AlignmentProperties'>Alignment properties</h2>
 
 <h3 id='TextAlignmentProperties'>Text alignment properties</h3>