Skip to content

Commit

Permalink
Merge pull request #5787 from processing/fixes5785
Browse files Browse the repository at this point in the history
fixes for #5785
  • Loading branch information
Qianqianye authored Sep 6, 2022
2 parents eda2e43 + 764edeb commit db02625
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 30 deletions.
100 changes: 73 additions & 27 deletions src/core/p5.Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
let chars;
let shiftedY;
let finalMaxHeight = Number.MAX_VALUE;
// fix for #5785 (top of bounding box)
let finalMinHeight = y;

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

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

let originalY = y;
let ascent = p.textAscent();

switch (this._textBaseline) {
case constants.BOTTOM:
shiftedY = y + maxHeight;
y = Math.max(shiftedY, y);
// fix for #5785 (top of bounding box)
finalMinHeight += ascent;
break;
case constants.CENTER:
shiftedY = y + maxHeight / 2;
y = Math.max(shiftedY, y);
break;
case constants.BASELINE:
baselineHacked = true;
this._textBaseline = constants.TOP;
// fix for #5785 (top of bounding box)
finalMinHeight += ascent / 2;
break;
}

// remember the max-allowed y-position for any line (fix to #928)
finalMaxHeight = y + maxHeight - p.textAscent();
finalMaxHeight = y + maxHeight - ascent;

// fix for #5785 (bottom of bounding box)
if (this._textBaseline === constants.CENTER) {
finalMaxHeight = originalY + maxHeight - ascent / 2;
}
} else {
// no text-height specified, show warning for BOTTOM / CENTER
if (this._textBaseline === constants.BOTTOM) {
return console.warn(
'textAlign(*, BOTTOM) requires x, y, width and height'
);
}
if (this._textBaseline === constants.CENTER) {
return console.warn(
'textAlign(*, CENTER) requires x, y, width and height'
);
}
}

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

let offset = 0;
const vAlign = p.textAlign().vertical;
if (vAlign === constants.CENTER) {
if (this._textBaseline === constants.CENTER) {
offset = (nlines.length - 1) * p.textLeading() / 2;
} else if (vAlign === constants.BOTTOM) {
} else if (this._textBaseline === constants.BOTTOM) {
offset = (nlines.length - 1) * p.textLeading();
}

Expand All @@ -324,18 +344,29 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
testLine = `${line + words[wordIndex]}` + ' ';
testWidth = this.textWidth(testLine);
if (testWidth > maxWidth && line.length > 0) {
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
this._renderText(
p,
line.trim(),
x,
y - offset,
finalMaxHeight,
finalMinHeight
);
line = `${words[wordIndex]}` + ' ';
y += p.textLeading();
} else {
line = testLine;
}
}
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
this._renderText(
p,
line.trim(),
x,
y - offset,
finalMaxHeight,
finalMinHeight
);
y += p.textLeading();
if (baselineHacked) {
this._textBaseline = constants.BASELINE;
}
}
} else {
let nlines = [];
Expand All @@ -356,10 +387,9 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {

nlines.push(line);
let offset = 0;
const vAlign = p.textAlign().vertical;
if (vAlign === constants.CENTER) {
if (this._textBaseline === constants.CENTER) {
offset = (nlines.length - 1) * p.textLeading() / 2;
} else if (vAlign === constants.BOTTOM) {
} else if (this._textBaseline === constants.BOTTOM) {
offset = (nlines.length - 1) * p.textLeading();
}

Expand All @@ -374,33 +404,49 @@ p5.Renderer.prototype.text = function(str, x, y, maxWidth, maxHeight) {
if (testWidth <= maxWidth) {
line += chars[charIndex];
} else if (testWidth > maxWidth && line.length > 0) {
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
this._renderText(
p,
line.trim(),
x,
y - offset,
finalMaxHeight,
finalMinHeight
);
y += p.textLeading();
line = `${chars[charIndex]}`;
}
}
}
this._renderText(p, line.trim(), x, y - offset, finalMaxHeight);
this._renderText(
p,
line.trim(),
x,
y - offset,
finalMaxHeight,
finalMinHeight
);
y += p.textLeading();

if (baselineHacked) {
this._textBaseline = constants.BASELINE;
}
}
} else {
// Offset to account for vertically centering multiple lines of text - no
// need to adjust anything for vertical align top or baseline
let offset = 0;
const vAlign = p.textAlign().vertical;
if (vAlign === constants.CENTER) {
if (this._textBaseline === constants.CENTER) {
offset = (lines.length - 1) * p.textLeading() / 2;
} else if (vAlign === constants.BOTTOM) {
} else if (this._textBaseline === constants.BOTTOM) {
offset = (lines.length - 1) * p.textLeading();
}

// Renders lines of text at any line breaks present in the original string
for (let i = 0; i < lines.length; i++) {
this._renderText(p, lines[i], x, y - offset, finalMaxHeight);
this._renderText(
p,
lines[i],
x,
y - offset,
finalMaxHeight,
finalMinHeight
);
y += p.textLeading();
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/core/p5.Renderer2D.js
Original file line number Diff line number Diff line change
Expand Up @@ -1190,9 +1190,9 @@ p5.Renderer2D.prototype.text = function(str, x, y, maxWidth, maxHeight) {
return p;
};

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

p.push(); // fix to #803
Expand Down
9 changes: 9 additions & 0 deletions test/manual-test-examples/p5.Font/textInRect/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<head>
<meta charset="UTF-8">
<script language="javascript" type="text/javascript" src="../../../../lib/p5.js"></script>

<script language="javascript" type="text/javascript" src="sketch.js"></script>

</head>
</html>
81 changes: 81 additions & 0 deletions test/manual-test-examples/p5.Font/textInRect/sketch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
let xpos = 50;
let ypos = 100;
let str =
'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';

function setup() {
createCanvas(1050, 800);
background(245);

let ta = textAscent();

textAlign(CENTER, TOP);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200, 200);
xpos += 250;

textAlign(CENTER, CENTER);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200, 200);
xpos += 250;

textAlign(CENTER, BOTTOM);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200, 200);
xpos += 250;

textAlign(CENTER, BASELINE);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200, 200);

textSize(18);
textAlign(CENTER, TOP);
text('TOP', 150, height / 2 - 40);
text('CENTER', 400, height / 2 - 40);
text('BOTTOM', 650, height / 2 - 40);
text('BASELINE', 900, height / 2 - 40);
textSize(12);

xpos = 50;
ypos += 400;

textAlign(CENTER, TOP);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200);
xpos += 250;

textAlign(CENTER, CENTER);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200);
xpos += 250;

textAlign(CENTER, BOTTOM);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200);
xpos += 250;

textAlign(CENTER, BASELINE);
rect(xpos, ypos, 200, 200);
text(str, xpos, ypos, 200);

textSize(18);
textAlign(CENTER, TOP);
text('TOP', 150, height / 2 - 40);
text('CENTER', 400, height / 2 - 40);
text('BOTTOM', 650, height / 2 - 40);
text('BASELINE', 900, height / 2 - 40);
text('TOP', 150, ypos + 270);
text('CENTER', 400, ypos + 270);
text('BOTTOM', 650, ypos + 270);
text('BASELINE', 900, ypos + 270);

fill(255);
noStroke();
textSize(24);

rect(0, height / 2, width, 15);
fill(0);
textAlign(LEFT, TOP);
text('text(s, x, y, w, h)', 20, 40);
text('text(s, x, y, w) [no height]', 20, height / 2 + 40);
}

0 comments on commit db02625

Please sign in to comment.