Project

General

Profile

putImagData_1.txt

Sergey Ivanovskiy, 10/16/2015 07:44 AM

Download (14.7 KB)

 
1
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js'
2
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js	2015-10-15 09:00:17 +0000
3
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js	2015-10-16 11:35:16 +0000
4
@@ -301,7 +301,39 @@
5
    this.pixData[1] = color[1];
6
    this.pixData[2] = color[2];
7
    
8
-   this.putImageData(this.ctx, this.pixel, x, y);
9
+   this.putImageData(this.pixel, x, y);
10
+};
11
+
12
+/**
13
+ * If the pixel location is outside of the last clipped rectangle return false, otherwise
14
+ * return true.
15
+ *
16
+ * @param    {Number} x
17
+ *           X coordinate of the pixel to be checked.
18
+ * @param    {Number} y
19
+ *           Y coordinate of the pixel to be checked.
20
+ * 
21
+ * @return   {Boolean}
22
+ *           The boolean value indicates the given pixel is in the last clipping region.
23
+ */
24
+CanvasRenderer.prototype.isInClipRegion = function(x, y)
25
+{
26
+   var lastClip = this.lastClippedRegion(true);
27
+   
28
+   if (lastClip != undefined)
29
+   {
30
+      var top    = lastClip.y;
31
+      var bottom = lastClip.y + lastClip.height - 1;
32
+      var left   = lastClip.x;
33
+      var right  = lastClip.x + lastClip.width - 1;
34
+      
35
+      if (y < top || y > bottom || x < left || x > right)
36
+      {
37
+         return false;
38
+      }
39
+   }
40
+   
41
+   return true;
42
 };
43
 
44
 /**
45
@@ -309,33 +341,33 @@
46
  * <p>
47
  * If the location is ouside of the last clipped rectangle, then this is a no-op.
48
  *
49
- * @param    {CanvasRenderingContext2D} ctx
50
- *           The canvas 2D graphics context on which to draw.
51
- * @param    {Image} pixel
52
- *           The pixel to be drawn.
53
+ * @param    {ImageData} imageData
54
+ *           The imageData to be drawn.
55
  * @param    {Number} x
56
  *           X coordinate of the pixel to be drawn.
57
  * @param    {Number} y
58
  *           Y coordinate of the pixel to be drawn.
59
  */
60
-CanvasRenderer.prototype.putImageData = function(ctx, pixel, x, y)
61
-{
62
-   var lastClip = this.lastClippedRegion(true);
63
-   
64
-   if (lastClip != undefined)
65
-   {
66
-      var top    = lastClip.y;
67
-      var bottom = lastClip.y + lastClip.height - 1;
68
-      var left   = lastClip.x;
69
-      var right  = lastClip.x + lastClip.width - 1;
70
-      
71
-      if (y < top || y > bottom || x < left || x > right)
72
-      {
73
-         return;
74
-      }
75
-   }
76
-   
77
-   ctx.putImageData(pixel, x, y);
78
+CanvasRenderer.prototype.putImageData = function(imageData, x, y)
79
+{
80
+   this.ctx.putImageData(imageData, x, y);
81
+};
82
+
83
+/**
84
+ * Creates a new ImageData object with the specified width and height. The new object is filled
85
+ * with transparent black pixels.
86
+ * 
87
+ * @param    {Number} width
88
+ *           The image width in pixels.
89
+ * @param    {Number} height
90
+ *           The image height in pixels.
91
+ * 
92
+ * @return   {ImageData}
93
+ *           The ImageData object with the specified width and height.
94
+ */
95
+CanvasRenderer.prototype.createImageData = function(width, height)
96
+{
97
+   return this.ctx.createImageData(width, height);
98
 };
99
 
100
 /**
101
@@ -361,14 +393,26 @@
102
  */
103
 CanvasRenderer.prototype.drawLineSegment = function(ctx, x1, y1, x2, y2, color)
104
 {
105
+   // holds the line pixels to draw
106
+   var path = [];
107
+
108
    x1 = x1 + this.origin.x;
109
    x2 = x2 + this.origin.x;
110
    
111
    y1 = y1 + this.origin.y;
112
    y2 = y2 + this.origin.y;
113
 
114
-   // holds the line pixels to draw
115
-   var path = [];
116
+   // intersect with clipping region
117
+   var d = this.cutLine(x1, y1, x2, y2);
118
+   if (d === null)
119
+   {
120
+      return path;
121
+   }
122
+   x1 = d[0];
123
+   y1 = d[1];
124
+   x2 = d[2];
125
+   y2 = d[3];
126
+   
127
    var dx = Math.abs(x2 - x1);
128
    var dy = Math.abs(y2 - y1);
129
    
130
@@ -484,7 +528,7 @@
131
 CanvasRenderer.prototype.strokeLineSegment = function(ctx, x1, y1, x2, y2, color)
132
 {
133
    var path = this.drawLineSegment(ctx, x1, y1, x2, y2, color);
134
-   this.strokesManager.applyStrokeToPath(this.ctx,
135
+   this.strokesManager.applyStrokeToPath(this,
136
          this.strokeStyleId,
137
          this.strokeWidth,
138
          color,
139
@@ -579,7 +623,7 @@
140
    this.drawLine(ctx, x + width - 1 - inset, y + height - inset, x + 1, y + height - inset, color, path);
141
    this.drawLine(ctx, x, y + height - inset, x, y + 1, color, path);// close the path
142
    
143
-   this.strokesManager.applyStrokeToPath(this.ctx,
144
+   this.strokesManager.applyStrokeToPath(this,
145
          this.strokeStyleId,
146
          this.strokeWidth,
147
          color,
148
@@ -635,7 +679,7 @@
149
          data[p + 3] = (imgData[offset + 3] * alpha + data[p + 3] * beta) >> 8;
150
       };
151
    };
152
-   this.putImageData(ctx, img, this.origin.x + x, this.origin.y + y);
153
+   this.putImageData(img, this.origin.x + x, this.origin.y + y);
154
 };
155
 
156
 /**
157
@@ -712,7 +756,7 @@
158
    this.drawLine(ctx, rightUpX, rightUpY, rightDownX, rightDownY, color, path);
159
    this.drawLine(ctx, bottomLeftX, bottomLeftY, bottomRightX, bottomRightY, color, path);
160
    this.drawLine(ctx, leftUpX, leftUpY, leftDownX, leftDownY, color, path);
161
-   this.strokesManager.applyStrokeToPath(this.ctx,
162
+   this.strokesManager.applyStrokeToPath(this,
163
          this.strokeStyleId,
164
          this.strokeWidth,
165
          color,
166
@@ -790,7 +834,7 @@
167
    var path = [];// create new pixels path to draw
168
    this.drawLine(ctx, x, y, x + width - 2 - inset, y, current, path);
169
    this.drawLine(ctx, x, y + 1, x, y + height - 1 - inset, current, path);
170
-   this.strokesManager.applyStrokeToPath(this.ctx,
171
+   this.strokesManager.applyStrokeToPath(this,
172
          this.strokeStyleId,
173
          this.strokeWidth,
174
          current,
175
@@ -802,7 +846,7 @@
176
    path = []; // create new pixels path to draw
177
    this.drawLine(ctx, x + 1, y + height - 1 - inset, x + width - 1 - inset, y + height - 1 - inset, current, path);
178
    this.drawLine(ctx, x + width - 1 - inset, y, x + width - 1 - inset, y + height - 2, current, path);
179
-   this.strokesManager.applyStrokeToPath(this.ctx,
180
+   this.strokesManager.applyStrokeToPath(this,
181
          this.strokeStyleId,
182
          this.strokeWidth,
183
          current,
184
@@ -880,7 +924,7 @@
185
 CanvasRenderer.prototype.strokePolygon = function(ctx, xPoints, yPoints, num, color, fill)
186
 {
187
    var path = this.drawPolygon(ctx, xPoints, yPoints, num, color, fill);
188
-   this.strokesManager.applyStrokeToPath(this.ctx,
189
+   this.strokesManager.applyStrokeToPath(this,
190
          this.strokeStyleId,
191
          this.strokeWidth,
192
          color,
193
@@ -1100,6 +1144,83 @@
194
 }
195
 
196
 /**
197
+ * Calculates the intersection of the given line segment with the last clipping region.
198
+ * 
199
+ * @param    {Number} x1
200
+ *           X coordinate of the starting pixel to be drawn.
201
+ * @param    {Number} y1
202
+ *           Y coordinate of the starting pixel to be drawn.
203
+ * @param    {Number} x2
204
+ *           X coordinate of the ending pixel to be drawn.
205
+ * @param    {Number} y2
206
+ *           Y coordinate of the ending pixel to be drawn.
207
+ * 
208
+ * @return   {Array}
209
+ *           The line intersection with the last clipping region in the form of this array 
210
+ *           [new_x1, new_y1, new_x2, new_y2].
211
+ */
212
+CanvasRenderer.prototype.cutLine = function (x1, y1, x2, y2)
213
+{
214
+   var lastClip = this.lastClippedRegion(true);
215
+   //xa, ya xb, yb is normalized region covered this line segment
216
+   var xa;
217
+   var xb;
218
+   var incx = (x1 < x2);
219
+   if (incx)
220
+   {
221
+      xa = x1;
222
+      xb = x2;
223
+   }
224
+   else
225
+   {
226
+      xa = x2;
227
+      xb = x1;
228
+   }
229
+   var ya;
230
+   var yb;
231
+   var incy = (y1 < y2);
232
+   if (incy)
233
+   {
234
+      ya = y1;
235
+      yb = y2;
236
+   }
237
+   else
238
+   {
239
+      ya = y2;
240
+      yb = y1;
241
+   }
242
+   
243
+   if (lastClip != undefined)
244
+   {
245
+      var top    = lastClip.y;
246
+      var bottom = lastClip.y + lastClip.height - 1;
247
+      var left   = lastClip.x;
248
+      var right  = lastClip.x + lastClip.width - 1;
249
+      
250
+      if (yb < top || ya > bottom || xb < left || xa > right)
251
+      {
252
+         return null;
253
+      }
254
+      xb = Math.min(right, xb);
255
+      xa = Math.max(left, xa);
256
+      yb = Math.min(bottom, yb);
257
+      ya = Math.max(top, ya);
258
+   }
259
+   // check that it is vertical or horizontal 
260
+   if ((x1 == x2) || (y1 == y2))
261
+   {
262
+      return [xa, ya, xb, yb];
263
+   }
264
+   var fxa;
265
+   var fxb;
266
+   
267
+   fxa = (y1 * (x2 - xa) / (x2 - x1)) + (y2 * (xa - x1) / (x2 - x1));
268
+   fxb = (y1 * (x2 - xb) / (x2 - x1)) + (y2 * (xb - x1) / (x2 - x1));
269
+   
270
+   return [xa, fxa, xb, fxb];
271
+}
272
+
273
+/**
274
  * Remove the most recently added rectangle from the current clipping region. The graphics
275
  * context state is popped to restore the previously used values.
276
  */
277
@@ -1272,7 +1393,7 @@
278
    this.replay();
279
                                 
280
    // re-blit the previously drawn content
281
-   this.putImageData(this.ctx, oldPixels, 0, 0);
282
+   this.putImageData(oldPixels, 0, 0);
283
 };   
284
 
285
 /**
286

    
287
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.strokes.js'
288
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.strokes.js	2015-09-21 18:08:56 +0000
289
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.strokes.js	2015-10-16 11:32:28 +0000
290
@@ -55,7 +55,8 @@
291
       SPECIFIED_WIDTH   : 1,
292
       DOTTED            : 2,
293
       DOTTED_SMALL      : 3,
294
-      DOTTED_SMALL_THIN : 4
295
+      DOTTED_SMALL_THIN : 4,
296
+      DOTTED_LARGE      : 5
297
    };
298
 
299
    var LineStroke =
300
@@ -70,7 +71,10 @@
301
       DOT_LINE_WIDTH      : 1.0,
302
       
303
       /** Dotted thin line width. */
304
-      DOT_LINE_THIN_WIDTH : 0.5
305
+      DOT_LINE_THIN_WIDTH : 0.5,
306
+      
307
+      /** */
308
+      DOT_STEP_LARGE      : 3
309
    };
310
 
311
    /**
312
@@ -93,6 +97,11 @@
313
          LineStroke.DOT_STEP_SMALL);
314
 
315
    /**
316
+    * Represents a dot style with 3 pixel to draw and then 3 pixel to pass.
317
+    */
318
+   var dotLargeStroke = new BasicStroke(LineStroke.DOT_LINE_WIDTH, CAP_BUTT, JOIN_MITER,
319
+         1.0, [LineStroke.DOT_STEP_LARGE, LineStroke.DOT_STEP_LARGE], 0);
320
+   /**
321
     * Represents a default style to draw a 1 pixel width solid line.
322
     */
323
    var defaultStroke = new BasicStroke(1.0, CAP_SQUARE, JOIN_MITER, 10.0, null, 0.0);
324
@@ -161,6 +170,8 @@
325
             return dotSmallStroke;
326
          case LineStrokeEnum.DOTTED_SMALL_THIN:
327
             return dotSmallThinStroke;
328
+         case LineStrokeEnum.DOTTED_LARGE:
329
+            return dotLargeStroke;
330
          default:
331
             return defaultStroke;
332
       }
333
@@ -169,7 +180,7 @@
334
    /**
335
     * Returns the stroke path renderer.
336
     * 
337
-    * @param    {CanvasRenderingContext2D} context
338
+    * @param    {CanvasRenderer} canvasRenderer
339
     *           The canvas renderer.
340
     * @param    {Number} strokeStyle
341
     *           The stroke style id according to the LineStroke enumeration.
342
@@ -181,18 +192,19 @@
343
     * 
344
     * @return   The stroke path renderer.
345
     */
346
-   function getStrokePathRenderer(context, strokeStyle, width, strokeColor)
347
+   function getStrokePathRenderer(canvasRenderer, strokeStyle, width, strokeColor)
348
    {
349
       var basicStroke = getLineStroke(strokeStyle, width);
350
       
351
       switch (strokeStyle)
352
       {
353
          case LineStrokeEnum.SPECIFIED_WIDTH:
354
-            return new WidenPathRenderer(context, basicStroke, strokeColor);
355
+            return new WidenPathRenderer(canvasRenderer, basicStroke, strokeColor);
356
          case LineStrokeEnum.DOTTED:
357
          case LineStrokeEnum.DOTTED_SMALL:
358
          case LineStrokeEnum.DOTTED_SMALL_THIN:
359
-            return new DotsPathRenderer(context, basicStroke, strokeColor);
360
+         case LineStrokeEnum.DOTTED_LARGE:
361
+            return new DotsPathRenderer(canvasRenderer, basicStroke, strokeColor);
362
          default:
363
             return { applyStroke : function (path) {} };
364
       }
365
@@ -202,7 +214,7 @@
366
     * Apply the given stroke style to the JS native canvas renderer.
367
     * 
368
     * @param    {CanvasRenderingContext2D} context
369
-    *           The canvas renderer.
370
+    *           The canvas renderer context.
371
     * @param    {Number} strokeStyle
372
     *           The stroke style id.
373
     * @param    {Number} width
374
@@ -235,7 +247,7 @@
375
    /**
376
     * Apply the given stroke style to the area outer bounds.
377
     * 
378
-    * @param    {CanvasRenderingContext2D} context
379
+    * @param    {CanvasRenderer} canvasRenderer
380
     *           The canvas renderer.
381
     * @param    {Number} strokeStyle
382
     *           The stroke style id.
383
@@ -247,13 +259,10 @@
384
     * @param    {Array} path
385
     *           The array of points that forms the outline of the target area.
386
     */
387
-   this.applyStrokeToPath = function(context, strokeStyle, width, strokeColor, path)
388
+   this.applyStrokeToPath = function(canvasRenderer, strokeStyle, width, strokeColor, path)
389
    {
390
-      if (context instanceof CanvasRenderingContext2D)
391
-      {
392
-         var renderer = getStrokePathRenderer(context, strokeStyle, width, strokeColor);
393
-         renderer.applyStroke(path);
394
-      }
395
+      var renderer = getStrokePathRenderer(canvasRenderer, strokeStyle, width, strokeColor);
396
+      renderer.applyStroke(path);
397
    }
398
    
399
    /**
400
@@ -280,7 +289,7 @@
401
    /**
402
     * Used to draw dash patterns on lines of pixels.
403
     * 
404
-    * @param    {CanvasRenderingContext2D} context
405
+    * @param    {CanvasRenderer} canvasRenderer
406
     *           The canvas renderer.
407
     * @param    {Object} basicStroke
408
     *           The stroke style object.
409
@@ -288,9 +297,9 @@
410
     *           The array of 3 integer values between 0 and 255 inclusive, representing
411
     *           a stroke color.
412
     */
413
-   function DotsPathRenderer(ctx, basicStroke, strokeColor)
414
+   function DotsPathRenderer(canvasRenderer, basicStroke, strokeColor)
415
    {
416
-      var pixel = ctx.createImageData(1, 1);
417
+      var pixel = canvasRenderer.createImageData(1, 1);
418
       var pixelData = pixel.data;
419
       pixelData[3] = 0xFF;
420
 
421
@@ -367,7 +376,7 @@
422
                pixelData[0] = strokeColor[0];
423
                pixelData[1] = strokeColor[1];
424
                pixelData[2] = strokeColor[2];
425
-               ctx.putImageData(pixel, point.x, point.y);
426
+               canvasRenderer.putImageData(pixel, point.x, point.y);
427
             }
428
          }
429
 
430
@@ -377,7 +386,7 @@
431
    /**
432
     * Used to widen lines of pixels.
433
     * 
434
-    * @param    {CanvasRenderingContext2D} context
435
+    * @param    {CanvasRenderer} canvasRenderer
436
     *           The canvas renderer.
437
     * @param    {Object} basicStroke
438
     *           The stroke style object.
439
@@ -385,10 +394,10 @@
440
     *           The array of 3 integer values between 0 and 255 inclusive, representing
441
     *           a stroke color.
442
     */
443
-   function WidenPathRenderer(ctx, basicStroke, strokeColor)
444
+   function WidenPathRenderer(canvasRenderer, basicStroke, strokeColor)
445
    {
446
       var width = basicStroke.getWidth();
447
-      var image = ctx.createImageData(width, width);
448
+      var image = canvasRenderer.createImageData(width, width);
449
       var imageData = image.data;
450
       
451
       for (var i = 0; i < 4 * width * width; i += 4)
452
@@ -410,7 +419,7 @@
453
          for (var i = 0; i < path.length; i++)
454
          {
455
             var point = path[i];
456
-            ctx.putImageData(image, point.x - (width >> 1), point.y - (width >> 1));
457
+            canvasRenderer.putImageData(image, point.x - (width >> 1), point.y - (width >> 1));
458
          }
459
       }
460
    }
461