Project

General

Profile

1811o_20150810_1.txt

Sergey Ivanovskiy, 08/10/2015 05:01 PM

Download (56.6 KB)

 
1
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js'
2
--- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js	2015-08-10 18:28:09 +0000
3
+++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js	2015-08-10 20:38:03 +0000
4
@@ -19,9 +19,9 @@
5
 **                  can be used for both ChUI and GUI web clients.
6
 ** 008 SBI 20150731 Applied "use strict" directive, fixed undeclared variables.
7
 ** 009 GES 20150709 Added support for MSG_READ_CLIPBOARD (server-driven clipboard request) and
8
-**                  MSG_WRITE_CLIPBOARD.
9
-** 010 SBI 20150807 Fixed a network order for reading int32 from binaries message
10
-** 011 CA  20150810 Added infrastructure for font and metrics related requests.
11
+**                  MSG_WRITE_CLIPBOARD, fixed a network order for reading int32
12
+**                  from binaries message.
13
+** 010 CA  20150810 Added infrastructure for font and metrics related requests.
14
 */
15
 
16
 "use strict";
17
@@ -219,7 +219,7 @@
18
 
19
       for (var i = 0; i < 4; i++)
20
       {
21
-         num |= message[offset + i] << (8 * (3-i));
22
+         num |= message[offset + i] << (8 * (3 - i));
23
       }
24
       
25
       return num;
26

    
27
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java'
28
--- src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java	1970-01-01 00:00:00 +0000
29
+++ src/com/goldencode/p2j/ui/client/gui/driver/BufferedImageDrawHelper.java	2015-08-10 20:28:50 +0000
30
@@ -0,0 +1,306 @@
31
+/*
32
+** Module   : BufferedImageDrawHelper.java
33
+** Abstract : Implements the helper function for images processing.
34
+**
35
+** Copyright (c) 2015, Golden Code Development Corporation.
36
+** ALL RIGHTS RESERVED. Use is subject to license terms.
37
+**
38
+**         Golden Code Development Corporation
39
+**                 CONFIDENTIAL
40
+**
41
+** -#- -I- --Date-- --------------------------------Description----------------------------------
42
+** 001 SBI 20150810 First version which implements the helper function for image processing
43
+**                  as a part of the common functionality used by swing and web clients.
44
+*/
45
+
46
+package com.goldencode.p2j.ui.client.gui.driver;
47
+
48
+import java.awt.*;
49
+import java.awt.image.*;
50
+
51
+/**
52
+ * BufferedImageDrawHelper implements the common functionality used by swing and web clients
53
+ * to transform images.
54
+ */
55
+public class BufferedImageDrawHelper implements ClientImageDrawHelper<BufferedImage>
56
+{
57
+
58
+   /**
59
+    * Do the common transformations on the target image.
60
+    * 
61
+    * @param    ps
62
+    *           The holder for images parameters.
63
+    * 
64
+    * @return The wrapped image with its with and its height.
65
+    */
66
+   @Override
67
+   public ImageWrapper<BufferedImage> processImage(PaintStructure<?, BufferedImage> ps)
68
+   {
69
+      BufferedImage img2draw = null;
70
+      int width  = 0;
71
+      int height = 0;
72
+      // scaling factors for vertical and horizontal
73
+      float kHor = 0;
74
+      float kVer = 0;
75
+      if (ps.xOffset == -1 && ps.yOffset == -1)
76
+      {
77
+         // full original image
78
+         img2draw = ((ImageWrapper<BufferedImage>)ps.img).getImage();
79
+         width    = ps.width;
80
+         height   = ps.height;
81
+         kHor = ((float)ps.width) / ((float) ps.img.getWidth());
82
+         kVer = ((float)ps.height) / ((float) ps.img.getHeight()); 
83
+      }
84
+      else
85
+      {
86
+         // need to recalc the width and height for subimage to cut
87
+         // to not go out of image borders
88
+         int widthToCut = ps.img.getWidth() - ps.xOffset;
89
+         if (widthToCut > ps.width)
90
+         {
91
+            widthToCut = ps.width;
92
+         }
93
+         int heightToCut = ps.img.getHeight() - ps.yOffset;
94
+         if (heightToCut > ps.height)
95
+         {
96
+            heightToCut = ps.height;
97
+         }
98
+         // partial image, get subimage
99
+         BufferedImage fullImg = ((ImageWrapper<BufferedImage>)ps.img).getImage();
100
+         BufferedImage bimg = fullImg.getSubimage(ps.xOffset,
101
+                                                  ps.yOffset,
102
+                                                  widthToCut,
103
+                                                  heightToCut);
104
+         
105
+         if (bimg != null)
106
+         {
107
+            img2draw = bimg;
108
+            width    = widthToCut;
109
+            height   = heightToCut;
110
+            kHor = ((float)ps.width) / ((float)widthToCut);
111
+            kVer = ((float)ps.height) / ((float)heightToCut); 
112
+         }
113
+      }
114
+      // finally draw the image
115
+      if (img2draw != null)
116
+      {
117
+         // check binary image options
118
+         // 3D color conversions
119
+         if (ps.convert3D)
120
+         {
121
+            img2draw = get3DColorsConvertedImage((BufferedImage)img2draw);
122
+         }
123
+         // transparency
124
+         if (ps.transparent)
125
+         {
126
+            int pixTrans = img2draw.getRGB(0, height - 1);
127
+            img2draw = getTransparentImage(img2draw, pixTrans);
128
+         }
129
+         // resizing
130
+         if (ps.stretchToFit)
131
+         {
132
+            if (ps.retainShape)
133
+            {
134
+               // need to calculate native aspect ratio for image
135
+               // if we have two different scaling factors for x and y we choose only one
136
+               // to keep scaling in both directions, this must be one that is smaller
137
+               if (kHor < kVer)
138
+               {
139
+                  width  = ps.width;
140
+                  height = Math.round(((float)height) * kHor);
141
+               }
142
+               else
143
+               {
144
+                  width = Math.round(((float)width) * kVer);
145
+                  height = ps.height;
146
+               }
147
+            }
148
+            else
149
+            {
150
+               width  = ps.width;
151
+               height = ps.height;
152
+            }
153
+         }
154
+      }
155
+
156
+      return new ImageWrapper<BufferedImage>(img2draw, height, width);
157
+   }
158
+
159
+   /**
160
+    * Converts the image replacing standard 3D colors with currently redefined.
161
+    * 
162
+    * @param   img
163
+    *          Initial image to convert.
164
+    * 
165
+    * @return   The image with replaced 3D colors color.
166
+    */
167
+   private BufferedImage get3DColorsConvertedImage(BufferedImage img)
168
+   {
169
+      // define custom image producer
170
+      ImageProducer ip = new FilteredImageSource(img.getSource(),
171
+                            new Convert3DColorsFilter(SystemColor.controlLtHighlight.getRGB(),
172
+                                                      SystemColor.control.getRGB(),
173
+                                                      SystemColor.controlShadow.getRGB(),
174
+                                                      SystemColor.controlText.getRGB()));
175
+      // convert image
176
+      return getBufferedImage(Toolkit.getDefaultToolkit().createImage(ip));
177
+   }
178
+
179
+   /**
180
+    * Converts the image into buffered image.
181
+    * 
182
+    * @param   imgToConvert
183
+    *          Initial image to convert.
184
+    * 
185
+    * @return   The buffered image for further use.
186
+    */
187
+   private BufferedImage getBufferedImage(java.awt.Image imgToConvert)
188
+   {
189
+      // create empty image
190
+      BufferedImage imgRes = new BufferedImage(imgToConvert.getWidth(null),
191
+                                               imgToConvert.getHeight(null),
192
+                                               BufferedImage.TYPE_INT_ARGB);
193
+
194
+      // copy data to newly created image
195
+      Graphics2D g2img = imgRes.createGraphics();
196
+      g2img.drawImage(imgToConvert, 0, 0, null);
197
+      g2img.dispose();
198
+      
199
+      return imgRes;
200
+   }
201
+
202
+   /**
203
+    * Custom RGB filter to change image transparency data on the fly.
204
+    */
205
+   static class TransparencyFilter
206
+   extends RGBImageFilter
207
+   {
208
+      /** Alpha channel constant. */
209
+      private static final int TRANSPARENCY_MASK = 0xFF000000;
210
+      
211
+      /** Pixel to use as transparent marker. */
212
+      int rgbCheck;
213
+      
214
+      /**
215
+       * Creates new filter with the given transparent pixel value.
216
+       *
217
+       * @param   pixTrans
218
+       *          The pixel sample we will consider as transparent.
219
+       */
220
+      TransparencyFilter(int pixTrans)
221
+      {
222
+         rgbCheck = pixTrans | TRANSPARENCY_MASK;
223
+      }
224
+
225
+      /**
226
+       * This is on the fly converter to turn on transparency for every pixels the sames as
227
+       * one we defined as marker on the filter construction.  This method is calling when image
228
+       * drawing is happening.
229
+       *
230
+       * @param   x
231
+       *          The X pixel coordinate.
232
+       * @param   y
233
+       *          The Y pixel coordinate.
234
+       * @param   pixel
235
+       *          The ARGB pixel value of the original image.
236
+       * 
237
+       * @return   The new ARGB pixel value after transformation to render.
238
+       */
239
+      public int filterRGB(int x, int y, int pixel)
240
+      {
241
+         return (pixel | TRANSPARENCY_MASK) == rgbCheck ? pixel & ~TRANSPARENCY_MASK : pixel; 
242
+      }
243
+   }
244
+
245
+   /**
246
+    * Converts the image to one having transparent color.
247
+    * 
248
+    * @param   img
249
+    *          Initial image to convert.
250
+    * @param   transPix
251
+    *          The color to be considered as transparent.
252
+    * 
253
+    * @return   The image with one tarnsparent color.
254
+    */
255
+   private BufferedImage getTransparentImage(BufferedImage img, int transPix)
256
+   {
257
+      // define custom image producer
258
+      ImageProducer ip = new FilteredImageSource(img.getSource(),
259
+                                                 new TransparencyFilter(transPix));
260
+      // convert image
261
+      return getBufferedImage(Toolkit.getDefaultToolkit().createImage(ip));
262
+   }
263
+
264
+   /**
265
+    * Custom RGB filter to change image 3D colors on the fly.
266
+    */
267
+   static class Convert3DColorsFilter
268
+   extends RGBImageFilter
269
+   {
270
+      /** Original 3D white color(255, 255, 255). */
271
+      private static final int COLOR_3D_WHITE   = 0x00FFFFFF;
272
+      
273
+      /** Original 3D light gray color(192, 192, 192). */
274
+      private static final int COLOR_3D_LT_GRAY = 0x00C0C0C0;
275
+      
276
+      /** Original 3D dark gray color(128, 128, 128). */
277
+      private static final int COLOR_3D_DK_GRAY = 0x00808080;
278
+      
279
+      /** Original 3D black color(0, 0, 0). */
280
+      private static final int COLOR_3D_BLACK   = 0x00000000;
281
+      
282
+      /** New value for 3D white. */
283
+      int newWhite;
284
+
285
+      /** New value for 3D light gray. */
286
+      int newLtGray;
287
+      
288
+      /** New value for 3D dark gray. */
289
+      int newDkGray;
290
+      
291
+      /** New value for 3D black. */
292
+      int newBlack;
293
+      
294
+      /**
295
+       * Creates new filter with the given 3D colors to replace.
296
+       *
297
+       * @param   white
298
+       *          The new value for white color.
299
+       * @param   ltGray
300
+       *          The new value for light gray color.
301
+       * @param   dkGray
302
+       *          The new value for dark gray color.
303
+       * @param   black
304
+       *          The new value for dark gray color.
305
+       */
306
+      Convert3DColorsFilter(int white, int ltGray, int dkGray, int black)
307
+      {
308
+         newWhite  = white;
309
+         newLtGray = ltGray;
310
+         newDkGray = dkGray;
311
+         newBlack  = black;
312
+      }
313
+
314
+      /**
315
+       * This is on the fly converter to change the 3D colors with one we passed on the filter
316
+       * construction.  This method is calling when image drawing is happening.
317
+       *
318
+       * @param   x
319
+       *          The X pixel coordinate.
320
+       * @param   y
321
+       *          The Y pixel coordinate.
322
+       * @param   pixel
323
+       *          The ARGB pixel value of the original image.
324
+       * 
325
+       * @return   The new ARGB pixel value after transformation to render.
326
+       */
327
+      public int filterRGB(int x, int y, int pixel)
328
+      {
329
+         return (pixel | COLOR_3D_WHITE) == COLOR_3D_WHITE ? newWhite : 
330
+                (pixel | COLOR_3D_LT_GRAY) == COLOR_3D_LT_GRAY ? newLtGray :
331
+                (pixel | COLOR_3D_DK_GRAY) == COLOR_3D_DK_GRAY ? newDkGray :
332
+                (pixel | COLOR_3D_BLACK) == COLOR_3D_BLACK ? newBlack : pixel; 
333
+      }
334
+   }
335
+
336
+}
337

    
338
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java'
339
--- src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java	1970-01-01 00:00:00 +0000
340
+++ src/com/goldencode/p2j/ui/client/gui/driver/ClientImageDrawHelper.java	2015-08-10 20:25:46 +0000
341
@@ -0,0 +1,34 @@
342
+/*
343
+** Module   : ClientImageDrawHelper.java
344
+** Abstract : Defines a helper function for images processing.
345
+**
346
+** Copyright (c) 2015, Golden Code Development Corporation.
347
+** ALL RIGHTS RESERVED. Use is subject to license terms.
348
+**
349
+**         Golden Code Development Corporation
350
+**                 CONFIDENTIAL
351
+**
352
+** -#- -I- --Date-- --------------------------------Description----------------------------------
353
+** 001 SBI 20150810 First version which defines a helper function for image processing.
354
+*/
355
+
356
+package com.goldencode.p2j.ui.client.gui.driver;
357
+
358
+/**
359
+ * Defines additional processing for images.
360
+ * 
361
+ * @param    <I>
362
+ *           The source image type.
363
+ */
364
+public interface ClientImageDrawHelper<I>
365
+{
366
+   /**
367
+    * Do the implemented transformations on the target image.
368
+    * 
369
+    * @param    ps
370
+    *           The holder for images parameters.
371
+    * 
372
+    * @return The wrapped image with its with and its height.
373
+    */
374
+   ImageWrapper<I> processImage(PaintStructure<?, I> ps);
375
+}
376

    
377
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/VirtualScreen.java'
378
--- src/com/goldencode/p2j/ui/client/gui/driver/VirtualScreen.java	1970-01-01 00:00:00 +0000
379
+++ src/com/goldencode/p2j/ui/client/gui/driver/VirtualScreen.java	2015-08-10 18:21:23 +0000
380
@@ -0,0 +1,64 @@
381
+/*
382
+** Module   : VirtualScreen.java
383
+** Abstract : Define methods to work with screen
384
+**
385
+** Copyright (c) 2015, Golden Code Development Corporation.
386
+** ALL RIGHTS RESERVED. Use is subject to license terms.
387
+**
388
+**         Golden Code Development Corporation
389
+**                 CONFIDENTIAL
390
+**
391
+** -#- -I- --Date-- --------------------------------Description----------------------------------
392
+** 001 SBI 20150810 First version which describes a virtual screen based on sRGB model.
393
+*/
394
+
395
+package com.goldencode.p2j.ui.client.gui.driver;
396
+
397
+import java.awt.image.DirectColorModel;
398
+
399
+/**
400
+ * VirtualScreen describes a virtual screen based on sRGB model. It provides an access
401
+ * to a screen pixel model and perform drawing operations.
402
+ */
403
+public interface VirtualScreen
404
+{
405
+   /**
406
+    * Returns RGBA model via pixels, each pixel is encoded as an integer.
407
+    * 
408
+    * @return   The array of pixels. 
409
+    */
410
+   int[] getPixels();
411
+   
412
+   /**
413
+    * Gets a screen width.
414
+    * 
415
+    * @return   The screen width.
416
+    */
417
+   int getScreenWidth();
418
+   
419
+   /**
420
+    * Gets a screen height.
421
+    * 
422
+    * @return   The screen height
423
+    */
424
+   int getScreenHeight();
425
+   
426
+   /**
427
+    * Describes a pixel format used for drawing.
428
+    * 
429
+    * @return The color model.
430
+    */
431
+   DirectColorModel getColorModel();
432
+   
433
+   /**
434
+    * Draw an image at the target position on the screen.
435
+    * 
436
+    * @param    image
437
+    *           The target image.
438
+    * @param    x
439
+    *           The x-coordinate of the target image position. 
440
+    * @param    y
441
+    *           The y-coordinate of the target image position.
442
+    */
443
+   void drawImage(ImageWrapper image, int x, int y);
444
+}
445

    
446
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java'
447
--- src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java	2015-08-07 20:47:38 +0000
448
+++ src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingEmulatedWindow.java	2015-08-10 20:31:10 +0000
449
@@ -53,7 +53,8 @@
450
 ** 026 HC  20150612 Support for modal windows.
451
 ** 027 HC  20150702 Implemented window modality independently on the actual UI driver. Improved
452
 **                  positioning of top-level windows on systems with multiple displays.
453
-** 028 GES 20150715 Cleanup of window resources by calling quit() on the content pane.
454
+** 028 GES 20150715 Cleanup of window resources by calling quit() on the content pane,
455
+**                  moved the common image processing functionalities to the separate unit.
456
 */
457
 
458
 package com.goldencode.p2j.ui.client.gui.driver.swing;
459
@@ -143,6 +144,7 @@
460
    /** Temporary context stored during <code>paintComponent()</code> operations. */
461
    private Graphics graphics = null;
462
    
463
+   private final BufferedImageDrawHelper drawHelper;
464
    /**
465
     * Constructor.
466
     * 
467
@@ -265,6 +267,7 @@
468
                                            new float[] {LineStroke.DOT_STEP_SMALL,
469
                                                         LineStroke.DOT_STEP_SMALL},
470
                                            LineStroke.DOT_STEP_SMALL);
471
+      drawHelper = new BufferedImageDrawHelper();
472
       // TODO: disable the popup of the window actions (min/max/close/etc) via key? 
473
    }
474
 
475
@@ -761,93 +764,9 @@
476
             g2.drawRoundRect(ps.x, ps.y, ps.width, ps.height, ps.arcDiameter, ps.arcDiameter);
477
             break;
478
          case DRAW_IMAGE:
479
-            BufferedImage img2draw = null;
480
-            int width  = 0;
481
-            int height = 0;
482
-            // scalng factors for vertical and horizontal
483
-            float kHor = 0;
484
-            float kVer = 0;
485
-            if (ps.xOffset == -1 && ps.yOffset == -1)
486
-            {
487
-               // full original image
488
-               img2draw = ((ImageWrapper<BufferedImage>)ps.img).getImage();
489
-               width    = ps.width;
490
-               height   = ps.height;
491
-               kHor = ((float)ps.width) / ((float) ps.img.getWidth());
492
-               kVer = ((float)ps.height) / ((float) ps.img.getHeight()); 
493
-            }
494
-            else
495
-            {
496
-               // need to recalc the width and height for subimage to cut
497
-               // to not go out of image borders
498
-               int widthToCut = ps.img.getWidth() - ps.xOffset;
499
-               if (widthToCut > ps.width)
500
-               {
501
-                  widthToCut = ps.width;
502
-               }
503
-               int heightToCut = ps.img.getHeight() - ps.yOffset;
504
-               if (heightToCut > ps.height)
505
-               {
506
-                  heightToCut = ps.height;
507
-               }
508
-               // partial image, get subimage
509
-               BufferedImage fullImg = ((ImageWrapper<BufferedImage>)ps.img).getImage();
510
-               BufferedImage bimg = fullImg.getSubimage(ps.xOffset,
511
-                                                        ps.yOffset,
512
-                                                        widthToCut,
513
-                                                        heightToCut);
514
-               
515
-               if (bimg != null)
516
-               {
517
-                  img2draw = bimg;
518
-                  width    = widthToCut;
519
-                  height   = heightToCut;
520
-                  kHor = ((float)ps.width) / ((float)widthToCut);
521
-                  kVer = ((float)ps.height) / ((float)heightToCut); 
522
-               }
523
-            }
524
-            // finally draw the image
525
-            if (img2draw != null)
526
-            {
527
-               // check binary image options
528
-               // 3D color conversions
529
-               if (ps.convert3D)
530
-               {
531
-                  img2draw = get3DColorsConvertedImage((BufferedImage)img2draw);
532
-               }
533
-               // transparency
534
-               if (ps.transparent)
535
-               {
536
-                  int pixTrans = img2draw.getRGB(0, height - 1);
537
-                  img2draw = getTransparentImage(img2draw, pixTrans);
538
-               }
539
-               // resizing
540
-               if (ps.stretchToFit)
541
-               {
542
-                  if (ps.retainShape)
543
-                  {
544
-                     // need to calculate native aspect ratio for image
545
-                     // if we have two different scaling factors for x and y we choose only one
546
-                     // to keep scaling in both directions, this must be one that is smaller
547
-                     if (kHor < kVer)
548
-                     {
549
-                        width  = ps.width;
550
-                        height = Math.round(((float)height) * kHor);
551
-                     }
552
-                     else
553
-                     {
554
-                        width = Math.round(((float)width) * kVer);
555
-                        height = ps.height;
556
-                     }
557
-                  }
558
-                  else
559
-                  {
560
-                     width  = ps.width;
561
-                     height = ps.height;
562
-                  }
563
-               }
564
-               // call Java backend
565
-               g2.drawImage(img2draw, ps.x, ps.y, width, height, pane);
566
+            ImageWrapper<BufferedImage> preparedImage = drawHelper.processImage(ps);
567
+            if (preparedImage.getImage() != null) {
568
+               g2.drawImage(preparedImage.getImage(), ps.x, ps.y, preparedImage.getWidth(), preparedImage.getHeight(), pane);
569
             }
570
             break;
571
          case FILL_RECT:
572
@@ -1135,68 +1054,6 @@
573
    }
574
    
575
    /**
576
-    * Converts the image to one having transparent color.
577
-    * 
578
-    * @param   img
579
-    *          Initial image to convert.
580
-    * @param   transPix
581
-    *          The color to be considered as transparent.
582
-    * 
583
-    * @return   The image with one tarnsparent color.
584
-    */
585
-   private BufferedImage getTransparentImage(BufferedImage img, int transPix)
586
-   {
587
-      // define custom image producer
588
-      ImageProducer ip = new FilteredImageSource(img.getSource(),
589
-                                                 new TransparencyFilter(transPix));
590
-      // convert image
591
-      return getBufferedImage(Toolkit.getDefaultToolkit().createImage(ip));
592
-   }
593
-   
594
-   /**
595
-    * Converts the image replacing standard 3D colors with currently redefined.
596
-    * 
597
-    * @param   img
598
-    *          Initial image to convert.
599
-    * 
600
-    * @return   The image with replaced 3D colors color.
601
-    */
602
-   private BufferedImage get3DColorsConvertedImage(BufferedImage img)
603
-   {
604
-      // define custom image producer
605
-      ImageProducer ip = new FilteredImageSource(img.getSource(),
606
-                            new Convert3DColorsFilter(SystemColor.controlLtHighlight.getRGB(),
607
-                                                      SystemColor.control.getRGB(),
608
-                                                      SystemColor.controlShadow.getRGB(),
609
-                                                      SystemColor.controlText.getRGB()));
610
-      // convert image
611
-      return getBufferedImage(Toolkit.getDefaultToolkit().createImage(ip));
612
-   }
613
-   
614
-   /**
615
-    * Converts the image into buffered image.
616
-    * 
617
-    * @param   imgToConvert
618
-    *          Initial image to convert.
619
-    * 
620
-    * @return   The buffered image for further use.
621
-    */
622
-   private BufferedImage getBufferedImage(java.awt.Image imgToConvert)
623
-   {
624
-      // create empty image
625
-      BufferedImage imgRes = new BufferedImage(imgToConvert.getWidth(null),
626
-                                               imgToConvert.getHeight(null),
627
-                                               BufferedImage.TYPE_INT_ARGB);
628
-
629
-      // copy data to newly created image
630
-      Graphics2D g2img = imgRes.createGraphics();
631
-      g2img.drawImage(imgToConvert, 0, 0, null);
632
-      g2img.dispose();
633
-      
634
-      return imgRes;
635
-   }
636
-    
637
-   /**
638
     * Draw a string using the current font, which will be scaled so that the final string will
639
     * have the specified legacy width and height.
640
     * <p>
641
@@ -1402,119 +1259,4 @@
642
       
643
       highlightRestoreBuffer = null;
644
    }
645
-   
646
-   /**
647
-    * Custom RGB filter to change image transparency data on the fly.
648
-    */
649
-   static class TransparencyFilter
650
-   extends RGBImageFilter
651
-   {
652
-      /** Alpha channel constant. */
653
-      private static final int TRANSPARENCY_MASK = 0xFF000000;
654
-      
655
-      /** Pixel to use as transparent marker. */
656
-      int rgbCheck;
657
-      
658
-      /**
659
-       * Creates new filter with the given transparent pixel value.
660
-       *
661
-       * @param   pixTrans
662
-       *          The pixel sample we will consider as transparent.
663
-       */
664
-      TransparencyFilter(int pixTrans)
665
-      {
666
-         rgbCheck = pixTrans | TRANSPARENCY_MASK;
667
-      }
668
-
669
-      /**
670
-       * This is on the fly converter to turn on transparency for every pixels the sames as
671
-       * one we defined as marker on the filter construction.  This method is calling when image
672
-       * drawing is happening.
673
-       *
674
-       * @param   x
675
-       *          The X pixel coordinate.
676
-       * @param   y
677
-       *          The Y pixel coordinate.
678
-       * @param   pixel
679
-       *          The ARGB pixel value of the original image.
680
-       * 
681
-       * @return   The new ARGB pixel value after transformation to render.
682
-       */
683
-      public int filterRGB(int x, int y, int pixel)
684
-      {
685
-         return (pixel | TRANSPARENCY_MASK) == rgbCheck ? pixel & ~TRANSPARENCY_MASK : pixel; 
686
-      }
687
-   }
688
-
689
-   /**
690
-    * Custom RGB filter to change image 3D colors on the fly.
691
-    */
692
-   static class Convert3DColorsFilter
693
-   extends RGBImageFilter
694
-   {
695
-      /** Original 3D white color(255, 255, 255). */
696
-      private static final int COLOR_3D_WHITE   = 0x00FFFFFF;
697
-      
698
-      /** Original 3D light gray color(192, 192, 192). */
699
-      private static final int COLOR_3D_LT_GRAY = 0x00C0C0C0;
700
-      
701
-      /** Original 3D dark gray color(128, 128, 128). */
702
-      private static final int COLOR_3D_DK_GRAY = 0x00808080;
703
-      
704
-      /** Original 3D black color(0, 0, 0). */
705
-      private static final int COLOR_3D_BLACK   = 0x00000000;
706
-      
707
-      /** New value for 3D white. */
708
-      int newWhite;
709
-
710
-      /** New value for 3D light gray. */
711
-      int newLtGray;
712
-      
713
-      /** New value for 3D dark gray. */
714
-      int newDkGray;
715
-      
716
-      /** New value for 3D black. */
717
-      int newBlack;
718
-      
719
-      /**
720
-       * Creates new filter with the given 3D colors to replace.
721
-       *
722
-       * @param   white
723
-       *          The new value for white color.
724
-       * @param   ltGray
725
-       *          The new value for light gray color.
726
-       * @param   dkGray
727
-       *          The new value for dark gray color.
728
-       * @param   black
729
-       *          The new value for dark gray color.
730
-       */
731
-      Convert3DColorsFilter(int white, int ltGray, int dkGray, int black)
732
-      {
733
-         newWhite  = white;
734
-         newLtGray = ltGray;
735
-         newDkGray = dkGray;
736
-         newBlack  = black;
737
-      }
738
-
739
-      /**
740
-       * This is on the fly converter to change the 3D colors with one we passed on the filter
741
-       * construction.  This method is calling when image drawing is happening.
742
-       *
743
-       * @param   x
744
-       *          The X pixel coordinate.
745
-       * @param   y
746
-       *          The Y pixel coordinate.
747
-       * @param   pixel
748
-       *          The ARGB pixel value of the original image.
749
-       * 
750
-       * @return   The new ARGB pixel value after transformation to render.
751
-       */
752
-      public int filterRGB(int x, int y, int pixel)
753
-      {
754
-         return (pixel | COLOR_3D_WHITE) == COLOR_3D_WHITE ? newWhite : 
755
-                (pixel | COLOR_3D_LT_GRAY) == COLOR_3D_LT_GRAY ? newLtGray :
756
-                (pixel | COLOR_3D_DK_GRAY) == COLOR_3D_DK_GRAY ? newDkGray :
757
-                (pixel | COLOR_3D_BLACK) == COLOR_3D_BLACK ? newBlack : pixel; 
758
-      }
759
-   }
760
 }
761

    
762
=== removed file 'src/com/goldencode/p2j/ui/client/gui/driver/web/DrawImageOp.java'
763
--- src/com/goldencode/p2j/ui/client/gui/driver/web/DrawImageOp.java	2015-08-07 20:47:38 +0000
764
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/DrawImageOp.java	1970-01-01 00:00:00 +0000
765
@@ -1,114 +0,0 @@
766
-/*
767
-** Module   : DrawImageOp.java
768
-** Abstract : Defines a draw image command.
769
-**
770
-** Copyright (c) 2015, Golden Code Development Corporation.
771
-** ALL RIGHTS RESERVED. Use is subject to license terms.
772
-**
773
-**         Golden Code Development Corporation
774
-**                 CONFIDENTIAL
775
-**
776
-** -#- -I- --Date-- --------------------------------Description----------------------------------
777
-** 001 SBI 20150807 First version which is a draw image command.
778
-** 
779
-** 
780
-*/
781
-
782
-package com.goldencode.p2j.ui.client.gui.driver.web;
783
-
784
-import java.awt.Image;
785
-import java.util.HashSet;
786
-
787
-import com.goldencode.p2j.ui.client.gui.driver.PaintPrimitives;
788
-import com.goldencode.p2j.ui.client.gui.driver.PaintStructure;
789
-
790
-/**
791
- * 
792
- * DrawImageOp performs a draw image on a virtual screen and prepares
793
- * a draw message to transfer via networks, holds a hash map of loaded images.
794
- *
795
- */
796
-public class DrawImageOp
797
-{
798
-
799
-   private final VirtualScreen virtualScreen;
800
-
801
-   private final HashSet<Integer> loadedImages;
802
-   /**
803
-    * 
804
-    * @param virtualScreen
805
-    */
806
-   public DrawImageOp(VirtualScreen virtualScreen)
807
-   {
808
-      this.virtualScreen = virtualScreen;
809
-      this.loadedImages = new HashSet<Integer>();
810
-   }
811
-
812
-   /**
813
-    * Write a 32-bit integer value into a binary message at a given offset.
814
-    *
815
-    * @param    message
816
-    *           Message content as an byte array.
817
-    * @param    offset
818
-    *           Offset into the message at which the integer should be written.
819
-    * @param    value
820
-    *           The 32-bit value to write.
821
-    */
822
-   private void writeMessageInt32(byte[] message, int offset, int value)
823
-   {
824
-      message[offset]     = (byte)((value >> 24) & 0x00FF);
825
-      message[offset + 1] = (byte)((value >> 16) & 0x00FF);
826
-      message[offset + 2] = (byte)((value >> 8)  & 0x00FF);
827
-      message[offset + 3] = (byte)( value        & 0x00FF);
828
-   }
829
-
830
-   /**
831
-    * Perform a draw image on a virtual screen, the image parameters provided
832
-    * in PaintStructure. A binary message format is defined as
833
-    * DRAW_IMAGE, 1 byte, operation id
834
-    * x, 4 bytes, an image x-offset
835
-    * y, 4 bytes, an image y-offset
836
-    * width, 4 bytes, an image width
837
-    * height, 4 bytes, an image width
838
-    * encoding, 1 byte, an image encoding schema, Raw or Hash
839
-    * imageHashCode, 4 bytes, an image hash code
840
-    * image binaries, 4*width*height bytes, an encoded image, it is omitted
841
-    * if an encoding is Hash.
842
-    * @param ps PaintStructure parameters for an image drawing
843
-    * @return byte[] a drawing image prepared to transfer via network. 
844
-    */
845
-   public byte[] execute(PaintStructure ps) {
846
-      int x = ps.xOffset;//4
847
-      int y = ps.yOffset;//4
848
-      Image image = (Image) ps.img.getImage();
849
-      int width = image.getWidth(null);//4
850
-      int height = image.getHeight(null);//4
851
-      virtualScreen.drawImage(image, x, y);
852
-      int imageHash = image.hashCode();
853
-      ImageEncoding encoding;
854
-      if (!loadedImages.contains(imageHash)) {
855
-         loadedImages.add(imageHash);
856
-         encoding = ImageEncoding.RAW;
857
-      } else {
858
-         encoding = ImageEncoding.HASH;
859
-      }
860
-      final byte[] encodedImage = new RawEncoder().packToBinaries(virtualScreen, x, y, width, height);
861
-      int msgLen = 22;
862
-      if (encoding == ImageEncoding.RAW) { 
863
-         msgLen += encodedImage.length;
864
-      }
865
-      byte[] drawImageMsg = new byte[msgLen];
866
-      drawImageMsg[0] = (byte) (PaintPrimitives.DRAW_IMAGE.ordinal());
867
-      writeMessageInt32(drawImageMsg, 1, x);
868
-      writeMessageInt32(drawImageMsg, 5, y);
869
-      writeMessageInt32(drawImageMsg, 9, width);
870
-      writeMessageInt32(drawImageMsg, 13, height);
871
-      drawImageMsg[17] = (byte) encoding.getValue();
872
-      writeMessageInt32(drawImageMsg, 18, imageHash);
873
-      if (encoding == ImageEncoding.RAW) {
874
-         System.arraycopy(encodedImage, 0, drawImageMsg, 22, encodedImage.length);
875
-      }
876
-      
877
-      return drawImageMsg;
878
-   }
879
-}
880

    
881
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java'
882
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java	2015-08-10 18:28:09 +0000
883
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebDriver.java	2015-08-10 20:40:35 +0000
884
@@ -13,13 +13,17 @@
885
 ** 002 CA  20150520 Changed signature for createFont.
886
 ** 003 HC  20150612 Compatibility changes related to support of modal windows.
887
 ** 004 HC  20150702 Implemented window modality independently on the actual UI driver.
888
-** 005 GES 20150701 Added GUI implementation for previously stubbed-out methods.
889
+** 005 GES 20150701 Added GUI implementation for previously stubbed-out methods,
890
+**                  implemented images drawing operation.
891
 ** 006 CA  20150808 Added GUI implementation for font and metrics-related APIs.
892
 */
893
 
894
 package com.goldencode.p2j.ui.client.gui.driver.web;
895
 
896
-//don't import the entire logging package as it has naming conflicts with jetty
897
+// TODO: remove this, it is there to allow compilation
898
+import java.awt.Font;
899
+import java.util.HashSet;
900
+// don't import the entire logging package as it has naming conflicts with jetty
901
 import java.util.logging.Level;
902
 import java.util.logging.Logger;
903
 
904
@@ -73,6 +77,12 @@
905
    /** Work-Area bounds. */ 
906
    private NativeDimension workarea;
907
    
908
+   /** Virtual screen for drawing in a memory */
909
+   private VirtualScreen virtualScreen;
910
+   
911
+   /** Images loaded by a client. */
912
+   private final HashSet<Integer> loadedImages;
913
+   
914
    /** A cache of font metrics objects, by their remote font ID. */
915
    private Map<Integer, FontMetricsHelper> fontMetricsCache = new HashMap<>();
916
    
917
@@ -97,6 +107,7 @@
918
       });
919
       
920
       this.config = config;
921
+      this.loadedImages = new HashSet<Integer>();
922
    }
923
    
924
    /**
925
@@ -123,7 +134,8 @@
926
       
927
       desktop  = new NativeDimension(width, height);
928
       workarea = new NativeDimension(width, taskbar ? height - TASKBAR_HEIGHT : height);
929
-
930
+      virtualScreen = new VirtualScreenImpl(width, height);
931
+      
932
       // calculate our resource base
933
       Resource cpres = EmbeddedWebServerImpl.calcResourceBase(GuiWebDriver.class, "res");
934
      
935
@@ -182,7 +194,20 @@
936
    {
937
       return new NativeRectangle(new NativePoint(0, 0), desktop); 
938
    }
939
-
940
+   
941
+   /**
942
+    * 
943
+    * @return
944
+    */
945
+   public VirtualScreen getVirtualScreen()
946
+   {
947
+      return virtualScreen;
948
+   }
949
+   
950
+   public boolean addImage(int imageHash) {
951
+      return this.loadedImages.add(imageHash);
952
+   }
953
+   
954
    /**
955
     * Returns an application-usable display area. For example, a task bar is
956
     * not counted as the usable area and it is always at the bottom of the
957

    
958
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java'
959
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java	2015-08-10 18:28:09 +0000
960
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java	2015-08-10 20:42:13 +0000
961
@@ -12,8 +12,8 @@
962
 ** 001 GES 20150504 First version which is just stubbed out.
963
 ** 002 HC  20150612 Compatibility changes related to support of paragraph layout.
964
 ** 003 HC  20150702 Improved positioning of top-level windows on systems with multiple displays.
965
-** 004 GES 20150701 Added GUI implementation for previously stubbed-out methods.
966
-** 005 SBI 20150807 Added an images drawing operation.
967
+** 004 GES 20150701 Added GUI implementation for previously stubbed-out methods,
968
+**                  implemented an images drawing operation.
969
 ** 006 CA  20150810 Implemented APIs and operations for font and text metrics, text drawing and 
970
 **                  font creation/selection. 
971
 */
972
@@ -58,6 +58,8 @@
973
    /** Locally cached title text. */
974
    private String title = null;
975
    
976
+   private final BufferedImageDrawHelper drawHelper;
977
+
978
    /**
979
     * Constructor.
980
     *
981
@@ -76,6 +78,7 @@
982
       this.lock      = (lock != null) ? lock : new Object();
983
       this.websock   = websock;
984
       this.webdriver = webdriver;
985
+      this.drawHelper = new BufferedImageDrawHelper();
986
    }
987
 
988
    /**
989
@@ -346,7 +349,7 @@
990
       {
991
          return websock.getParagraphHeight(text, font.font, maxWidth);
992
       }
993
-   }   
994
+   }
995
    
996
    /**
997
     * Draw using a paint operation.
998
@@ -379,7 +382,25 @@
999
             websock.drawRoundRect(ps.x, ps.y, ps.width, ps.height, ps.arcDiameter);
1000
             break;
1001
          case DRAW_IMAGE:
1002
-            websock.drawImage(ps);
1003
+            ImageWrapper wrappedImage = drawHelper.processImage(ps);
1004
+            VirtualScreen virtualScreen = webdriver.getVirtualScreen();
1005
+            int imageHash = wrappedImage.getImage().hashCode();
1006
+            ImageEncoding encoding;
1007
+            byte[] encodedImage;
1008
+            if (webdriver.addImage(imageHash))
1009
+            {
1010
+               encoding = ImageEncoding.RAW;
1011
+               virtualScreen.drawImage(wrappedImage, ps.x, ps.y);
1012
+               encodedImage = new RawEncoder().packToBinaries(virtualScreen, ps.x, ps.y,
1013
+                        wrappedImage.getWidth(), wrappedImage.getHeight());
1014
+            }
1015
+            else
1016
+            {
1017
+               encoding = ImageEncoding.HASH;
1018
+               encodedImage = null;
1019
+            }
1020
+            websock.drawImage(ps.x, ps.y, wrappedImage.getWidth(), wrappedImage.getHeight(),
1021
+                     encoding, imageHash, encodedImage);
1022
             break;
1023
          case FILL_RECT:
1024
             websock.fillRect(ps.x, ps.y, ps.width, ps.height);
1025

    
1026
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java'
1027
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java	2015-08-10 18:28:09 +0000
1028
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java	2015-08-10 20:44:32 +0000
1029
@@ -10,16 +10,13 @@
1030
 **
1031
 ** -#- -I- --Date-- --------------------------------Description----------------------------------
1032
 ** 001 GES 20150331 First version which is a placeholder using the common parent code as ChUI.
1033
-** 002 GES 20150701 Added messages for a first pass at GUI support.
1034
-** 003 SBI 20150807 Added an images drawing operation.
1035
-** 004 CA  20150810 Added operations for font, metrics and string drawing.
1036
+** 002 GES 20150701 Added messages for a first pass at GUI support,
1037
+**                  implemented an images drawing operation.
1038
+** 003 CA  20150810 Added operations for font, metrics and string drawing.
1039
 */
1040
 
1041
 package com.goldencode.p2j.ui.client.gui.driver.web;
1042
 
1043
-import java.awt.color.ColorSpace;
1044
-import java.awt.image.DataBuffer;
1045
-import java.awt.image.DirectColorModel;
1046
 import java.util.*;
1047
 
1048
 import com.goldencode.p2j.ui.client.driver.web.*;
1049
@@ -53,21 +50,6 @@
1050
    private int pendingBytes = 0;
1051
    
1052
    /**
1053
-    * Defines a pixels model as sRGB 32bits per a pixel
1054
-    */
1055
-   private final DirectColorModel colorModel = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
1056
-            32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000, true, DataBuffer.TYPE_INT);
1057
-   /**
1058
-    * TODO to get client screen width and height.
1059
-    */
1060
-   private final VirtualScreen virtualScreen = new VirtualScreenImpl(colorModel, 800, 600);
1061
-   
1062
-   /**
1063
-    * Image drawing manager holds a hash map of loaded images
1064
-    */
1065
-   private final DrawImageOp drawImageOp = new DrawImageOp(virtualScreen);
1066
-   
1067
-   /**
1068
     * A map with the received messages from java-script side.  Requests which require a 
1069
     * "synchronous" approach must call {@link #waitForResult(int)} for the expected operation.
1070
     */
1071
@@ -284,11 +266,45 @@
1072
    }
1073
 
1074
    /**
1075
-    * Draw a given image on the virtual screen and prepare it to transfer. 
1076
-    * @param imageParameters PaintStructure 
1077
+    * Draw a given image on the virtual screen and prepare it to transfer.
1078
+    * 
1079
+    * @param    x
1080
+    *           The x-coordinate of the image position.
1081
+    * @param    y
1082
+    *           The y-coordinate of the image position.
1083
+    * @param    width
1084
+    *           The width of the image.
1085
+    * @param    height
1086
+    *           The height of the image.
1087
+    * @param    encoding
1088
+    *           The encoding id.
1089
+    * @param    imageHash
1090
+    *           The image hash code, its own id.
1091
+    * @param    encodedImage
1092
+    *           The encoded image represented by bytes.
1093
     */
1094
-   public void drawImage(PaintStructure imageParameters) {
1095
-      addDrawingOp(drawImageOp.execute(imageParameters));
1096
+   public void drawImage(int x, int y, int width, int height, ImageEncoding encoding,
1097
+            int imageHash, byte[] encodedImage)
1098
+   {
1099
+      int msgLen = 22;
1100
+      if (encoding == ImageEncoding.RAW)
1101
+      {
1102
+         msgLen += encodedImage.length;
1103
+      }
1104
+      byte[] drawImageMsg = new byte[msgLen];
1105
+      drawImageMsg[0] = (byte) (PaintPrimitives.DRAW_IMAGE.ordinal());
1106
+      writeMessageInt32(drawImageMsg, 1, x);
1107
+      writeMessageInt32(drawImageMsg, 5, y);
1108
+      writeMessageInt32(drawImageMsg, 9, width);
1109
+      writeMessageInt32(drawImageMsg, 13, height);
1110
+      drawImageMsg[17] = (byte) encoding.getValue();
1111
+      writeMessageInt32(drawImageMsg, 18, imageHash);
1112
+      if (encoding == ImageEncoding.RAW)
1113
+      {
1114
+         System.arraycopy(encodedImage, 0, drawImageMsg, 22, encodedImage.length);
1115
+      }
1116
+
1117
+      addDrawingOp(drawImageMsg);
1118
    }
1119
 
1120
    /**
1121
@@ -1227,10 +1243,13 @@
1122
    }
1123
    
1124
    /**
1125
-    * Add a prepared drawing to the pending operations list
1126
-    * @param message byte[] prepared drawing to transfer
1127
+    * Add a prepared drawing to the pending operations list.
1128
+    * 
1129
+    * @param    message
1130
+    *           The prepared drawing to transfer.
1131
     */
1132
-   private void addDrawingOp(byte[] message) {
1133
+   private void addDrawingOp(byte[] message)
1134
+   {
1135
       drawingOps.add(message);
1136
       pendingBytes += message.length;
1137
    }
1138

    
1139
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/ImageEncoding.java'
1140
--- src/com/goldencode/p2j/ui/client/gui/driver/web/ImageEncoding.java	2015-08-07 20:47:38 +0000
1141
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/ImageEncoding.java	2015-08-10 18:26:19 +0000
1142
@@ -9,7 +9,7 @@
1143
 **                 CONFIDENTIAL
1144
 **
1145
 ** -#- -I- --Date-- --------------------------------Description----------------------------------
1146
-** 001 SBI 20150807 First version which describes a schema for Raw encoding and MD5 hash encoding
1147
+** 001 SBI 20150810 First version which describes a schema for Raw encoding and MD5 hash encoding
1148
 **                  that is used to transfer images md5 hashes via networks.
1149
 ** 
1150
 */
1151
@@ -17,10 +17,8 @@
1152
 package com.goldencode.p2j.ui.client.gui.driver.web;
1153
 
1154
 /**
1155
- * 
1156
- * ImageEncoding defines Raw encoding and Hash encoding
1157
- * that is used to transfer images ids instead of their binaries via networks.
1158
- * 
1159
+ * ImageEncoding defines Raw encoding and Hash encoding that is used to transfer images ids
1160
+ * instead of their binaries via networks.
1161
  */
1162
 public enum ImageEncoding
1163
 {
1164
@@ -35,7 +33,8 @@
1165
 
1166
    /**
1167
     * Returns an encoding well-known id.
1168
-    * @return int an encoding id
1169
+    * 
1170
+    * @return The encoding id.
1171
     */
1172
    public int getValue()
1173
    {
1174

    
1175
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/PixelsEncoder.java'
1176
--- src/com/goldencode/p2j/ui/client/gui/driver/web/PixelsEncoder.java	2015-08-07 20:47:38 +0000
1177
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/PixelsEncoder.java	2015-08-10 19:34:35 +0000
1178
@@ -9,27 +9,36 @@
1179
 **                 CONFIDENTIAL
1180
 **
1181
 ** -#- -I- --Date-- --------------------------------Description----------------------------------
1182
-** 001 SBI 20150807 First version which describes a schema for encoding of a rectangle
1183
+** 001 SBI 20150810 First version which describes a schema for encoding of a rectangle
1184
 **                  on a provided virtual screen.
1185
 */
1186
 
1187
 package com.goldencode.p2j.ui.client.gui.driver.web;
1188
 
1189
+import com.goldencode.p2j.ui.client.gui.driver.VirtualScreen;
1190
+
1191
 /**
1192
- * 
1193
- * PixelsEncoder
1194
- *
1195
+ * PixelsEncoder describes an encoding method to pack a screen's rectangular area
1196
+ * to binaries.
1197
  */
1198
 public interface PixelsEncoder
1199
 {
1200
    /**
1201
     * Encode the rectangular area on the screen to transfer.
1202
-    * @param screen virtual screen with the defined color model
1203
-    * @param x int a position of the left side of the target rectangle along the screen horizon
1204
-    * @param y int a position of the upper side of the target rectangle along the screen's vertical
1205
-    * @param w int a width of the target rectangular area
1206
-    * @param h int a height of the target rectangular area
1207
-    * @return
1208
+    * 
1209
+    * @param    screen
1210
+    *           The virtual screen with the defined color model.
1211
+    * @param    x
1212
+    *           The position of the left side of the target rectangle along the screen horizon.
1213
+    * @param    y
1214
+    *           The position of the upper side of the target rectangle along the screen's
1215
+    *           vertical.
1216
+    * @param    w
1217
+    *           The width of the target rectangular area.
1218
+    * @param    h
1219
+    *           The height of the target rectangular area.
1220
+    * 
1221
+    * @return   The encoded message contents.
1222
     */
1223
    byte[] packToBinaries(VirtualScreen screen, int x, int y, int w, int h);
1224
 }
1225

    
1226
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/RawEncoder.java'
1227
--- src/com/goldencode/p2j/ui/client/gui/driver/web/RawEncoder.java	2015-08-07 20:47:38 +0000
1228
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/RawEncoder.java	2015-08-10 19:32:20 +0000
1229
@@ -18,21 +18,39 @@
1230
 
1231
 import java.awt.image.DirectColorModel;
1232
 
1233
+import com.goldencode.p2j.ui.client.gui.driver.VirtualScreen;
1234
+
1235
 /**
1236
- * 
1237
  * RawEncoder implements Raw encoding based on RFB specification documents:
1238
  * https://www.realvnc.com/docs/rfbproto.pdf
1239
  * https://tools.ietf.org/html/rfc6143
1240
  * This implementation supports only sRGB pixels models with 32 bits per a pixel.
1241
  */
1242
-class RawEncoder implements PixelsEncoder
1243
+class RawEncoder
1244
+implements PixelsEncoder
1245
 {
1246
-
1247
+   /** Defines a 32 bits per a pixel integer constant. */
1248
    private final static int TRUE_COLOR_BITS_PER_PIXEL = 32;
1249
-   
1250
+
1251
+   /**
1252
+    * Encode the rectangular area on the screen to transfer.
1253
+    * 
1254
+    * @param    screen
1255
+    *           The virtual screen with the defined color model.
1256
+    * @param    x
1257
+    *           The position of the left side of the target rectangle along the screen horizon.
1258
+    * @param    y
1259
+    *           The position of the upper side of the target rectangle along the screen's
1260
+    *           vertical.
1261
+    * @param    w
1262
+    *           The width of the target rectangular area.
1263
+    * @param    h
1264
+    *           The height of the target rectangular area.
1265
+    * 
1266
+    * @return   The encoded message contents.
1267
+    */
1268
    @Override
1269
-   public byte[] packToBinaries(VirtualScreen screen, int x, int y,
1270
-            int w, int h)
1271
+   public byte[] packToBinaries(VirtualScreen screen, int x, int y, int w, int h)
1272
    {
1273
       byte[] encodedRectangle = null;
1274
       int b = 0;
1275
@@ -45,11 +63,12 @@
1276
       int p = y * scanline + x;
1277
       int[] pixels = screen.getPixels();
1278
       DirectColorModel colorModel = screen.getColorModel();
1279
-      if (colorModel.getPixelSize() == TRUE_COLOR_BITS_PER_PIXEL) {
1280
-         encodedRectangle = new byte[ numberOfPixels << 2 ];
1281
-         for( ; i < numberOfPixels; i++, s++, p++ )
1282
+      if (colorModel.getPixelSize() == TRUE_COLOR_BITS_PER_PIXEL)
1283
+      {
1284
+         encodedRectangle = new byte[numberOfPixels << 2];
1285
+         for (; i < numberOfPixels; i++, s++, p++)
1286
          {
1287
-            if( s == w )
1288
+            if (s == w)
1289
             {
1290
                s = 0;
1291
                p += jump;
1292
@@ -60,11 +79,12 @@
1293
             encodedRectangle[b++] = (byte) colorModel.getBlue(pixel);
1294
             encodedRectangle[b++] = (byte) colorModel.getAlpha(pixel);
1295
          }
1296
-      } else {
1297
+      }
1298
+      else
1299
+      {
1300
          throw new UnsupportedOperationException("Supported only 32 bits per a pixel");
1301
       }
1302
-      
1303
+
1304
       return encodedRectangle;
1305
    }
1306
-
1307
 }
1308

    
1309
=== removed file 'src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreen.java'
1310
--- src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreen.java	2015-08-07 20:47:38 +0000
1311
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreen.java	1970-01-01 00:00:00 +0000
1312
@@ -1,53 +0,0 @@
1313
-/*
1314
-** Module   : VirtualScreen.java
1315
-** Abstract : Define methods to work with screen
1316
-**
1317
-** Copyright (c) 2015, Golden Code Development Corporation.
1318
-** ALL RIGHTS RESERVED. Use is subject to license terms.
1319
-**
1320
-**         Golden Code Development Corporation
1321
-**                 CONFIDENTIAL
1322
-**
1323
-** -#- -I- --Date-- --------------------------------Description----------------------------------
1324
-** 001 SBI 20150807 First version which describes a virtual screen based on sRGB model.
1325
-*/
1326
-
1327
-package com.goldencode.p2j.ui.client.gui.driver.web;
1328
-
1329
-import java.awt.Image;
1330
-import java.awt.image.DirectColorModel;
1331
-
1332
-/**
1333
- * VirtualScreen describes a virtual screen based on sRGB model. It provides
1334
- * an access to a screen pixel model and perform drawing operations.
1335
- */
1336
-public interface VirtualScreen
1337
-{
1338
-   /**
1339
-    * 
1340
-    * @return pixels int[] RGBA model via pixels 
1341
-    */
1342
-   int[] getPixels();
1343
-   /**
1344
-    * Gets a screen width.
1345
-    * @return int a screen width
1346
-    */
1347
-   int getScreenWidth();
1348
-   /**
1349
-    * Gets a screen height.
1350
-    * @return height a screen height
1351
-    */
1352
-   int getScreenHeight();
1353
-   /**
1354
-    * Describes a pixel format used for drawing.
1355
-    * @return DirectColorModel color model
1356
-    */
1357
-   DirectColorModel getColorModel();
1358
-   /**
1359
-    * Draw an image at the target position on the screen
1360
-    * @param image Image
1361
-    * @param x int x-coordinate of the target image position 
1362
-    * @param y int y-coordinate of the target image position
1363
-    */
1364
-   void drawImage(Image image, int x, int y);
1365
-}
1366

    
1367
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreenImpl.java'
1368
--- src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreenImpl.java	2015-08-07 20:47:38 +0000
1369
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/VirtualScreenImpl.java	2015-08-10 19:50:52 +0000
1370
@@ -9,7 +9,7 @@
1371
 **                 CONFIDENTIAL
1372
 **
1373
 ** -#- -I- --Date-- --------------------------------Description----------------------------------
1374
-** 001 SBI 20150807 First version which implements a virtual screen based on sRGB model.
1375
+** 001 SBI 20150810 First version which implements a virtual screen based on sRGB model.
1376
 */
1377
 
1378
 package com.goldencode.p2j.ui.client.gui.driver.web;
1379
@@ -17,6 +17,7 @@
1380
 import java.awt.Color;
1381
 import java.awt.Graphics2D;
1382
 import java.awt.Image;
1383
+import java.awt.color.ColorSpace;
1384
 import java.awt.image.BufferedImage;
1385
 import java.awt.image.DataBuffer;
1386
 import java.awt.image.DataBufferInt;
1387
@@ -26,74 +27,130 @@
1388
 import java.awt.image.SinglePixelPackedSampleModel;
1389
 import java.awt.image.WritableRaster;
1390
 
1391
+import com.goldencode.p2j.ui.client.gui.driver.ImageWrapper;
1392
+import com.goldencode.p2j.ui.client.gui.driver.VirtualScreen;
1393
+
1394
 
1395
 /**
1396
- * 
1397
  * VirtualScreenImpl is an implementation of VirtualScreen drawings operations.
1398
- *
1399
  */
1400
-class VirtualScreenImpl implements VirtualScreen
1401
+class VirtualScreenImpl
1402
+implements VirtualScreen
1403
 {
1404
-
1405
+   /** The color model that defines pixels representation */
1406
    private final DirectColorModel colorModel;
1407
+   
1408
+   /** The screen width. */
1409
    private final int width;
1410
+   
1411
+   /** The screen height. */
1412
    private final int height;
1413
+   
1414
+   /** The pixels array.*/
1415
    private final int[] pixels;
1416
+   
1417
+   /** The canvas in a memory to draw images. */
1418
    private final BufferedImage screen;
1419
 
1420
-   /**
1421
-    * Constructs a virtual screen of the given width and height
1422
-    * based on the given pixels model.
1423
-    * 
1424
-    * @param colorModel DirectColorModel pixels model based on sRGB
1425
-    * @param width int a screen width
1426
-    * @param height int a screen height 
1427
+
1428
+   /**
1429
+    * Constructs a virtual screen with the default color model model as sRGB 32bits per a pixel.
1430
+    * 
1431
+    * @param    width
1432
+    *           The screen width.
1433
+    * @param    height
1434
+    *           The screen height.
1435
+    */
1436
+   public VirtualScreenImpl(int width, int height)
1437
+   {
1438
+      this(new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), 32, 0xFF, 0xFF00,
1439
+               0xFF0000, 0xFF000000, true, DataBuffer.TYPE_INT), width, height);
1440
+   }
1441
+
1442
+   /**
1443
+    * Constructs a virtual screen of the given width and height based on the given pixels model.
1444
+    * 
1445
+    * @param    colorModel
1446
+    *           The pixels model based on sRGB.
1447
+    * @param    width
1448
+    *           The screen width.
1449
+    * @param    height
1450
+    *           The screen height.
1451
     */
1452
    public VirtualScreenImpl(DirectColorModel colorModel, int width, int height)
1453
    {
1454
       this.colorModel = colorModel;
1455
       this.width = width;
1456
       this.height = height;
1457
-      this.pixels = new int[width*height];
1458
-      final DataBuffer data = new DataBufferInt(pixels, pixels.length);
1459
-      final SampleModel sampleModel = new SinglePixelPackedSampleModel(
1460
-               DataBuffer.TYPE_INT, width,  height, colorModel.getMasks());
1461
-      final WritableRaster raster = Raster.createWritableRaster(sampleModel, data, null);
1462
+      this.pixels = new int[width * height];
1463
+      DataBuffer data = new DataBufferInt(pixels, pixels.length);
1464
+      SampleModel sampleModel = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT,
1465
+               width, height, colorModel.getMasks());
1466
+      WritableRaster raster = Raster.createWritableRaster(sampleModel, data, null);
1467
       this.screen = new BufferedImage(colorModel, raster, true, null);
1468
    }
1469
 
1470
+   /**
1471
+    * Returns RGBA model via pixels, each pixel is encoded as an integer.
1472
+    * 
1473
+    * @return   The array of pixels. 
1474
+    */
1475
    @Override
1476
    public int[] getPixels()
1477
    {
1478
       return pixels;
1479
    }
1480
 
1481
+   /**
1482
+    * Gets a screen width.
1483
+    * 
1484
+    * @return   The screen width.
1485
+    */
1486
    @Override
1487
    public int getScreenWidth()
1488
    {
1489
       return width;
1490
    }
1491
 
1492
+   /**
1493
+    * Gets a screen height.
1494
+    * 
1495
+    * @return   The screen height
1496
+    */
1497
    @Override
1498
    public int getScreenHeight()
1499
    {
1500
       return height;
1501
    }
1502
 
1503
+   /**
1504
+    * Describes a pixel format used for drawing.
1505
+    * 
1506
+    * @return The color model.
1507
+    */
1508
    @Override
1509
    public DirectColorModel getColorModel()
1510
    {
1511
       return colorModel;
1512
    }
1513
 
1514
+   /**
1515
+    * Draw an image at the target position on the screen.
1516
+    * 
1517
+    * @param    image
1518
+    *           The target image.
1519
+    * @param    x
1520
+    *           The x-coordinate of the target image position. 
1521
+    * @param    y
1522
+    *           The y-coordinate of the target image position.
1523
+    */
1524
    @Override
1525
-   public void drawImage(Image image, int x, int y)
1526
+   public void drawImage(ImageWrapper image, int x, int y)
1527
    {
1528
       Graphics2D g2 = screen.createGraphics();
1529
       g2.setColor(new Color(0,0,0));
1530
       g2.fillRect(0, 0, getScreenWidth(), getScreenHeight());
1531
-      g2.drawImage(image, x, y, null);
1532
+      g2.drawImage((Image) image.getImage(), x, y, null);
1533
       g2.dispose();
1534
    }
1535
-
1536
 }
1537

    
1538
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js'
1539
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js	2015-08-10 12:43:49 +0000
1540
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js	2015-08-10 20:35:16 +0000
1541
@@ -13,8 +13,8 @@
1542
 **                  Renamed objects to match the more generic web client approach (not just
1543
 **                  ChUI). Moved some logic to common code locations.
1544
 ** 002 SBI 20150731 Applied "use strict" directive, fixed undeclared variables.
1545
-** 003 GES 20150720 Total rewrite to implement a first pass at GUI support.
1546
-** 004 SBI 20150807 Added a drawing image operation
1547
+** 003 GES 20150720 Total rewrite to implement a first pass at GUI support,
1548
+**                  added a drawing image operation.
1549
 */
1550
 
1551
 "use strict";
1552
@@ -448,8 +448,6 @@
1553
                //console.debug("encoding type: " + encoding);
1554
                var key = p2j.socket.readInt32BinaryMessage(message, idx + 18);
1555
                console.debug("hash: " + key);
1556
-               var img = ctx.createImageData(width, height);
1557
-               var data = img.data;
1558
                var pixelsInBytes = width * height * 4;
1559
                var imgData;
1560
                var imgDataOffset;
1561
@@ -461,14 +459,7 @@
1562
                   imgDataOffset = idx + 22;
1563
                   loadedImages.set(key, message.subarray(imgDataOffset, imgDataOffset + pixelsInBytes));
1564
                }
1565
-               for (var i = 0, j = imgDataOffset; i < pixelsInBytes; i += 4, j += 4) {
1566
-                   data[i]     = imgData[j];
1567
-                   data[i + 1] = imgData[j + 1];
1568
-                   data[i + 2] = imgData[j + 2];
1569
-                   data[i + 3] = imgData[j + 3];
1570
-               }
1571
-               ctx.putImageData(img, x, y);
1572
-
1573
+               drawImage(x, y, width, height, imgData, imgDataOffset);
1574
                break;
1575
             case ops.FILL_RECT:
1576
                x      = p2j.socket.readInt32BinaryMessage(message, idx + 1);
1577
@@ -764,7 +755,26 @@
1578
       drawLine(ctx, x + width, y + 1, x + width, y + height, color);
1579
       drawLine(ctx, x + 1, y + height, x + width - 1, y + height, color);
1580
    }                         
1581
-         
1582
+   
1583
+   /**
1584
+    * 
1585
+    */
1586
+   function drawImage(x, y, width, height, imgData, imgDataOffset)
1587
+   {
1588
+      var img = ctx.createImageData(width, height);
1589
+      var data = img.data;
1590
+      var pixelsInBytes = width * height * 4;
1591
+
1592
+      for (var i = 0, j = imgDataOffset; i < pixelsInBytes; i += 4, j += 4)
1593
+      {
1594
+         data[i]     = imgData[j];
1595
+         data[i + 1] = imgData[j + 1];
1596
+         data[i + 2] = imgData[j + 2];
1597
+         data[i + 3] = imgData[j + 3];
1598
+     }
1599
+     ctx.putImageData(img, x, y);
1600
+   }
1601
+   
1602
    /**
1603
     * Convert a standard fillStyle or strokeStyle color into an array of [ R, G, B ] values.
1604
     *
1605