Pivot
  1. Pivot
  2. PIVOT-166

WatermarkDecorator paints outside its bounds

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.3
    • Component/s: wtk-effects
    • Labels:
      None

      Description

      Run the WatermarkDecoratorTest to see this behavior. WatermarkDecorator reports the component's bounds in getBounds(), it uses an identity transform, and it doesn't alter the clip rect of the graphics, yet the watermark is being painted outside the bounds of the decorated component (in the case of the test, the decorated component is the CardPane that lives in the TablePane's row beklow the line).

        Activity

        Todd Volkert made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Todd Volkert made changes -
        Resolution Won't Fix [ 2 ]
        Status Resolved [ 5 ] Reopened [ 4 ]
        Hide
        Todd Volkert added a comment -

        The bug exists in WatermarkDecorator then, so I'm re-opening as such

        Show
        Todd Volkert added a comment - The bug exists in WatermarkDecorator then, so I'm re-opening as such
        Todd Volkert made changes -
        Summary Decorators are given incorrect clip rect WatermarkDecorator paints outside its bounds
        Fix Version/s 1.3 [ 12313779 ]
        Greg Brown made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 1.3 [ 12313779 ]
        Resolution Won't Fix [ 2 ]
        Hide
        Greg Brown added a comment -

        This is by design. Decorators are always clipped to the parent's bounds, since many decorators need to draw outside the component's bounds (e.g. drop shadows).

        Since decorators use a chained prepare/update model, we can't assume that it is OK to clip to the decorated bounds in the prepare() phase, since that clip rect may not be valid for subsequent decorator update()s, and almost certainly won't be valid for the component itself, which paints into a copy of the final prepared graphics but must be clipped to the intersection of its own bounds and the current clip (not the intersections of all preceding decorator prepare() calls).

        As a result, the only assumption that decorators can make is that drawing will be clipped to the parent's bounds.

        Show
        Greg Brown added a comment - This is by design. Decorators are always clipped to the parent's bounds, since many decorators need to draw outside the component's bounds (e.g. drop shadows). Since decorators use a chained prepare/update model, we can't assume that it is OK to clip to the decorated bounds in the prepare() phase, since that clip rect may not be valid for subsequent decorator update()s, and almost certainly won't be valid for the component itself, which paints into a copy of the final prepared graphics but must be clipped to the intersection of its own bounds and the current clip (not the intersections of all preceding decorator prepare() calls). As a result, the only assumption that decorators can make is that drawing will be clipped to the parent's bounds.
        Todd Volkert made changes -
        Field Original Value New Value
        Summary WatermarkDecorator overruns its bounds Decorators are given incorrect clip rect
        Description Run the WatermarkDecoratorTest to see this behavior. WatermarkDecorator reports the component's bounds in getBounds(), it uses an identity transform, and it doesn't alter the clip rect of the graphics, yet the watermark is being painted outside the bounds of the decorated component (in the case of the test, the decorated component is the CardPane that lives in the TablePane's row beklow the line).

        It's possible that the Graphics.rotate() that WatermarkDecorator applies in update() is the cause of this, and maybe it should return a rotate transform in getTransform() - this is where I'll start the investigation.
        Run the WatermarkDecoratorTest to see this behavior. WatermarkDecorator reports the component's bounds in getBounds(), it uses an identity transform, and it doesn't alter the clip rect of the graphics, yet the watermark is being painted outside the bounds of the decorated component (in the case of the test, the decorated component is the CardPane that lives in the TablePane's row beklow the line).
        Hide
        Todd Volkert added a comment -

        I've tracked this down to Container.paint(), and the problem is not with or unique to WatermarkDecorator. The issue is that we only clip to the child component's bounds on componentGraphics, which is a copy of decoratedGraphics. Thus, decoratedGraphics never gets the clip, and it's left with the clip of its parent.

        It's possible that this is meant as a feature - I know that decorators are allowed to paint outside their bounds but not their parent's bounds. However, I thought that this meant that decorators were supposed to restrict their decorated bounds to the bounds of their parent (as a matter of policy), and that they would be given a clip equal to their decorated bounds. It's pretty confusing to report your decorated bounds as that of your component and to be given a larger clip. In the case of the watermark decorator, it has to call graphics primitives methods on regions outside of its decorated bounds, and it relies on that clip.

        The bottom line is: should WatermarkDecorator and those like it be changed to clip to their bounds before they draw, or should this be addressed on Container?

        Show
        Todd Volkert added a comment - I've tracked this down to Container.paint(), and the problem is not with or unique to WatermarkDecorator. The issue is that we only clip to the child component's bounds on componentGraphics, which is a copy of decoratedGraphics. Thus, decoratedGraphics never gets the clip, and it's left with the clip of its parent. It's possible that this is meant as a feature - I know that decorators are allowed to paint outside their bounds but not their parent's bounds. However, I thought that this meant that decorators were supposed to restrict their decorated bounds to the bounds of their parent (as a matter of policy), and that they would be given a clip equal to their decorated bounds. It's pretty confusing to report your decorated bounds as that of your component and to be given a larger clip. In the case of the watermark decorator, it has to call graphics primitives methods on regions outside of its decorated bounds, and it relies on that clip. The bottom line is: should WatermarkDecorator and those like it be changed to clip to their bounds before they draw, or should this be addressed on Container?
        Todd Volkert created issue -

          People

          • Assignee:
            Todd Volkert
            Reporter:
            Todd Volkert
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development