Search code examples
javapiccolo

Unable to stretch zero rectange in Piccolo2D?


Why isn't first and third rectangle appear in the sample below?

Looks like rectangle is broken once it has zero size.

package tests.piccolo;

import org.piccolo2d.extras.PFrame;
import org.piccolo2d.nodes.PPath;

public class Try_EmptyRectangle {

    public static void main(String[] args) {

        new PFrame() {

            @Override
            public void initialize() {

                PPath rect1 = PPath.createRectangle(0, 0, 0, 0);
                PPath rect2 = PPath.createRectangle(0, 100, 1, 1);
                PPath rect3 = PPath.createRectangle(0, 200, 1, 1);

                getCanvas().getLayer().addChild(rect1);
                getCanvas().getLayer().addChild(rect2);


                rect1.setWidth(50);
                rect1.setHeight(50);

                rect2.setWidth(50);
                rect2.setHeight(50);

                rect3.setWidth(0);
                rect3.setHeight(0);
                rect3.setWidth(50);
                rect3.setHeight(50);


            }



        };

    }

}

Solution

  • This looks like a bug. PPath internally wraps GeneralPath. PPath.createRectangle(0, 0, 0, 0) initializes GeneralPath to a zero size rectangle shape. Then changing PPath width/height triggers the bounds change. PPath overrides internalUpdateBounds() in order to scale the path to fit into the specified bounds. There seem to be a problem with zero sized path:

    protected void internalUpdateBounds(final double x, final double y, final double width, final double height) {
        final Rectangle2D pathBounds = path.getBounds2D();
        ...
        final double scaleX;
        if (adjustedWidth == 0 || pathBounds.getWidth() == 0) {
                scaleX = 1;
        }
        ...
        final double scaleY;
        if (adjustedHeight == 0 || pathBounds.getHeight() == 0) {
             scaleY = 1;
        }
        ...
        TEMP_TRANSFORM.scale(scaleX, scaleY);
        ...
        path.transform(TEMP_TRANSFORM);
    }
    

    scaleX and scaleY are always 1. So the path is actually never scaled and remains zero size.