Skip to content

Commit db02625

Browse files
authored
Merge pull request #5787 from processing/fixes5785
fixes for #5785
2 parents eda2e43 + 764edeb commit db02625

File tree

4 files changed

+166
-30
lines changed

4 files changed

+166
-30
lines changed

src/core/p5.Renderer.js

+73-27
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
233233
let chars;
234234
let shiftedY;
235235
let finalMaxHeight = Number.MAX_VALUE;
236+
// fix for #5785 (top of bounding box)
237+
let finalMinHeight = y;
236238

237239
if (!(this._doFill || this._doStroke)) {
238240
return;
@@ -263,29 +265,48 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
263265
break;
264266
}
265267

266-
let baselineHacked = false;
267268
if (typeof maxHeight !== 'undefined') {
268269
if (this._rectMode === constants.CENTER) {
269270
y -= maxHeight / 2;
270271
}
271272

273+
let originalY = y;
274+
let ascent = p.textAscent();
275+
272276
switch (this._textBaseline) {
273277
case constants.BOTTOM:
274278
shiftedY = y + maxHeight;
275279
y = Math.max(shiftedY, y);
280+
// fix for #5785 (top of bounding box)
281+
finalMinHeight += ascent;
276282
break;
277283
case constants.CENTER:
278284
shiftedY = y + maxHeight / 2;
279285
y = Math.max(shiftedY, y);
280-
break;
281-
case constants.BASELINE:
282-
baselineHacked = true;
283-
this._textBaseline = constants.TOP;
286+
// fix for #5785 (top of bounding box)
287+
finalMinHeight += ascent / 2;
284288
break;
285289
}
286290

287291
// remember the max-allowed y-position for any line (fix to #928)
288-
finalMaxHeight = y + maxHeight - p.textAscent();
292+
finalMaxHeight = y + maxHeight - ascent;
293+
294+
// fix for #5785 (bottom of bounding box)
295+
if (this._textBaseline === constants.CENTER) {
296+
finalMaxHeight = originalY + maxHeight - ascent / 2;
297+
}
298+
} else {
299+
// no text-height specified, show warning for BOTTOM / CENTER
300+
if (this._textBaseline === constants.BOTTOM) {
301+
return console.warn(
302+
'textAlign(*, BOTTOM) requires x, y, width and height'
303+
);
304+
}
305+
if (this._textBaseline === constants.CENTER) {
306+
return console.warn(
307+
'textAlign(*, CENTER) requires x, y, width and height'
308+
);
309+
}
289310
}
290311

291312
// Render lines of text according to settings of textWrap
@@ -310,10 +331,9 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
310331
}
311332

312333
let offset = 0;
313-
const vAlign = p.textAlign().vertical;
314-
if (vAlign === constants.CENTER) {
334+
if (this._textBaseline === constants.CENTER) {
315335
offset = (nlines.length - 1) * p.textLeading() / 2;
316-
} else if (vAlign === constants.BOTTOM) {
336+
} else if (this._textBaseline === constants.BOTTOM) {
317337
offset = (nlines.length - 1) * p.textLeading();
318338
}
319339

@@ -324,18 +344,29 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
324344
testLine = `${line + words[wordIndex]}` + ' ';
325345
testWidth = this.textWidth(testLine);
326346
if (testWidth > maxWidth && line.length > 0) {
327-
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
347+
this._renderText(
348+
p,
349+
line.trim(),
350+
x,
351+
y - offset,
352+
finalMaxHeight,
353+
finalMinHeight
354+
);
328355
line = `${words[wordIndex]}` + ' ';
329356
y += p.textLeading();
330357
} else {
331358
line = testLine;
332359
}
333360
}
334-
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
361+
this._renderText(
362+
p,
363+
line.trim(),
364+
x,
365+
y - offset,
366+
finalMaxHeight,
367+
finalMinHeight
368+
);
335369
y += p.textLeading();
336-
if (baselineHacked) {
337-
this._textBaseline = constants.BASELINE;
338-
}
339370
}
340371
} else {
341372
let nlines = [];
@@ -356,10 +387,9 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
356387

357388
nlines.push(line);
358389
let offset = 0;
359-
const vAlign = p.textAlign().vertical;
360-
if (vAlign === constants.CENTER) {
390+
if (this._textBaseline === constants.CENTER) {
361391
offset = (nlines.length - 1) * p.textLeading() / 2;
362-
} else if (vAlign === constants.BOTTOM) {
392+
} else if (this._textBaseline === constants.BOTTOM) {
363393
offset = (nlines.length - 1) * p.textLeading();
364394
}
365395

@@ -374,33 +404,49 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
374404
if (testWidth <= maxWidth) {
375405
line += chars[charIndex];
376406
} else if (testWidth > maxWidth && line.length > 0) {
377-
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
407+
this._renderText(
408+
p,
409+
line.trim(),
410+
x,
411+
y - offset,
412+
finalMaxHeight,
413+
finalMinHeight
414+
);
378415
y += p.textLeading();
379416
line = `${chars[charIndex]}`;
380417
}
381418
}
382419
}
383-
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
420+
this._renderText(
421+
p,
422+
line.trim(),
423+
x,
424+
y - offset,
425+
finalMaxHeight,
426+
finalMinHeight
427+
);
384428
y += p.textLeading();
385-
386-
if (baselineHacked) {
387-
this._textBaseline = constants.BASELINE;
388-
}
389429
}
390430
} else {
391431
// Offset to account for vertically centering multiple lines of text - no
392432
// need to adjust anything for vertical align top or baseline
393433
let offset = 0;
394-
const vAlign = p.textAlign().vertical;
395-
if (vAlign === constants.CENTER) {
434+
if (this._textBaseline === constants.CENTER) {
396435
offset = (lines.length - 1) * p.textLeading() / 2;
397-
} else if (vAlign === constants.BOTTOM) {
436+
} else if (this._textBaseline === constants.BOTTOM) {
398437
offset = (lines.length - 1) * p.textLeading();
399438
}
400439

401440
// Renders lines of text at any line breaks present in the original string
402441
for (let i = 0; i < lines.length; i++) {
403-
this._renderText(p, lines[i], x, y - offset, finalMaxHeight);
442+
this._renderText(
443+
p,
444+
lines[i],
445+
x,
446+
y - offset,
447+
finalMaxHeight,
448+
finalMinHeight
449+
);
404450
y += p.textLeading();
405451
}
406452
}

src/core/p5.Renderer2D.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1190,9 +1190,9 @@ p5.Renderer2D.prototype.text = function(str, x, y, maxWidth, maxHeight) {
11901190
return p;
11911191
};
11921192

1193-
p5.Renderer2D.prototype._renderText = function(p, line, x, y, maxY) {
1194-
if (y >= maxY) {
1195-
return; // don't render lines beyond our maxY position
1193+
p5.Renderer2D.prototype._renderText = function(p, line, x, y, maxY, minY) {
1194+
if (y < minY || y >= maxY) {
1195+
return; // don't render lines beyond our minY/maxY bounds (see #5785)
11961196
}
11971197

11981198
p.push(); // fix to #803
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html>
2+
<head>
3+
<meta charset="UTF-8">
4+
<script language="javascript" type="text/javascript" src="../../../../lib/p5.js"></script>
5+
6+
<script language="javascript" type="text/javascript" src="sketch.js"></script>
7+
8+
</head>
9+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
let xpos = 50;
2+
let ypos = 100;
3+
let str =
4+
'One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Thirteen Fourteen Fifteen Sixteen Seventeen Eighteen Nineteen Twenty Twenty-one Twenty-two Twenty-three Twenty-four Twenty-five Twenty-six Twenty-seven Twenty-eight Twenty-nine Thirty Thirty-one Thirty-two Thirty-three Thirty-four Thirty-five Thirty-six Thirty-seven Thirty-eight Thirty-nine Forty Forty-one Forty-two Forty-three Forty-four Forty-five Forty-six Forty-seven Forty-eight Forty-nine Fifty Fifty-one Fifty-two Fifty-three';
5+
6+
function setup() {
7+
createCanvas(1050, 800);
8+
background(245);
9+
10+
let ta = textAscent();
11+
12+
textAlign(CENTER, TOP);
13+
rect(xpos, ypos, 200, 200);
14+
text(str, xpos, ypos, 200, 200);
15+
xpos += 250;
16+
17+
textAlign(CENTER, CENTER);
18+
rect(xpos, ypos, 200, 200);
19+
text(str, xpos, ypos, 200, 200);
20+
xpos += 250;
21+
22+
textAlign(CENTER, BOTTOM);
23+
rect(xpos, ypos, 200, 200);
24+
text(str, xpos, ypos, 200, 200);
25+
xpos += 250;
26+
27+
textAlign(CENTER, BASELINE);
28+
rect(xpos, ypos, 200, 200);
29+
text(str, xpos, ypos, 200, 200);
30+
31+
textSize(18);
32+
textAlign(CENTER, TOP);
33+
text('TOP', 150, height / 2 - 40);
34+
text('CENTER', 400, height / 2 - 40);
35+
text('BOTTOM', 650, height / 2 - 40);
36+
text('BASELINE', 900, height / 2 - 40);
37+
textSize(12);
38+
39+
xpos = 50;
40+
ypos += 400;
41+
42+
textAlign(CENTER, TOP);
43+
rect(xpos, ypos, 200, 200);
44+
text(str, xpos, ypos, 200);
45+
xpos += 250;
46+
47+
textAlign(CENTER, CENTER);
48+
rect(xpos, ypos, 200, 200);
49+
text(str, xpos, ypos, 200);
50+
xpos += 250;
51+
52+
textAlign(CENTER, BOTTOM);
53+
rect(xpos, ypos, 200, 200);
54+
text(str, xpos, ypos, 200);
55+
xpos += 250;
56+
57+
textAlign(CENTER, BASELINE);
58+
rect(xpos, ypos, 200, 200);
59+
text(str, xpos, ypos, 200);
60+
61+
textSize(18);
62+
textAlign(CENTER, TOP);
63+
text('TOP', 150, height / 2 - 40);
64+
text('CENTER', 400, height / 2 - 40);
65+
text('BOTTOM', 650, height / 2 - 40);
66+
text('BASELINE', 900, height / 2 - 40);
67+
text('TOP', 150, ypos + 270);
68+
text('CENTER', 400, ypos + 270);
69+
text('BOTTOM', 650, ypos + 270);
70+
text('BASELINE', 900, ypos + 270);
71+
72+
fill(255);
73+
noStroke();
74+
textSize(24);
75+
76+
rect(0, height / 2, width, 15);
77+
fill(0);
78+
textAlign(LEFT, TOP);
79+
text('text(s, x, y, w, h)', 20, 40);
80+
text('text(s, x, y, w) [no height]', 20, height / 2 + 40);
81+
}

0 commit comments

Comments
 (0)