Skip to content

Commit 528d4cc

Browse files
author
Dmitriy Kubyshkin
committed
Added simple font metrics class.
1 parent 67e04cf commit 528d4cc

File tree

6 files changed

+120
-4
lines changed

6 files changed

+120
-4
lines changed

demo/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<script type="text/javascript" src="http://localhost:4000/lib.js"></script>
1010
<script type="text/javascript" charset="utf-8">
1111
document.addEventListener('DOMContentLoaded', function(){
12-
var CanvasTextEditor = require('editor');
12+
var CanvasTextEditor = require('CanvasTextEditor');
1313
var editor = new CanvasTextEditor;
1414
document.body.appendChild(editor.getEl());
1515
}, false);

lib/editor.js renamed to lib/CanvasTextEditor.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
"use strict";
2+
3+
var FontMetrics = require('FontMetrics');
4+
15
/**
26
* Simple plain-text text editor using html5 canvas.
37
* @constructor
48
*/
59
var CanvasTextEditor = function() {
10+
this._metrics = new FontMetrics('"Courier New", Courier, monospace', 14);
611
this._createWrapper();
712
this._createCanvas();
813
this._createInput();
@@ -36,13 +41,15 @@ CanvasTextEditor.prototype._createWrapper = function() {
3641
*/
3742
CanvasTextEditor.prototype._createCanvas = function() {
3843
this.canvas = document.createElement('canvas');
39-
this.wrapper.appendChild(this.canvas);
4044
this.canvas.style.display = 'block';
4145
this.context = this.canvas.getContext('2d');
4246
this.resize(640, 480);
4347

4448
// Placeholder function just to see that it's working
45-
this.context.fillText('Test', 0, 10);
49+
this.context.font = this._metrics.getSize() + 'px ' + this._metrics.getFamily()
50+
this.context.fillText('Test', 0, this._metrics.getBaseline());
51+
52+
this.wrapper.appendChild(this.canvas);
4653
};
4754

4855
/**

lib/FontMetrics.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"use strict";
2+
3+
/**
4+
* A simple wrapper for system fonts to provide
5+
* @param {String} family Font Family (same as in CSS)
6+
* @param {Number} size Size in px
7+
* @constructor
8+
*/
9+
var FontMetrics = function(family, size) {
10+
this._family = family || (family = "Monaco, 'Courier New', Courier, monospace");
11+
this._size = parseInt(size) || (size = 12);
12+
13+
// Preparing container
14+
var line = document.createElement('div'),
15+
body = document.body;
16+
line.style.position = 'absolute';
17+
line.style.whiteSpace = 'nowrap';
18+
line.style.font = size + 'px ' + family;
19+
body.appendChild(line);
20+
21+
// Now we can measure width and height of the letter
22+
line.innerHTML = 'm'; // It doesn't matter what text goes here
23+
this._width = line.offsetHeight;
24+
this._height = line.offsetHeight;
25+
26+
// Now creating 1px sized item that will be aligned to baseline
27+
// to calculate baseline shift
28+
var span = document.createElement('span');
29+
span.style.display = 'inline-block';
30+
span.style.overflow = 'hidden';
31+
span.style.width = '1px';
32+
span.style.height = '1px';
33+
line.appendChild(span);
34+
35+
// Baseline is important for positioning text on canvas
36+
this._baseline = span.offsetTop + span.offsetHeight;
37+
38+
document.body.removeChild(line);
39+
};
40+
41+
module.exports = FontMetrics;
42+
43+
/**
44+
* Returns font family
45+
* @return {String}
46+
*/
47+
FontMetrics.prototype.getFamily = function() {
48+
return this._family;
49+
};
50+
51+
/**
52+
* Returns font family
53+
* @return {Number}
54+
*/
55+
FontMetrics.prototype.getSize = function() {
56+
return this._size;
57+
};
58+
59+
/**
60+
* Returns line height in px
61+
* @return {Number}
62+
*/
63+
FontMetrics.prototype.getHeight = function() {
64+
return this._height;
65+
};
66+
67+
/**
68+
* Returns line height in px
69+
* @return {Number}
70+
*/
71+
FontMetrics.prototype.getWidth = function() {
72+
return this._width;
73+
};
74+
75+
/**
76+
* Returns line height in px
77+
* @return {Number}
78+
*/
79+
FontMetrics.prototype.getBaseline = function() {
80+
return this._baseline;
81+
};

test/runner.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
<!-- include spec files here... -->
1717
<script type="text/javascript" src="spec/EditorSpec.js"></script>
18+
<script type="text/javascript" src="spec/FontMetricsSpec.js"></script>
1819

1920
<script type="text/javascript">
2021
(function() {

test/spec/EditorSpec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
describe("CanvasTextEditor", function() {
2-
var CanvasTextEditor = require('editor');
2+
var CanvasTextEditor = require('CanvasTextEditor');
33

44
it("should be possible to instatiate", function() {
55
var editor = new CanvasTextEditor;

test/spec/FontMetricsSpec.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
describe("CanvasTextEditor", function() {
2+
var FontMetrics = require('FontMetrics');
3+
4+
it("should support getters for family and size", function() {
5+
var family = 'Arial, sans-serif',
6+
size = 18,
7+
metrics = new FontMetrics(family, size);
8+
9+
expect(metrics.getFamily()).toEqual(family);
10+
expect(metrics.getSize()).toEqual(size);
11+
12+
metrics = new FontMetrics;
13+
14+
expect(metrics.getFamily()).toBeTruthy();
15+
expect(metrics.getSize()).toBeTruthy();
16+
});
17+
18+
it("should calculate font metrics", function(){
19+
20+
var metrics = new FontMetrics;
21+
22+
expect(metrics.getHeight()).toBeTruthy();
23+
expect(metrics.getWidth()).toBeTruthy();
24+
expect(metrics.getBaseline()).toBeTruthy();
25+
26+
});
27+
});

0 commit comments

Comments
 (0)