W3C home > Mailing lists > Public > www-svg@w3.org > May 2003

RE: SVG 1.2 Working Draft: Comments on 3.2.7 Expression-based at tribute values

From: Fred P. <fprog26@hotmail.com>
Date: Mon, 12 May 2003 03:13:22 -0400
To: www-svg@w3.org
Cc: Kim.Marriott@infotech.monash.edu.au, arazdow@mathsoft.com
Message-ID: <BAY2-F34n8kRZ5SaauB00007733@hotmail.com>

I think the arguments of Professor Kim Marriott
describes exactly what some of the things that we tried to achieve.

Especially his formal PDF article on one-way constrained SVG.
This is especially true for rendering UML diagrams using SVG,
similar to Visio or Rational Rose, using an SVG web client.

Let's take a simple case of springs:


       0         1         2         3
(0,0) 012345678901234567890123456789012345
      0+----------------------------------+
      1|          z            z          |
      2|   (9,3)  z    (22,3)  z          |
      3|        +---+        +---+        |
      4|zzzzzzzz| A |zzzzzzzz| B |zzzzzzzz|
      5|        +---+        +---+        |
      6|          z            z          |
      7|          z            z          |
      8+----------------------------------+ (W,H)


Spring conversion into one-way constraint functions can be derived with some 
low level logic:
Notice that any thing calculation are integer based mostly using floor(x)

      A.x = (document.width  - A.width  - B.width) * 1/3 + 1
          = (35 - 5 - 5) * 1/3 + 1
          = (25        ) * 1/3 + 1
          = 8.33 + 1
          = 8    + 1
          = 9

      A.y = (document.height - A.height - B.height) * 1/2 + 1
          = (8 - 3) / 2 + 1
          = 5 /2 + 1
          = 2.5 + 1
          = 2 + 1
          = 3

      B.x = (document.width  - A.width  - B.width) * 2/3 + A.width + 1
          = (35 - 5 - 5) * 2/3 + 5 + 1
          = (25        ) * 2/3 + 5 + 1
          = 16.67 + 6
          = 16 + 6
          = 22

      B.y = (document.height - A.height - B.height) * 1/2 + 1
          = (8 - 3) / 2 + 1
          = 5 /2 + 1
          = 2.5 + 1
          = 2 + 1
          = 3

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg SYSTEM 
"http://www.w3.org/TR/2000/03/WD-SVG-20000303/DTD/svg-20000303-stylable.dtd">
<svg height="300" width="300"
   xmlns:xlink="http://www.w3.org/2000/xlink/namespace/"
>
<defs>
  <!-- Assuming you want 10px spacing between the box border and the text 
-->
  <constant id="offset" value="10px"/>
</defs>

<rect id="A"
      x="eval( (document.width  - A.width  - B.width ) * 1/3 + 1 );"
      y="eval( (document.height - A.height - B.height) * 1/2 + 1 );"
  width="eval( offset + textA.width  + offset );"
height="eval( offset + textA.height + offset );"
  style="fill:#00FFFF; stroke:#000000; stroke-width:1; shape-rendering: 
optimizeSpeed;"
/>

<rect id="B"
      x="eval( (document.width  - A.width  - B.width ) * 2/3 + A.width + 1 
);"
      y="eval( (document.height - A.height - B.height) * 1/2 + 1 );"
  width="eval( offset + textB.width  + offset );"
height="eval( offset + textB.height + offset );"
  style="fill:#00FFFF; stroke:#000000; stroke-width:1; shape-rendering: 
optimizeSpeed;"
/>

<text id="textA"
      x="eval( A.x + offset );"
      y="eval( A.y + offset );"
  style="font:arial; font-size:8pt; text-rendering:optimizeSpeed;"
>A</text>

<text id="textB"
      x="eval( B.x + offset );"
      y="eval( B.y + offset );"
  style="font:arial; font-size:8pt; text-rendering:optimizeSpeed;"
>B</text>
</svg>

Acyclic Dependancy:
===================

A.width  --> textA.width
A.height --> textA.height
B.width  --> textB.width
B.height --> textB.height

textA.x --> A.x --> document.width  | A.width  | B.width   --> textA.width  
| textB.width
textA.y --> A.y --> document.height | A.height | B.height  --> textA.height 
| textB.height
textB.x --> B.x --> document.width  | A.width  | B.width   --> textA.width  
| textB.width
textB.y --> B.y --> document.height | A.height | B.height  --> textA.height 
| textB.height


As you can see, it's quite straight-forword to derive expression for GUI 
widget spring equations,
at least for square box spacing approximation of complex shapes like a cloud 
or triangle and similar.


For your <path/> example, I think something like this should make everyone 
happy:

  <path d="M {if {viewport.right-viewport.left > 10px} then
                          {viewport.left+10px}
                        else
                          {0.5*viewport.right+0.5*viewport.left}}...."/>


becomes:

  <path d="M
    eval( if ( viewport.right-viewport.left > 10px )
          { return new Point( viewport.left+10px, 10px ); }
          else
          { return new Point( 0.5*viewport.right+0.5*viewport.left, 10px ); 
}
        );
        l 1 0 l 0 1 l -1 0z"/>


The following notation might be needed:

<defs>
   <expression id='len' value='eval( viewport.width/2 + 10px );' />
</defs>

  <path d="M
    eval( if ( viewport.right-viewport.left > 10px )
          { return new Point( viewport.left+10px, 10px ); }
          else
          { return new Point( 0.5*viewport.right+0.5*viewport.left, 10px ); 
}
        );
        l eval( len ) 0 l 0 eval( len ) l eval( -1 * len ) 0z"/>


Here we see clearly why  eval( x )  is needed to not confound  the l 'el' 
relative line command
and the variable name len.

or use { } as mentionned:


  <path d="M
   {eval( if ( viewport.right-viewport.left > 10px )
          { return new Point( viewport.left+10px, 10px ); }
          else
          { return new Point( 0.5*viewport.right+0.5*viewport.left, 10px ); 
}
        ); }
        l 1 0 l 0 1 l -1 0z"/>


The following might be needed:

<defs>
   <expression id='len' value='eval( viewport.width/2 + 10px );' />
</defs>

  <path d="M
   {eval( if ( viewport.right-viewport.left > 10px )
          { return new Point( viewport.left+10px, 10px ); }
          else
          { return new Point( 0.5*viewport.right+0.5*viewport.left, 10px ); 
}
        ); }
        l {eval( len )} 0 l 0 {eval( len )} l {eval( -1 * len )} 0z"/>


or simply

  <path d="M
   {eval( if ( viewport.right-viewport.left > 10px )
          { return new Point( viewport.left+10px, 10px ); }
          else
          { return new Point( 0.5*viewport.right+0.5*viewport.left, 10px ); 
}
        ); }
        l {len} 0 l 0 {len} l {-len} 0z"/>


Anybody else, would be enthusiast to have such functionality?

BTW, all those inlined calculation could be ECMAScript based
and therefore hooked-up directly to existing embedded SVG ECMAscript 
engines,
allowing for 'safe' recursive functions.

Sincerely yours,
Fred.

_________________________________________________________________
Add photos to your messages with MSN 8. Get 2 months FREE*.  
http://join.msn.com/?page=features/featuredemail
Received on Monday, 12 May 2003 03:13:30 GMT

This archive was generated by hypermail 2.3.1 : Friday, 8 March 2013 15:54:25 GMT