Skip to content

Commit

Permalink
Fix some issues with line breaks in canvas objects.
Browse files Browse the repository at this point in the history
These bugs were exposed by comment objects, now that explicit line
breaks in comments are actually working.

- Text paste turned each newline in the pasted text into two consecutive
  newlines. This is actually the expected behavior of insertText
  according to the specs, as newlines are interpreted as paragraph
  breaks, not line breaks. So we now insert lines one by one, and
  manually add the line breaks instead.

- Empty lines weren't rendered correctly by text_to_tspans, as empty
  tspans are just ignored in the layout algorithm. So we now use
  absolute instead of relative baseline offsets there.
  • Loading branch information
agraef committed Sep 20, 2024
1 parent 9bc441d commit 2f7b346
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
19 changes: 17 additions & 2 deletions pd/nw/pd_canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -717,8 +717,23 @@ var canvas_events = (function() {
},
text_paste: function(evt) {
evt.preventDefault();
document.execCommand("insertText", false,
evt.clipboardData.getData("text"));
var text = evt.clipboardData.getData("text");
// ag: We need to insert each line individually here, with
// line breaks in between. Otherwise the behavior of
// "insertText" is to insert a *paragraph* break between
// lines, so that we get two newlines for each newline in the
// input. (Who thought that this was a good design? There's
// probably a reason why this WebKit API is deprecated, but
// since there's no replacement for it, we have to use it.)
// Also note that we skip the line break at the end of the
// paste buffer, since it will be stripped off on the C side
// during object creation anyway.
var lines = text.split("\n");
for (var i = 0; i < lines.length; i++) {
document.execCommand("insertText", false, lines[i]);
if (i < lines.length-1)
document.execCommand("insertLineBreak", false);
}
grow_svg_for_element(textbox());
},
floating_text_click: function(evt) {
Expand Down
9 changes: 6 additions & 3 deletions pd/nw/pdgui.js
Original file line number Diff line number Diff line change
Expand Up @@ -3794,13 +3794,16 @@ function text_to_tspans(cid, svg_text, text) {
len = lines.length;
// Get fontsize (minus the trailing "px")
fontsize = svg_text.getAttribute("font-size").slice(0, -2);
var dy = text_line_height_kludge(+fontsize, "gui");
for (i = 0; i < len; i++) {
// ag: We need to specify absolute y offsets for the baseline
// positions here. Relative dy offsets, which were used previously,
// don't advance the y position if no glyphs are rendered, so empty
// lines aren't rendered correctly.
tspan = create_item(cid, "tspan", {
dy: i == 0 ? 0 : text_line_height_kludge(+fontsize, "gui") + "px",
y: ((i+1)*dy) + "px",
x: 0
});
// tspan needs at least one char so that empty lines are preserved
if (lines[i] == "") lines[i] = " ";
// find a way to abstract away the canvas array and the DOM here
text_node = patchwin[cid].window.document
.createTextNode(lines[i]);
Expand Down
14 changes: 1 addition & 13 deletions pd/src/g_rtext.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,17 +312,6 @@ static void rtext_senditup(t_rtext *x, int action, int *widthp, int *heightp,
ncolumns = foundit_c;
nlines++;
}
// append new line in case we end our input with an \n
// suppressed at the end of a comment (backport from pd-l2ork)
int iscomment = pd_class(&x->x_text->te_pd) == text_class &&
x->x_text->te_type == T_TEXT;
if (!iscomment && x_bufsize_c > 0 && (x->x_buf[x->x_bufsize - 1] == '\n' || x->x_buf[x->x_bufsize - 1] == '\v'))
{
nlines++;
tempbuf[outchars_b++] = '\n';
//tempbuf[outchars_b] = '\0';
//outchars_b++;
}
if (!reportedindex)
*indexp = outchars_b;
if (nlines < 1) nlines = 1;
Expand Down Expand Up @@ -653,8 +642,7 @@ void rtext_activate(t_rtext *x, int state)
null terminated. If this becomes a problem we can revisit
it later */
tmpbuf = t_getbytes(x->x_bufsize + 1);
sprintf(tmpbuf, "%.*s", (int)x->x_bufsize, x->x_buf);
/* in case x_bufsize is 0... */
snprintf(tmpbuf, x->x_bufsize+1, "%s", x->x_buf);
tmpbuf[x->x_bufsize] = '\0';
gui_vmess("gui_textarea", "xssiiiisiiiiiii",
canvas,
Expand Down

0 comments on commit 2f7b346

Please sign in to comment.