Straw man variable stroke-width syntax proposal

Dear all,

I've put together a strawman proposal for the syntax for variable-width 
stroke incorporating many of the suggestions raised in the recent telcon.

I warned you you'll hate it but I hope it gets the ball rolling. I'm 
sure you can make it great!


Initial observation: Combining percentage-based offsets with 
length-based offsets doesn't make much sense

   e.g. '50%: 1.2, 13em: 1.1'

This is because depending on the length of the path, '50%' may occur 
before or after '13em'.

Therefore I've split the 'type' of the offset out into a separate 
property; a little bit like "patternContentUnits" etc.


Proposed properties at a glance:

    stroke-width: <percentage> | <length>
    stroke-widths-array:
      [ [ [<percentage>|<length>|<number>] S* ":" S* ]? <number> ]#
      (Or maybe: [ [ <number> S* ":" S* ]? <number> ]#)
    stroke-widths-position: percent | length | point
    stroke-widths-repeat: no-repeat | repeat
    stroke-widths: [ <position> || repeat> ]? <array>


Proposed properties in detail:

  stroke-width - As currently defined, specifies the _base_stroke_width_.

  stroke-widths-array:
    [ [ [<percentage>|<length>|<number>] S* ":" S* ]? <number> ]#

    The optional number/length/percentage before the ':' represents the 
offset.

    The application of the offset depends on the value of 
'stroke-widths-position' (defined below) as follows:
       'percent': percentage of the path length (<percentage> or 
<number> where 0.2 -> 20%)
       'length': absolute length along the path in user units (<length> 
or <number> where <number> is user units)
       'point': integer part of the <number> is the index of the point 
in the path, fractional part is a percentage between that point and the 
end of the segment (as per Inkscape). e.g. '3.2' is a point 20% along 
the 4th segment in the path (the index is 0-based).

    Note that <number> can be used in all three cases so it's possible 
to change the stroke-widths-position property without changing 
stroke-widths-array.

    If we introduce support for asymmetric stroke widths the format 
would be:

    [ [ [<percentage>|<length>|<number>] S* ":" S* ]? 
<number>(/<number>)? ]#

    [ Sorry about the line-wrapping there, the only part that changes is 
the last part becomes: <number>(/<number>)? ]

    In this case the last two numbers represent the width on the 
left-side of the stroke (/) and the right-side of the stroke respectively.

    The offsets must be in ascending order. If not we process up to the 
last item that is ascending order and only apply that far. (For lengths 
we'd have to specify when they are resolved.)

    When an offset is omitted, it is filled in based on the value of 
stroke-widths-position as follows:
      'percent' and 'length': evenly space between values which have an 
offset. If the first value has no offset use '0'. If the last value has 
no offset make it match the end of the path.
      'point': If the first value has no offset, make it '0.0' (the 
first point). For every other value, take the previous offset, increment 
by 1.0 and then apply floor(). i.e. <no-offset>, 2.3, <no-offset>, 
<no-offset> becomes 0.0, 2.3, 3.0, 4.0

    The final <number> is the magnification factor on the 
_base_stroke_width_ (specified by 'stroke-width'), e.g. 1.1 for 1.1x the 
stroke width. We could also make this [ <number> | <percentage> ].

    Issue: For length-based offsets, if you have an offset of '3em' and 
'12px' the order can change if you set the font-size on an ancestor.

    Alternative proposal, just always use <number> for the offset, i.e.:

        stroke-widths-array ::= [ [ <number> S* ":" S* ]? <number> ]#

    (<number> can still be used to describe a percentage as a fraction 
or a length using user units as defined above).

  stroke-widths-position: percent | length | point
    Initial: 'percent'
    Specifies how the offsets in stroke-widths-array are applied as 
specified above.

  stroke-widths-repeat: no-repeat | repeat
    Initial: 'no-repeat'
    (The 'no-repeat' keyword matches the value for CSS' 
background-repeat property)

   For stroke-widths-array lists that don't fill up to the end of the 
path, 'repeat' makes it repeat the pattern.

    Possible future value: 'reflect' which alternates the pattern

    I'm not quite sure how to avoid sudden jumps when using 'percent' or 
'length' here. Maybe you need 'reflect' for this case?

  stroke-widths: [ <position> || repeat> ]? <array>
    Shorthand for the above (forgive the abbreviated syntax).


Examples:

a) A hair stroke pattern

   .hair {
     stroke-width: 10px;
     stroke-widths: 0.1, 70%: 1.1, 0.3;
     stroke-linecap: round;
   }

b) A bulging pattern like a snake that has eaten a lot of eggs.

   .snake {
     stroke-width: 30px;
     stroke-widths: length repeat 0.5, 30px: 1, 60px: 0.5
   }

c) A box where the alternate corners are thicker

   rect.sharpBox {
     stroke: black;
     stroke-width: 5px;
     stroke-widths: point 1, 1.5, 1, 1.5;
     fill: white;
     paint-order: stroke;
   }

d) An n-pointed star where the outside points and inside points differ 
in stroke width

   star.sharp {
     stroke-widths: point repeat 1, 1.5;
   }

e) A path created using touch input

   <path d="M123 345C...." stroke-widths-position="points" 
stroke-widths-array="1, 1.1, 1.15..." />


I look forward to your suggestions!

Best regards,

Brian

Received on Friday, 10 May 2013 05:43:41 UTC