Closed Mrfence97 closed 3 years ago
Very nice! Thank you so much for that - I believe we should definitely consider the "use" use-case, because in my experiencethis is one of the most valuable usages of "currentColor". We might analyse the "defs" and search for occurences of "currentColor" and then opt-out of the PDF-sharing of the elements - I don't believe you can parameterized PDF elements - any ideas, @HackbrettXXX ?
I've pushed another commit that adds <use>
and mostly adds 'stop-color'
support.
<use>
The current color
context is passed down to the refContext
used to render the element referenced by the <use>
. Note the API of getRendered()
in ReferencesHandler
has been changed to include the color
. This color
is used in the key to map an element to the rendered element as a different PDF FormObject is required if a different color
is used! An optimisation (as @yGuy suggests) would be look in the 'defs' to see if currentcolor
is actually used. If it's not, there's no need to create a different FormObject even if the active color
is different! Currently this is not implemented.
'stop-color'
The stop-color
support isn't perfect. If currentcolor
is used within a <stop>
, browser implementations always use the color
active where the <stop>
is declared (and having a different color
when the gradient is actually used has no effect). However, as things stand there is no easy way to access the color
value active where the <stop>
is declared. Opening test/specs/current-color/spec.svg
is a browser, you'll see the squares located at (3,0)
and (3,2)
have a magenta gradient (inherited from the color
in the parents <defs>
). Currently the package renders these squares as fully black.
A potential fix would be to use getComputedStyles()
on the <stop>
(or <xGradient>
) element to access the current color
, but this requires the SVG to be rendered by the browser! An alternative could be to walk up the parent elements of the <stop>
(or <xGradient>
) to work out which color
is active.
Thanks for these improvements.
<use>
I think it's fine how you implemented it for now. If you want you can implement the performance improvement, but this has low priority for me.
stop-color
I think it would be good if we would implement this like in the browser. Walking up the DOM from the gradient element should be ok. Make sure to use the getAttribute
function from the 'utils/node.tsfile to check for the
colorproperty. You can use the
StyleSheets` instance from the context where the gradient is referenced. This instance is valid everywhere.
stop-color
I've pushed another commit that adds full currentcolor
support for stop-color
. As was suggested, in the Gradient
node's apply()
method, the DOM is walked up to calculate the color
set in the <stop>
's context.
To easily walk up the DOM, I've added a parent
member to the base SvgNode
class that is set for every node by parse()
to its parent SvgNode
.
This PR implements "currentcolour" support for the
fill
andstroke
properties.As per the SVG 1.1 (and 2.0) color spec, a user may specify a
color
property that is inherited by all child nodes. If thefill
orstroke
of any such nodes are set to "currentcolor", then the inheritedcolor
is used.This is implemented by adding a
color
member toAtrributeState
(that defaults to black).parseColor
is amended to take in the currentContext
so that if "currentcolor" is passed, thecolor
in theContext
'sAttributeState
is returned.Note the implementation is imperfect for two reasons:
stop-color
in gradients. Current browser implementations only ever use thecolor
in-scope of the gradient as defined inside the<defs>
tag; however, noContext
is consumed when aGradient
node is created (as far as I can tell). This means there is no way to access this 'within<defs>
' context. Therefore "currentcolor" is always black if used inside a gradient.~ Done: see commit/comment below.color
to flow into the shadow-DOM if a<use>
tag is used. However, theAttributeState
is not passed down when aUse
node is rendered, so the current color is inaccessible. So, again "currentcolor" is always black if used inside an element that is referenced with<use>
.~ Done: see commit/comment below.Hopefully someone can assist with these problems!
A number of test cases are also added.