=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java' --- src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java 2015-08-13 14:51:06 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java 2015-10-10 08:29:27 +0000 @@ -30,11 +30,16 @@ * * @param ps * The holder for images parameters. + * @param transformImage + * The transform image flag that indicates the original image must be transformed + * iff this boolean flag is true, otherwise the method returns the unchanged image + * with new calculated bounds. * * @return The wrapped image with its with and its height. */ @Override - public ImageWrapper processImage(PaintStructure ps) + public ImageWrapper processImage(PaintStructure ps, + boolean transformImage) { BufferedImage img2draw = null; int width = 0; @@ -65,12 +70,21 @@ { heightToCut = ps.height; } + + BufferedImage fullImg = ((ImageWrapper)ps.img).getImage(); + BufferedImage bimg; // partial image, get subimage - BufferedImage fullImg = ((ImageWrapper)ps.img).getImage(); - BufferedImage bimg = fullImg.getSubimage(ps.xOffset, - ps.yOffset, - widthToCut, - heightToCut); + if (transformImage) + { + bimg = fullImg.getSubimage(ps.xOffset, + ps.yOffset, + widthToCut, + heightToCut); + } + else + { + bimg = fullImg; + } if (bimg != null) { @@ -86,12 +100,12 @@ { // check binary image options // 3D color conversions - if (ps.convert3D) + if (ps.convert3D && transformImage) { img2draw = get3DColorsConvertedImage((BufferedImage)img2draw); } // transparency - if (ps.transparent) + if (ps.transparent && transformImage) { int pixTrans = img2draw.getRGB(0, height - 1); img2draw = getTransparentImage(img2draw, pixTrans); === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java' --- src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java 2015-08-13 14:51:06 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java 2015-10-10 08:24:45 +0000 @@ -27,8 +27,12 @@ * * @param ps * The holder for images parameters. + * @param transformImage + * The transform image flag that indicates the original image must be transformed + * iff this boolean flag is true, otherwise the method returns the unchanged image + * with new calculated bounds. * * @return The wrapped image with its with and its height. */ - public ImageWrapper processImage(PaintStructure ps); + public ImageWrapper processImage(PaintStructure ps, boolean transformImage); } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/ImageWrapper.java' --- src/com/goldencode/p2j/ui/client/gui/driver/ImageWrapper.java 2015-05-18 20:48:28 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/ImageWrapper.java 2015-10-10 08:52:50 +0000 @@ -74,4 +74,45 @@ { return width; } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + height; + result = prime * result + ((image == null) ? 0 : image.hashCode()); + result = prime * result + width; + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ImageWrapper other = (ImageWrapper) obj; + if (height != other.height) + return false; + if (image == null) + { + if (other.image != null) + return false; + } + else if (!image.equals(other.image)) + return false; + if (width != other.width) + return false; + return true; + } } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/PaintStructure.java' --- src/com/goldencode/p2j/ui/client/gui/driver/PaintStructure.java 2015-09-16 16:53:54 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/PaintStructure.java 2015-10-10 09:14:46 +0000 @@ -34,6 +34,18 @@ */ public class PaintStructure { + /** convert 3d image bit mask */ + private static final int CONVERT_3D_MASK = 1; + + /** transparent image bit mask */ + private static final int TRANSPARENT_MASK = 2; + + /** stretch to fit image bit mask */ + private static final int STRETCH_TO_FIT_MASK = 4; + + /** retain shape image bit mask */ + private static final int RETAIN_SHAPE_MASK = 8; + /** Paint operation */ public PaintPrimitives id; @@ -119,4 +131,169 @@ { this.id = id; } + + /** + * Return the embedded image structure filled with the required parameters to draw the target. + * + * @return The embedded image structure. + */ + public EmbeddedImageStructure getEmbeddedImageStructure() + { + return new EmbeddedImageStructure(); + } + + /** + * Encapsulates the image drawing parameters and the image caching hash code. + */ + public class EmbeddedImageStructure + { + /** + * Returns the image canvas width. + * + * @return The width. + */ + public int getWidth() + { + return width; + } + + /** + * Returns the image canvas height. + * + * @return The canvas height. + */ + public int getHeight() + { + return height; + } + + /** + * The image drawing offset along x-axis. + * + * @return The xOffset + */ + public int getxOffset() + { + return xOffset; + } + + /** + * The image drawing offset along y-axis. + * + * @return The yOffset. + */ + public int getyOffset() + { + return yOffset; + } + + /** + * Returns the wrapped image to draw. + * + * @return The wrapped image. + */ + public ImageWrapper getImage() + { + return img; + } + + /** + * Encodes image conversions: 3d, transparent, stretch, retain. + * + * @return The bits mask that encodes image conversions. + */ + public int getImageConversionMask() + { + int mask = 0; + if (convert3D) + { + mask |= CONVERT_3D_MASK; + } + if (transparent) + { + mask |= TRANSPARENT_MASK; + } + if (stretchToFit) + { + mask |= STRETCH_TO_FIT_MASK; + } + if (retainShape) + { + mask |= RETAIN_SHAPE_MASK; + } + + return mask; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + getImageConversionMask(); + result = prime * result + ((img == null) ? 0 : img.hashCode()); + result = prime * result + height; + result = prime * result + width; + result = prime * result + xOffset; + result = prime * result + yOffset; + return result; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + EmbeddedImageStructure other = (EmbeddedImageStructure) obj; + + if (getImageConversionMask() != other.getImageConversionMask()) + { + return false; + } + if (getImage() == null) + { + if (other.getImage() != null) + { + return false; + } + } + else if (!getImage().equals(other.getImage())) + { + return false; + } + if (width != other.getWidth()) + { + return false; + } + if (height != other.getHeight()) + { + return false; + } + if (xOffset != other.getxOffset()) + { + return false; + } + if (yOffset != other.getyOffset()) + { + return false; + } + return true; + } + } } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java' --- src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java 2015-10-06 19:09:18 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java 2015-10-10 09:18:27 +0000 @@ -716,7 +716,7 @@ g2.drawRoundRect(ps.x, ps.y, ps.width, ps.height, ps.arcDiameter, ps.arcDiameter); break; case DRAW_IMAGE: - ImageWrapper preparedImage = drawHelper.processImage(ps); + ImageWrapper preparedImage = drawHelper.processImage(ps, true); if (preparedImage.getImage() != null) { g2.drawImage(preparedImage.getImage(), ps.x, ps.y, preparedImage.getWidth(), preparedImage.getHeight(), pane); } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java' --- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-09-29 14:43:06 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-10-10 09:15:46 +0000 @@ -320,12 +320,13 @@ break; case DRAW_IMAGE: { - ImageWrapper wrappedImage = drawHelper.processImage(ps); - Object[] imageEncodedPacket = encodeImage(ps.x, ps.y, wrappedImage); + int hashCode = ps.getEmbeddedImageStructure().hashCode(); + Object[] imageEncodedPacket = encodeImage(ps, hashCode); int imageHash = (Integer) imageEncodedPacket[0]; ImageEncoding encoding = (ImageEncoding) imageEncodedPacket[1]; byte[] encodedImage = (byte[]) imageEncodedPacket[2]; - websock.drawImage(ps.x, ps.y, wrappedImage.getWidth(), wrappedImage.getHeight(), + ImageWrapper embeddedImage = (ImageWrapper) imageEncodedPacket[3]; + websock.drawImage(ps.x, ps.y, embeddedImage.getWidth(), embeddedImage.getHeight(), encoding, imageHash, encodedImage); } break; @@ -417,12 +418,13 @@ break; case SET_ICON: { - ImageWrapper wrappedImage = drawHelper.processImage(ps); - Object[] imageEncodedPacket = encodeImage(ps.x, ps.y, wrappedImage); + int hashCode = ps.getEmbeddedImageStructure().hashCode(); + Object[] imageEncodedPacket = encodeImage(ps, hashCode); int imageHash = (Integer) imageEncodedPacket[0]; ImageEncoding encoding = (ImageEncoding) imageEncodedPacket[1]; byte[] encodedImage = (byte[]) imageEncodedPacket[2]; - websock.setIconImage(wrappedImage.getWidth(), wrappedImage.getHeight(), encoding, + ImageWrapper embeddedImage = (ImageWrapper) imageEncodedPacket[3]; + websock.setIconImage(embeddedImage.getWidth(), embeddedImage.getHeight(), encoding, imageHash, encodedImage); } break; @@ -436,37 +438,39 @@ * the image hash in its first element, the image encoding in its second element * and the encoded image or null in its third element depending on its loaded state. * - * @param x - * The x-coordinate of the target image position. - * @param y - * The y-coordinate of the target image position. - * @param wrappedImage - * The wrapped image. + * @param ps + * The paint structure filled with the target image parameters. + * @param imageHash + * The image unique id. * - * @return The 3-elements array that holds the image hash in its first element, - * the image encoding in its second element and the bytes array of the encoded image - * or null in its third element. + * @return The 4-elements array that holds the image hash in its first element, the image + * encoding in its second element, the bytes array of the encoded image or null + * in its third element and the embedded image in its forth element. */ - private final Object[] encodeImage(int x, int y, ImageWrapper wrappedImage) + private final Object[] encodeImage(PaintStructure ps, int imageHash) { VirtualScreen virtualScreen = webdriver.getVirtualScreen(); - int imageHash = wrappedImage.getImage().hashCode(); ImageEncoding encoding; byte[] encodedImage; + ImageWrapper embeddedImage; if (webdriver.addImageUsage(imageHash, windowId)) { + int x = ps.x; + int y = ps.y; + embeddedImage = drawHelper.processImage(ps, true); encoding = ImageEncoding.RAW; - virtualScreen.drawImage(wrappedImage, x, y); + virtualScreen.drawImage(embeddedImage, x, y); encodedImage = new RawEncoder().packToBinaries(virtualScreen, x, y, - wrappedImage.getWidth(), wrappedImage.getHeight()); + embeddedImage.getWidth(), embeddedImage.getHeight()); } else { encoding = ImageEncoding.HASH; encodedImage = null; + embeddedImage = drawHelper.processImage(ps, false); } - return new Object[] {imageHash, encoding, encodedImage}; + return new Object[] {imageHash, encoding, encodedImage, embeddedImage}; } /**