Skip to content

Commit 46814aa

Browse files
author
Lauren McCarthy
committed
Merge pull request #368 from scottgarner/master
Removed textHeight() and add textAscent() and textDescent() per #356.
2 parents 975d150 + 931dbaf commit 46814aa

File tree

1 file changed

+114
-22
lines changed

1 file changed

+114
-22
lines changed

src/typography/attributes.js

Lines changed: 114 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ define(function (require) {
1616
p5.prototype._textFont = 'sans-serif';
1717
p5.prototype._textSize = 12;
1818
p5.prototype._textStyle = constants.NORMAL;
19+
p5.prototype._textAscent = null;
20+
p5.prototype._textDescent = null;
1921

2022
/**
2123
* Sets the current alignment for drawing text. The parameters LEFT, CENTER,
@@ -46,27 +48,6 @@ define(function (require) {
4648
}
4749
};
4850

49-
/**
50-
* Calculates and returns the height of any character or text string.
51-
*
52-
* @method textHeight
53-
* @param {String} s the String of characters to measure
54-
* @example
55-
* <div>
56-
* <code>
57-
* background(0);
58-
* fill(255);
59-
* textSize(14);
60-
* s = "String.";
61-
* text(s, 10, 23);
62-
* console.log(textHeight(s));
63-
* </code>
64-
* </div>
65-
*/
66-
p5.prototype.textHeight = function(s) {
67-
return this.drawingContext.measureText(s).height;
68-
};
69-
7051
/**
7152
* Sets the spacing between lines of text in units of pixels. This
7253
* setting will be used in all subsequent calls to the text() function.
@@ -173,15 +154,126 @@ define(function (require) {
173154
return this.drawingContext.measureText(s).width;
174155
};
175156

157+
/**
158+
* Returns ascent of the current font at its current size.
159+
* @example
160+
* <div>
161+
* <code>
162+
* var base = height * 0.75;
163+
* var scalar = 0.8; // Different for each font
164+
*
165+
* textSize(32); // Set initial text size
166+
* var a = textAscent() * scalar; // Calc ascent
167+
* line(0, base-a, width, base-a);
168+
* text("dp", 0, base); // Draw text on baseline
169+
*
170+
* textSize(64); // Increase text size
171+
* a = textAscent() * scalar; // Recalc ascent
172+
* line(40, base-a, width, base-a);
173+
* text("dp", 40, base); // Draw text on baseline
174+
* </code>
175+
* </div>
176+
*/
177+
p5.prototype.textAscent = function() {
178+
if (this._textAscent == null) { this._updateTextMetrics(); }
179+
return this._textAscent;
180+
};
181+
182+
/**
183+
* Returns descent of the current font at its current size.
184+
* @example
185+
* <div>
186+
* <code>
187+
* var base = height * 0.75;
188+
* var scalar = 0.8; // Different for each font
189+
*
190+
* textSize(32); // Set initial text size
191+
* var a = textDescent() * scalar; // Calc ascent
192+
* line(0, base+a, width, base+a);
193+
* text("dp", 0, base); // Draw text on baseline
194+
*
195+
* textSize(64); // Increase text size
196+
* a = textDescent() * scalar; // Recalc ascent
197+
* line(40, base+a, width, base+a);
198+
* text("dp", 40, base); // Draw text on baseline
199+
* </code>
200+
* </div>
201+
*/
202+
p5.prototype.textDescent = function() {
203+
if (this._textDescent == null) { this._updateTextMetrics(); }
204+
return this._textDescent;
205+
};
206+
176207
/**
177208
* Helper fxn to apply text properties.
178-
*
179209
*/
180210
p5.prototype._applyTextProperties = function () {
211+
this._setProperty('_textAscent', null);
212+
this._setProperty('_textDescent', null);
213+
181214
var str = this._textStyle + ' ' + this._textSize + 'px ' + this._textFont;
182215
this.drawingContext.font = str;
183216
};
184217

218+
/**
219+
* Helper fxn to measure ascent and descent.
220+
* Adapted from http://stackoverflow.com/a/25355178
221+
*/
222+
p5.prototype._updateTextMetrics = function () {
223+
224+
var text = document.createElement('span');
225+
text.style.fontFamily = this._textFont;
226+
text.style.fontSize = this._textSize + 'px';
227+
text.innerHTML = 'ABCjgq|';
228+
229+
var block = document.createElement('div');
230+
block.style.display = 'inline-block';
231+
block.style.width = '1px';
232+
block.style.height = '0px';
233+
234+
var container = document.createElement('div');
235+
container.appendChild(text);
236+
container.appendChild(block);
237+
238+
container.style.height = '0px';
239+
container.style.overflow = 'hidden';
240+
document.body.appendChild(container);
241+
242+
block.style.verticalAlign = 'baseline';
243+
var blockOffset = this._calculateOffset(block);
244+
var textOffset = this._calculateOffset(text);
245+
var ascent = blockOffset[1] - textOffset[1];
246+
247+
block.style.verticalAlign = 'bottom';
248+
blockOffset = this._calculateOffset(block);
249+
textOffset = this._calculateOffset(text);
250+
var height = blockOffset[1] - textOffset[1];
251+
var descent = height - ascent;
252+
253+
document.body.removeChild(container);
254+
255+
this._setProperty('_textAscent', ascent);
256+
this._setProperty('_textDescent', descent);
257+
};
258+
259+
/**
260+
* Helper fxn to measure ascent and descent.
261+
* Adapted from http://stackoverflow.com/a/25355178
262+
*/
263+
p5.prototype._calculateOffset = function (object) {
264+
var currentLeft = 0, currentTop = 0;
265+
if( object.offsetParent ) {
266+
do {
267+
currentLeft += object.offsetLeft;
268+
currentTop += object.offsetTop;
269+
} while( object = object.offsetParent );
270+
} else {
271+
currentLeft += object.offsetLeft;
272+
currentTop += object.offsetTop;
273+
}
274+
return [currentLeft,currentTop];
275+
};
276+
185277
return p5;
186278

187279
});

0 commit comments

Comments
 (0)