JDK-8226789 : Path rendered incorrectly when it goes outside the clipping region
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: openjfx11,openjfx12,openjfx13
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_10
  • CPU: x86_64
  • Submitted: 2019-06-26
  • Updated: 2019-07-29
  • Resolved: 2019-07-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
openjfx13Fixed
Related Reports
Relates :  
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
JavaFX 12.0.1 (also tested with Java 13-ea+9 with the same outcome)

openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12+33)
OpenJDK 64-Bit Server VM (build 12+33, mixed mode, sharing)

Windows 10 version 1903

A DESCRIPTION OF THE PROBLEM :
A path in a shape of a square with a circular hole is constructed. Before that, a rectangular clipping region is set so that the lower two vertices of the square are outside of it. Rendering such path produces wrong result.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the provided program.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No path artifacts.
ACTUAL -
Wrong path rendered.

---------- BEGIN SOURCE ----------
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class PathBug extends Application {

	@Override
	public void start(Stage primaryStage) {
	    double w = 400;
	    double h = 400;

	    Canvas canvas = new Canvas(w, h);
	    GraphicsContext gc = canvas.getGraphicsContext2D();

	    
	    gc.setFill(Color.BLACK);
	    gc.fillRect(0, 0, w, h);

	    // Setting the clip to exclude the lower 50 pixels.
	    gc.beginPath();
	    gc.rect(0, 0, w, h-50);
	    gc.closePath();
	    gc.clip();   // Comment this line out to see the intended shape.

	    // Constructing a path that should look like a square with a hole. 
	    gc.beginPath();
	    gc.rect(20, 20, w-40, h-40);
	    gc.arc(200, 200, 100, 100, 0, 360);
	    gc.closePath();

	    gc.setFill(Color.CORNFLOWERBLUE);
	    gc.fill();

	    
	    StackPane root = new StackPane();
	    root.getChildren().add(canvas);
	    Scene scene = new Scene(root);

	    primaryStage.setScene(scene);
	    primaryStage.show();
	}


	public static void main(String[] args) {
		Application.launch(args);
	}
}

---------- END SOURCE ----------

FREQUENCY : always



Comments
Raising priority to P3 since this is a regression with no good workaround.
26-07-2019

Changeset: 030420e44e74 Author: lbourges Date: 2019-07-25 09:54 +0200 URL: https://hg.openjdk.java.net/openjfx/13-dev/rt/rev/030420e44e74 8226789: Path rendered incorrectly when it goes outside the clipping region Summary: fixed closePath() to preserve last position and its outcode in Stroker and TransformingPathConsumer2D.PathClipFilter Reviewed-by: kcr, serb
26-07-2019

Testing looks good, and this is a safe fix for a clipping case that isn't working, so pushing this to 13-dev for openjfx13.
26-07-2019

Changeset: 6ca3e8aadafc Author: lbourges Date: 2019-07-25 09:54 +0200 URL: https://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/6ca3e8aadafc
25-07-2019

I reproduced the problem: It is related to closePath() implementation in PathClipFilter (and Stroker) as the reproducer code calls rect() rhen arc() that leads to the sequence moveTo(), lineTo() x4, closePath() followed by lineTo(), curveTo() x4, closePath()... Marlin clipper does not handle properly closePath + lineTo (not tested) instead of closePath + moveTo + lineTo (tested). As a workaround for now, just discard Marlin clipper by setting -Dprism.marlin.clip=false. I already have a simple fix that I am intensively testing with ClipPathTest and your test code so I hope to submit soon a patch
01-07-2019

This is a regression introduced in the Marlin 0.9.2 upgrade, JDK-8204621. I verified that this bug does not happen with FX in JDK 10, and does not happen if I locally revert Marlin to the state before the 0.9.2 upgrade.
27-06-2019