Skip to content

Commit 3cb3ca8

Browse files
bhaweshkckevinrushforth
authored andcommitted
8202990: javafx webview css filter property with display scaling
Reviewed-by: kcr, ajoseph
1 parent a5ecfb6 commit 3cb3ca8

File tree

4 files changed

+200
-1
lines changed

4 files changed

+200
-1
lines changed

modules/javafx.web/src/main/java/com/sun/javafx/webkit/prism/WCGraphicsPrismContext.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,7 @@ private void blend(Graphics g) {
15461546
// blending on canvas
15471547
dstImg = (PrDrawable) Effect.getCompatibleImage(fctx, clip.width, clip.height);
15481548
Graphics dstG = dstImg.createGraphics();
1549+
state.apply(dstG);
15491550
((PrismImage) image).draw(dstG,
15501551
0, 0, clip.width, clip.height,
15511552
clip.x, clip.y, clip.width, clip.height);

modules/javafx.web/src/main/native/Source/WebCore/platform/graphics/java/ImageJava.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ImageBuffer;
4545
namespace WebCore {
4646

4747
void Image::drawImage(GraphicsContext& gc, const FloatRect &dstRect, const FloatRect &srcRect,
48-
CompositeOperator, BlendMode)
48+
CompositeOperator compositeOperator, BlendMode)
4949
{
5050
if (gc.paintingDisabled()) {
5151
return;
@@ -56,6 +56,9 @@ void Image::drawImage(GraphicsContext& gc, const FloatRect &dstRect, const Float
5656
return;
5757
}
5858

59+
CompositeOperator oldCompositeOperator = gc.compositeOperation();
60+
gc.setCompositeOperation(compositeOperator);
61+
5962
gc.platformContext()->rq().freeSpace(72)
6063
<< (jint)com_sun_webkit_graphics_GraphicsDecoder_DRAWIMAGE
6164
<< currFrame
@@ -64,6 +67,8 @@ void Image::drawImage(GraphicsContext& gc, const FloatRect &dstRect, const Float
6467
<< srcRect.x() << srcRect.y()
6568
<< srcRect.width() << srcRect.height();
6669

70+
gc.setCompositeOperation(oldCompositeOperator);
71+
6772
if (imageObserver())
6873
imageObserver()->didDraw(*this);
6974
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package test.javafx.scene.web;
27+
28+
import java.util.concurrent.CountDownLatch;
29+
import javafx.application.Application;
30+
import javafx.application.Platform;
31+
import javafx.scene.Scene;
32+
import javafx.scene.image.PixelReader;
33+
import javafx.scene.image.WritableImage;
34+
import javafx.scene.paint.Color;
35+
import javafx.scene.web.WebView;
36+
import javafx.stage.Stage;
37+
import org.junit.AfterClass;
38+
import org.junit.Before;
39+
import org.junit.BeforeClass;
40+
import org.junit.Test;
41+
import test.util.Util;
42+
43+
import static javafx.concurrent.Worker.State.SUCCEEDED;
44+
import static org.junit.Assert.assertNotNull;
45+
import static org.junit.Assert.assertTrue;
46+
import static org.junit.Assert.fail;
47+
48+
public class CSSFilterTest {
49+
private static final CountDownLatch launchLatch = new CountDownLatch(1);
50+
51+
// Maintain one application instance
52+
static CSSFilterTestApp cssFilterTestApp;
53+
54+
private WebView webView;
55+
56+
public static class CSSFilterTestApp extends Application {
57+
Stage primaryStage = null;
58+
59+
@Override
60+
public void init() {
61+
CSSFilterTest.cssFilterTestApp = this;
62+
}
63+
64+
@Override
65+
public void start(Stage primaryStage) throws Exception {
66+
Platform.setImplicitExit(false);
67+
this.primaryStage = primaryStage;
68+
launchLatch.countDown();
69+
}
70+
}
71+
72+
private static String colorToString(Color c) {
73+
int r = (int)(c.getRed() * 255.0);
74+
int g = (int)(c.getGreen() * 255.0);
75+
int b = (int)(c.getBlue() * 255.0);
76+
int a = (int)(c.getOpacity() * 255.0);
77+
return "rgba(" + r + "," + g + "," + b + "," + a + ")";
78+
}
79+
80+
private void assertColorEquals(String msg, Color expected, Color actual, double delta) {
81+
if (!testColorEquals(expected, actual, delta)) {
82+
fail(msg + " expected:" + colorToString(expected)
83+
+ " but was:" + colorToString(actual));
84+
}
85+
}
86+
87+
private void assertColorNotEquals(String msg, Color notExpected, Color actual, double delta) {
88+
if (testColorEquals(notExpected, actual, delta)) {
89+
fail(msg + " not expected:" + colorToString(notExpected)
90+
+ " but was:" + colorToString(actual));
91+
}
92+
}
93+
94+
protected boolean testColorEquals(Color expected, Color actual, double delta) {
95+
double deltaRed = Math.abs(expected.getRed() - actual.getRed());
96+
double deltaGreen = Math.abs(expected.getGreen() - actual.getGreen());
97+
double deltaBlue = Math.abs(expected.getBlue() - actual.getBlue());
98+
double deltaOpacity = Math.abs(expected.getOpacity() - actual.getOpacity());
99+
return (deltaRed <= delta && deltaGreen <= delta && deltaBlue <= delta && deltaOpacity <= delta);
100+
}
101+
102+
@BeforeClass
103+
public static void setupOnce() {
104+
// Start the Test Application
105+
new Thread(() -> Application.launch(CSSFilterTestApp.class, (String[])null)).start();
106+
107+
assertTrue("Timeout waiting for FX runtime to start", Util.await(launchLatch));
108+
}
109+
110+
@AfterClass
111+
public static void tearDownOnce() {
112+
Platform.exit();
113+
}
114+
115+
@Before
116+
public void setupTestObjects() {
117+
Platform.runLater(() -> {
118+
webView = new WebView();
119+
cssFilterTestApp.primaryStage.setScene(new Scene(webView));
120+
cssFilterTestApp.primaryStage.show();
121+
});
122+
}
123+
124+
@Test public void testCSSFilterRendering() {
125+
final CountDownLatch webViewStateLatch = new CountDownLatch(1);
126+
127+
Util.runAndWait(() -> {
128+
assertNotNull(webView);
129+
webView.getEngine().getLoadWorker().stateProperty().
130+
addListener((observable, oldValue, newValue) -> {
131+
if (newValue == SUCCEEDED) {
132+
webView.requestFocus();
133+
}
134+
});
135+
136+
webView.focusedProperty().
137+
addListener((observable, oldValue, newValue) -> {
138+
if (newValue) {
139+
webViewStateLatch.countDown();
140+
}
141+
});
142+
143+
final String urlString = CSSFilterTest.class.getResource("simpleImagewithfilter.html").toExternalForm();
144+
webView.getEngine().load(urlString);
145+
});
146+
147+
assertTrue("Timeout when waiting for focus change ", Util.await(webViewStateLatch));
148+
Util.sleep(1000);
149+
150+
Util.runAndWait(() -> {
151+
WritableImage snapshot = cssFilterTestApp.primaryStage.getScene().snapshot(null);
152+
PixelReader pr = snapshot.getPixelReader();
153+
154+
final double delta = 0.07;
155+
Color whiteColor = Color.rgb(255, 255, 255);
156+
Color blueColor = Color.rgb(0, 0, 255);
157+
158+
assertColorEquals("Color should be opaque white:",
159+
whiteColor, pr.getColor(0, 0), delta);
160+
assertColorEquals("Color should be opaque white:",
161+
whiteColor, pr.getColor(5, 0), delta);
162+
assertColorEquals("Color should be opaque white:",
163+
whiteColor, pr.getColor(0, 5), delta);
164+
165+
assertColorEquals("Color should be opaque blue:",
166+
blueColor, pr.getColor(25, 25), delta);
167+
assertColorEquals("Color should be opaque blue:",
168+
blueColor, pr.getColor(190, 200), delta);
169+
assertColorEquals("Color should be opaque blue:",
170+
blueColor, pr.getColor(200, 190), delta);
171+
assertColorEquals("Color should be opaque blue:",
172+
blueColor, pr.getColor(200, 200), delta);
173+
174+
assertColorNotEquals("Color should not be opaque white:",
175+
whiteColor, pr.getColor(220, 220), delta);
176+
assertColorNotEquals("Color should not be opaque blue:",
177+
blueColor, pr.getColor(220, 220), delta);
178+
});
179+
}
180+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
</head>
5+
<style type="text/css">
6+
img {
7+
-webkit-filter: drop-shadow(43px 43px 20px black);
8+
}
9+
</style>
10+
<body>
11+
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////2wBDAf//////////////////////////////////////////////////////////////////////////////////////wgARCADIAMgDAREAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAL/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQL/2gAMAwEAAhADEAAAAZ1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/8QAFBABAAAAAAAAAAAAAAAAAAAAkP/aAAgBAQABBQIcf//EABQRAQAAAAAAAAAAAAAAAAAAAJD/2gAIAQMBAT8BHH//xAAUEQEAAAAAAAAAAAAAAAAAAACQ/9oACAECAQE/ARx//8QAFBABAAAAAAAAAAAAAAAAAAAAkP/aAAgBAQAGPwIcf//EABQQAQAAAAAAAAAAAAAAAAAAAJD/2gAIAQEAAT8hHH//2gAMAwEAAgADAAAAELbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb//xAAUEQEAAAAAAAAAAAAAAAAAAACQ/9oACAEDAQE/EBx//8QAFBEBAAAAAAAAAAAAAAAAAAAAkP/aAAgBAgEBPxAcf//EABQQAQAAAAAAAAAAAAAAAAAAAJD/2gAIAQEAAT8QHH//2Q==" alt="Mountain View" width="200" height="200">
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)