GiovineItalia / Compose.jl

Declarative vector graphics
http://giovineitalia.github.io/Compose.jl/latest/
Other
248 stars 81 forks source link

Fillopacity: new issues #318

Closed Mattriks closed 6 years ago

Mattriks commented 6 years ago

@tlnagy, @bjarthur Here is a MWE of the subsequent #314 issue in Compose (this example reproduces the code in Gadfly's Guide.background). Note the comments:

set_default_graphic_size(14cm,4cm)
panela = compose(context(order=1), rectangle(), fill(nothing), fillopacity(0.0) )
draw(SVG(), panela) # works in IJulia
draw(SVG("panela.svg"), panela) # opening file in browser shows error

The reason that error occurs is that fill(nothing) is RGBA(0,0,0,0), and hence in svg "fill-opacity=0" gets printed twice: once from fill(nothing) and once from fillopacity(0.0).
Perhaps a warning should be thrown in Compose - suggesting to the user that they can't use any xxxA fill color e.g. RGBA(0,0,0,0)and fillopacity() together for svg i.e. you can't specify the fill opacity twice for svg. In Gadfly, there are two options to solve the issue: i) make theme.panel_fill a e.g. RGBA color (it is), and deprecate theme.panel_opacity ii) make theme.panel_fill a e.g. RGB color, and use theme.panel_opacity to control opacity

Note that option i) is actually what is done in Gadfly's render(plot::Plot) function, which has a fill(nothing) statement, and no fillopacity() statement, because fill(nothing) is RGBA(0,0,0,0). Thoughts?

bjarthur commented 6 years ago

i think #316 was on the right track, and all that needs to be added to it is to change the definition of svg_fmt_color to handle alpha values.

the SVG spec permits one to use either RGB or RGBA for fill colors.

Mattriks commented 6 years ago

I think updating svg_fmt_color to handle the rgba spec is good. I also found an example which shows that in svg fill="rgba()" and fill-opacity can be used together (which seems to have a multiplicative effect? i.e. 0.5*0.5 in the example).

Mattriks commented 6 years ago

I've been testing some new code using the svg rgba spec, and the question arises: What do you want the default behaviour for svg to be in this example?:

set_default_graphic_size(4cm,4cm)
img = compose(context(), 
        (context(), circle(0.5,0.5,0.3), fill(HSVA(45,1,1,0.5)), fillopacity(0.3) )
)
draw(SVG(), img)

There are two choices: i) The alpha values get multiplied i.e 0.5*0.3 which is the default in svg ii) Override the SVG behaviour by letting Compose change the color to HSVA(45,1,1,1) if fillopacity(x) is supplied. Then the final fill-opacity will be x.

Option ii) will take a bit more work then option i).

tlnagy commented 6 years ago

I think option i is reasonable, especially since this is the default behavior of SVG.

If the user provides a RGBA color with A ⊄ {0, 1} and fillopacity then I think it's reasonable to assume multiplicative behavior. I think we should make sure to add a note about this behavior in fillopacity.