Merge pull request #4889 from storytold/fix/4826-join-point-text

Fix #4826: Artwork Cleanup's Join Point Text stacks one-line type into one object
This commit is contained in:
BFlat
2026-10-31 21:03:20 +07:00
committed by GitHub
32 changed files with 188 additions and 4 deletions
+89 -1
View File
@@ -1,5 +1,5 @@
//! Artwork Cleanup's text tools: Break Text into Lines / Paragraphs / Words / Glyphs, Combine Point
//! Text, Split Text at Cursor, Remove Line / Paragraph Breaks, Set Alignment, Keep Position, Reset
//! Text, Join Point Text, Split Text at Cursor, Remove Line / Paragraph Breaks, Set Alignment, Keep Position, Reset
//! Text Transform and Replace Missing Fonts. Each is one undo step. Pieces keep their characters'
//! styles and stay where the layout drew them: each is moved so the glyph of its first character
//! lands where it was.
@@ -57,6 +57,15 @@ pub fn specs() -> Vec<CommandSpec> {
has_selection,
combine_text
),
cmd!(
"addon.cleanup.joinText",
"Join Point Text",
["Object", "Plug-ins", "Artwork Cleanup"],
None,
"{ids?: [id…] (default: the selection)} join one-line horizontal point type into one point type object, as one undo step: pieces turned and sheared like the top-left one are read as lines (baselines within 0.4 em of each other), top to bottom, each line's pieces left to right with a space between them; each line becomes a paragraph, left aligned, and keeps the distance between baselines as its leading. The text keeps its character styles; the object takes the top-left piece's place and paint, and the other pieces go → {id (selected), joined (pieces merged into it), lines}",
has_selection,
join_text
),
cmd!(
"addon.cleanup.removeBreaks",
"Remove Breaks",
@@ -641,6 +650,85 @@ fn combine_text(s: &mut Session, p: &Value) -> Result<Value> {
Ok(json!({ "ids": ids, "combined": combined }))
}
fn join_text(s: &mut Session, p: &Value) -> Result<Value> {
const C: &str = "addon.cleanup.joinText";
let d = &s.doc()?.doc;
let pieces: Vec<Piece> =
texts_under(d, &checked_ids_or_selection(s, p, C)?)?.into_iter().filter_map(|id| Piece::of(d, id).map(|p| p.0)).collect();
// The piece top-left on the page sets the turn; the others turned like it are read in that frame.
let on_page = |p: &Piece| Affine::new([p.turn[0], p.turn[1], p.turn[2], p.turn[3], 0.0, 0.0]) * p.at;
let first = pieces.iter().min_by(|x, y| {
let (a, b) = (on_page(x), on_page(y));
a.y.total_cmp(&b.y).then(a.x.total_cmp(&b.x))
});
let mut kept: Vec<&Piece> = first.map(|f| pieces.iter().filter(|p| p.turned_like(f)).collect()).unwrap_or_default();
kept.sort_by(|x, y| x.at.y.total_cmp(&y.at.y).then(x.at.x.total_cmp(&y.at.x)));
// Lines, top to bottom, by baseline; each line's pieces left to right.
let mut lines: Vec<Vec<&Piece>> = vec![];
for piece in kept {
match lines.last_mut().filter(|l| l.first().is_some_and(|f| (f.at.y - piece.at.y).abs() <= SAME_LINE * f.size.min(piece.size))) {
Some(l) => l.push(piece),
None => lines.push(vec![piece]),
}
}
for line in &mut lines {
line.sort_by(|x, y| x.at.x.total_cmp(&y.at.x));
}
let joined: usize = lines.iter().map(Vec::len).sum();
let (Some(top), true) = (lines.first().and_then(|l| l.first()).copied(), joined >= 2) else {
return Err(EngineError::Other("Select two or more one-line point type objects to join".into()));
};
let mut runs: Vec<vectorcraft_doc::TextRun> = vec![];
let mut prev_y = None;
for line in &lines {
let y = line.first().map_or(top.at.y, |p| p.at.y);
// The line keeps the distance from the baseline above as its leading.
let leading = prev_y.map(|above| y - above).filter(|l: &f64| l.is_finite() && *l > 0.0);
prev_y = Some(y);
let last = |runs: &[vectorcraft_doc::TextRun]| runs.iter().rev().find(|r| !r.text.is_empty()).map(|r| r.style.clone()).unwrap_or_default();
if !runs.is_empty() {
runs.push(vectorcraft_doc::TextRun::new("\n", last(&runs)));
}
let start = runs.len();
for (k, piece) in line.iter().enumerate() {
let blank = runs.last().is_some_and(|r| r.text.ends_with(char::is_whitespace)) || piece.t.plain_text().starts_with(char::is_whitespace);
if k > 0 && !blank {
runs.push(vectorcraft_doc::TextRun::new(" ", last(&runs)));
}
runs.extend(piece.t.runs.iter().cloned());
}
if let Some(l) = leading {
for r in runs.iter_mut().skip(start) {
r.style.leading = Some(l);
}
}
}
let mut m = top.t.clone();
m.set_all_paras(ParaStyle { justify: Justify::Left, ..top.t.para.clone() });
m.runs = runs;
edit::normalize(&mut m.runs);
m.ruby.clear();
// The top-left piece's first glyph stays where it was.
let [a, b, c, dd] = top.turn;
let base = Affine::new([a, b, c, dd, 0.0, 0.0]) * Affine::translate(top.at.to_vec2());
m.xf = base;
let x0 = glyph_starting(&layout(&m), 0).map_or(0.0, |g| g.x);
m.xf = base * Affine::translate((-x0, 0.0));
refresh_bounds(&mut m);
let id = top.id;
let gone: Vec<NodeId> = lines.iter().flatten().map(|p| p.id).filter(|g| *g != id).collect();
let count = lines.len();
s.edit("Join Point Text", |d, sel| {
if let Some(n) = d.node_mut(id) {
n.kind = NodeKind::Text(Box::new(m));
}
d.remove_many(&gone)?;
sel.set([id]);
Ok(())
})?;
Ok(json!({ "id": id.0, "joined": joined, "lines": count }))
}
/// Remove the breaks `brk` in bytes `a..b` of `t`: one between two words becomes a space → how many
/// went.
fn strip_breaks(t: &mut TextObject, a: usize, b: usize, brk: char) -> usize {
@@ -176,6 +176,40 @@ fn combine_joins_only_pieces_on_one_line_turned_alike() {
assert!(other(s.execute("addon.cleanup.combineText", &json!({}))).contains("combine"));
}
/// Join Point Text makes one object of stacked one-line pieces: lines top to bottom as paragraphs,
/// pieces on a line left to right, each line's baseline where it was (its leading is the distance
/// from the line above), in one undo step. A piece turned unlike the top-left one stays.
#[test]
fn join_stacks_lines_into_one_object_with_their_spacing() {
let mut s = session();
let a = text(&mut s, json!({"x": 50, "y": 100, "text": "First", "size": 20}));
let b = text(&mut s, json!({"x": 120, "y": 101, "text": "line", "size": 20}));
let c = text(&mut s, json!({"x": 50, "y": 130, "text": "Second", "size": 20}));
let d = text(&mut s, json!({"x": 50, "y": 166, "text": "Third", "size": 20}));
let turned = text(&mut s, json!({"x": 300, "y": 300, "text": "Turned", "size": 20, "rotation": 45}));
let was = glyphs(&s, &[a, c, d]);
select(&mut s, &[d, b, turned, c, a]);
let steps = undo_steps(&s);
let r = s.execute("addon.cleanup.joinText", &json!({})).unwrap();
assert_eq!(undo_steps(&s), steps + 1);
assert_eq!((r["id"].as_u64(), r["joined"].as_u64(), r["lines"].as_u64()), (Some(a.0), Some(4), Some(3)));
let t = obj(&s, a);
assert_eq!(t.plain_text(), "First line\nSecond\nThird");
assert_eq!(t.runs.iter().filter(|r| r.text.contains("Third")).map(|r| r.style.leading).collect::<Vec<_>>(), [Some(36.0)]);
// Each line's first glyph is where it was.
let now = glyphs(&s, &[a]);
for ch in ['F', 'S', 'T'] {
let (p, q) = (was.iter().find(|g| g.0 == ch).unwrap().1, now.iter().find(|g| g.0 == ch).unwrap().1);
assert!((p - q).hypot() < 0.05, "{ch}: {p:?} moved to {q:?}");
}
let doc = &s.doc().unwrap().doc;
assert!(doc.node(b).is_none() && doc.node(c).is_none() && doc.node(d).is_none() && doc.node(turned).is_some());
select(&mut s, &[turned]);
assert!(other(s.execute("addon.cleanup.joinText", &json!({}))).contains("join"));
s.execute("edit.undo", &json!({})).unwrap();
assert!(s.doc().unwrap().doc.node(c).is_some(), "undo brings the pieces back");
}
#[test]
fn remove_line_and_paragraph_breaks() {
let mut s = session();
+2
View File
@@ -601,6 +601,8 @@ fn structured_junk() {
("addon.cleanup.breakText", json!({"by": "words", "ids": "all"})),
("addon.cleanup.combineText", json!({"ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})),
("addon.cleanup.combineText", json!({"ids": [-1, 1e308]})),
("addon.cleanup.joinText", json!({"ids": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]})),
("addon.cleanup.joinText", json!({"ids": [-1, 1e308, "x"]})),
("addon.cleanup.removeBreaks", json!({"kind": "paragraph", "ids": [1, 2, 3, 4, 5, 6, 7, 8, u64::MAX]})),
("addon.cleanup.removeBreaks", json!({"kind": 3})),
("addon.cleanup.removeBreaks", json!({"kind": "line", "ids": null})),
+3 -1
View File
@@ -38,7 +38,7 @@ fn replace_fonts() -> Value {
/// modifier click does, command, params).
type TextRow = (Option<&'static str>, Vec<(&'static str, Option<&'static str>, &'static str, Value)>);
fn text_rows() -> [TextRow; 4] {
fn text_rows() -> [TextRow; 5] {
let align = |a: &str| json!({ "align": a });
let by = |b: &str| json!({ "by": b });
[
@@ -66,6 +66,7 @@ fn text_rows() -> [TextRow; 4] {
],
),
(None, vec![("Combine Point Text", None, "addon.cleanup.combineText", json!({}))]),
(None, vec![("Join Point Text", None, "addon.cleanup.joinText", json!({}))]),
]
}
@@ -98,6 +99,7 @@ pub fn menu() -> Vec<Item> {
let align = |a: &str| json!({ "align": a });
items.extend([
Item::Cmd("Combine Point Text", "addon.cleanup.combineText", json!({})),
Item::Cmd("Join Point Text", "addon.cleanup.joinText", json!({})),
Item::Cmd("Break Text into Lines", "addon.cleanup.breakText", by("lines")),
Item::Cmd("Break Text into Paragraphs", "addon.cleanup.breakText", by("paragraphs")),
Item::Cmd("Break Text into Words", "addon.cleanup.breakText", by("words")),
@@ -95,6 +95,7 @@ fn the_plugins_submenu_runs_the_text_tools() {
let cleanup = ["Object", "Plug-ins", "Artwork Cleanup"];
for (label, id) in [
("Combine Point Text", "addon.cleanup.combineText"),
("Join Point Text", "addon.cleanup.joinText"),
("Break Text into Lines", "addon.cleanup.breakText"),
("Break Text into Paragraphs", "addon.cleanup.breakText"),
("Break Text into Glyphs", "addon.cleanup.breakText"),
+2
View File
@@ -5800,6 +5800,7 @@ anchor Points: Точки:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Разделяне на текст
Combine Point Text Обединяване на точков текст
Join Point Text Съединяване на точков текст
Remove Breaks Премахване на прекъсвания
Split Text at Cursor Разделяне на текст при курсора
Set Alignment, Keep Position Задаване на подравняване със запазване на позицията
@@ -5828,6 +5829,7 @@ breakText Glyphs Глифи
@msg Select horizontal point or area type whose text fits Изберете хоризонтален точков текст или текст в зона, чийто текст се побира
@msg Nothing to split at the cursor При курсора няма какво да се раздели
@msg Select two or more one-line point type objects on one baseline to combine Изберете два или повече едноредови обекта с точков текст на една базова линия, за да ги обедините
@msg Select two or more one-line point type objects to join Изберете два или повече едноредови обекта с точков текст, за да ги съедините
@msg No line breaks to remove Няма прекъсвания на редове за премахване
@msg No paragraph breaks to remove Няма прекъсвания на абзаци за премахване
@msg Too many breaks to remove at once Твърде много прекъсвания за премахване наведнъж
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5901,6 +5901,7 @@ anchor Points: Punts:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Divideix el text
Combine Point Text Combina el text de punt
Join Point Text Uneix el text de punt
Remove Breaks Elimina els salts
Split Text at Cursor Divideix el text al cursor
Set Alignment, Keep Position Defineix l’alineació i manté la posició
@@ -5929,6 +5930,7 @@ breakText Glyphs Glifs
@msg Select horizontal point or area type whose text fits Seleccioneu text de punt o d’àrea horitzontal el text del qual hi càpiga
@msg Nothing to split at the cursor No hi ha res a dividir al cursor
@msg Select two or more one-line point type objects on one baseline to combine Seleccioneu dos o més objectes de text de punt d’una línia sobre una mateixa línia de base per combinar-los
@msg Select two or more one-line point type objects to join Seleccioneu dos o més objectes de text de punt d’una línia per unir-los
@msg No line breaks to remove No hi ha salts de línia per eliminar
@msg No paragraph breaks to remove No hi ha salts de paràgraf per eliminar
@msg Too many breaks to remove at once Massa salts per eliminar-los alhora
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5910,6 +5910,7 @@ anchor Points: Body:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Rozdělit text
Combine Point Text Sloučit bodový text
Join Point Text Spojit bodový text
Remove Breaks Odstranit zalomení
Split Text at Cursor Rozdělit text u kurzoru
Set Alignment, Keep Position Nastavit zarovnání, zachovat polohu
@@ -5938,6 +5939,7 @@ breakText Glyphs Glyfy
@msg Select horizontal point or area type whose text fits Vyberte vodorovný bodový text nebo text v oblasti, jehož text se vejde
@msg Nothing to split at the cursor U kurzoru není co rozdělit
@msg Select two or more one-line point type objects on one baseline to combine Vyberte dva nebo více jednořádkových objektů bodového textu na jednom účaří, abyste je sloučili
@msg Select two or more one-line point type objects to join Vyberte dva nebo více jednořádkových objektů bodového textu, abyste je spojili
@msg No line breaks to remove Žádná zalomení řádků k odstranění
@msg No paragraph breaks to remove Žádná zalomení odstavců k odstranění
@msg Too many breaks to remove at once Příliš mnoho zalomení k odstranění najednou
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5815,6 +5815,7 @@ anchor Points: Punkter:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Opdel tekst
Combine Point Text Kombiner punkttekst
Join Point Text Sammenføj punkttekst
Remove Breaks Fjern skift
Split Text at Cursor Opdel tekst ved markøren
Set Alignment, Keep Position Angiv justering, bevar placering
@@ -5843,6 +5844,7 @@ breakText Glyphs Glyffer
@msg Select horizontal point or area type whose text fits Vælg vandret punkt- eller områdetekst, hvis tekst kan være der
@msg Nothing to split at the cursor Intet at opdele ved markøren
@msg Select two or more one-line point type objects on one baseline to combine Vælg to eller flere punkttekstobjekter på én linje på samme grundlinje for at kombinere dem
@msg Select two or more one-line point type objects to join Vælg to eller flere punkttekstobjekter på én linje for at sammenføje dem
@msg No line breaks to remove Ingen linjeskift at fjerne
@msg No paragraph breaks to remove Ingen afsnitsskift at fjerne
@msg Too many breaks to remove at once For mange skift til at fjerne på én gang
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5495,6 +5495,7 @@ anchor Points: Punkte:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Text aufteilen
Combine Point Text Punkttext zusammenfügen
Join Point Text Punkttext verbinden
Remove Breaks Umbrüche entfernen
Split Text at Cursor Text an der Einfügemarke teilen
Set Alignment, Keep Position Ausrichtung festlegen, Position beibehalten
@@ -5523,6 +5524,7 @@ breakText Glyphs Glyphen
@msg Select horizontal point or area type whose text fits Wählen Sie horizontalen Punkt- oder Flächentext aus, dessen Text hineinpasst
@msg Nothing to split at the cursor An der Einfügemarke gibt es nichts zu teilen
@msg Select two or more one-line point type objects on one baseline to combine Wählen Sie zwei oder mehr einzeilige Punkttextobjekte auf einer Grundlinie aus, um sie zusammenzufügen
@msg Select two or more one-line point type objects to join Wählen Sie zwei oder mehr einzeilige Punkttextobjekte aus, um sie zu verbinden
@msg No line breaks to remove Keine Zeilenumbrüche zu entfernen
@msg No paragraph breaks to remove Keine Absatzumbrüche zu entfernen
@msg Too many breaks to remove at once Zu viele Umbrüche, um sie auf einmal zu entfernen
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5862,6 +5862,7 @@ anchor Points: Σημεία:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Διαίρεση κειμένου
Combine Point Text Συνδυασμός κειμένου σημείου
Join Point Text Ένωση κειμένου σημείου
Remove Breaks Αφαίρεση αλλαγών
Split Text at Cursor Διαίρεση κειμένου στον δρομέα
Set Alignment, Keep Position Ορισμός στοίχισης με διατήρηση θέσης
@@ -5890,6 +5891,7 @@ breakText Glyphs Γλύφοι
@msg Select horizontal point or area type whose text fits Επιλέξτε οριζόντιο κείμενο σημείου ή περιοχής του οποίου το κείμενο χωράει
@msg Nothing to split at the cursor Δεν υπάρχει τίποτα για διαίρεση στον δρομέα
@msg Select two or more one-line point type objects on one baseline to combine Επιλέξτε δύο ή περισσότερα μονογραμμικά αντικείμενα κειμένου σημείου στην ίδια γραμμή βάσης για να τα συνδυάσετε
@msg Select two or more one-line point type objects to join Επιλέξτε δύο ή περισσότερα μονογραμμικά αντικείμενα κειμένου σημείου για να τα ενώσετε
@msg No line breaks to remove Δεν υπάρχουν αλλαγές γραμμής για αφαίρεση
@msg No paragraph breaks to remove Δεν υπάρχουν αλλαγές παραγράφου για αφαίρεση
@msg Too many breaks to remove at once Πάρα πολλές αλλαγές για αφαίρεση ταυτόχρονα
Can't render this file because it contains an unexpected character in line 164 and column 5.
+2
View File
@@ -5853,6 +5853,7 @@ anchor Points: Puntos:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Dividir texto
Combine Point Text Combinar texto de punto
Join Point Text Unir texto de punto
Remove Breaks Quitar saltos
Split Text at Cursor Dividir texto en el cursor
Set Alignment, Keep Position Definir alineación manteniendo la posición
@@ -5881,6 +5882,7 @@ breakText Glyphs Glifos
@msg Select horizontal point or area type whose text fits Seleccione texto de punto o de área horizontal cuyo texto quepa
@msg Nothing to split at the cursor No hay nada que dividir en el cursor
@msg Select two or more one-line point type objects on one baseline to combine Seleccione dos o más objetos de texto de punto de una línea sobre la misma línea base para combinarlos
@msg Select two or more one-line point type objects to join Seleccione dos o más objetos de texto de punto de una línea para unirlos
@msg No line breaks to remove No hay saltos de línea que quitar
@msg No paragraph breaks to remove No hay saltos de párrafo que quitar
@msg Too many breaks to remove at once Demasiados saltos para quitarlos a la vez
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5941,6 +5941,7 @@ anchor Points: Pisteet:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Jaa teksti
Combine Point Text Yhdistä pisteteksti
Join Point Text Liitä pisteteksti
Remove Breaks Poista vaihdot
Split Text at Cursor Jaa teksti kohdistimen kohdalta
Set Alignment, Keep Position Aseta tasaus, säilytä sijainti
@@ -5969,6 +5970,7 @@ breakText Glyphs Merkit
@msg Select horizontal point or area type whose text fits Valitse vaakasuora piste- tai alueteksti, jonka teksti mahtuu
@msg Nothing to split at the cursor Kohdistimen kohdalla ei ole jaettavaa
@msg Select two or more one-line point type objects on one baseline to combine Valitse kaksi tai useampia yksirivisiä pistetekstiobjekteja samalla perusviivalla yhdistääksesi ne
@msg Select two or more one-line point type objects to join Valitse kaksi tai useampia yksirivisiä pistetekstiobjekteja liittääksesi ne
@msg No line breaks to remove Ei poistettavia rivinvaihtoja
@msg No paragraph breaks to remove Ei poistettavia kappaleenvaihtoja
@msg Too many breaks to remove at once Liian monta vaihtoa poistettavaksi kerralla
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5909,6 +5909,7 @@ anchor Points: Points :
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Diviser le texte
Combine Point Text Combiner le texte de point
Join Point Text Joindre le texte de point
Remove Breaks Supprimer les sauts
Split Text at Cursor Diviser le texte au curseur
Set Alignment, Keep Position Définir l’alignement en conservant la position
@@ -5937,6 +5938,7 @@ breakText Glyphs Glyphes
@msg Select horizontal point or area type whose text fits Sélectionnez du texte de point ou captif horizontal dont le texte tient dans son cadre
@msg Nothing to split at the cursor Rien à diviser au curseur
@msg Select two or more one-line point type objects on one baseline to combine Sélectionnez au moins deux objets texte de point d’une ligne sur une même ligne de base pour les combiner
@msg Select two or more one-line point type objects to join Sélectionnez au moins deux objets texte de point d’une ligne pour les joindre
@msg No line breaks to remove Aucun saut de ligne à supprimer
@msg No paragraph breaks to remove Aucun saut de paragraphe à supprimer
@msg Too many breaks to remove at once Trop de sauts à supprimer en une fois
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5897,6 +5897,7 @@ anchor Points: Pontok:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Szöveg felosztása
Combine Point Text Pontszöveg egyesítése
Join Point Text Pontszöveg összekapcsolása
Remove Breaks Törések eltávolítása
Split Text at Cursor Szöveg felosztása a kurzornál
Set Alignment, Keep Position Igazítás beállítása, helyzet megtartása
@@ -5925,6 +5926,7 @@ breakText Glyphs Glifák
@msg Select horizontal point or area type whose text fits Jelöljön ki vízszintes pont- vagy területszöveget, amelynek szövege elfér
@msg Nothing to split at the cursor A kurzornál nincs mit felosztani
@msg Select two or more one-line point type objects on one baseline to combine Az egyesítéshez jelöljön ki legalább két egysoros pontszöveg-objektumot egy alapvonalon
@msg Select two or more one-line point type objects to join Az összekapcsoláshoz jelöljön ki legalább két egysoros pontszöveg-objektumot
@msg No line breaks to remove Nincs eltávolítandó sortörés
@msg No paragraph breaks to remove Nincs eltávolítandó bekezdéstörés
@msg Too many breaks to remove at once Túl sok törés az egyszerre történő eltávolításhoz
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5815,6 +5815,7 @@ anchor Points: Titik:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Pisahkan teks
Combine Point Text Gabungkan teks titik
Join Point Text Satukan teks titik
Remove Breaks Hapus pemisah
Split Text at Cursor Pisahkan teks di kursor
Set Alignment, Keep Position Atur perataan, pertahankan posisi
@@ -5843,6 +5844,7 @@ breakText Glyphs Glif
@msg Select horizontal point or area type whose text fits Pilih teks titik atau teks area horizontal yang teksnya muat
@msg Nothing to split at the cursor Tidak ada yang dapat dipisahkan di kursor
@msg Select two or more one-line point type objects on one baseline to combine Pilih dua atau lebih objek teks titik satu baris pada satu garis dasar untuk menggabungkannya
@msg Select two or more one-line point type objects to join Pilih dua atau lebih objek teks titik satu baris untuk menyatukannya
@msg No line breaks to remove Tidak ada putus baris untuk dihapus
@msg No paragraph breaks to remove Tidak ada putus paragraf untuk dihapus
@msg Too many breaks to remove at once Terlalu banyak pemisah untuk dihapus sekaligus
Can't render this file because it contains an unexpected character in line 2168 and column 5.
+2
View File
@@ -5529,6 +5529,7 @@ anchor Points: Punti:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Dividi testo
Combine Point Text Combina testo con punto
Join Point Text Unisci testo con punto
Remove Breaks Rimuovi interruzioni
Split Text at Cursor Dividi testo al cursore
Set Alignment, Keep Position Imposta allineamento mantenendo la posizione
@@ -5557,6 +5558,7 @@ breakText Glyphs Glifi
@msg Select horizontal point or area type whose text fits Seleziona testo con punto o in area orizzontale il cui testo ci sta
@msg Nothing to split at the cursor Niente da dividere al cursore
@msg Select two or more one-line point type objects on one baseline to combine Seleziona due o più oggetti di testo con punto su una riga sulla stessa linea di base per combinarli
@msg Select two or more one-line point type objects to join Seleziona due o più oggetti di testo con punto su una riga per unirli
@msg No line breaks to remove Nessuna interruzione di riga da rimuovere
@msg No paragraph breaks to remove Nessuna interruzione di paragrafo da rimuovere
@msg Too many breaks to remove at once Troppe interruzioni da rimuovere in una volta
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5595,6 +5595,7 @@ anchor Points: ポイント:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text テキストを分割
Combine Point Text ポイント文字を結合
Join Point Text ポイント文字を連結
Remove Breaks 改行を削除
Split Text at Cursor カーソル位置でテキストを分割
Set Alignment, Keep Position 位置を保って行揃えを設定
@@ -5623,6 +5624,7 @@ breakText Glyphs 字形
@msg Select horizontal point or area type whose text fits テキストが収まっている横組みのポイント文字またはエリア内文字を選択してください
@msg Nothing to split at the cursor カーソル位置で分割するものがありません
@msg Select two or more one-line point type objects on one baseline to combine 結合するには、同じベースライン上にある 1 行のポイント文字オブジェクトを 2 つ以上選択してください
@msg Select two or more one-line point type objects to join 連結するには、1 行のポイント文字オブジェクトを 2 つ以上選択してください
@msg No line breaks to remove 削除する強制改行がありません
@msg No paragraph breaks to remove 削除する段落の区切りがありません
@msg Too many breaks to remove at once 一度に削除する改行が多すぎます
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5900,6 +5900,7 @@ anchor Points: წერტილები:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text ტექსტის დაყოფა
Combine Point Text წერტილის ტექსტის გაერთიანება
Join Point Text წერტილის ტექსტის შეერთება
Remove Breaks წყვეტების წაშლა
Split Text at Cursor ტექსტის დაყოფა კურსორთან
Set Alignment, Keep Position სწორების დაყენება მდებარეობის შენარჩუნებით
@@ -5928,6 +5929,7 @@ breakText Glyphs გლიფები
@msg Select horizontal point or area type whose text fits აირჩიეთ ჰორიზონტალური წერტილის ან არის ტექსტი, რომლის ტექსტიც ეტევა
@msg Nothing to split at the cursor კურსორთან დასაყოფი არაფერია
@msg Select two or more one-line point type objects on one baseline to combine გასაერთიანებლად აირჩიეთ ერთ საბაზისო ხაზზე მდებარე ორი ან მეტი ერთსტრიქონიანი წერტილის ტექსტის ობიექტი
@msg Select two or more one-line point type objects to join შესაერთებლად აირჩიეთ ორი ან მეტი ერთსტრიქონიანი წერტილის ტექსტის ობიექტი
@msg No line breaks to remove წასაშლელი სტრიქონის წყვეტები არ არის
@msg No paragraph breaks to remove წასაშლელი აბზაცის წყვეტები არ არის
@msg Too many breaks to remove at once ერთდროულად წასაშლელად ძალიან ბევრი წყვეტაა
Can't render this file because it is too large.
+2
View File
@@ -5492,6 +5492,7 @@ anchor Points: 포인트:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text 텍스트 나누기
Combine Point Text 포인트 문자 결합
Join Point Text 포인트 문자 연결
Remove Breaks 나누기 제거
Split Text at Cursor 커서 위치에서 텍스트 나누기
Set Alignment, Keep Position 위치를 유지하며 정렬 설정
@@ -5520,6 +5521,7 @@ breakText Glyphs 글리프
@msg Select horizontal point or area type whose text fits 텍스트가 모두 들어가는 가로 포인트 문자 또는 영역 문자를 선택하십시오
@msg Nothing to split at the cursor 커서 위치에서 나눌 내용이 없습니다
@msg Select two or more one-line point type objects on one baseline to combine 결합하려면 같은 기준선에 있는 한 줄짜리 포인트 문자 오브젝트를 두 개 이상 선택하십시오
@msg Select two or more one-line point type objects to join 연결하려면 한 줄짜리 포인트 문자 오브젝트를 두 개 이상 선택하십시오
@msg No line breaks to remove 제거할 강제 줄 바꿈이 없습니다
@msg No paragraph breaks to remove 제거할 단락 나누기가 없습니다
@msg Too many breaks to remove at once 한 번에 제거할 나누기가 너무 많습니다
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5859,6 +5859,7 @@ anchor Points: Punten:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Tekst splitsen
Combine Point Text Punttekst combineren
Join Point Text Punttekst samenvoegen
Remove Breaks Einden verwijderen
Split Text at Cursor Tekst splitsen bij cursor
Set Alignment, Keep Position Uitlijning instellen, positie behouden
@@ -5887,6 +5888,7 @@ breakText Glyphs Glyphs
@msg Select horizontal point or area type whose text fits Selecteer horizontale punt- of vlaktekst waarvan de tekst past
@msg Nothing to split at the cursor Niets te splitsen bij de cursor
@msg Select two or more one-line point type objects on one baseline to combine Selecteer twee of meer punttekstobjecten van één regel op één basislijn om ze te combineren
@msg Select two or more one-line point type objects to join Selecteer twee of meer punttekstobjecten van één regel om ze samen te voegen
@msg No line breaks to remove Geen regeleinden om te verwijderen
@msg No paragraph breaks to remove Geen alinea-einden om te verwijderen
@msg Too many breaks to remove at once Te veel einden om in één keer te verwijderen
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5765,6 +5765,7 @@ anchor Points: Punkty:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Podziel tekst
Combine Point Text Połącz tekst punktowy
Join Point Text Złącz tekst punktowy
Remove Breaks Usuń podziały
Split Text at Cursor Podziel tekst w miejscu kursora
Set Alignment, Keep Position Ustaw wyrównanie, zachowaj położenie
@@ -5793,6 +5794,7 @@ breakText Glyphs Glify
@msg Select horizontal point or area type whose text fits Zaznacz poziomy tekst punktowy lub akapitowy, którego tekst się mieści
@msg Nothing to split at the cursor Nie ma nic do podzielenia w miejscu kursora
@msg Select two or more one-line point type objects on one baseline to combine Zaznacz co najmniej dwa jednowierszowe obiekty tekstu punktowego na jednej linii bazowej, aby je połączyć
@msg Select two or more one-line point type objects to join Zaznacz co najmniej dwa jednowierszowe obiekty tekstu punktowego, aby je złączyć
@msg No line breaks to remove Brak podziałów wiersza do usunięcia
@msg No paragraph breaks to remove Brak podziałów akapitu do usunięcia
@msg Too many breaks to remove at once Zbyt wiele podziałów do usunięcia naraz
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5828,6 +5828,7 @@ anchor Points: Pontos:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Dividir Texto
Combine Point Text Combinar Texto de Ponto
Join Point Text Unir Texto de Ponto
Remove Breaks Remover Quebras
Split Text at Cursor Dividir Texto no Cursor
Set Alignment, Keep Position Definir Alinhamento, Manter Posição
@@ -5856,6 +5857,7 @@ breakText Glyphs Glifos
@msg Select horizontal point or area type whose text fits Selecione texto de ponto ou de área horizontal cujo texto caiba
@msg Nothing to split at the cursor Nada a dividir no cursor
@msg Select two or more one-line point type objects on one baseline to combine Selecione dois ou mais objetos de texto de ponto de uma linha na mesma linha de base para combiná-los
@msg Select two or more one-line point type objects to join Selecione dois ou mais objetos de texto de ponto de uma linha para uni-los
@msg No line breaks to remove Nenhuma quebra de linha a remover
@msg No paragraph breaks to remove Nenhuma quebra de parágrafo a remover
@msg Too many breaks to remove at once Quebras demais para remover de uma vez
Can't render this file because it contains an unexpected character in line 6 and column 47.
+2
View File
@@ -5888,6 +5888,7 @@ anchor Points: Точки:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Разбить текст
Combine Point Text Объединить текст из точки
Join Point Text Соединить текст из точки
Remove Breaks Удалить разрывы
Split Text at Cursor Разбить текст у курсора
Set Alignment, Keep Position Задать выравнивание, сохранив положение
@@ -5916,6 +5917,7 @@ breakText Glyphs Глифы
@msg Select horizontal point or area type whose text fits Выделите горизонтальный текст из точки или в области, текст которого помещается
@msg Nothing to split at the cursor У курсора нечего разбивать
@msg Select two or more one-line point type objects on one baseline to combine Выделите два или более однострочных объекта текста из точки на одной базовой линии, чтобы объединить их
@msg Select two or more one-line point type objects to join Выделите два или более однострочных объекта текста из точки, чтобы соединить их
@msg No line breaks to remove Нет разрывов строк для удаления
@msg No paragraph breaks to remove Нет разрывов абзацев для удаления
@msg Too many breaks to remove at once Слишком много разрывов для удаления за один раз
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5963,6 +5963,7 @@ shape Open Öppen
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Dela upp text
Combine Point Text Kombinera punkttext
Join Point Text Sammanfoga punkttext
Remove Breaks Ta bort brytningar
Split Text at Cursor Dela text vid markören
Set Alignment, Keep Position Ställ in justering, behåll position
@@ -5991,6 +5992,7 @@ breakText Glyphs Glyfer
@msg Select horizontal point or area type whose text fits Markera vågrät punkt- eller områdestext vars text får plats
@msg Nothing to split at the cursor Inget att dela vid markören
@msg Select two or more one-line point type objects on one baseline to combine Markera två eller fler enradiga punkttextobjekt på samma baslinje för att kombinera dem
@msg Select two or more one-line point type objects to join Markera två eller fler enradiga punkttextobjekt för att sammanfoga dem
@msg No line breaks to remove Inga radbrytningar att ta bort
@msg No paragraph breaks to remove Inga styckebrytningar att ta bort
@msg Too many breaks to remove at once För många brytningar att ta bort på en gång
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2
View File
@@ -5868,6 +5868,7 @@ anchor Points: Noktalar:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Metni Böl
Combine Point Text Nokta Metnini Birleştir
Join Point Text Nokta Metnini Bağla
Remove Breaks Kesmeleri Kaldır
Split Text at Cursor Metni İmleçte Böl
Set Alignment, Keep Position Hizalamayı Ayarla, Konumu Koru
@@ -5896,6 +5897,7 @@ breakText Glyphs Glifler
@msg Select horizontal point or area type whose text fits Metni sığan yatay nokta veya alan metni seçin
@msg Nothing to split at the cursor İmleçte bölünecek bir şey yok
@msg Select two or more one-line point type objects on one baseline to combine Birleştirmek için aynı taban çizgisinde iki veya daha fazla tek satırlı nokta metni nesnesi seçin
@msg Select two or more one-line point type objects to join Bağlamak için iki veya daha fazla tek satırlı nokta metni nesnesi seçin
@msg No line breaks to remove Kaldırılacak satır sonu yok
@msg No paragraph breaks to remove Kaldırılacak paragraf sonu yok
@msg Too many breaks to remove at once Bir kerede kaldırılacak çok fazla kesme var
Can't render this file because it contains an unexpected character in line 5 and column 25.
+2
View File
@@ -5509,6 +5509,7 @@ anchor Points: Точки:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Розбити текст
Combine Point Text Об’єднати текст із точки
Join Point Text З’єднати текст із точки
Remove Breaks Видалити розриви
Split Text at Cursor Розбити текст біля курсора
Set Alignment, Keep Position Задати вирівнювання, зберігши положення
@@ -5537,6 +5538,7 @@ breakText Glyphs Гліфи
@msg Select horizontal point or area type whose text fits Виділіть горизонтальний текст із точки або в області, текст якого вміщується
@msg Nothing to split at the cursor Біля курсора нічого розбивати
@msg Select two or more one-line point type objects on one baseline to combine Виділіть два або більше однорядкових об’єктів тексту з точки на одній базовій лінії, щоб об’єднати їх
@msg Select two or more one-line point type objects to join Виділіть два або більше однорядкових об’єктів тексту з точки, щоб з’єднати їх
@msg No line breaks to remove Немає розривів рядків для видалення
@msg No paragraph breaks to remove Немає розривів абзаців для видалення
@msg Too many breaks to remove at once Забагато розривів, щоб видалити їх за раз
Can't render this file because it contains an unexpected character in line 178 and column 5.
+2
View File
@@ -5511,6 +5511,7 @@ anchor Points: Điểm:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text Tách văn bản
Combine Point Text Kết hợp chữ điểm
Join Point Text Nối chữ điểm
Remove Breaks Xóa ngắt
Split Text at Cursor Tách văn bản tại con trỏ
Set Alignment, Keep Position Đặt căn lề, giữ vị trí
@@ -5539,6 +5540,7 @@ breakText Glyphs Glyph
@msg Select horizontal point or area type whose text fits Chọn chữ điểm hoặc chữ vùng nằm ngang có văn bản vừa khung
@msg Nothing to split at the cursor Không có gì để tách tại con trỏ
@msg Select two or more one-line point type objects on one baseline to combine Chọn hai đối tượng chữ điểm một dòng trở lên trên cùng một đường cơ sở để kết hợp
@msg Select two or more one-line point type objects to join Chọn hai đối tượng chữ điểm một dòng trở lên để nối
@msg No line breaks to remove Không có xuống dòng nào để xóa
@msg No paragraph breaks to remove Không có ngắt đoạn nào để xóa
@msg Too many breaks to remove at once Quá nhiều ngắt để xóa cùng lúc
Can't render this file because it contains an unexpected character in line 200 and column 5.
+2
View File
@@ -5752,6 +5752,7 @@ anchor Points: 点:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text 拆分文本
Combine Point Text 合并点文字
Join Point Text 连接点文字
Remove Breaks 删除换行
Split Text at Cursor 在光标处拆分文本
Set Alignment, Keep Position 设置对齐并保持位置
@@ -5780,6 +5781,7 @@ breakText Glyphs 字形
@msg Select horizontal point or area type whose text fits 请选择文本能完全容纳的横排点文字或区域文字
@msg Nothing to split at the cursor 光标处没有可拆分的内容
@msg Select two or more one-line point type objects on one baseline to combine 请选择同一基线上两个或更多单行点文字对象以合并
@msg Select two or more one-line point type objects to join 请选择两个或更多单行点文字对象以连接
@msg No line breaks to remove 没有要删除的强制换行
@msg No paragraph breaks to remove 没有要删除的段落换行
@msg Too many breaks to remove at once 一次要删除的换行过多
Can't render this file because it contains an unexpected character in line 2 and column 73.
+2
View File
@@ -5548,6 +5548,7 @@ anchor Points: 點:
# Artwork Cleanup add-on: its text tools (Object › Plug-ins › Artwork Cleanup and the panel's Text row) and their messages.
Break Text 分割文字
Combine Point Text 合併點文字
Join Point Text 連接點文字
Remove Breaks 移除換行
Split Text at Cursor 在游標處分割文字
Set Alignment, Keep Position 設定對齊並保持位置
@@ -5576,6 +5577,7 @@ breakText Glyphs 字符
@msg Select horizontal point or area type whose text fits 請選取文字能完整容納的橫排點文字或區域文字
@msg Nothing to split at the cursor 游標處沒有可分割的內容
@msg Select two or more one-line point type objects on one baseline to combine 請選取同一基線上兩個或更多單行點文字物件以合併
@msg Select two or more one-line point type objects to join 請選取兩個或更多單行點文字物件以連接
@msg No line breaks to remove 沒有要移除的強制換行
@msg No paragraph breaks to remove 沒有要移除的段落換行
@msg Too many breaks to remove at once 一次要移除的換行過多
Can't render this file because it contains an unexpected character in line 6 and column 47.
+5
View File
@@ -5773,6 +5773,11 @@ glyph of its first character lands where it was drawn.
more than 1 em, another look (paint, opacity, effects) or a piece that can't keep its place once joined (a ligature
forming across the join) starts another object. Each object made takes the place and paint of its leftmost piece. The
main use is type from a PDF that arrives one glyph per object.
- `addon.cleanup.joinText {ids?}` (Join Point Text) joins one-line horizontal point type into one point type object,
for text that arrives one line or fragment per object. Pieces turned and sheared like the top-left one are read as
lines (baselines within 0.4 em), top to bottom; a line's pieces join left to right with a space between them. Each
line becomes a left-aligned paragraph whose leading is the distance from the baseline above, so the lines stay where
they were. Character styles stay; the object takes the top-left piece's place and paint. Returns `{id, joined, lines}`.
- `addon.cleanup.removeBreaks {kind, ids?}` removes the forced line breaks (`kind: "line"`) or paragraph returns
(`"paragraph"`) in the characters selected with a Type tool, else in all the text of the selected type. A break
between two words becomes a space; merged paragraphs take the first one's paragraph style.
+4 -2
View File
@@ -1,6 +1,6 @@
# Parity with Adobe Illustrator
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-31 · **Change:** minor (G13: Direct Selection snaps a dragged line end square to straight paths and grazing curves; Path Precision Tools add-on: Shared Edge Merge Tool; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-31 · **Change:** minor (Artwork Cleanup add-on: Join Point Text, #4826; scores unchanged; previously: G13: Direct Selection snaps a dragged line end square to straight paths and grazing curves; Path Precision Tools add-on: Shared Edge Merge Tool; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
## Feature submission evidence
@@ -19,6 +19,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
| Date | Change | Summary |
|---|---|---|
| 2026-10-31 | minor | Artwork Cleanup add-on: Join Point Text (`addon.cleanup.joinText`) joins stacked one-line point type into one object, a paragraph per line keeping its baseline (#4826); scores unchanged. |
| 2026-10-31 | minor | Width tool: a stroke with a width profile keeps its shape while the view zooms out; the minimum visible width goes to its widest point instead of scaling the whole profile (#995); scores unchanged. |
| 2026-10-31 | minor | Patterns: Grid Repeat Options has a Preview checkbox, as the public grid options page lists (#2651); scores unchanged. |
| 2026-10-31 | minor | Hardening: a gradient mesh read from a file is budgeted at about a million quads, so a huge one no longer exhausts memory when drawn or exported (#3592); scores unchanged. |
@@ -1244,7 +1245,8 @@ alone; Fix All as one step; scopes; rejoin within the gap only) and `addons::cle
The add-on's text tools (2026-10-31) work on the shared text layout: Break Text into lines, paragraphs, words or glyphs
and Split Text at Cursor make point type pieces placed by the glyph of their first character, Combine Point Text merges
one-line point type back with every glyph where it was (tracking and spaces, checked against the layout), and Remove
one-line point type back with every glyph where it was (tracking and spaces, checked against the layout), Join Point
Text stacks one-line pieces into one object of paragraphs that keep their baselines (#4826), and Remove
Line / Paragraph Breaks, Set Alignment, Keep Position, Reset Text Transform and Replace Missing Fonts. Tests:
`cmd::addons::cleanup::text::tests` in `vectorcraft-engine` (glyphs kept in place, styles kept, one undo step,
refusals), `addons::cleanup::tests` in `vectorcraft-ui-egui` (the submenu and the panel's Text row run them) and