Skip to content

Commit 1431c2c

Browse files
Merge from master
2 parents 17c3065 + b560b8c commit 1431c2c

File tree

5 files changed

+235
-241
lines changed

5 files changed

+235
-241
lines changed

modules/javafx.web/src/main/java/com/sun/javafx/webkit/PasteboardImpl.java

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,8 @@
2626
package com.sun.javafx.webkit;
2727

2828
import com.sun.javafx.tk.Toolkit;
29-
import com.sun.javafx.webkit.UIClientImpl;
3029
import com.sun.webkit.Pasteboard;
31-
import com.sun.webkit.graphics.WCGraphicsManager;
30+
import com.sun.webkit.graphics.WCImage;
3231
import com.sun.webkit.graphics.WCImageFrame;
3332
import java.io.File;
3433
import java.io.IOException;
@@ -66,20 +65,17 @@ final class PasteboardImpl implements Pasteboard {
6665
clipboard.setContent(content);
6766
}
6867

69-
@Override public void writeImage(WCImageFrame wcImage) {
70-
Object platformImage = WCGraphicsManager.getGraphicsManager().
71-
toPlatformImage(wcImage.getFrame());
72-
Image fxImage = Toolkit.getImageAccessor().fromPlatformImage(platformImage);
68+
@Override public void writeImage(WCImageFrame frame) {
69+
final WCImage img = frame.getFrame();
70+
final Image fxImage = img != null && !img.isNull() ? Toolkit.getImageAccessor().fromPlatformImage(img.getPlatformImage()) : null;
7371
if (fxImage != null) {
7472
ClipboardContent content = new ClipboardContent();
7573
content.putImage(fxImage);
76-
String fileExtension = wcImage.getFrame().getFileExtension();
74+
String fileExtension = img.getFileExtension();
7775
try {
7876
File imageDump = File.createTempFile("jfx", "." + fileExtension);
7977
imageDump.deleteOnExit();
80-
ImageIO.write(UIClientImpl.toBufferedImage(fxImage),
81-
fileExtension,
82-
imageDump);
78+
ImageIO.write(img.toBufferedImage(), fileExtension, imageDump);
8379
content.putFiles(Arrays.asList(imageDump));
8480
} catch (IOException | SecurityException e) {
8581
// Nothing specific to be done as of now

modules/javafx.web/src/main/java/com/sun/javafx/webkit/UIClientImpl.java

+12-171
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,14 @@
3333
import static javafx.scene.web.WebEvent.STATUS_CHANGED;
3434
import static javafx.scene.web.WebEvent.VISIBILITY_CHANGED;
3535

36-
import com.sun.javafx.tk.Toolkit;
3736
import com.sun.webkit.UIClient;
3837
import com.sun.webkit.WebPage;
3938
import com.sun.webkit.graphics.WCImage;
4039
import com.sun.webkit.graphics.WCRectangle;
41-
import java.awt.AlphaComposite;
42-
import java.awt.Graphics2D;
43-
import java.awt.image.BufferedImage;
44-
import java.awt.image.DataBufferInt;
45-
import java.awt.image.SampleModel;
46-
import java.awt.image.SinglePixelPackedSampleModel;
4740
import java.io.File;
4841
import java.io.IOException;
4942
import java.io.UnsupportedEncodingException;
5043
import java.nio.ByteBuffer;
51-
import java.nio.IntBuffer;
5244
import java.security.AccessControlContext;
5345
import java.security.AccessController;
5446
import java.security.PrivilegedAction;
@@ -58,10 +50,6 @@
5850
import java.util.Map;
5951
import javafx.event.EventHandler;
6052
import javafx.geometry.Rectangle2D;
61-
import javafx.scene.image.Image;
62-
import javafx.scene.image.PixelFormat;
63-
import javafx.scene.image.PixelReader;
64-
import javafx.scene.image.WritablePixelFormat;
6553
import javafx.scene.input.ClipboardContent;
6654
import javafx.scene.input.DataFormat;
6755
import javafx.scene.input.Dragboard;
@@ -342,7 +330,7 @@ private static DataFormat getDataFormat(String mimeType) {
342330
//never happens
343331
}
344332
}
345-
if (image != null) {
333+
if (image != null && !image.isNull()) {
346334
ByteBuffer dragImageOffset = ByteBuffer.allocate(8);
347335
dragImageOffset.rewind();
348336
dragImageOffset.putInt(imageOffsetX);
@@ -364,26 +352,18 @@ private static DataFormat getDataFormat(String mimeType) {
364352
//QuantumClipboard.putContent have to be rewritten in Glass manner
365353
//with postponed data requests (DelayedCallback data object).
366354
if (isImageSource) {
367-
Object platformImage = image.getWidth() > 0 && image.getHeight() > 0 ?
368-
image.getPlatformImage() : null;
369355
String fileExtension = image.getFileExtension();
370-
if (platformImage != null) {
371-
try {
372-
File temp = File.createTempFile("jfx", "." + fileExtension);
373-
temp.deleteOnExit();
374-
ImageIO.write(
375-
toBufferedImage(Toolkit.getImageAccessor().fromPlatformImage(
376-
Toolkit.getToolkit().loadPlatformImage(
377-
platformImage
378-
)
379-
)),
380-
fileExtension,
381-
temp);
382-
content.put(DataFormat.FILES, Arrays.asList(temp));
383-
} catch (IOException | SecurityException e) {
384-
//That is ok. It was just an attempt.
385-
//e.printStackTrace();
386-
}
356+
try {
357+
File temp = File.createTempFile("jfx", "." + fileExtension);
358+
temp.deleteOnExit();
359+
ImageIO.write(
360+
image.toBufferedImage(),
361+
fileExtension,
362+
temp);
363+
content.put(DataFormat.FILES, Arrays.asList(temp));
364+
} catch (IOException | SecurityException e) {
365+
//That is ok. It was just an attempt.
366+
//e.printStackTrace();
387367
}
388368
}
389369
}
@@ -403,143 +383,4 @@ private static DataFormat getDataFormat(String mimeType) {
403383
return accessor.getView() != null && content != null;
404384
}
405385

406-
private static int
407-
getBestBufferedImageType(PixelFormat<?> fxFormat, BufferedImage bimg,
408-
boolean isOpaque)
409-
{
410-
if (bimg != null) {
411-
int bimgType = bimg.getType();
412-
if (bimgType == BufferedImage.TYPE_INT_ARGB ||
413-
bimgType == BufferedImage.TYPE_INT_ARGB_PRE ||
414-
(isOpaque &&
415-
(bimgType == BufferedImage.TYPE_INT_BGR ||
416-
bimgType == BufferedImage.TYPE_INT_RGB)))
417-
{
418-
// We will allow the caller to give us a BufferedImage
419-
// that has an alpha channel, but we might not otherwise
420-
// construct one ourselves.
421-
// We will also allow them to choose their own premultiply
422-
// type which may not match the image.
423-
// If left to our own devices we might choose a more specific
424-
// format as indicated by the choices below.
425-
return bimgType;
426-
}
427-
}
428-
switch (fxFormat.getType()) {
429-
default:
430-
case BYTE_BGRA_PRE:
431-
case INT_ARGB_PRE:
432-
return BufferedImage.TYPE_INT_ARGB_PRE;
433-
case BYTE_BGRA:
434-
case INT_ARGB:
435-
return BufferedImage.TYPE_INT_ARGB;
436-
case BYTE_RGB:
437-
return BufferedImage.TYPE_INT_RGB;
438-
case BYTE_INDEXED:
439-
return (fxFormat.isPremultiplied()
440-
? BufferedImage.TYPE_INT_ARGB_PRE
441-
: BufferedImage.TYPE_INT_ARGB);
442-
}
443-
}
444-
445-
private static WritablePixelFormat<IntBuffer>
446-
getAssociatedPixelFormat(BufferedImage bimg)
447-
{
448-
switch (bimg.getType()) {
449-
// We lie here for xRGB, but we vetted that the src data was opaque
450-
// so we can ignore the alpha. We use ArgbPre instead of Argb
451-
// just to get a loop that does not have divides in it if the
452-
// PixelReader happens to not know the data is opaque.
453-
case BufferedImage.TYPE_INT_RGB:
454-
case BufferedImage.TYPE_INT_ARGB_PRE:
455-
return PixelFormat.getIntArgbPreInstance();
456-
case BufferedImage.TYPE_INT_ARGB:
457-
return PixelFormat.getIntArgbInstance();
458-
default:
459-
// Should not happen...
460-
throw new InternalError("Failed to validate BufferedImage type");
461-
}
462-
}
463-
464-
private static boolean checkFXImageOpaque(PixelReader pr, int iw, int ih) {
465-
for (int x = 0; x < iw; x++) {
466-
for (int y = 0; y < ih; y++) {
467-
Color color = pr.getColor(x,y);
468-
if (color.getOpacity() != 1.0) {
469-
return false;
470-
}
471-
}
472-
}
473-
return true;
474-
}
475-
476-
private static BufferedImage fromFXImage(Image img, BufferedImage bimg) {
477-
PixelReader pr = img.getPixelReader();
478-
if (pr == null) {
479-
return null;
480-
}
481-
int iw = (int) img.getWidth();
482-
int ih = (int) img.getHeight();
483-
PixelFormat<?> fxFormat = pr.getPixelFormat();
484-
boolean srcPixelsAreOpaque = false;
485-
switch (fxFormat.getType()) {
486-
case INT_ARGB_PRE:
487-
case INT_ARGB:
488-
case BYTE_BGRA_PRE:
489-
case BYTE_BGRA:
490-
// Check fx image opacity only if
491-
// supplied BufferedImage is without alpha channel
492-
if (bimg != null &&
493-
(bimg.getType() == BufferedImage.TYPE_INT_BGR ||
494-
bimg.getType() == BufferedImage.TYPE_INT_RGB)) {
495-
srcPixelsAreOpaque = checkFXImageOpaque(pr, iw, ih);
496-
}
497-
break;
498-
case BYTE_RGB:
499-
srcPixelsAreOpaque = true;
500-
break;
501-
}
502-
int prefBimgType = getBestBufferedImageType(pr.getPixelFormat(), bimg, srcPixelsAreOpaque);
503-
if (bimg != null) {
504-
int bw = bimg.getWidth();
505-
int bh = bimg.getHeight();
506-
if (bw < iw || bh < ih || bimg.getType() != prefBimgType) {
507-
bimg = null;
508-
} else if (iw < bw || ih < bh) {
509-
Graphics2D g2d = bimg.createGraphics();
510-
g2d.setComposite(AlphaComposite.Clear);
511-
g2d.fillRect(0, 0, bw, bh);
512-
g2d.dispose();
513-
}
514-
}
515-
if (bimg == null) {
516-
bimg = new BufferedImage(iw, ih, prefBimgType);
517-
}
518-
DataBufferInt db = (DataBufferInt)bimg.getRaster().getDataBuffer();
519-
int data[] = db.getData();
520-
int offset = bimg.getRaster().getDataBuffer().getOffset();
521-
int scan = 0;
522-
SampleModel sm = bimg.getRaster().getSampleModel();
523-
if (sm instanceof SinglePixelPackedSampleModel) {
524-
scan = ((SinglePixelPackedSampleModel)sm).getScanlineStride();
525-
}
526-
527-
WritablePixelFormat<IntBuffer> pf = getAssociatedPixelFormat(bimg);
528-
pr.getPixels(0, 0, iw, ih, pf, data, offset, scan);
529-
return bimg;
530-
}
531-
532-
// Method to implement the following via reflection:
533-
// SwingFXUtils.fromFXImage(img, null)
534-
public static BufferedImage toBufferedImage(Image img) {
535-
try {
536-
return fromFXImage(img, null);
537-
} catch (Exception ex) {
538-
ex.printStackTrace(System.err);
539-
}
540-
541-
// return null upon any exception
542-
return null;
543-
}
544-
545386
}

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

+85-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,18 +25,23 @@
2525

2626
package com.sun.javafx.webkit.prism;
2727

28-
import com.sun.javafx.tk.Toolkit;
2928
import java.awt.image.BufferedImage;
29+
import java.awt.image.DataBufferInt;
30+
import java.awt.image.SampleModel;
31+
import java.awt.image.SinglePixelPackedSampleModel;
3032
import java.io.ByteArrayOutputStream;
3133
import java.io.IOException;
34+
import java.nio.IntBuffer;
3235
import java.util.Base64;
3336
import java.util.Iterator;
37+
import javafx.scene.image.PixelFormat;
38+
import javafx.scene.image.WritablePixelFormat;
3439
import javax.imageio.ImageIO;
3540
import javax.imageio.ImageWriter;
3641

3742
import com.sun.javafx.webkit.UIClientImpl;
38-
import com.sun.prism.Image;
3943
import com.sun.prism.Graphics;
44+
import com.sun.prism.Image;
4045
import com.sun.webkit.graphics.WCImage;
4146

4247
/**
@@ -65,8 +70,8 @@ public void deref() {
6570

6671
@Override
6772
protected final byte[] toData(String mimeType) {
68-
Object image = UIClientImpl.toBufferedImage(Toolkit.getImageAccessor().fromPlatformImage(getImage()));
69-
if (image instanceof BufferedImage) {
73+
final BufferedImage image = toBufferedImage(mimeType.equals("image/jpeg"));
74+
if (image != null) {
7075
Iterator<ImageWriter> it = ImageIO.getImageWritersByMIMEType(mimeType);
7176
while (it.hasNext()) {
7277
ByteArrayOutputStream output = new ByteArrayOutputStream();
@@ -98,4 +103,79 @@ protected final String toDataURL(String mimeType) {
98103
}
99104
return null;
100105
}
106+
107+
private static int
108+
getBestBufferedImageType(PixelFormat<?> fxFormat)
109+
{
110+
switch (fxFormat.getType()) {
111+
default:
112+
case BYTE_BGRA_PRE:
113+
case INT_ARGB_PRE:
114+
return BufferedImage.TYPE_INT_ARGB_PRE;
115+
case BYTE_BGRA:
116+
case INT_ARGB:
117+
return BufferedImage.TYPE_INT_ARGB;
118+
case BYTE_RGB:
119+
return BufferedImage.TYPE_INT_RGB;
120+
case BYTE_INDEXED:
121+
return (fxFormat.isPremultiplied()
122+
? BufferedImage.TYPE_INT_ARGB_PRE
123+
: BufferedImage.TYPE_INT_ARGB);
124+
}
125+
}
126+
127+
private static WritablePixelFormat<IntBuffer>
128+
getAssociatedPixelFormat(BufferedImage bimg)
129+
{
130+
switch (bimg.getType()) {
131+
// We lie here for xRGB, but we vetted that the src data was opaque
132+
// so we can ignore the alpha. We use ArgbPre instead of Argb
133+
// just to get a loop that does not have divides in it if the
134+
// PixelReader happens to not know the data is opaque.
135+
case BufferedImage.TYPE_INT_RGB:
136+
case BufferedImage.TYPE_INT_ARGB_PRE:
137+
return PixelFormat.getIntArgbPreInstance();
138+
case BufferedImage.TYPE_INT_ARGB:
139+
return PixelFormat.getIntArgbInstance();
140+
default:
141+
// Should not happen...
142+
throw new InternalError("Failed to validate BufferedImage type");
143+
}
144+
}
145+
146+
private static BufferedImage fromFXImage(Image img, boolean forceRGB) {
147+
final int iw = (int) img.getWidth();
148+
final int ih = (int) img.getHeight();
149+
final int destImageType = forceRGB ? BufferedImage.TYPE_INT_RGB : getBestBufferedImageType(img.getPlatformPixelFormat());
150+
final BufferedImage bimg = new BufferedImage(iw, ih, destImageType);
151+
final DataBufferInt db = (DataBufferInt) bimg.getRaster().getDataBuffer();
152+
final int data[] = db.getData();
153+
final int offset = bimg.getRaster().getDataBuffer().getOffset();
154+
int scan = 0;
155+
final SampleModel sm = bimg.getRaster().getSampleModel();
156+
if (sm instanceof SinglePixelPackedSampleModel) {
157+
scan = ((SinglePixelPackedSampleModel)sm).getScanlineStride();
158+
}
159+
160+
final WritablePixelFormat<IntBuffer> pf = getAssociatedPixelFormat(bimg);
161+
img.getPixels(0, 0, iw, ih, pf, data, offset, scan);
162+
return bimg;
163+
}
164+
165+
private BufferedImage toBufferedImage(boolean forceRGB) {
166+
try {
167+
return fromFXImage(getImage(), forceRGB);
168+
} catch (Exception ex) {
169+
ex.printStackTrace(System.err);
170+
}
171+
172+
// return null upon any exception
173+
return null;
174+
}
175+
176+
@Override
177+
public BufferedImage toBufferedImage() {
178+
return toBufferedImage(false);
179+
}
180+
101181
}

0 commit comments

Comments
 (0)