=== added file 'src/com/goldencode/p2j/ui/client/chui/driver/web/res/p2j.mouse.js'
--- src/com/goldencode/p2j/ui/client/chui/driver/web/res/p2j.mouse.js 1970-01-01 00:00:00 +0000
+++ src/com/goldencode/p2j/ui/client/chui/driver/web/res/p2j.mouse.js 2016-06-06 06:02:53 +0000
@@ -0,0 +1,15 @@
+/*
+** Module : p2j.mouse.js
+** Abstract : CHUI mouse support module
+**
+** Copyright (c) 2016, Golden Code Development Corporation.
+** ALL RIGHTS RESERVED. Use is subject to license terms.
+**
+** Golden Code Development Corporation
+** CONFIDENTIAL
+**
+** -#- -I- --Date-- ------------------------------Description----------------------------------
+** 001 SBI 20160605 The first version defines the empty sub module.
+*/
+
+"use strict";
=== modified file 'src/com/goldencode/p2j/ui/client/chui/driver/web/res/p2j.screen.js'
--- src/com/goldencode/p2j/ui/client/chui/driver/web/res/p2j.screen.js 2015-08-11 12:06:47 +0000
+++ src/com/goldencode/p2j/ui/client/chui/driver/web/res/p2j.screen.js 2016-06-08 00:09:05 +0000
@@ -22,6 +22,7 @@
** 009 SBI 20150731 Applied "use strict" directive, fixed undeclared variables,
** added end-lines on copy.
** 010 GES 20150716 Dynamically create the canvas that is the "default window".
+** 011 SBI 20160607 Fixed the font height detection.
*/
"use strict";
@@ -401,15 +402,35 @@
font = cfg.font.size + 'px ' + cfg.font.name;
bold = 'bold ' + font;
-
+ console.debug("Font name: " + font);
ctx.font = font;
dx = ctx.measureText('\u2500').width;
+ // closest integer
+ dx = (dx + 0.5) | 0;
+
dy = fontMetrics.cellHeight(font);
- canvas.width = cols * dx;
+ console.debug("dx: " + dx + " dy:" + dy);
+
+ var vertical = fontMetrics.calculatePureTextHeight(font, '\u2502');
+ var offset = 0;
+ if (dy > vertical)
+ {
+ offset = dy - vertical;
+ }
+ // to cover dy with vertical lines it is required to draw two '\u2502' chars
+ me.verticalOffset = offset;
+
+ console.debug("verticalOffset=" + me.verticalOffset);
+
+ canvas.width = cols * dx;
canvas.height = rows * dy;
+// console.debug("cols: " + cols + " rows:" + rows);
+//
+// console.debug("width: " + canvas.width + " height: " + canvas.height);
+
ctx.fillStyle = cfg.font.color.b;
ctx.fillRect(0, 0, canvas.width, canvas.height);
@@ -433,13 +454,14 @@
}
// export some values
- me.canvasWidth = canvas.width;
+ me.canvasWidth = canvas.width;
me.canvasHeight = canvas.height;
- me.charWidth = dx;
+ me.charWidth = dx;
me.charHeight = dy;
// container center aligned
- document.getElementById(cfg.container).style.width = me.canvasWidth + 'px';
+ document.getElementById(cfg.container).style.width = me.canvasWidth + 'px';
+ //document.getElementById(cfg.container).style.height = me.canvasHeight + 'px';
canvas.focus();
};
@@ -619,12 +641,19 @@
ctx.save();
ctx.beginPath();
- ctx.rect(x, y, dx, dy);
+ ctx.rect(x, y - me.verticalOffset, dx, dy + me.verticalOffset);
ctx.clip();
-
- ctx.fillText(text, x, y, dx);
+ // TODO to separate border drawings
+ // to fix vertical border drawings
+ if (me.verticalOffset > 0 && text.indexOf('\u2502') >= 0)
+ {
+ ctx.fillText('\u2502', x, y - me.verticalOffset);
+ ctx.fillText('\u2502', x, y + me.verticalOffset);
+ //console.debug(text + " x=" + x + " y=" + y + " f=" + ctx.font + " dx=" + dx + " dy=" + dy);
+ }
+ ctx.fillText(text, x, y, dx);
- ctx.restore();
+ ctx.restore();
};
/**
@@ -643,10 +672,13 @@
var width = 128;
/** Canvas use to measure metrics. */
- var fontCanvas;
+ var fontCanvas = document.createElement('canvas');
+ fontCanvas.height = height;
+ fontCanvas.width = width;
+
/** 2D graphical context. */
- var fontCtx;
+ var fontCtx = fontCanvas.getContext('2d');
/**
* Get font height.
@@ -657,66 +689,171 @@
*/
me.cellHeight = function(font)
{
- fontCanvas = document.createElement('canvas');
- fontCanvas.setAttribute('height', height);
- fontCanvas.setAttribute('width', width);
- fontCtx = fontCanvas.getContext('2d');
- fontCtx.fillStyle = 'black';
- fontCtx.fillRect(0, 0, width, height);
+ // character height
+ me.charHeight = calculatePureTextHeight(font, '\u2503Eghy');
+
+ return me.charHeight;
+ };
+
+ /**
+ * Calculates the pure text height for the given font without antialiasing.
+ *
+ * @param {String}
+ * The string font representation
+ * @param {String}
+ * The text to measure its height.
+ *
+ * @return The height in pixels that is occupied by the given text for the provided font
+ * without antialiasing.
+ */
+ function calculatePureTextHeight(font, text)
+ {
+ fontCtx.clearRect(0, 0, width, height);
fontCtx.textBaseline = 'top';
fontCtx.fillStyle = 'white';
fontCtx.font = font;
- fontCtx.fillText('\u2503Eghy', 0, 0);
-
- var pixels = fontCtx.getImageData(0, 0, width, height).data;
-
- // row numbers where we first find letter end where it ends
+ fontCtx.fillText(text, 0, 0);
+
+ var image = fontCtx.getImageData(0, 0, width, height);
+ var d = calculatePixelsDistribution(image);
+ //console.debug(d);
+ var s = calculateMeanAndVariance(d, 0, height, 0);
+ //console.debug(s);
+ return findValuableDomain(d, 0, height, s[0], s[1], 0);
+ };
+
+ /**
+ * Calculate pixels horizontal distribution for the given image
+ *
+ * @param {ImageData} img
+ * The provided image to test.
+ * @return The array built from the average of sqrt(R*R + G*G + B*B) along horizontals.
+ */
+ function calculatePixelsDistribution(img)
+ {
+ var awidth = img.width;
+ var aheight = img.height;
+ var data = img.data;
+ var x = 0;
+ var y = 0;
+ var w = 0;
+ var distribution = [];
+ var count = 0;
+ var pixelsInBytes = awidth * aheight * 4;
+ for (var p = 0; p < pixelsInBytes;)
+ {
+ if (distribution[y] === undefined)
+ {
+ distribution[y] = 0;
+ }
+ w = Math.sqrt(data[p] * data[p] + data[p + 1] * data[p + 1] + data[p + 2] * data[p + 2] /*+ data[p + 3] * data[p + 3]*/);
+ if (w > 0)
+ {
+ // console.debug(p + ":" + data[p] + ":" + data[p + 1] + ":" + data[p + 2])
+ count++;
+ distribution[y] += w;
+ }
+ x++;
+ if (x === width)
+ {
+ distribution[y] = distribution[y] / (count > 0 ? count : 1);
+// distribution[y] = (distribution[y] / count + 0.5) | 0;
+ y++;
+ x = 0;
+ count = 0;
+ }
+ p += 4;
+ };
+ return distribution;
+ }
+
+ /**
+ * Calculate the mean and the variance for the target distribution along the provided
+ * segment and the given threshold.
+ *
+ * @param {Array} d
+ * The target distribution.
+ * @param {Integer} i1
+ * The point that defines the distribution domain.
+ * @param {Integer} i2
+ * The point that defines the distribution domain.
+ * @param {Number} threshold
+ * Defines the low bound for the distribution values.
+ *
+ * @return The 2-elements array filled with the mean and the variance.
+ */
+ function calculateMeanAndVariance(d, i1, i2, threshold)
+ {
+ var n = 0;
+ var mean = 0;
+ var M2 = 0;
+ var delta = 0;
+ for (var i = i1; i < i2; i++)
+ {
+ if (d[i] > threshold)
+ {
+ n++;
+ delta = d[i] - mean;
+ mean += delta / n;
+ M2 += delta * (d[i] - mean);
+ }
+ }
+ var v;
+ if (n < 2)
+ {
+ v = undefined;
+ }
+ else
+ {
+ v = M2 / (n - 1);
+ }
+
+ return [mean, v];
+ }
+
+ /**
+ * Defines the valuable domain for this distribution taken into account its mean and
+ * its variance throwing out values that are less or equal than the provided threshold.
+ *
+ * @param {Array} d
+ * The target distribution.
+ * @param {Integer} i1
+ * The point that defines the distribution domain.
+ * @param {Integer} i2
+ * The point that defines the distribution domain.
+ * @param {Number} mean
+ * The mean of the given distribution d.
+ * @param {Number} variance
+ * The variance of the given distribution d.
+ * @param {Number} threshold
+ * Defines the low bound for the distribution values.
+ *
+ * @return The valuable domain width for the target distribution.
+ */
+ function findValuableDomain(d, i1, i2, mean, variance, threshold)
+ {
var beg = -1;
+ for (var i = i1; i < i2; i++)
+ {
+ if (d[i] > threshold && ((d[i] - mean) * (d[i] - mean)) <= 9 * variance)
+ {
+ beg = i;
+ break;
+ }
+ }
var end = -1;
-
- for (var row = 0; row < height; row++)
+ for (var i = i2 - 1; i >= i1; i--)
{
- for (var col = 0; col < width; col++)
+ if (d[i] > threshold && ((d[i] - mean) * (d[i] - mean)) <= 9 * variance)
{
- var index = (row * width + col) * 4;
-
- // if pixel is not white (background color)
- if (pixels[index] === 0)
- {
- // we havent met white (font color) pixel
- // on the row and the letters was detected
- if (col === (width - 1) && beg !== -1)
- {
- end = row;
- row = height;
- break;
- }
- }
- else
- {
- // we find top of letter
- if (beg === -1)
- {
- beg = row;
- }
- // ..letters body
- break;
- }
+ end = i;
+ break;
}
}
-
- // space at top
- me.top = beg;
-
- // character height
- me.charHeight = end - beg;
-
- // cell height top + charHeight
- me.cellHeight = end;
-
- // cell height
- return p2j.isWindows ? end : end - 1;
- };
+ return end - beg + 1;
+ }
+
+ me.calculatePureTextHeight = calculatePureTextHeight;
return me;
})();
=== modified file 'src/com/goldencode/p2j/ui/client/driver/web/index.html'
--- src/com/goldencode/p2j/ui/client/driver/web/index.html 2016-06-03 10:10:16 +0000
+++ src/com/goldencode/p2j/ui/client/driver/web/index.html 2016-06-06 08:10:15 +0000
@@ -131,6 +131,6 @@
-
+