1
|
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/WebClientMessageTypes.java'
|
2
|
--- src/com/goldencode/p2j/ui/client/driver/web/WebClientMessageTypes.java 2015-08-20 14:07:03 +0000
|
3
|
+++ src/com/goldencode/p2j/ui/client/driver/web/WebClientMessageTypes.java 2015-08-20 14:14:14 +0000
|
4
|
@@ -126,4 +126,7 @@
|
5
|
|
6
|
/** Restack the z-order of all windows. */
|
7
|
public static final byte MSG_RESTACK_WINDOWS = (byte) 0x95;
|
8
|
+
|
9
|
+ /** Set the stroke style for a window. */
|
10
|
+ public static final byte MSG_SET_STROKE_STYLE = (byte) 0x96;
|
11
|
}
|
12
|
|
13
|
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/index.html'
|
14
|
--- src/com/goldencode/p2j/ui/client/driver/web/index.html 2015-08-12 17:42:50 +0000
|
15
|
+++ src/com/goldencode/p2j/ui/client/driver/web/index.html 2015-08-20 12:40:07 +0000
|
16
|
@@ -9,6 +9,7 @@
|
17
|
|
18
|
<script type="text/javascript" src="/common/p2j.js"></script>
|
19
|
<script type="text/javascript" src="/common/p2j.sound.js"></script>
|
20
|
+ <script type="text/javascript" src="/client/p2j.strokes.js"></script>
|
21
|
<script type="text/javascript" src="/client/p2j.screen.js"></script>
|
22
|
<script type="text/javascript" src="/common/p2j.socket.js"></script>
|
23
|
<script type="text/javascript" src="/common/p2j.keymap.js"></script>
|
24
|
|
25
|
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js'
|
26
|
--- src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js 2015-08-20 14:07:03 +0000
|
27
|
+++ src/com/goldencode/p2j/ui/client/driver/web/res/p2j.socket.js 2015-08-20 14:15:40 +0000
|
28
|
@@ -24,7 +24,7 @@
|
29
|
** requests.
|
30
|
** 010 GES 20150818 Added more GUI message support including fonts, cursors and z-order.
|
31
|
** Once the web socket has connected, notify the Java side, so that it can start
|
32
|
-** sending requests.
|
33
|
+** sending requests, added line strokes.
|
34
|
*/
|
35
|
|
36
|
"use strict";
|
37
|
@@ -534,6 +534,13 @@
|
38
|
}
|
39
|
p2j.screen.restackZOrderEntries(winids);
|
40
|
break;
|
41
|
+ case 0x96:
|
42
|
+ // set line stroke
|
43
|
+ var strokeStyle = me.readInt32BinaryMessage(message, 1);
|
44
|
+ var strokeWidth = me.readInt32BinaryMessage(message, 5);
|
45
|
+ var wid = me.readInt32BinaryMessage(message, 9);
|
46
|
+ p2j.screen.setLineStroke(strokeStyle, strokeWidth, wid);
|
47
|
+ break;
|
48
|
};
|
49
|
}
|
50
|
else
|
51
|
|
52
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java'
|
53
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-08-18 19:50:34 +0000
|
54
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebEmulatedWindow.java 2015-08-20 10:02:03 +0000
|
55
|
@@ -17,7 +17,7 @@
|
56
|
** font creation/selection.
|
57
|
** 005 GES 20150817 Removed isOnTop() since it is unnecessary. The saveFocusListeners(),
|
58
|
** restoreFocusListeners() and moveToTop() are only needed for Swing usage and
|
59
|
-** have been removed from this class.
|
60
|
+** have been removed from this class, added line strokes.
|
61
|
*/
|
62
|
|
63
|
package com.goldencode.p2j.ui.client.gui.driver.web;
|
64
|
@@ -362,6 +362,7 @@
|
65
|
websock.setColor(ps.color.getRed(), ps.color.getGreen(), ps.color.getBlue());
|
66
|
break;
|
67
|
case SET_LINE_STROKE:
|
68
|
+ websock.setLineStroke(ps.stroke.ordinal(), Math.round(ps.strokeWidth), getWindowId());
|
69
|
break;
|
70
|
case SET_FONT:
|
71
|
websock.setFont(ps.font.font);
|
72
|
|
73
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java'
|
74
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java 2015-08-20 14:07:03 +0000
|
75
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/GuiWebSocket.java 2015-08-20 14:17:12 +0000
|
76
|
@@ -12,8 +12,8 @@
|
77
|
** 001 GES 20150331 First version which is a placeholder using the common parent code as ChUI.
|
78
|
** 002 GES 20150701 Added messages for a first pass at GUI support,
|
79
|
** implemented an images drawing operation.
|
80
|
-** 003 CA 20150810 Added operations for font, metrics and string drawing. Added z-order
|
81
|
-** support.
|
82
|
+** 003 CA 20150810 Added operations for font, metrics and string drawing. Added z-order,
|
83
|
+** line strokes.
|
84
|
** 004 CA 20150820 Moved the message receiving APIs to parent class.
|
85
|
*/
|
86
|
|
87
|
@@ -1231,6 +1231,31 @@
|
88
|
}
|
89
|
|
90
|
/**
|
91
|
+ * Sends MSG_SET_STROKE_STYLE to order the current window stroke to be changed
|
92
|
+ * on the client side. It sends a window its stroke style and line width. All possible stroke
|
93
|
+ * styles are listed by LineStroke enumeration.
|
94
|
+ *
|
95
|
+ * @param strokeStyle
|
96
|
+ * The known stroke style id.
|
97
|
+ * @param width
|
98
|
+ * The stroke line width.
|
99
|
+ * @param wid
|
100
|
+ * The window id.
|
101
|
+ */
|
102
|
+ public void setLineStroke(int strokeStyle, int width, int wid)
|
103
|
+ {
|
104
|
+ byte[] message = new byte[13];
|
105
|
+
|
106
|
+ message[0] = WebClientMessageTypes.MSG_SET_STROKE_STYLE;
|
107
|
+
|
108
|
+ writeMessageInt32(message, 1, strokeStyle);
|
109
|
+ writeMessageInt32(message, 5, width);
|
110
|
+ writeMessageInt32(message, 9, wid);
|
111
|
+
|
112
|
+ sendBinaryMessage(message);
|
113
|
+ }
|
114
|
+
|
115
|
+ /**
|
116
|
* Draw a string at the specified location.
|
117
|
*
|
118
|
* @param text
|
119
|
|
120
|
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js'
|
121
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-08-19 20:05:05 +0000
|
122
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-08-20 14:22:24 +0000
|
123
|
@@ -84,6 +84,8 @@
|
124
|
SET_TITLE : 29
|
125
|
};
|
126
|
|
127
|
+ var strokesManager = new LineStrokes();
|
128
|
+
|
129
|
/**
|
130
|
* Constructor for a Window class that represents a Progress 4GL window instance.
|
131
|
*
|
132
|
@@ -138,12 +140,17 @@
|
133
|
// eliminate anti-aliasing of images
|
134
|
this.ctx.imageSmoothingEnabled = false;
|
135
|
|
136
|
+ // the current window stroke style
|
137
|
+ this.strokeStyle = strokesManager.getDefaultStrokeStyle();
|
138
|
+ // the current window stroke width
|
139
|
+ this.strokeWidth = 1;
|
140
|
+
|
141
|
// force all drawing to be inside pixel "cells" instead of "stradling" between two cells
|
142
|
// which is the default; this eliminates much of the worst of the anti-aliasing and
|
143
|
// positioning problems inherent in canvas operations; this will also save off the
|
144
|
// current state of the graphics context so that it can be restored later
|
145
|
this.translate(0.5, 0.5);
|
146
|
- }
|
147
|
+ };
|
148
|
|
149
|
/**
|
150
|
* Cleanup any resources, including any linkages to the window from an owning window.
|
151
|
@@ -353,7 +360,7 @@
|
152
|
this.ctx.rect(x, y, width, height);
|
153
|
this.ctx.clip();
|
154
|
}
|
155
|
- }
|
156
|
+ }
|
157
|
};
|
158
|
|
159
|
/**
|
160
|
@@ -430,7 +437,7 @@
|
161
|
Window.prototype.resize = function(width, height)
|
162
|
{
|
163
|
// save off the previously drawn content
|
164
|
- var oldPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
165
|
+ var oldPixels = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
|
166
|
|
167
|
// this is expensive, but we really do need to change the overall size of the canvas
|
168
|
this.canvas.width = width;
|
169
|
@@ -441,7 +448,7 @@
|
170
|
this.replay();
|
171
|
|
172
|
// re-blit the previously drawn content
|
173
|
- ctx.putImageData(oldPixels, 0, 0);
|
174
|
+ this.ctx.putImageData(oldPixels, 0, 0);
|
175
|
};
|
176
|
|
177
|
/**
|
178
|
@@ -454,6 +461,42 @@
|
179
|
{
|
180
|
this.canvas.style.cursor = style;
|
181
|
};
|
182
|
+
|
183
|
+ /**
|
184
|
+ * Sets the stroke style.
|
185
|
+ *
|
186
|
+ * @param {Number} strokeStyle
|
187
|
+ * The predefined stroke style.
|
188
|
+ */
|
189
|
+ Window.prototype.setStrokeStyle = function(strokeStyle)
|
190
|
+ {
|
191
|
+ this.strokeStyle = strokeStyle;
|
192
|
+ };
|
193
|
+
|
194
|
+ /**
|
195
|
+ * Sets the stroke line width.
|
196
|
+ *
|
197
|
+ * @param {Number} width
|
198
|
+ * The stroke line width.
|
199
|
+ */
|
200
|
+ Window.prototype.setStrokeWidth = function(width)
|
201
|
+ {
|
202
|
+ this.strokeWidth = width;
|
203
|
+ };
|
204
|
+
|
205
|
+ /**
|
206
|
+ * Sets the line stroke.
|
207
|
+ *
|
208
|
+ * @param {Number} strokeStyle
|
209
|
+ * The predefined stroke style.
|
210
|
+ * @param {Number} width
|
211
|
+ * The stroke line width.
|
212
|
+ */
|
213
|
+ Window.prototype.setLineStroke = function(strokeStyle, width)
|
214
|
+ {
|
215
|
+ this.setStrokeStyle(strokeStyle);
|
216
|
+ this.setStrokeWidth(width);
|
217
|
+ };
|
218
|
|
219
|
/**
|
220
|
* Draw the given list of operations in the canvas.
|
221
|
@@ -521,11 +564,11 @@
|
222
|
// in this case, the "y" is the height in which it needs to be vertically centered
|
223
|
y = y / 2;
|
224
|
|
225
|
- ctx.textBaseline = 'middle';
|
226
|
+ this.ctx.textBaseline = 'middle';
|
227
|
}
|
228
|
else
|
229
|
{
|
230
|
- ctx.textBaseline = 'top';
|
231
|
+ this.ctx.textBaseline = 'top';
|
232
|
}
|
233
|
|
234
|
this.ctx.fillText(text, x, y);
|
235
|
@@ -554,16 +597,16 @@
|
236
|
var lheight = p2j.socket.readInt32BinaryMessage(message, idx + offset);
|
237
|
offset = offset + 4;
|
238
|
|
239
|
- var textWidth = p2j.fonts.getTextWidth(this.currentFont, text);
|
240
|
- var textHeight = p2j.fonts.getTextHeight(this.currentFont, text);
|
241
|
+ var textWidth = p2j.fonts.getTextWidth(currentFont, text);
|
242
|
+ var textHeight = p2j.fonts.getTextHeight(currentFont, text);
|
243
|
|
244
|
var widthScale = lwidth / textWidth;
|
245
|
var heightScale = lheight / textHeight;
|
246
|
|
247
|
// scale drawing context to computed width
|
248
|
// this scales the desired structure.x as well so it needs adjusting
|
249
|
- ctx.save();
|
250
|
- ctx.scale(widthScale, heightScale);
|
251
|
+ this.ctx.save();
|
252
|
+ this.ctx.scale(widthScale, heightScale);
|
253
|
|
254
|
var scaleBackWidth = 1 / widthScale;
|
255
|
var scaleBackHeight = 1 / heightScale;
|
256
|
@@ -573,15 +616,15 @@
|
257
|
// in this case, the "y" is the height in which it needs to be vertically centered
|
258
|
y = y / 2;
|
259
|
|
260
|
- ctx.textBaseline = 'middle';
|
261
|
+ this.ctx.textBaseline = 'middle';
|
262
|
}
|
263
|
else
|
264
|
{
|
265
|
- ctx.textBaseline = 'top';
|
266
|
+ this.ctx.textBaseline = 'top';
|
267
|
}
|
268
|
|
269
|
- ctx.fillText(text, x * scaleBackWidth, y * scaleBackHeight);
|
270
|
- ctx.restore();
|
271
|
+ this.ctx.fillText(text, x * scaleBackWidth, y * scaleBackHeight);
|
272
|
+ this.ctx.restore();
|
273
|
|
274
|
break;
|
275
|
case ops.DRAW_PARAGRAPH:
|
276
|
@@ -605,7 +648,7 @@
|
277
|
width = p2j.socket.readInt32BinaryMessage(message, idx + offset);
|
278
|
offset = offset + 4;
|
279
|
|
280
|
- ctx.textBaseline = 'top';
|
281
|
+ this.ctx.textBaseline = 'top';
|
282
|
|
283
|
me.layoutParagraphWorker(text, fontId, x, y, width, true);
|
284
|
|
285
|
@@ -615,7 +658,9 @@
|
286
|
var y1 = p2j.socket.readInt32BinaryMessage(message, idx + 5);
|
287
|
var x2 = p2j.socket.readInt32BinaryMessage(message, idx + 9);
|
288
|
var y2 = p2j.socket.readInt32BinaryMessage(message, idx + 13);
|
289
|
- drawLine(this.ctx, x1, y1, x2, y2, this.rawColor);
|
290
|
+ strokesManager.applyStrokeToPath(this.ctx,
|
291
|
+ this.strokeStyle, this.strokeWidth, this.rawColor,
|
292
|
+ drawLine(this.ctx, x1, y1, x2, y2, this.rawColor));
|
293
|
this.ctx.stroke();
|
294
|
break;
|
295
|
case ops.DRAW_RECT:
|
296
|
@@ -623,7 +668,9 @@
|
297
|
y = p2j.socket.readInt32BinaryMessage(message, idx + 5);
|
298
|
width = p2j.socket.readInt32BinaryMessage(message, idx + 9);
|
299
|
height = p2j.socket.readInt32BinaryMessage(message, idx + 13);
|
300
|
- drawRect(this.ctx, x, y, width, height, this.rawColor, false);
|
301
|
+ strokesManager.applyStrokeToPath(this.ctx,
|
302
|
+ this.strokeStyle, this.strokeWidth, this.rawColor,
|
303
|
+ drawRect(this.ctx, x, y, width, height, this.rawColor, false));
|
304
|
break;
|
305
|
case ops.DRAW_ROUND_RECT:
|
306
|
x = p2j.socket.readInt32BinaryMessage(message, idx + 1);
|
307
|
@@ -658,7 +705,7 @@
|
308
|
imgDataOffset = idx + 22;
|
309
|
loadedImages.set(key, message.subarray(imgDataOffset, imgDataOffset + pixelsInBytes));
|
310
|
}
|
311
|
- drawImage(x, y, width, height, imgData, imgDataOffset);
|
312
|
+ drawImage(this.ctx, x, y, width, height, imgData, imgDataOffset);
|
313
|
break;
|
314
|
case ops.FILL_RECT:
|
315
|
x = p2j.socket.readInt32BinaryMessage(message, idx + 1);
|
316
|
@@ -673,7 +720,7 @@
|
317
|
width = p2j.socket.readInt32BinaryMessage(message, idx + 9);
|
318
|
height = p2j.socket.readInt32BinaryMessage(message, idx + 13);
|
319
|
diameter = p2j.socket.readInt32BinaryMessage(message, idx + 17);
|
320
|
- drawRoundRect(ctx, x, y, width, height, diameter, this.rawColor, true);
|
321
|
+ drawRoundRect(this.ctx, x, y, width, height, diameter, this.rawColor, true);
|
322
|
break;
|
323
|
case ops.FILL_POLYGON:
|
324
|
idx += 1;
|
325
|
@@ -719,14 +766,14 @@
|
326
|
case ops.SET_FONT:
|
327
|
fontId = p2j.socket.readInt32BinaryMessage(message, idx + 1);
|
328
|
|
329
|
- this.setFont(fontId);
|
330
|
+ this.setFont(this.ctx, fontId);
|
331
|
break;
|
332
|
case ops.SET_FONT_STYLE:
|
333
|
var style = p2j.socket.readInt32BinaryMessage(message, idx + 1);
|
334
|
|
335
|
- if (p2j.fonts.setFontStyle(this.currentFont, style))
|
336
|
+ if (p2j.fonts.setFontStyle(currentFont, style))
|
337
|
{
|
338
|
- fname = p2j.fonts.getFontName(this.currentFont);
|
339
|
+ fname = p2j.fonts.getFontName(currentFont);
|
340
|
|
341
|
this.ctx.font = fname;
|
342
|
}
|
343
|
@@ -792,7 +839,7 @@
|
344
|
function isValidWindowId(wid)
|
345
|
{
|
346
|
return (typeof wid === 'number') && (wid % 1 === 0) && wid > 0;
|
347
|
- }
|
348
|
+ };
|
349
|
|
350
|
/**
|
351
|
* Checks if the given value already exists as a window id.
|
352
|
@@ -805,8 +852,8 @@
|
353
|
function isExistingWindowId(wid)
|
354
|
{
|
355
|
return winlist[wid] instanceof Window;
|
356
|
- }
|
357
|
-
|
358
|
+ };
|
359
|
+
|
360
|
/**
|
361
|
* Obtain the specified window.
|
362
|
*
|
363
|
@@ -819,8 +866,8 @@
|
364
|
function getWindow(wid)
|
365
|
{
|
366
|
return winlist[wid] instanceof Window ? winlist[wid] : null;
|
367
|
- }
|
368
|
-
|
369
|
+ };
|
370
|
+
|
371
|
/**
|
372
|
* Find the index of the given window in the z-order list.
|
373
|
*
|
374
|
@@ -855,8 +902,8 @@
|
375
|
}
|
376
|
|
377
|
return found;
|
378
|
- }
|
379
|
-
|
380
|
+ };
|
381
|
+
|
382
|
/**
|
383
|
* Adds the given window to the end of the z-order list, setting the z-order value as needed.
|
384
|
*
|
385
|
@@ -875,7 +922,7 @@
|
386
|
|
387
|
// assign the z-order
|
388
|
win.canvas.style.zIndex = zidx;
|
389
|
- }
|
390
|
+ };
|
391
|
|
392
|
/**
|
393
|
* Removes the given window from the z-order list and resets the z-order values of all
|
394
|
@@ -898,7 +945,7 @@
|
395
|
}
|
396
|
|
397
|
return removeZOrderEntryWorker(found);
|
398
|
- }
|
399
|
+ };
|
400
|
|
401
|
/**
|
402
|
* Removes the given element from the z-order list and resets the z-order values of all
|
403
|
@@ -924,7 +971,7 @@
|
404
|
}
|
405
|
|
406
|
return removed;
|
407
|
- }
|
408
|
+ };
|
409
|
|
410
|
/**
|
411
|
* Moves the given window to the top of the z-order list and resets the z-order values of all
|
412
|
@@ -945,7 +992,7 @@
|
413
|
|
414
|
addZOrderEntry(entry.id, entry.win);
|
415
|
}
|
416
|
- }
|
417
|
+ };
|
418
|
|
419
|
/**
|
420
|
* Directly draw the specified pixel in the given color.
|
421
|
@@ -959,14 +1006,14 @@
|
422
|
* @param {Number[]} color
|
423
|
* Array of 3 integer values between 0 and 255 inclusive, representing an RGB color.
|
424
|
*/
|
425
|
- function drawPixel(ctx, x, y, color)
|
426
|
+ Window.prototype.drawPixel = function(ctx, x, y, color)
|
427
|
{
|
428
|
- pixData[0] = color[0];
|
429
|
- pixData[1] = color[1];
|
430
|
- pixData[2] = color[2];
|
431
|
+ this.pixData[0] = color[0];
|
432
|
+ this.pixData[1] = color[1];
|
433
|
+ this.pixData[2] = color[2];
|
434
|
|
435
|
- ctx.putImageData(pixel, x, y);
|
436
|
- }
|
437
|
+ this.ctx.putImageData(pixel, x, y);
|
438
|
+ };
|
439
|
|
440
|
/**
|
441
|
* Draw a line in the given color from (x1, y1) to (x2, y2) inclusive, using direct drawing.
|
442
|
@@ -985,9 +1032,14 @@
|
443
|
* Y coordinate of the ending pixel to be drawn.
|
444
|
* @param {Number[]} color
|
445
|
* Array of 3 integer values between 0 and 255 inclusive, representing an RGB color.
|
446
|
+ *
|
447
|
+ * @return {Array} path
|
448
|
+ * The {x:.,y:.} point per a pixel array that represents the rectangle outerline.
|
449
|
*/
|
450
|
- function drawLine(ctx, x1, y1, x2, y2, color)
|
451
|
+ Window.prototype.drawLine = function(ctx, x1, y1, x2, y2, color)
|
452
|
{
|
453
|
+ // holds the line pixels to draw
|
454
|
+ var path = [];
|
455
|
var dx = Math.abs(x2 - x1);
|
456
|
var dy = Math.abs(y2 - y1);
|
457
|
|
458
|
@@ -1004,7 +1056,11 @@
|
459
|
|
460
|
while (true)
|
461
|
{
|
462
|
- drawPixel(ctx, x, y, color);
|
463
|
+ if (strokesManager.isDirectDrawingStrokeStyle(this.strokeStyle))
|
464
|
+ {
|
465
|
+ drawPixel(ctx, x, y, color);
|
466
|
+ }
|
467
|
+ path.push({x : x, y : y});
|
468
|
|
469
|
if (x == x2 && y == y2)
|
470
|
break;
|
471
|
@@ -1023,7 +1079,9 @@
|
472
|
y += yIncr;
|
473
|
}
|
474
|
}
|
475
|
- }
|
476
|
+
|
477
|
+ return path;
|
478
|
+ };
|
479
|
|
480
|
/**
|
481
|
* Fill or stroke the current path on the given context, first using the current path as a
|
482
|
@@ -1052,8 +1110,8 @@
|
483
|
}
|
484
|
|
485
|
ctx.restore();
|
486
|
- }
|
487
|
-
|
488
|
+ };
|
489
|
+
|
490
|
/**
|
491
|
* Draw a rectangle in the given color and dimensions with the line drawing being overwritten
|
492
|
* using direct drawing to eliminate the negative/unwanted effects of alni-aliasing.
|
493
|
@@ -1073,8 +1131,11 @@
|
494
|
* This will be used for the border lines and when in fill mode, also the interior.
|
495
|
* @param {Boolean} fill
|
496
|
* <code>true</code> to fill the drawn rectangle with the given color.
|
497
|
+ *
|
498
|
+ * @return {Array} path
|
499
|
+ * The {x:.,y:.} point per a pixel array that represents the rectangle outerline.
|
500
|
*/
|
501
|
- function drawRect(ctx, x, y, width, height, color, fill)
|
502
|
+ Window.prototype.drawRect = function(ctx, x, y, width, height, color, fill)
|
503
|
{
|
504
|
// use vector operations for the interior of the rectangle
|
505
|
if (fill)
|
506
|
@@ -1085,15 +1146,20 @@
|
507
|
}
|
508
|
|
509
|
// now overdraw the stroked portion to eliminate anit-aliasing
|
510
|
- drawLine(ctx, x, y, x + width, y, color);
|
511
|
- drawLine(ctx, x, y + 1, x, y + height, color);
|
512
|
- drawLine(ctx, x + width, y + 1, x + width, y + height, color);
|
513
|
- drawLine(ctx, x + 1, y + height, x + width - 1, y + height, color);
|
514
|
- }
|
515
|
+ // to draw rectangle following a clockwise direction
|
516
|
+ var path = drawLine(ctx, x, y, x + width, y, color);
|
517
|
+ Array.prototype.push.apply(path, drawLine(ctx, x + width, y + 1, x + width, y + height, color));
|
518
|
+ Array.prototype.push.apply(path, drawLine(ctx, x + width - 1, y + height, x + 1, y + height, color));
|
519
|
+ Array.prototype.push.apply(path, drawLine(ctx, x, y + height, x, y + 1, color));// close the path
|
520
|
+
|
521
|
+ return path;
|
522
|
+ };
|
523
|
|
524
|
/**
|
525
|
* It draws an image on the canvas.
|
526
|
*
|
527
|
+ * @param {CanvasRenderingContext2D} ctx
|
528
|
+ * The canvas 2D graphics context on which to draw.
|
529
|
* @param {Number} x
|
530
|
* X coordinate of the top left corner.
|
531
|
* @param {Number} y
|
532
|
@@ -1107,7 +1173,7 @@
|
533
|
* @param {Number} imgDataOffset
|
534
|
* The offset of the encoded image data.
|
535
|
*/
|
536
|
- function drawImage(x, y, width, height, imgData, imgDataOffset)
|
537
|
+ Window.prototype.drawImage = function(ctx, x, y, width, height, imgData, imgDataOffset)
|
538
|
{
|
539
|
var img = ctx.createImageData(width, height);
|
540
|
var data = img.data;
|
541
|
@@ -1121,7 +1187,7 @@
|
542
|
data[i + 3] = imgData[j + 3];
|
543
|
}
|
544
|
ctx.putImageData(img, x, y);
|
545
|
- }
|
546
|
+ };
|
547
|
|
548
|
/**
|
549
|
* Convert a standard fillStyle or strokeStyle color into an array of [ R, G, B ] values.
|
550
|
@@ -1162,7 +1228,7 @@
|
551
|
}
|
552
|
|
553
|
return [ r, g, b ];
|
554
|
- }
|
555
|
+ };
|
556
|
|
557
|
/**
|
558
|
* Test if the given argument is an array of 3 integer values.
|
559
|
@@ -1199,7 +1265,7 @@
|
560
|
}
|
561
|
|
562
|
return true;
|
563
|
- }
|
564
|
+ };
|
565
|
|
566
|
/**
|
567
|
* Convert the given array of 3 integer values into an HTML color string.
|
568
|
@@ -1219,7 +1285,7 @@
|
569
|
return "rgb(" + color[0].toString() + ", "
|
570
|
+ color[1].toString() + ", "
|
571
|
+ color[2].toString() + ")";
|
572
|
- }
|
573
|
+ };
|
574
|
|
575
|
/**
|
576
|
* Convert the given array of RGB values into a lighter color in a manner that is compatible
|
577
|
@@ -1254,7 +1320,7 @@
|
578
|
var b = Math.min(Math.floor(bIn / SCALE_FACTOR), 255);
|
579
|
|
580
|
return [ r, g, b ];
|
581
|
- }
|
582
|
+ };
|
583
|
|
584
|
/**
|
585
|
* Convert the given array of RGB values into a darker color in a manner that is compatible
|
586
|
@@ -1277,7 +1343,7 @@
|
587
|
var b = Math.max(0, Math.floor(color[2] * SCALE_FACTOR));
|
588
|
|
589
|
return [ r, g, b ];
|
590
|
- }
|
591
|
+ };
|
592
|
|
593
|
/**
|
594
|
* Draw a rounded rectangle with the given context, dimensions and fill.
|
595
|
@@ -1302,7 +1368,7 @@
|
596
|
* <code>true</code> to fill the rectangle with the current color, otherwise just
|
597
|
* stroke the rectangle.
|
598
|
*/
|
599
|
- function drawRoundRect(ctx, x, y, width, height, diameter, color, fill)
|
600
|
+ Window.prototype.drawRoundRect = function(ctx, x, y, width, height, diameter, color, fill)
|
601
|
{
|
602
|
var radius = diameter / 2;
|
603
|
|
604
|
@@ -1352,7 +1418,7 @@
|
605
|
drawLine(ctx, rightUpX, rightUpY, rightDownX, rightDownY, color);
|
606
|
drawLine(ctx, bottomLeftX, bottomLeftY, bottomRightX, bottomRightY, color);
|
607
|
drawLine(ctx, leftUpX, leftUpY, leftDownX, leftDownY, color);
|
608
|
- }
|
609
|
+ };
|
610
|
|
611
|
/**
|
612
|
* Draw a slightly shaded "3D" rectangle with the given context, dimensions and fill. In
|
613
|
@@ -1380,7 +1446,7 @@
|
614
|
* @param {Boolean} raise
|
615
|
* <code>true</code> to draw in raised mode.
|
616
|
*/
|
617
|
- function draw3DRect(ctx, x, y, width, height, color, fill, raised)
|
618
|
+ Window.prototype.draw3DRect = function(ctx, x, y, width, height, color, fill, raised)
|
619
|
{
|
620
|
// save off our colors
|
621
|
var oriFillColor = ctx.fillStyle;
|
622
|
@@ -1422,8 +1488,8 @@
|
623
|
// restore our colors
|
624
|
ctx.fillStyle = oriFillColor;
|
625
|
ctx.strokeStyle = oriStrokeColor;
|
626
|
- }
|
627
|
-
|
628
|
+ };
|
629
|
+
|
630
|
/**
|
631
|
* Draw a closed polygon with the given context, vertices and fill.
|
632
|
*
|
633
|
@@ -1441,7 +1507,7 @@
|
634
|
* <code>true</code> to fill the rectangle with the current color, otherwise just
|
635
|
* stroke the rectangle.
|
636
|
*/
|
637
|
- function drawPolygon(ctx, xPoints, yPoints, num, color, fill)
|
638
|
+ Window.prototype.drawPolygon = function(ctx, xPoints, yPoints, num, color, fill)
|
639
|
{
|
640
|
var i;
|
641
|
|
642
|
@@ -1462,26 +1528,28 @@
|
643
|
{
|
644
|
drawLine(ctx, xPoints[i], yPoints[i], xPoints[i + 1], yPoints[i + 1], color);
|
645
|
}
|
646
|
- }
|
647
|
+ };
|
648
|
|
649
|
/**
|
650
|
* Set the font in the current context. If the current font does not get changed, then this
|
651
|
* will be a no-op.
|
652
|
*
|
653
|
+ * @param {CanvasRenderingContext2D} ctx
|
654
|
+ * The canvas 2D graphics context on which to draw.
|
655
|
* @param {Number} fontId
|
656
|
* The font identifier.
|
657
|
*/
|
658
|
- function setFont(fontId)
|
659
|
+ function setFont(ctx, fontId)
|
660
|
{
|
661
|
- if (fontId != this.currentFont)
|
662
|
+ if (fontId != currentFont)
|
663
|
{
|
664
|
var fname = p2j.fonts.getFontName(fontId);
|
665
|
|
666
|
- this.ctx.font = fname;
|
667
|
+ ctx.font = fname;
|
668
|
|
669
|
- this.currentFont = fontId;
|
670
|
+ currentFont = fontId;
|
671
|
}
|
672
|
- }
|
673
|
+ };
|
674
|
|
675
|
/**
|
676
|
* Find the next split position, so that the sub-text fits the given width.
|
677
|
@@ -1535,7 +1603,7 @@
|
678
|
while (end < txt.length);
|
679
|
|
680
|
return end;
|
681
|
- }
|
682
|
+ };
|
683
|
|
684
|
/**
|
685
|
* Split the word starting on the given index so that it fits the specified width.
|
686
|
@@ -1568,7 +1636,7 @@
|
687
|
}
|
688
|
|
689
|
return end;
|
690
|
- }
|
691
|
+ };
|
692
|
|
693
|
/**
|
694
|
* Find the next occurrence of the character given by the specified regex, starting from the
|
695
|
@@ -1587,7 +1655,7 @@
|
696
|
{
|
697
|
var indexOf = txt.substring(start).search(regex);
|
698
|
return (indexOf >= 0) ? (indexOf + start) : indexOf;
|
699
|
- }
|
700
|
+ };
|
701
|
|
702
|
/**
|
703
|
* Create a new top-level window (and the canvas that backs it).
|
704
|
@@ -1770,13 +1838,16 @@
|
705
|
/**
|
706
|
* Draw text on canvas.
|
707
|
*
|
708
|
- * @param {number} x x coordinate
|
709
|
- * @param {number} y y coordinate
|
710
|
- * @param {string} text text to draw
|
711
|
- * @param {number} a attribute
|
712
|
- * @param {object} v color pairs
|
713
|
+ * @param {CanvasRenderingContext2D} ctx
|
714
|
+ * The canvas 2D graphics context on which to draw.
|
715
|
+ * @param {Number} x
|
716
|
+ * The x coordinate.
|
717
|
+ * @param {Number} y
|
718
|
+ * The y coordinate.
|
719
|
+ * @param {String} text
|
720
|
+ * The text to draw
|
721
|
*/
|
722
|
- var drawText = function(ctx, x, y, text)
|
723
|
+ Window.prototype.drawText = function(ctx, x, y, text)
|
724
|
{
|
725
|
// TODO calc width and height
|
726
|
var width;
|
727
|
@@ -1902,6 +1973,25 @@
|
728
|
};
|
729
|
|
730
|
/**
|
731
|
+ * Sets the line stroke for a window with the given id.
|
732
|
+ *
|
733
|
+ * @param {Number} strokeStyle
|
734
|
+ * The predefined stroke style.
|
735
|
+ * @param {Number} width
|
736
|
+ * The stroke line width.
|
737
|
+ * @param {Number} wid
|
738
|
+ * Denotes the active window id.
|
739
|
+ */
|
740
|
+ me.setLineStroke = function(strokeStyle, width, wid)
|
741
|
+ {
|
742
|
+ var win = getWindow(wid);
|
743
|
+ if (win)
|
744
|
+ {
|
745
|
+ win.setLineStroke(strokeStyle, width);
|
746
|
+ }
|
747
|
+ };
|
748
|
+
|
749
|
+ /**
|
750
|
* Clear the screen.
|
751
|
*/
|
752
|
me.clear = function()
|
753
|
@@ -1941,6 +2031,8 @@
|
754
|
* The method performs a layout operation on the supplied text and returns the resulting
|
755
|
* paragraph height while maintaining the supplied maximum width.
|
756
|
*
|
757
|
+ * @param {CanvasRenderingContext2D} ctx
|
758
|
+ * The canvas 2D graphics context on which to draw.
|
759
|
* @param {String} txt
|
760
|
* The paragraph text.
|
761
|
* @param {Number} font
|
762
|
@@ -1957,7 +2049,7 @@
|
763
|
*
|
764
|
* @return {Number} The paragraph height.
|
765
|
*/
|
766
|
- me.layoutParagraphWorker = function(txt, font, x, y, width, draw)
|
767
|
+ me.layoutParagraphWorker = function(ctx, txt, font, x, y, width, draw)
|
768
|
{
|
769
|
var newLine = true;
|
770
|
var i = 0;
|
771
|
@@ -1965,9 +2057,9 @@
|
772
|
if (draw)
|
773
|
{
|
774
|
// unless we are drawing, there is no need in changing the context font
|
775
|
- this.ctx.save();
|
776
|
+ ctx.save();
|
777
|
|
778
|
- this.setFont(font);
|
779
|
+ this.setFont(ctx, font);
|
780
|
}
|
781
|
|
782
|
var height = 0;
|
783
|
@@ -1992,7 +2084,7 @@
|
784
|
|
785
|
if (draw)
|
786
|
{
|
787
|
- this.ctx.restore();
|
788
|
+ ctx.restore();
|
789
|
}
|
790
|
|
791
|
return height;
|
792
|
|
793
|
=== added file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.strokes.js'
|
794
|
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.strokes.js 1970-01-01 00:00:00 +0000
|
795
|
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.strokes.js 2015-08-20 09:36:41 +0000
|
796
|
@@ -0,0 +1,398 @@
|
797
|
+/*
|
798
|
+** Module : p2j.strokes.js
|
799
|
+** Abstract : GUI-specific screen management
|
800
|
+**
|
801
|
+** Copyright (c) 2014-2015, Golden Code Development Corporation.
|
802
|
+** ALL RIGHTS RESERVED. Use is subject to license terms.
|
803
|
+**
|
804
|
+** Golden Code Development Corporation
|
805
|
+** CONFIDENTIAL
|
806
|
+**
|
807
|
+** -#- -I- --Date-- ------------------------------Description----------------------------------
|
808
|
+** 001 SBI 20150819 The first version defines LineStrokes class as a strokes manager.
|
809
|
+*/
|
810
|
+
|
811
|
+"use strict";
|
812
|
+
|
813
|
+/**
|
814
|
+ * Defines the known stroke styles and methods to draw styled outer lines.
|
815
|
+ */
|
816
|
+function LineStrokes()
|
817
|
+{
|
818
|
+ /**
|
819
|
+ * Joins path segments by extending their outside edges until
|
820
|
+ * they meet.
|
821
|
+ */
|
822
|
+ var JOIN_MITER = 0;
|
823
|
+
|
824
|
+ /**
|
825
|
+ * Joins path segments by rounding off the corner at a radius
|
826
|
+ * of half the line width.
|
827
|
+ */
|
828
|
+ var JOIN_ROUND = 1;
|
829
|
+
|
830
|
+ /**
|
831
|
+ * Joins path segments by connecting the outer corners of their
|
832
|
+ * wide outlines with a straight segment.
|
833
|
+ */
|
834
|
+ var JOIN_BEVEL = 2;
|
835
|
+
|
836
|
+ /**
|
837
|
+ * Ends unclosed subpaths and dash segments with no added
|
838
|
+ * decoration.
|
839
|
+ */
|
840
|
+ var CAP_BUTT = 0;
|
841
|
+
|
842
|
+ /**
|
843
|
+ * Ends unclosed subpaths and dash segments with a round
|
844
|
+ * decoration that has a radius equal to half of the width
|
845
|
+ * of the pen.
|
846
|
+ */
|
847
|
+ var CAP_ROUND = 1;
|
848
|
+
|
849
|
+ /**
|
850
|
+ * Ends unclosed subpaths and dash segments with a square
|
851
|
+ * projection that extends beyond the end of the segment
|
852
|
+ * to a distance equal to half of the line width.
|
853
|
+ */
|
854
|
+ var CAP_SQUARE = 2;
|
855
|
+
|
856
|
+ /**
|
857
|
+ * This is the list of all possible line stoke types.
|
858
|
+ */
|
859
|
+ var LineStrokeEnum =
|
860
|
+ {
|
861
|
+ DEFAULT : 0,
|
862
|
+ SPECIFIED_WIDTH : 1,
|
863
|
+ DOTTED : 2,
|
864
|
+ DOTTED_SMALL : 3,
|
865
|
+ DOTTED_SMALL_THIN : 4
|
866
|
+ };
|
867
|
+
|
868
|
+ var LineStroke =
|
869
|
+ {
|
870
|
+ /** Dotted line specific parameter. */
|
871
|
+ DOT_STEP : 2.0,
|
872
|
+
|
873
|
+ /** Dotted line specific parameter. */
|
874
|
+ DOT_STEP_SMALL : 1.0,
|
875
|
+
|
876
|
+ /** Dotted line width. */
|
877
|
+ DOT_LINE_WIDTH : 1.0,
|
878
|
+
|
879
|
+ /** Dotted thin line width. */
|
880
|
+ DOT_LINE_THIN_WIDTH : 0.5
|
881
|
+ };
|
882
|
+
|
883
|
+ var dotStroke = new BasicStroke(LineStroke.DOT_LINE_WIDTH, CAP_BUTT, JOIN_BEVEL, 0.0,
|
884
|
+ [LineStroke.DOT_STEP, LineStroke.DOT_STEP], LineStroke.DOT_STEP);
|
885
|
+
|
886
|
+ var dotSmallStroke = new BasicStroke(LineStroke.DOT_LINE_WIDTH, CAP_BUTT, JOIN_BEVEL, 0.0,
|
887
|
+ [LineStroke.DOT_STEP_SMALL, LineStroke.DOT_STEP_SMALL], LineStroke.DOT_STEP_SMALL);
|
888
|
+
|
889
|
+ var dotSmallThinStroke = new BasicStroke(LineStroke.DOT_LINE_THIN_WIDTH, CAP_BUTT,
|
890
|
+ JOIN_BEVEL, 0.0, [LineStroke.DOT_STEP_SMALL, LineStroke.DOT_STEP_SMALL],
|
891
|
+ LineStroke.DOT_STEP_SMALL);
|
892
|
+
|
893
|
+ var defaultStroke = new BasicStroke(1.0, CAP_SQUARE, JOIN_MITER, 10.0, null, 0.0);
|
894
|
+
|
895
|
+ /** Holds all java script styles of how the ends of lines are drawn. */
|
896
|
+ var caps = [ "butt", "round", "square"];
|
897
|
+
|
898
|
+ /**
|
899
|
+ * Holds all java script styles of how two connecting segments with non-zero lengths
|
900
|
+ * in a shape are joined together.
|
901
|
+ */
|
902
|
+ var joins = [ "miter", "round", "bevel"];
|
903
|
+
|
904
|
+ /**
|
905
|
+ * Holds properties for line drawing styles.
|
906
|
+ *
|
907
|
+ * @param width
|
908
|
+ * The width of lines to draw.
|
909
|
+ * @param cap
|
910
|
+ * The decoration of the line ends.
|
911
|
+ * @param join
|
912
|
+ * The decoration applied where path segments meet.
|
913
|
+ * @param miterlimit
|
914
|
+ * The limit to trim the miter join.
|
915
|
+ * @param dash
|
916
|
+ * The array representing the dashing pattern.
|
917
|
+ * @param dash_phase
|
918
|
+ * The offset to start the dashing pattern.
|
919
|
+ */
|
920
|
+ function BasicStroke(width, cap, join, miterLimit, dash, dash_phase)
|
921
|
+ {
|
922
|
+ this.getWidth = function() { return width; };
|
923
|
+ this.getCap = function() { return caps[cap]; };
|
924
|
+
|
925
|
+ this.getJoin = function() { return joins[join]; };
|
926
|
+ this.getMiterLimit = function() { return miterLimit; };
|
927
|
+
|
928
|
+ this.getDash = function() { return dash; };
|
929
|
+ this.getDashPhase = function() { return dash_phase; };
|
930
|
+ };
|
931
|
+
|
932
|
+ /**
|
933
|
+ * Returns the stroke style object.
|
934
|
+ *
|
935
|
+ * @param {Number} strokeStyle
|
936
|
+ * The stroke style id according to the LineStroke enumeration.
|
937
|
+ * @param {Number} width
|
938
|
+ * The line width.
|
939
|
+ *
|
940
|
+ * @return The basic line stroke object.
|
941
|
+ */
|
942
|
+ function getLineStroke(strokeStyle, width)
|
943
|
+ {
|
944
|
+ switch(strokeStyle)
|
945
|
+ {
|
946
|
+ case LineStrokeEnum.SPECIFIED_WIDTH:
|
947
|
+ return new BasicStroke(width, CAP_SQUARE, JOIN_MITER, 10.0, null, 0.0);
|
948
|
+ case LineStrokeEnum.DOTTED:
|
949
|
+ return dotStroke;
|
950
|
+ case LineStrokeEnum.DOTTED_SMALL:
|
951
|
+ return dotSmallStroke;
|
952
|
+ case LineStrokeEnum.DOTTED_SMALL_THIN:
|
953
|
+ return dotSmallThinStroke;
|
954
|
+ default:
|
955
|
+ return defaultStroke;
|
956
|
+ }
|
957
|
+ };
|
958
|
+
|
959
|
+ /**
|
960
|
+ * Returns the stroke path renderer.
|
961
|
+ *
|
962
|
+ * @param {CanvasRenderingContext2D} context
|
963
|
+ * The canvas renderer.
|
964
|
+ * @param {Number} strokeStyle
|
965
|
+ * The stroke style id according to the LineStroke enumeration.
|
966
|
+ * @param {Number} width
|
967
|
+ * The line width.
|
968
|
+ * @param {Number[]} strokeColor
|
969
|
+ * The array of 3 integer values between 0 and 255 inclusive, representing
|
970
|
+ * a stroke color.
|
971
|
+ *
|
972
|
+ * @return The stroke path renderer.
|
973
|
+ */
|
974
|
+ function getStrokePathRenderer(context, strokeStyle, width, strokeColor)
|
975
|
+ {
|
976
|
+ var basicStroke = getLineStroke(strokeStyle, width);
|
977
|
+ switch(strokeStyle)
|
978
|
+ {
|
979
|
+ case LineStrokeEnum.SPECIFIED_WIDTH:
|
980
|
+ return new WidenPathRenderer(context, basicStroke, strokeColor);
|
981
|
+ case LineStrokeEnum.DOTTED:
|
982
|
+ case LineStrokeEnum.DOTTED_SMALL:
|
983
|
+ case LineStrokeEnum.DOTTED_SMALL_THIN:
|
984
|
+ return new DotsPathRenderer(context, basicStroke, strokeColor);
|
985
|
+ default:
|
986
|
+ return { applyStroke : function (path) {} };
|
987
|
+ }
|
988
|
+ };
|
989
|
+
|
990
|
+ /**
|
991
|
+ * Apply the given stroke style to the JS native canvas renderer.
|
992
|
+ *
|
993
|
+ * @param {CanvasRenderingContext2D} context
|
994
|
+ * The canvas renderer.
|
995
|
+ * @param {Number} strokeStyle
|
996
|
+ * The stroke style id.
|
997
|
+ * @param {Number} width
|
998
|
+ * The line width.
|
999
|
+ */
|
1000
|
+ this.apply = function(context, strokeStyle, width)
|
1001
|
+ {
|
1002
|
+ if (context instanceof CanvasRenderingContext2D)
|
1003
|
+ {
|
1004
|
+ var basicStroke = getLineStroke(strokeStyle, width);
|
1005
|
+ context.lineWidth = basicStroke.getWidth();
|
1006
|
+
|
1007
|
+ context.lineCap = basicStroke.getCap();
|
1008
|
+
|
1009
|
+ context.lineJoin = basicStroke.getJoin();
|
1010
|
+
|
1011
|
+ context.miterLimit = basicStroke.getMiterLimit();
|
1012
|
+ if (basicStroke.getDash())
|
1013
|
+ {
|
1014
|
+ context.setLineDash(basicStroke.getDash());
|
1015
|
+ }
|
1016
|
+ else
|
1017
|
+ {
|
1018
|
+ context.setLineDash([]);
|
1019
|
+ }
|
1020
|
+ context.lineDashOffset = basicStroke.getDashPhase();
|
1021
|
+ }
|
1022
|
+ }
|
1023
|
+
|
1024
|
+ /**
|
1025
|
+ * Apply the given stroke style to the area outer bounds.
|
1026
|
+ *
|
1027
|
+ * @param {CanvasRenderingContext2D} context
|
1028
|
+ * The canvas renderer.
|
1029
|
+ * @param {Number} strokeStyle
|
1030
|
+ * The stroke style id.
|
1031
|
+ * @param {Number} width
|
1032
|
+ * The line width.
|
1033
|
+ * @param {Number[]} strokeColor
|
1034
|
+ * The array of 3 integer values between 0 and 255 inclusive, representing
|
1035
|
+ * a stroke color.
|
1036
|
+ * @param {Array} path
|
1037
|
+ * The array of points that forms the outline of the target area.
|
1038
|
+ */
|
1039
|
+ this.applyStrokeToPath = function(context, strokeStyle, width, strokeColor, path)
|
1040
|
+ {
|
1041
|
+ if (context instanceof CanvasRenderingContext2D)
|
1042
|
+ {
|
1043
|
+ var renderer = getStrokePathRenderer(context, strokeStyle, width, strokeColor);
|
1044
|
+ renderer.applyStroke(path);
|
1045
|
+ }
|
1046
|
+ }
|
1047
|
+
|
1048
|
+
|
1049
|
+ this.isDirectDrawingStrokeStyle = function(strokeStyle)
|
1050
|
+ {
|
1051
|
+ return LineStrokeEnum.DEFAULT == strokeStyle;
|
1052
|
+ }
|
1053
|
+
|
1054
|
+ this.getDefaultStrokeStyle = function()
|
1055
|
+ {
|
1056
|
+ return LineStrokeEnum.DEFAULT;
|
1057
|
+ }
|
1058
|
+
|
1059
|
+ /**
|
1060
|
+ * Used to draw dash patterns on lines of pixels.
|
1061
|
+ *
|
1062
|
+ * @param {CanvasRenderingContext2D} context
|
1063
|
+ * The canvas renderer.
|
1064
|
+ * @param {Object} basicStroke
|
1065
|
+ * The stroke style object.
|
1066
|
+ * @param {Number[]} strokeColor
|
1067
|
+ * The array of 3 integer values between 0 and 255 inclusive, representing
|
1068
|
+ * a stroke color.
|
1069
|
+ */
|
1070
|
+ function DotsPathRenderer(ctx, basicStroke, strokeColor)
|
1071
|
+ {
|
1072
|
+ var pixel = ctx.createImageData(1, 1);
|
1073
|
+ var pixelData = pixel.data;
|
1074
|
+ pixelData[3] = 0xFF;
|
1075
|
+
|
1076
|
+ /**
|
1077
|
+ * Normalizes a dash offset distance according to the given dash pattern.
|
1078
|
+ * A normalized dash offset distance is a distance that is cut the corresponding segment
|
1079
|
+ * from the dash pattern that is extended periodically in order to cover the target dash
|
1080
|
+ * offset.
|
1081
|
+ *
|
1082
|
+ * @param {Array} dash
|
1083
|
+ * The dash array that specifies the number of units to be drawn followed
|
1084
|
+ * by the number of units to be skipped.
|
1085
|
+ * @param {Number} dashOffset
|
1086
|
+ * The offset distance from the first pattern point to the point which becomes
|
1087
|
+ * a start point of the dash pattern.
|
1088
|
+ *
|
1089
|
+ * @return The container {startPhase : phase, startDashOn : dashOn, startIdx : idx},
|
1090
|
+ * where the startPhase field holds a normalized dash offset, startDashOn defines
|
1091
|
+ * to draw or to skip, the value of startIdx is the current dash pattern index.
|
1092
|
+ */
|
1093
|
+ function normalize(dash, dashOffset)
|
1094
|
+ {
|
1095
|
+ var phase = dashOffset;
|
1096
|
+ var idx = 0;
|
1097
|
+ var dashOn = true;
|
1098
|
+ var d;
|
1099
|
+ while (phase >= (d = dash[idx]))
|
1100
|
+ {
|
1101
|
+ phase -= d;
|
1102
|
+ idx = (idx + 1) % dash.length;
|
1103
|
+ dashOn = !dashOn;
|
1104
|
+ }
|
1105
|
+
|
1106
|
+ return {startPhase : phase, startDashOn : dashOn, startIdx : idx};
|
1107
|
+ }
|
1108
|
+
|
1109
|
+ /**
|
1110
|
+ * Apply the given stroke to the line of pixels called a path.
|
1111
|
+ *
|
1112
|
+ * @param {Array} path
|
1113
|
+ * The array of points that forms the outline of the target area.
|
1114
|
+ */
|
1115
|
+ this.applyStroke = function (path)
|
1116
|
+ {
|
1117
|
+ var dash = basicStroke.getDash();
|
1118
|
+ if (!dash || dash.length == 0)
|
1119
|
+ {
|
1120
|
+ return;
|
1121
|
+ }
|
1122
|
+ var dashOffset = basicStroke.getDashPhase();
|
1123
|
+ var len = dash.length;
|
1124
|
+
|
1125
|
+ var patternObj = normalize(dash, dashOffset);
|
1126
|
+
|
1127
|
+ var dashOn = patternObj.startDashOn;
|
1128
|
+ var phase = patternObj.startPhase;
|
1129
|
+ var idx = patternObj.startIdx;
|
1130
|
+ var rest = dash[idx] - phase;
|
1131
|
+ for (var i = 0; i < path.length; i++)
|
1132
|
+ {
|
1133
|
+ var point = path[i];
|
1134
|
+ if (rest < 1)
|
1135
|
+ {
|
1136
|
+ idx = (idx + 1) % len;
|
1137
|
+ rest = dash[idx];
|
1138
|
+ dashOn = !dashOn;
|
1139
|
+ }
|
1140
|
+ rest -= 1;
|
1141
|
+
|
1142
|
+ if (dashOn)
|
1143
|
+ {
|
1144
|
+ pixelData[0] = strokeColor[0];
|
1145
|
+ pixelData[1] = strokeColor[1];
|
1146
|
+ pixelData[2] = strokeColor[2];
|
1147
|
+ ctx.putImageData(pixel, point.x, point.y);
|
1148
|
+ }
|
1149
|
+ }
|
1150
|
+
|
1151
|
+ }
|
1152
|
+ }
|
1153
|
+
|
1154
|
+ /**
|
1155
|
+ * Used to widen lines of pixels.
|
1156
|
+ *
|
1157
|
+ * @param {CanvasRenderingContext2D} context
|
1158
|
+ * The canvas renderer.
|
1159
|
+ * @param {Object} basicStroke
|
1160
|
+ * The stroke style object.
|
1161
|
+ * @param {Number[]} strokeColor
|
1162
|
+ * The array of 3 integer values between 0 and 255 inclusive, representing
|
1163
|
+ * a stroke color.
|
1164
|
+ */
|
1165
|
+ function WidenPathRenderer(ctx, basicStroke, strokeColor)
|
1166
|
+ {
|
1167
|
+ var width = basicStroke.getWidth();
|
1168
|
+ var image = ctx.createImageData(width, width);
|
1169
|
+ var imageData = image.data;
|
1170
|
+
|
1171
|
+ for (var i = 0; i < 4 * width * width; i += 4)
|
1172
|
+ {
|
1173
|
+ imageData[i] = strokeColor[0];
|
1174
|
+ imageData[i + 1] = strokeColor[1];
|
1175
|
+ imageData[i + 2] = strokeColor[2];
|
1176
|
+ imageData[i + 3] = 0xFF;
|
1177
|
+ }
|
1178
|
+
|
1179
|
+ /**
|
1180
|
+ * To widen the line of pixels called a path according to the stroke style.
|
1181
|
+ *
|
1182
|
+ * @param {Array} path
|
1183
|
+ * The array of points that forms the outline of the target area.
|
1184
|
+ */
|
1185
|
+ this.applyStroke = function (path)
|
1186
|
+ {
|
1187
|
+ for (var i = 0; i < path.length; i++)
|
1188
|
+ {
|
1189
|
+ var point = path[i];
|
1190
|
+ ctx.putImageData(image, point.x - (width >> 1), point.y - (width >> 1));
|
1191
|
+ }
|
1192
|
+ }
|
1193
|
+ }
|
1194
|
+}
|
1195
|
\ No newline at end of file
|
1196
|
|