=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.keymap.js' --- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.keymap.js 2015-10-12 08:01:00 +0000 +++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.keymap.js 2015-10-12 15:13:00 +0000 @@ -17,6 +17,7 @@ ** 005 GES 20150701 Added a clarifying comment. ** 006 SBI 20150922 Rewrite to create separate ChUI and GUI implementations. ** 007 SBI 20151006 Improvements to support better GUI key processing compatibility. +** 008 SBI 20151011 Added SHIFT + DEL key label to return 639 as its key code. */ "use strict"; @@ -1120,7 +1121,7 @@ basicKeys[650] = "MIDDLE-MOUSE-DBLCLICK"; // differences for multi-byte keys - extendedKeys[639] = "SHIFT-DELETE"; + extendedKeys[639] = "SHIFT-DEL"; extendedKeys[1021] = "SHIFT-SHIFT-TAB"; extendedKeys[1024] = "ALT"; extendedKeys[1033] = "ALT-CTRL-I"; === modified file 'src/com/goldencode/p2j/ui/client/gui/GuiKeyboard.java' --- src/com/goldencode/p2j/ui/client/gui/GuiKeyboard.java 2015-10-12 08:42:54 +0000 +++ src/com/goldencode/p2j/ui/client/gui/GuiKeyboard.java 2015-10-12 15:13:08 +0000 @@ -13,6 +13,7 @@ ** 002 CA 20141220 Added mapping for COPY/CTRL-C key function. ** 003 GES 20150708 Added alternative mappings for CUT/COPY/PASTE key functions. ** 004 VIG 20150916 Added keyboard layout support. +** 005 SBI 20151011 Added SHIFT + DEL key label to return 639 as its key code. */ package com.goldencode.p2j.ui.client.gui; === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java' --- src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java 2015-10-11 21:09:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java 2015-10-12 16:10:42 +0000 @@ -11,6 +11,8 @@ ** -#- -I- --Date-- --------------------------------Description---------------------------------- ** 001 SBI 20150810 First version which implements the helper function for image processing ** as a part of the common functionality used by swing and web clients. +** 002 SBI 20151011 Added new method to calculate the transformed image bounds to support images +** caching. */ package com.goldencode.p2j.ui.client.gui.driver; @@ -28,13 +30,13 @@ /** * Do the common transformations on the target image. * - * @param ps + * @param embeddedImageStructure * The holder for images parameters. * * @return The wrapped image with its width and its height. */ @Override - public ImageWrapper processImage(PaintStructure ps) + public ImageWrapper processImage(EmbeddedImageStructure embeddedImageStructure) { BufferedImage img2draw = null; int width = 0; @@ -42,33 +44,33 @@ // scaling factors for vertical and horizontal float kHor = 0; float kVer = 0; - if (ps.xOffset == -1 && ps.yOffset == -1) + if (embeddedImageStructure.getXOffset() == -1 && embeddedImageStructure.getYOffset() == -1) { // full original image - img2draw = ((ImageWrapper)ps.img).getImage(); - width = ps.width; - height = ps.height; - kHor = ((float)ps.width) / ((float) ps.img.getWidth()); - kVer = ((float)ps.height) / ((float) ps.img.getHeight()); + img2draw = embeddedImageStructure.getWrappedImage(); + width = embeddedImageStructure.getWidth(); + height = embeddedImageStructure.getHeight(); + kHor = ((float)embeddedImageStructure.getWidth()) / ((float) embeddedImageStructure.getImage().getWidth()); + kVer = ((float)embeddedImageStructure.getHeight()) / ((float) embeddedImageStructure.getImage().getHeight()); } else { // need to recalc the width and height for subimage to cut // to not go out of image borders - int widthToCut = ps.img.getWidth() - ps.xOffset; - if (widthToCut > ps.width) + int widthToCut = embeddedImageStructure.getImage().getWidth() - embeddedImageStructure.getXOffset(); + if (widthToCut > embeddedImageStructure.getWidth()) { - widthToCut = ps.width; + widthToCut = embeddedImageStructure.getWidth(); } - int heightToCut = ps.img.getHeight() - ps.yOffset; - if (heightToCut > ps.height) + int heightToCut = embeddedImageStructure.getImage().getHeight() - embeddedImageStructure.getYOffset(); + if (heightToCut > embeddedImageStructure.getHeight()) { - heightToCut = ps.height; + heightToCut = embeddedImageStructure.getHeight(); } // partial image, get subimage - BufferedImage fullImg = ((ImageWrapper)ps.img).getImage(); - BufferedImage bimg = fullImg.getSubimage(ps.xOffset, - ps.yOffset, + BufferedImage fullImg = embeddedImageStructure.getWrappedImage(); + BufferedImage bimg = fullImg.getSubimage(embeddedImageStructure.getXOffset(), + embeddedImageStructure.getYOffset(), widthToCut, heightToCut); @@ -77,8 +79,8 @@ img2draw = bimg; width = widthToCut; height = heightToCut; - kHor = ((float)ps.width) / ((float)widthToCut); - kVer = ((float)ps.height) / ((float)heightToCut); + kHor = ((float)embeddedImageStructure.getWidth()) / ((float)widthToCut); + kVer = ((float)embeddedImageStructure.getHeight()) / ((float)heightToCut); } } // finally draw the image @@ -86,39 +88,39 @@ { // check binary image options // 3D color conversions - if (ps.convert3D) + if (embeddedImageStructure.is3D()) { - img2draw = get3DColorsConvertedImage((BufferedImage)img2draw); + img2draw = get3DColorsConvertedImage(img2draw); } // transparency - if (ps.transparent) + if (embeddedImageStructure.isTransparent()) { int pixTrans = img2draw.getRGB(0, height - 1); img2draw = getTransparentImage(img2draw, pixTrans); } // resizing - if (ps.stretchToFit) + if (embeddedImageStructure.isStretchToFit()) { - if (ps.retainShape) + if (embeddedImageStructure.isRetainShape() && kHor != kVer) { // need to calculate native aspect ratio for image // if we have two different scaling factors for x and y we choose only one // to keep scaling in both directions, this must be one that is smaller if (kHor < kVer) { - width = ps.width; + width = embeddedImageStructure.getWidth(); height = Math.round(((float)height) * kHor); } else { width = Math.round(((float)width) * kVer); - height = ps.height; + height = embeddedImageStructure.getHeight(); } } else { - width = ps.width; - height = ps.height; + width = embeddedImageStructure.getWidth(); + height = embeddedImageStructure.getHeight(); } } } @@ -129,69 +131,69 @@ /** * Calculate the transformed image bounds. * - * @param ps + * @param embeddedImageStructure * The holder for images parameters. * * @return The 2-elements array filled with new transformed image width and its new height. */ @Override - public Integer[] calculateImageBounds(PaintStructure ps) + public Integer[] calculateImageBounds(EmbeddedImageStructure embeddedImageStructure) { int width = 0; int height = 0; // scaling factors for vertical and horizontal float kHor = 0; float kVer = 0; - if (ps.xOffset == -1 && ps.yOffset == -1) + if (embeddedImageStructure.getXOffset() == -1 && embeddedImageStructure.getYOffset() == -1) { - width = ps.width; - height = ps.height; - kHor = ((float)ps.width) / ((float) ps.img.getWidth()); - kVer = ((float)ps.height) / ((float) ps.img.getHeight()); + width = embeddedImageStructure.getWidth(); + height = embeddedImageStructure.getHeight(); + kHor = ((float)embeddedImageStructure.getWidth()) / ((float) embeddedImageStructure.getImage().getWidth()); + kVer = ((float)embeddedImageStructure.getHeight()) / ((float) embeddedImageStructure.getImage().getHeight()); } else { // need to recalc the width and height for subimage to cut // to not go out of image borders - int widthToCut = ps.img.getWidth() - ps.xOffset; - if (widthToCut > ps.width) + int widthToCut = embeddedImageStructure.getImage().getWidth() - embeddedImageStructure.getXOffset(); + if (widthToCut > embeddedImageStructure.getWidth()) { - widthToCut = ps.width; + widthToCut = embeddedImageStructure.getWidth(); } - int heightToCut = ps.img.getHeight() - ps.yOffset; - if (heightToCut > ps.height) + int heightToCut = embeddedImageStructure.getImage().getHeight() - embeddedImageStructure.getYOffset(); + if (heightToCut > embeddedImageStructure.getHeight()) { - heightToCut = ps.height; + heightToCut = embeddedImageStructure.getHeight(); } width = widthToCut; height = heightToCut; - kHor = ((float)ps.width) / ((float)widthToCut); - kVer = ((float)ps.height) / ((float)heightToCut); + kHor = ((float)embeddedImageStructure.getWidth()) / ((float)widthToCut); + kVer = ((float)embeddedImageStructure.getHeight()) / ((float)heightToCut); } // resizing - if (ps.stretchToFit) + if (embeddedImageStructure.isStretchToFit()) { - if (ps.retainShape) + if (embeddedImageStructure.isRetainShape() && kHor != kVer) { // need to calculate native aspect ratio for image // if we have two different scaling factors for x and y we choose only one // to keep scaling in both directions, this must be one that is smaller if (kHor < kVer) { - width = ps.width; + width = embeddedImageStructure.getWidth(); height = Math.round(((float)height) * kHor); } else { width = Math.round(((float)width) * kVer); - height = ps.height; + height = embeddedImageStructure.getHeight(); } } else { - width = ps.width; - height = ps.height; + width = embeddedImageStructure.getWidth(); + height = embeddedImageStructure.getHeight(); } } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java' --- src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java 2015-10-11 21:09:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java 2015-10-12 16:10:55 +0000 @@ -10,11 +10,12 @@ ** ** -#- -I- --Date-- --------------------------------Description---------------------------------- ** 001 SBI 20150810 First version which defines a helper function for image processing. +** 002 SBI 20151011 Added new method to calculate the transformed image bounds to support images +** caching. */ package com.goldencode.p2j.ui.client.gui.driver; -import java.awt.image.BufferedImage; /** * Defines additional processing for images. @@ -27,20 +28,20 @@ /** * Do the implemented transformations on the target image. * - * @param ps + * @param embeddedImageStructure * The holder for images parameters. * * @return The wrapped image with its width and its height. */ - public ImageWrapper processImage(PaintStructure ps); + public ImageWrapper processImage(EmbeddedImageStructure embeddedImageStructure); /** * Calculate the transformed image bounds. * - * @param ps + * @param embeddedImageStructure * The holder for images parameters. * * @return The 2-elements array filled with new transformed image width and its new height. */ - public Integer[] calculateImageBounds(PaintStructure ps); + public Integer[] calculateImageBounds(EmbeddedImageStructure embeddedImageStructure); } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/EmbeddedImageStructure.java' --- src/com/goldencode/p2j/ui/client/gui/driver/EmbeddedImageStructure.java 2015-10-11 21:09:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/EmbeddedImageStructure.java 2015-10-12 16:21:37 +0000 @@ -14,14 +14,13 @@ package com.goldencode.p2j.ui.client.gui.driver; -import java.util.Arrays; -import java.util.List; +import java.util.*; /** * Encapsulates the image drawing parameters. */ -public class EmbeddedImageStructure +public class EmbeddedImageStructure { /** convert 3d image bit mask */ static final int CONVERT_3D_MASK = 1; @@ -49,7 +48,7 @@ private final int yOffset; /** Image to draw */ - private final ImageWrapper img; + private final ImageWrapper img; /** The bits mask that encodes image conversions. */ private final int imageConversionMask; @@ -57,7 +56,7 @@ /** * @param paintStructure */ - EmbeddedImageStructure(PaintStructure paintStructure) + private EmbeddedImageStructure(PaintStructure paintStructure) { this.width = paintStructure.width; this.height = paintStructure.height; @@ -72,7 +71,7 @@ * * @return The bits mask that encodes image conversions. */ - private static byte encodeImageConversionMask(PaintStructure paintStructure) + private static byte encodeImageConversionMask(PaintStructure paintStructure) { byte mask = 0; if (paintStructure.convert3D) @@ -120,7 +119,7 @@ * * @return The xOffset */ - public int getxOffset() + public int getXOffset() { return this.xOffset; } @@ -130,22 +129,32 @@ * * @return The yOffset. */ - public int getyOffset() + public int getYOffset() { return this.yOffset; } /** - * Returns the wrapped image to draw. + * Returns the wrapped image. * * @return The wrapped image. */ - public ImageWrapper getImage() + public ImageWrapper getImage() { return this.img; } /** + * Returns the target image to draw. + * + * @return The target image to draw. + */ + public I getWrappedImage() + { + return (this.img != null) ? this.img.getImage() : null; + } + + /** * Encodes image conversions: 3d, transparent, stretch, retain. * * @return The bits mask that encodes image conversions. @@ -168,4 +177,72 @@ this.imageConversionMask, this.img.getUniqueId() }); } + + /** + * Helper method to get the conversion mask is supported or not. + * + * @param conversion + * The conversion mask that can be one of CONVERT_3D_MASK, RETAIN_SHAPE_MASK, + * STRETCH_TO_FIT_MASK, TRANSPARENT_MASK. + * + * @return true iff the target conversion is supported. + */ + private boolean hasConversion(int conversion) + { + return (this.imageConversionMask & conversion) == conversion; + } + + /** + * Indicates the image should retain shape. + * + * @return true iff the image should retain shape. + */ + public boolean isRetainShape() + { + return hasConversion(RETAIN_SHAPE_MASK); + } + + /** + * Indicates the image should be 3D style. + * + * @return true iff the image should have 3D style. + */ + public boolean is3D() + { + return hasConversion(CONVERT_3D_MASK); + } + + /** + * Indicates the image should stretch to fit the embedded space. + * + * @return true iff the image should stretch to fit the embedded space. + */ + public boolean isStretchToFit() + { + return hasConversion(STRETCH_TO_FIT_MASK); + } + + /** + * Indicates the image should be transparent. + * + * @return true iff the image should be transparent. + */ + public boolean isTransparent() + { + return hasConversion(TRANSPARENT_MASK); + } + + /** + * Creates the embedded image structure filled with the required parameters to draw the target. + * + * @param ps + * The paint structure. + * + * @return The embedded image structure. + */ + public static EmbeddedImageStructure create(PaintStructure ps) + { + return new EmbeddedImageStructure(ps); + } + } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/ImageWrapper.java' --- src/com/goldencode/p2j/ui/client/gui/driver/ImageWrapper.java 2015-10-11 21:09:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/ImageWrapper.java 2015-10-12 16:24:07 +0000 @@ -10,11 +10,12 @@ ** ** -#- -I- --Date-- ---------------------------------Description--------------------------------- ** 001 GES 20150420 First version. +** 002 SBI 20151012 Added unique ids support. */ package com.goldencode.p2j.ui.client.gui.driver; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.*; /** * Contains the state for a native image which can be accessed in a general purpose manner. @@ -66,16 +67,6 @@ } /** - * Returns the image unique id. - * - * @return The image unique id. - */ - public int getUniqueId() - { - return uniqueId; - } - - /** * Obtain the contained native image instance. * * @return The contained image. @@ -104,4 +95,14 @@ { return width; } + + /** + * Returns the image unique id. + * + * @return The image unique id. + */ + public int getUniqueId() + { + return uniqueId; + } } === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/PaintStructure.java' --- src/com/goldencode/p2j/ui/client/gui/driver/PaintStructure.java 2015-10-11 21:09:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/PaintStructure.java 2015-10-12 15:13:55 +0000 @@ -118,14 +118,5 @@ { 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(this); - } + } === 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-12 16:27:03 +0000 @@ -68,6 +68,7 @@ ** SwingUtilities.invokeAndWait must be bracketed in a save/restore bracket state ** calls, to allow the AWTEventThread to process the request; otherwise, deadlocks ** may occur. +** 033 SBI 20151012 Changed the image helper method signature to be more specific. */ package com.goldencode.p2j.ui.client.gui.driver.swing; @@ -716,7 +717,8 @@ 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( + EmbeddedImageStructure.create(ps)); 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-10-11 21:09:40 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-10-12 16:12:48 +0000 @@ -23,7 +23,8 @@ ** 006 CA 20150929 Fixed multi-window drawing issues caused by concurrent drawing access to the ** GuiDriver: all access to the driver is done exclusively, each thread taking ** and releasing ownership for the duration of the drawing operation or other -** GUI API invocation which requires access to the underlying physical window. +** GUI API invocation which requires access to the underlying physical window. +** 007 SBI 20151011 Fixed images caching. */ package com.goldencode.p2j.ui.client.gui.driver.web; @@ -448,7 +449,7 @@ */ private final Object[] encodeImage(PaintStructure ps) { - EmbeddedImageStructure embeddedImageStructure = ps.getEmbeddedImageStructure(); + EmbeddedImageStructure embeddedImageStructure = EmbeddedImageStructure.create(ps); List imageSeal = embeddedImageStructure.getObjectSeal(); VirtualScreen virtualScreen = webdriver.getVirtualScreen(); ImageEncoding encoding; @@ -460,7 +461,7 @@ { int x = ps.x; int y = ps.y; - ImageWrapper embeddedImage = drawHelper.processImage(ps); + ImageWrapper embeddedImage = drawHelper.processImage(embeddedImageStructure); imageId = embeddedImage.getUniqueId(); webdriver.mapSealToUniqueId(imageSeal, imageId); imageWidth = embeddedImage.getWidth(); @@ -475,7 +476,7 @@ imageId = webdriver.getUniqueIdForSeal(imageSeal); encoding = ImageEncoding.HASH; encodedImage = null; - Integer[] imageBounds = drawHelper.calculateImageBounds(ps); + Integer[] imageBounds = drawHelper.calculateImageBounds(embeddedImageStructure); imageWidth = imageBounds[0]; imageHeight = imageBounds[1]; }