svg2: Removed getStrokeBBox() and extended getBBox() with its functio...

details:   https://svgwg.org/hg/svg2/rev/c144d4186eeb
branches:  
changeset: 599:c144d4186eeb
user:      Cameron McCormack <cam@mcc.id.au>
date:      Tue Feb 04 15:03:33 2014 +1100
description:
Removed getStrokeBBox() and extended getBBox() with its functionality (plus more). (ACTION-3581)

diffstat:

 master/changes.html          |    5 +-
 master/coords.html           |  111 +++++++++++++++++++++++++++++++++++++++++++
 master/style/default_svg.css |    9 +++
 master/types.html            |   53 +++++++------------
 4 files changed, 144 insertions(+), 34 deletions(-)

diffs (332 lines):

diff --git a/master/changes.html b/master/changes.html
--- a/master/changes.html
+++ b/master/changes.html
@@ -72,29 +72,31 @@ have been made.</p>
   <li>Added an <a>SVGGraphicsElement</a> interface.</li>
 
   <li>Added an <a>SVGGeometryElement</a> interface with isPointInFill and isPointInStroke methods.</li>
 
   <li>Removed the SVGExternalResourcesRequired interface.</li>
 
   <li>Added constructors to <a>SVGNumber</a>, <a>SVGLength</a>, <a>SVGAngle</a> and <a>SVGRect</a>.</li>
 
-  <li>Added <a href="types.html#__svg__SVGGraphicsElement__getStrokeBBox">getStrokeBBox</a> to get the tight stroke bounding box.</li>
+  <li>Added getStrokeBBox on <a>SVGGraphicsElement</a> to get the tight stroke bounding box.</li>
 
   <li>Added base value accessors on <a>SVGAnimatedLength</a> and <a>SVGAnimatedLengthList</a> for each of the CSS length units supported.</li>
 
   <li>Make viewportElement and ownerSVGElement on <a>SVGElement</a> nullable.</li>
 
   <li>Removed the getPresentationAttribute operation on <a>SVGElement</a> and the SVGColor and SVGICCColor interfaces.</li>
 
   <li class='added-since-last-wd'>Added <a href="types.html#__svg__SVGElement__focus">focus</a> and <a href="types.html#__svg__SVGElement__blur">blur</a> operations and <a href='types.html#__svg__SVGElement__tabIndex'>tabIndex</a> attribute to <a>SVGElement</a>.</li>
 
   <li class='added-since-last-wd'>Added <a href="types.html#__svg__SVGDocument__activeElement">activeElement</a> attribute to <a>Document</a>.</li>
 
   <li class='added-since-last-wd'>Made <a>SVGElement</a> implement the <a>GlobalEventHandlers</a> interface from HTML.</li>
+
+  <li class='added-since-last-wd'>Removed getStrokeBBox from <a>SVGGraphicsElement</a> and extended <a href="types.html#__svg__SVGGraphicsElement__getBBox">getBBox</a> with a dictionary argument that controls which parts of the element are included in the returned bounding box.</li>
 </ul>
 
 <h3 id="structure">Document Structure chapter</h3>
 
 <ul>
   <li>Deprecated the <code>suspendRedraw</code>, <code>unsuspendRedraw</code> and <code>unsuspendRedrawAll</code> methods in the SVGSVGElement interface.</li>
 
   <li>Removed the <span class="attr-name">'externalResourcesRequired'</span> attribute.</li>
@@ -124,16 +126,17 @@ have been made.</p>
   <li>Removed the <span class="attr-name">'contentStyleType'</span> attribute.</li>
 </ul>
 
 <h3 id="coords">Coordinate Systems, Transformations and Units chapter</h3>
 
 <ul>
   <li>Added constructors to <a>SVGPoint</a>, <a>SVGMatrix</a> and <a>SVGTransform</a>.</li>
   <li>Make <a>SVGMatrix</a>.skew{X,Y} throw an exception on bad values.</li>
+  <li class='added-since-last-wd'>Added an algorithm which can compute a bounding box for an element.</li>
 </ul>
 
 <h3 id="paths">Paths chapter</h3>
 
 <ul>
   <li class="added-since-last-wd">Added new <strong>B</strong> and
   <strong>b</strong> "bearing" path commands.</li>
 </ul>
diff --git a/master/coords.html b/master/coords.html
--- a/master/coords.html
+++ b/master/coords.html
@@ -1024,26 +1024,137 @@ size as the middle rectangle, which is s
 user units. In particular, note that the <a>'stroke-width'</a> property in the
 middle rectangle is set to 1% of the
 <code>sqrt((<em>actual-width</em>)**2 +
 (<em>actual-height</em>)**2) / sqrt(2)</code>, which in this
 case is .01*sqrt(4000*4000+2000*2000)/sqrt(2), or 31.62. The
 bottom rectangle of the group illustrates what happens when
 values specified in percentage units are scaled.</p>
 
+<div class="ready-for-wg-review">
+
+<h2 id="BoundingBoxes">Bounding boxes</h2>
+
+<p>The bounding box of an element is an axis-aligned rectangle in a given
+coordinate system that tightly contains certain parts of the element.
+The following algorithm describes how to compute the bounding box for a
+given element.  The inputs to the algorithm are:</p>
+
+<ul>
+  <li><var>element</var>, the element we are computing a bounding box for;</li>
+  <li><var>space</var>, a coordinate space in which the bounding box will be computed;</li>
+  <li><var>fill</var>, a boolean indicating whether the bounding box includes the geometry of the element and its descendants;</li>
+  <li><var>stroke</var>, a boolean indicating whether the bounding box includes the stroke of the element and its descendants;</li>
+  <li><var>markers</var>, a boolean indicating whether the bounding box includes the markers of the element and its descendants; and</li>
+  <li><var>clipped</var>, a boolean indicating whether the bounding box is affected by any clipping paths applied to the element and its descendants.</li>
+</ul>
+
+<p class='issue'>Need to define what the union of rectangles with no area means.</p>
+
+<p>The algorithm to compute the bounding box is as follows, depending on the type of <var>element</var>:</p>
+
+<dl class="switch">
+  <dt>a <a>shape</a></dt>
+  <dt>a <a>text content element</a></dt>
+  <dt>an <a>'a'</a> element within a <a>text content element</a></dt>
+  <dd>
+    <ol class="algorithm">
+      <li>Let <var>box</var> be a rectangle initialized to (0, 0, 0, 0).</li>
+      <li>Let <var>fill-shape</var> be the <a>equivalent path</a> of <var>element</var>
+      if it is a <a>shape</a>, or a shape that includes each of the glyph cells corresponding
+      to the text within the elements otherwise.</li>
+      <li>If <var>fill</var> is true, then set <var>box</var> to the tightest rectangle
+      in the coordinate system <var>space</var> that contains <var>fill-shape</var>.
+      <p class='issue'>We should say something about allowed approximations such as using the bounding
+      box of a Bézier segment's control points.</p></li>
+      <li>If <var>stroke</var> is true and the element's <a>'stroke'</a> is anything other than
+      <span class='prop-value'>none</span>, then set <var>box</var> to be the union of <var>box</var> and the
+      tightest rectangle in coordinate system <var>space</var> that contains the <a href="painting.html#StrokeShape">stroke shape</a> of the
+      element, with the assumption that the element has no dash pattern.</li>
+      <li>If <var>markers</var> is true, then for each marker <var>marker</var> rendered on the element:
+        <ol>
+          <li>For each descendant <a>graphics element</a> <var>child</var> of the <a>'marker element'</a> element
+          that defines <var>marker</var>'s content:
+            <ol>
+              <li>If <var>child</var> has an ancestor element within the <a>'marker element'</a> that is
+              <span class='prop-value'>'display: none'</span>, has a failing <a>conditional processing attribute</a>,
+              or is not an <a>'a'</a>, <a>'g'</a>, <a>'svg'</a> or <a>'switch'</a> element, then
+              continue to the next descendant <a>graphics element</a>.</li>
+              <li>Otherwise, set <var>box</var> to be the union of <var>box</var> and the result of invoking the
+              algorithm to compute a bounding box with <var>child</var> as the element,
+              <var>space</var> as the target coordinate space, true for <var>fill</var>,
+              <var>stroke</var> and <var>markers</var>, and <var>clipped</var> for <var>clipped</var>.
+              <p class='issue'>Need to determine whether <span class='prop-value'>'display: none'</span> on the
+              <a>'marker element'</a> element itself has any effect here.</p></li>
+            </ol>
+          </li>
+        </ol>
+      </li>
+      <li>If <var>clipped</var> is true and the value of <a>'clip-path'</a> on <var>element</var> is not
+      <span class='prop-value'>none</span>, then set <var>box</var> to be the tighest rectangle
+      in coordinate system <var>space</var> that contains the intersection of <var>box</var> and the clipping path.</li>
+      <li>Return <var>box</var>.</li>
+    </ol>
+  </dd>
+  <dt>a <a>container element</a></dt>
+  <dt><a>'use'</a></dt>
+  <dd>
+    <ol class="algorithm">
+      <li>Let <var>box</var> be a rectangle initialized to (0, 0, 0, 0).</li>
+      <li>Let <var>parent</var> be the <a>container element</a> if it is one, or the
+      root of the <a>'use'</a> element's shadow tree otherwise.</li>
+      <li>For each descendant <a>graphics element</a> <var>child</var> of <var>parent</var>:
+        <ol>
+          <li>If <var>child</var> has an ancestor element within <var>parent</var> that is
+          <span class='prop-value'>'display: none'</span>, has a failing <a>conditional processing attribute</a>,
+          or is not an <a>'a'</a>, <a>'g'</a>, <a>'svg'</a> or <a>'switch'</a> element, then
+          continue to the next descendant <a>graphics element</a>.</li>
+          <li>Otherwise, set <var>box</var> to be the union of <var>box</var> and the result of invoking the
+          algorithm to compute a bounding box with <var>child</var> as the element
+          and the same values for <var>space</var>, <var>fill</var>, <var>stroke</var>,
+          <var>markers</var> and <var>clipped</var> as the corresponding algorithm input values.</li>
+        </ol>
+      </li>
+      <li>Return <var>box</var>.</li>
+    </ol>
+  </dd>
+  <dt><a>'canvas'</a></dt>
+  <dt><a>'foreignObject'</a></dt>
+  <dt><a>'iframe'</a></dt>
+  <dt><a>'image'</a></dt>
+  <dt><a>'video'</a></dt>
+  <dd>
+    <ol class="algorithm">
+      <li>Return the tightest rectangle in coordinate space <var>space</var> that
+      contains the rectangle defined by the 
+      <span class='attr-name'>'x'</span>,
+      <span class='attr-name'>'y'</span>,
+      <span class='attr-name'>'width'</span> and
+      <span class='attr-name'>'height'</span> attributes of the element.
+      <p class='issue'>This returns a bounding box even if <var>fill</var> is false. Is this what we want?</p>
+      </li>
+    </ol>
+  </dd>
+</dl>
+
+</div>
+
 <h2 id="ObjectBoundingBoxUnits">Object bounding box units</h2>
 
 <p id="ObjectBoundingBox">The following elements offer the option of expressing
 coordinate values and lengths as fractions (and, in some cases,
 percentages) of the <a>bounding box</a>,
 by setting a specified attribute to <span class="attr-value">'objectBoundingBox'</span>
 on the given element:</p>
 
 <p class="issue">Need a line for <a>'meshGradient'</a>.</p>
 
+<p class="issue">Need to invoke the bounding box computation algorithm from the previous
+section with <var>fill</var> = true and the other options false.</p>
+
 <table class='vert'>
   <tr>
     <th>Element</th>
     <th>Attribute</th>
     <th>Effect</th>
   </tr>
   <tr>
     <edit:with element='linearGradient'>
diff --git a/master/style/default_svg.css b/master/style/default_svg.css
--- a/master/style/default_svg.css
+++ b/master/style/default_svg.css
@@ -374,16 +374,25 @@ table.propdef.attrdef th:first-child + t
 table.propdef.attrdef td:first-child + td { width: auto }
 
 table.propdef.attrdef th:first-child + th + th,
 table.propdef.attrdef td:first-child + td + td { width: 6em }
 
 table.propdef.attrdef th:first-child + th + th + th,
 table.propdef.attrdef td:first-child + td + td + td { width: 6em; padding-right: 0 !important }
 
+ol.algorithm ol {
+  border-left: 1px solid #90b8de;
+  margin-left: 1em;
+}
+ol.algorithm ol.algorithm {
+  border-left: none;
+  margin-left: 0;
+}
+
 /* HTML5-like switch statements. */
 dl.switch > dd > ol.only {
   margin-left: 0;
 }
 dl.switch > dd > ol.algorithm {
   margin-left: -2em;
 }
 dl.switch {
diff --git a/master/types.html b/master/types.html
--- a/master/types.html
+++ b/master/types.html
@@ -4012,24 +4012,30 @@ Corresponds to value <span class="attr-v
   </table>
 </div>
 
 <p>Interface <a>SVGGraphicsElement</a> represents SVG elements whose primary purpose
 is to directly render graphics into a group. The
 <a>'transform'</a> property applies to all <a>SVGGraphicsElement</a>. All <a>SVGGraphicsElement</a>
 have a bounding box in current user space.</p>
 
-<pre class="idl">interface <b>SVGGraphicsElement</b> : <a>SVGElement</a> {
+<pre class="idl">dictionary <b id="SVGBoundingBoxOptions">SVGBoundingBoxOptions</b> {
+  bool fill = true;
+  bool stroke = false;
+  bool markers = false;
+  bool clipped = false;
+};
+
+interface <b>SVGGraphicsElement</b> : <a>SVGElement</a> {
   readonly attribute <a class="idlinterface" href="coords.html#InterfaceSVGAnimatedTransformList">SVGAnimatedTransformList</a> <a href="types.html#__svg__SVGGraphicsElement__transform">transform</a>;
 
   readonly attribute <a class="idlinterface" href="types.html#InterfaceSVGElement">SVGElement</a>? <a href="types.html#__svg__SVGGraphicsElement__nearestViewportElement">nearestViewportElement</a>;
   readonly attribute <a class="idlinterface" href="types.html#InterfaceSVGElement">SVGElement</a>? <a href="types.html#__svg__SVGGraphicsElement__farthestViewportElement">farthestViewportElement</a>;
 
-  <a class="idlinterface" href="types.html#InterfaceSVGRect">SVGRect</a> <a href="types.html#__svg__SVGGraphicsElement__getBBox">getBBox</a>();
-  <a class="idlinterface" href="types.html#InterfaceSVGRect">SVGRect</a> <a href="types.html#__svg__SVGGraphicsElement__getStrokeBBox">getStrokeBBox</a>();
+  <a class="idlinterface" href="types.html#InterfaceSVGRect">SVGRect</a> <a href="types.html#__svg__SVGGraphicsElement__getBBox">getBBox</a>(optional <a href="#SVGBoundingBoxOptions">SVGBoundingBoxOptions</a> options);
   <a class="idlinterface" href="coords.html#InterfaceSVGMatrix">SVGMatrix</a>? <a href="types.html#__svg__SVGGraphicsElement__getCTM">getCTM</a>();
   <a class="idlinterface" href="coords.html#InterfaceSVGMatrix">SVGMatrix</a>? <a href="types.html#__svg__SVGGraphicsElement__getScreenCTM">getScreenCTM</a>();
   <a class="idlinterface" href="coords.html#InterfaceSVGMatrix">SVGMatrix</a> <a href="types.html#__svg__SVGGraphicsElement__getTransformToElement">getTransformToElement</a>(<a class="idlinterface" href="types.html#InterfaceSVGGraphicsElement">SVGGraphicsElement</a> element);
 };
 
 <a>SVGGraphicsElement</a> implements <a>SVGTests</a>;</pre>
 
 <dl class="interface">
@@ -4058,59 +4064,40 @@ have a bounding box in current user spac
           The farthest ancestor <a>'svg'</a> element. Null if the current element
           is the <a>outermost svg element</a>.
         </div>
       </dd>
     </dl>
   </dd>
   <dt class="operations-header">Operations:</dt>
   <dd>
+    <div class="ready-for-wg-review">
     <dl class="attributes">
-      <dt id="__svg__SVGGraphicsElement__getBBox" class="operation first-child"><a class="idlinterface" href="types.html#InterfaceSVGRect">SVGRect</a> <b>getBBox</b>()</dt>
+      <dt id="__svg__SVGGraphicsElement__getBBox" class="operation first-child"><a class="idlinterface" href="types.html#InterfaceSVGRect">SVGRect</a> <b>getBBox</b>(optional <a href="#SVGBoundingBoxOptions">SVGBoundingBoxOptions</a> <var>options</var>)</dt>
       <dd class="operation">
         <div>
-          Returns the tight bounding box in current user space (i.e., after
-          application of the <a>'transform'</a> property) on the
-          geometry of all contained graphics elements, exclusive of stroking, clipping, masking and
-          filter effects. Note that getBBox must return the actual bounding box
-          at the time the method was called, even in case the element has not
-          yet been rendered.
+          <p>Returns the result of invoking the <a href="coords.html#BoundingBoxes">bounding box algorithm</a>
+          for the element, with <var>fill</var>, <var>stroke</var>, <var>markers</var>
+          and <var>clipped</var> members of the <var>options</var> dictionary argument
+          used to control which parts of the element are included in the bounding box,
+	  using the element's user space as the coordinate system to return the
+	  bounding box in.</p>
         </div>
         <dl class="operation">
           <dt class="returns-header">Returns</dt>
           <dd>
             <div>
               An <a>SVGRect</a> object that defines the bounding box.
             </div>
           </dd>
         </dl>
       </dd>
-      <dt id="__svg__SVGGraphicsElement__getStrokeBBox" class="operation"><a class="idlinterface" href="types.html#InterfaceSVGRect">SVGRect</a> <b>getStrokeBBox</b>()</dt>
-      <dd class="operation">
-        <div>
-          Returns the union of the tight bounding box (see <a>getBBox</a>), the stroke
-          bounding box and the stroke bounding box of applied markers in current user space
-          (i.e., after application of the <a>'transform'</a> property) on the
-          geometry of all contained graphics elements, exclusive of clipping, masking and
-          filter effects. The stroke bounding box takes the stroke style
-          properties <a>'stroke-width'</a>, <a>'stroke-linecap'</a>, <a>'stroke-linejoin'</a>,
-          <a>'stroke-miterlimit'</a>, <a>'stroke-dasharray'</a> and <a>'stroke-dashoffset'</a>
-          into account. Note that getStrokeBBox must
-          return the actual union of the bounding box at the time the method was called,
-          even in case the element has not yet been rendered.
-        </div>
-        <dl class="operation">
-          <dt class="returns-header">Returns</dt>
-          <dd>
-            <div>
-              An <a>SVGRect</a> object that defines the stroke bounding box.
-            </div>
-          </dd>
-        </dl>
-      </dd>
+    </dl>
+    </div>
+    <dl class="attributes">
       <dt id="__svg__SVGGraphicsElement__getCTM" class="operation"><a class="idlinterface" href="coords.html#InterfaceSVGMatrix">SVGMatrix</a>? <b>getCTM</b>()</dt>
       <dd class="operation">
         <div>
           Returns the transformation matrix from current user units (i.e., after
           application of the <a>'transform'</a> property) to the viewport
           coordinate system for the <a>nearestViewportElement</a>. Note that null 
           is returned if this element is not hooked into the document tree.
         </div>

Received on Tuesday, 4 February 2014 04:06:17 UTC