Inkpad icon indicating copy to clipboard operation
Inkpad copied to clipboard

A round trip through SVG causes the contents of hidden layers to import with 0.0 opacity.

Open sprang opened this issue 12 years ago • 3 comments

sprang avatar Oct 25 '13 00:10 sprang

Most likely cause:

WDSVGParser --> endG does not properly check for valid stringptr from [state_ style:kWDPropertyOpacity] opacity is never stored when 1.0 (in WDLayer --> SVGElement)

There are at least 2 places in endG where that is relevant, but this mistake might occur elsewhere and for other values also?

code should probably be changed to:

            if ([state_ style:kWDPropertyOpacity])
            { layer.opacity = [[state_ style:kWDPropertyOpacity] floatValue]; }
            if ([state_ style:kWDPropertyOpacity])
            state_.wdElement.opacity *= [[state_ style:kWDPropertyOpacity] floatValue];

32Beat avatar Feb 01 '14 09:02 32Beat

Still happens with the latest SVG merge. To clarify, the layer opacity is not 0.0, but the opacity of the layer contents are 0.0.

sprang avatar Feb 06 '14 18:02 sprang

Okay, perhaps the following is happening:

When writing SVG, WDLayer writes the "visibility" property as "hidden", and subsequent WDElements don't have a "visibility" property so they don't write anything. This is fine.

When reading SVG, the parser pushes the layer visibility on the stack, and the property is assumed to propagate to subsequent elements that respond to "visibility". WDElements do not respond to visibility so the code tries to emulate visibility by forcing opacity to 0

From WDSVGStyleParser:

- (void) styleOpacityBlendAndShadow:(WDElement *)element
{
    NSString *opacity = [stack_ style:kWDPropertyOpacity];
    NSString *visibility = [stack_ style:kWDPropertyVisibility]; // <---- finds the last layer entry
    NSString *display= [stack_ style:kWDPropertyDisplay];

    // Hack !!!
    if ([display isEqualToString:@"none"] || [visibility isEqualToString:@"hidden"]) {
        element.opacity = 0;
    } else {
        element.opacity = [opacity floatValue];
    }

WDElements don't seem to write "visibility" or "display" so that should simply be ignored. I believe this should read

- (void) styleOpacityBlendAndShadow:(WDElement *)element
{
    NSString *opacity = [stack_ style:kWDPropertyOpacity];
    element.opacity = opacity ? [opacity floatValue] : 1.0;

Which may however mean that the opacity from previous elements is propagated to subsequent elements under some circumstances. i.e.: [stack_ style:] does a reverse search, and opacity = 1.0 does not generate an opacity entry for an element, thus if the parser first encounters an element with opacity 0.5 (with an SVG opacity entry) and then parses an element with opacity 1.0 (without an SVG opacity entry) it will inadvertently propagate 0.5 to the second element.

32Beat avatar Feb 06 '14 20:02 32Beat