=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/EmulatedWindowState.java'
--- src/com/goldencode/p2j/ui/client/gui/driver/EmulatedWindowState.java 2015-09-07 21:26:31 +0000
+++ src/com/goldencode/p2j/ui/client/gui/driver/EmulatedWindowState.java 2015-09-08 10:10:09 +0000
@@ -452,12 +452,22 @@
extra = String.format(" x = %d; y = %d", ps.x, ps.y);
break;
case DRAW_STRING:
- extra = String.format(" text = %s; x = %d; y = %d, centered = %b",
+ extra = String.format(" text = %s; x = %d; y = %d; centered = %b",
ps.text,
ps.x,
ps.y,
ps.centered);
break;
+ case DRAW_STRING_SCALED:
+ extra = String.format(
+ " text = %s; x = %d; y = %d; centered = %b; lwidth = %d; lheight = %d",
+ ps.text,
+ ps.x,
+ ps.y,
+ ps.centered,
+ ps.width,
+ ps.height);
+ break;
case SET_TITLE:
extra = String.format(" title = %s", ps.title);
break;
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js'
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js 2015-09-06 23:47:37 +0000
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.canvas_renderer.js 2015-09-08 09:58:48 +0000
@@ -23,15 +23,18 @@
* The canvas 2D graphics context on which to draw.
* @param {LinesStroke} strokesManager
* The stroke manager
+ * @param {Object} fontsManager
+ * The p2j fonts manager.
* @param {Object} logger
* The p2j logger.
*/
-function CanvasRenderer(canvas, ctx, strokesManager, logger)
+function CanvasRenderer(canvas, ctx, strokesManager, fontsManager, logger)
{
this.canvas = canvas;
this.ctx = ctx;
this.strokesManager = strokesManager;
this.logger = logger;
+ this.fontsManager = fontsManager;
/** Color scaling factor, compatible with Java2D. */
var SCALE_FACTOR = 0.7;
@@ -233,6 +236,35 @@
}
/**
+ * Fill or stroke the current path on the given context, first using the current path as a
+ * clipping region. This ensures that the drawing of the path will not extend outside of the
+ * path by a half-pixel (which it would otherwise). The state of the context is saved on
+ * entry and restored after the drawing operation, so there will be no residual clipping
+ * region when this function returns.
+ *
+ * @param {CanvasRenderingContext2D} ctx
+ * The canvas 2D graphics context on which to draw.
+ * @param {Boolean} fill
+ * true
to fill the drawn rectangle with the given color.
+ */
+CanvasRenderer.prototype.renderClosedPath = function(ctx, fill)
+{
+ ctx.save();
+ ctx.clip();
+
+ if (fill)
+ {
+ ctx.fill();
+ }
+ else
+ {
+ ctx.stroke();
+ }
+
+ ctx.restore();
+};
+
+/**
* Adjust the origin for pixel drawing on the canvas.
*
* @param {Number} x
@@ -421,35 +453,6 @@
}
/**
- * Fill or stroke the current path on the given context, first using the current path as a
- * clipping region. This ensures that the drawing of the path will not extend outside of the
- * path by a half-pixel (which it would otherwise). The state of the context is saved on
- * entry and restored after the drawing operation, so there will be no residual clipping
- * region when this function returns.
- *
- * @param {CanvasRenderingContext2D} ctx
- * The canvas 2D graphics context on which to draw.
- * @param {Boolean} fill
- * true
to fill the drawn rectangle with the given color.
- */
-function renderClosedPath(ctx, fill)
-{
- ctx.save();
- ctx.clip();
-
- if (fill)
- {
- ctx.fill();
- }
- else
- {
- ctx.stroke();
- }
-
- ctx.restore();
-};
-
-/**
* Draw a rectangle in the given color and dimensions with the line drawing being overwritten
* using direct drawing to eliminate the negative/unwanted effects of alni-aliasing.
*
@@ -483,7 +486,7 @@
inset = 1;
ctx.beginPath();
ctx.rect(x, y, width - inset, height - inset);
- renderClosedPath(ctx, fill);
+ this.renderClosedPath(ctx, fill);
}
// now overdraw the stroked portion to eliminate anti-aliasing, we draw in a
@@ -527,7 +530,7 @@
inset = 1;
ctx.beginPath();
ctx.rect(x, y, width - inset, height - inset);
- renderClosedPath(ctx, fill);
+ this.renderClosedPath(ctx, fill);
}
// now overdraw the stroked portion to eliminate anti-aliasing, we draw in a
@@ -662,7 +665,7 @@
ctx.quadraticCurveTo(northWestX, northWestY, topLeftX, topLeftY);
ctx.closePath();
- renderClosedPath(ctx, fill);
+ this.renderClosedPath(ctx, fill);
// overdraw the anti-aliased line segments
var path = [];
@@ -738,7 +741,7 @@
ctx.fillStyle = this.createColorString(current);
ctx.beginPath();
ctx.rect(x, y, width - 2, height - 2);
- renderClosedPath(ctx, fill);
+ this.renderClosedPath(ctx, fill);
}
current = raised ? lighter : darker;
@@ -807,7 +810,7 @@
ctx.lineTo(xPoints[i], yPoints[i]);
}
ctx.closePath();
- renderClosedPath(ctx, fill);
+ this.renderClosedPath(ctx, fill);
}
var path = [];
// now overdraw the stroked portion
@@ -1144,3 +1147,90 @@
this.ctx.translate(x, y);
};
+
+/**
+ * Draws a given text at the given (x,y) position.
+ *
+ * @param {Number} text
+ * The text to draw.
+ * @param {Number} x
+ * The X-axis of the coordinate for the text starting point.
+ * @param {Number} y
+ * The Y-axis of the coordinate for the text starting point or the height
+ * of the text rectangle from the most top screen position.
+ * @param {Boolean} centered
+ * Defines the text base line and the interpretation of y.
+ * If it is true, the text base line is set to 'middle' and interprets y as a height,
+ * otherwise the text base line is set to 'bottom'.
+ */
+CanvasRenderer.prototype.drawText = function(text, x, y, centered)
+{
+ if (centered)
+ {
+ // in this case, the "y" is the height in which it needs to be vertically centered
+ y = y / 2;
+
+ this.ctx.textBaseline = 'middle';
+ }
+ else
+ {
+ this.ctx.textBaseline = 'bottom';
+ }
+
+ this.ctx.fillText(text, x, y);
+}
+
+/**
+ * Draws a given text at the given (x,y) position fitted to the given text rectangle.
+ *
+ * @param {Number} currentFont
+ * The current font ID, in the js font-table.
+ * @param {Number} text
+ * The text to draw.
+ * @param {Number} x
+ * The X-axis of the coordinate for the text starting point.
+ * @param {Number} y
+ * The Y-axis of the coordinate for the text starting point or the height
+ * of the text rectangle from the most top screen position.
+ * @param {Boolean} centered
+ * Defines the text base line and the interpretation of y.
+ * If it is true, the text base line is set to 'middle' and interprets y as a height,
+ * otherwise the text base line is set to 'bottom'.
+ * @param {Number} lwidth
+ * The space width to be used to display the given text.
+ * The text is scaled to fit this width, squeezed or extended
+ * @param {Number} lheight
+ * The space height to be used to display the given text.
+ * The text is scaled to fit this height, squeezed or extended.
+ */
+CanvasRenderer.prototype.drawScaledText = function(currentFont, text, x, y, centered, lwidth, lheight)
+{
+ var textWidth = this.fontsManager.getTextWidth(currentFont, text);
+ var textHeight = this.fontsManager.getTextHeight(currentFont, text);
+
+ var widthScale = lwidth / textWidth;
+ var heightScale = lheight / textHeight;
+
+ // scale drawing context to computed width
+ // this scales the desired structure.x as well so it needs adjusting
+ this.ctx.save();
+ this.ctx.scale(widthScale, heightScale);
+
+ var scaleBackWidth = 1 / widthScale;
+ var scaleBackHeight = 1 / heightScale;
+
+ if (centered)
+ {
+ // in this case, the "y" is the height in which it needs to be vertically centered
+ y = y / 2;
+
+ this.ctx.textBaseline = 'middle';
+ }
+ else
+ {
+ this.ctx.textBaseline = 'bottom';
+ }
+
+ this.ctx.fillText(text, x * scaleBackWidth, y * scaleBackHeight);
+ this.ctx.restore();
+}
\ No newline at end of file
=== modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js'
--- src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-09-07 21:26:31 +0000
+++ src/com/goldencode/p2j/ui/client/gui/driver/web/res/p2j.screen.js 2015-09-08 09:59:32 +0000
@@ -184,7 +184,8 @@
this.iconHeight = 0;
/** Creates canvas renderer. */
- this.canvasRenderer = new CanvasRenderer(this.canvas, this.ctx, strokesManager, p2j.logger);
+ this.canvasRenderer = new CanvasRenderer(this.canvas, this.ctx, strokesManager,
+ p2j.fonts, p2j.logger);
/** List of widgets which are aware of mouse events. */
this.mouseAwareWidgets = new Array();
@@ -556,20 +557,7 @@
y = p2j.socket.readInt32BinaryMessage(message, idx + offset);
offset = offset + 4;
- if (centered)
- {
- // in this case, the "y" is the height in which it needs to be vertically centered
- y = y / 2;
-
- this.ctx.textBaseline = 'middle';
- }
- else
- {
- this.ctx.textBaseline = 'bottom';
- }
-
- this.ctx.fillText(text, x, y);
-
+ this.canvasRenderer.drawText(text, x, y, centered);
extra = " text = " + text + "; x = " + x + "; y = " + y +
"; centered = " + centered;
break;
@@ -597,35 +585,10 @@
var lheight = p2j.socket.readInt32BinaryMessage(message, idx + offset);
offset = offset + 4;
- var textWidth = p2j.fonts.getTextWidth(currentFont, text);
- var textHeight = p2j.fonts.getTextHeight(currentFont, text);
-
- var widthScale = lwidth / textWidth;
- var heightScale = lheight / textHeight;
-
- // scale drawing context to computed width
- // this scales the desired structure.x as well so it needs adjusting
- this.ctx.save();
- this.ctx.scale(widthScale, heightScale);
-
- var scaleBackWidth = 1 / widthScale;
- var scaleBackHeight = 1 / heightScale;
-
- if (centered)
- {
- // in this case, the "y" is the height in which it needs to be vertically centered
- y = y / 2;
-
- this.ctx.textBaseline = 'middle';
- }
- else
- {
- this.ctx.textBaseline = 'bottom';
- }
-
- this.ctx.fillText(text, x * scaleBackWidth, y * scaleBackHeight);
- this.ctx.restore();
-
+ this.canvasRenderer.drawScaledText(currentFont, text, x, y, centered, lwidth, lheight);
+ extra = " text = " + text + "; x = " + x + "; y = " + y +
+ "; centered = " + centered +
+ "; lwidth = " + lwidth + "; lheight = " + lheight;
break;
case ops.DRAW_PARAGRAPH:
offset = 1;