Document Info: Objects gives the paths' total length (#1958)

Document Info › Objects counts the paths but didn't say how long they are,
which sign and print work reads there (an LED strip along the letters, a
cut line). `document.info` now adds up the length of every path it counts,
the pieces of compound paths included and guides left out, and returns it
as `pathLength` (pt); the Objects section shows it as Path Length in the
document's units, right after the Paths count, so Selection Only gives the
selected paths' length. The label is translated in the catalogs that
cover the menus; pt-br only takes strings the UI itself shows.
This commit is contained in:
Ayberk A.
2026-10-16 04:08:12 +07:00
committed by bflatastic
parent 7135a377f8
commit a86ff7f177
16 changed files with 61 additions and 5 deletions
+43 -3
View File
@@ -18,7 +18,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Document Info",
["Window", "Document Info"],
None,
"{selectionOnly?, category?: document|objects|graphicStyles|spotColors|patterns|gradients|symbols|fonts|fontDetails|linkedImages|embeddedImages (only that one in sections and the text), format?: \"text\" (→ {text}: the report Document Info › Save… and Package write)} → {document, objects: {paths, compoundPaths, groups, …}, fonts, images, swatches, graphicStyleNames (with selectionOnly: the styles the selected objects are linked to), …, sections: [{id, title, rows: [[label, value]]}] (the panel's categories; fontDetails: each font's file and whether its licence lets it be embedded)}",
"{selectionOnly?, category?: document|objects|graphicStyles|spotColors|patterns|gradients|symbols|fonts|fontDetails|linkedImages|embeddedImages (only that one in sections and the text), format?: \"text\" (→ {text}: the report Document Info › Save… and Package write)} → {document, objects: {paths, compoundPaths, groups, …}, pathLength: pt (the paths' total length, compound paths' included, guides left out), fonts, images, swatches, graphicStyleNames (with selectionOnly: the styles the selected objects are linked to), …, sections: [{id, title, rows: [[label, value]]}] (the panel's categories; fontDetails: each font's file and whether its licence lets it be embedded)}",
has_doc,
info
),
@@ -128,7 +128,13 @@ fn sections(d: &Document, info: &Value, fonts: &BTreeSet<super::fonts::UsedFont>
rows
}
"objects" => {
OBJECT_LABELS.iter().filter_map(|(k, label)| Some((label.to_string(), info["objects"][k].as_u64()?.to_string()))).collect()
let mut rows: Vec<(String, String)> =
OBJECT_LABELS.iter().filter_map(|(k, label)| Some((label.to_string(), info["objects"][k].as_u64()?.to_string()))).collect();
// The paths' total length, in the document's units, right after their count.
if let Some(at) = rows.iter().position(|(label, _)| label == "Paths") {
rows.insert(at + 1, ("Path Length".into(), u.format(info["pathLength"].as_f64().unwrap_or(0.0))));
}
rows
}
"graphicStyles" => names("graphicStyleNames"),
"spotColors" => names("spotColors"),
@@ -229,6 +235,9 @@ fn info(s: &mut Session, p: &Value) -> Result<Value> {
let roots: Vec<&Node> =
if selection_only { st.selection.objects.iter().filter_map(|id| d.node(*id)).collect() } else { d.layers.iter().map(|l| &**l).collect() };
let mut counts: BTreeMap<&str, usize> = BTreeMap::new();
// The paths' total length, as Document Info › Objects shows it (the length of a cut line, a
// strip of LEDs along the letters, #1958).
let mut path_length = 0.0;
let mut fonts = BTreeSet::new();
let mut images: BTreeMap<String, Value> = BTreeMap::new();
let mut image_rows: Vec<ImageRow> = vec![];
@@ -243,7 +252,13 @@ fn info(s: &mut Session, p: &Value) -> Result<Value> {
NodeKind::Group { clip: true, .. } => Some("clipGroups"),
NodeKind::Group { .. } => Some("groups"),
NodeKind::Path { guide: true, .. } => Some("guides"),
NodeKind::Path { .. } => Some("paths"),
NodeKind::Path { path, .. } => {
let l = path.length();
if l.is_finite() {
path_length += l;
}
Some("paths")
}
NodeKind::Compound { .. } => Some("compoundPaths"),
NodeKind::Text(t) => {
for run in &t.runs {
@@ -308,6 +323,7 @@ fn info(s: &mut Session, p: &Value) -> Result<Value> {
let mut out = json!({
"document": document_summary(d),
"objects": counts,
"pathLength": path_length,
"fonts": font_names,
"images": images,
"symbols": symbols,
@@ -405,6 +421,30 @@ mod tests {
assert!(i["objects"]["textObjects"].is_null() && i["objects"]["paths"] == 1);
}
/// Document Info › Objects gives the paths' total length in the document's units (#1958): an
/// open line, a closed rectangle's perimeter and a compound path's pieces count, a guide doesn't.
#[test]
fn info_gives_the_paths_total_length() {
let mut s = Session::new();
s.execute("file.new", &json!({"width": 400, "height": 400, "units": "Millimeters"})).unwrap();
let line = s.execute("shape.line", &json!({"x1": 0, "y1": 0, "x2": 72, "y2": 0})).unwrap()["id"].clone();
let rect = s.execute("shape.rectangle", &json!({"x": 100, "y": 100, "width": 10, "height": 20})).unwrap()["id"].clone();
let length = |s: &mut Session, p: Value| s.execute("document.info", &p).unwrap()["pathLength"].as_f64().unwrap();
assert!((length(&mut s, json!({})) - 132.0).abs() < 1e-6);
s.execute("select.set", &json!({"ids": [line]})).unwrap();
assert!((length(&mut s, json!({"selectionOnly": true})) - 72.0).abs() < 1e-6);
let rows = s.execute("document.info", &json!({"selectionOnly": true, "category": "objects"})).unwrap()["sections"][0]["rows"].clone();
assert_eq!(rows, json!([["Paths", "1"], ["Path Length", "25.4 mm"]]));
// A compound path's pieces are paths: their lengths count.
let other = s.execute("shape.rectangle", &json!({"x": 200, "y": 200, "width": 5, "height": 5})).unwrap()["id"].clone();
s.execute("select.set", &json!({"ids": [rect, other]})).unwrap();
s.execute("object.compoundPath.make", &json!({})).unwrap();
assert!((length(&mut s, json!({"selectionOnly": true})) - 80.0).abs() < 1e-6);
// Nothing with no paths, and no length row.
s.execute("select.none", &json!({})).unwrap();
assert_eq!(length(&mut s, json!({"selectionOnly": true})), 0.0);
}
#[test]
fn embedding_permissions_read_from_fs_type() {
assert_eq!(embedding_label(0), "embedding allowed");
+1
View File
@@ -2856,6 +2856,7 @@ theme Appearance Motiv
Width Profile Profil šířky
Objects Objekty
Paths Cesty
Path Length Délka cest
Add Guide Přidat vodítko
Edit Selection Upravit výběr
Recall Selection Vyvolat výběr
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2002,6 +2002,7 @@
Pathfinder Options… Pathfinder-Optionen…
Pathfinders: Pathfinder:
Paths Pfade
Path Length Pfadlänge
Paths: {paths} Anchors: {anchors} Colors: {colors} Pfade: {paths} Ankerpunkte: {anchors} Farben: {colors}
Pattern Muster
Pattern Editing Musterbearbeitung
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2051,6 +2051,7 @@
Pathfinder Options… Opciones de Buscatrazos…
Pathfinders: Buscatrazos:
Paths Trazados
Path Length Longitud de los trazados
Paths: {paths} Anchors: {anchors} Colors: {colors} Trazados: {paths} Anclas: {anchors} Colores: {colors}
Pattern Motivo
Pattern Editing Edición de motivo
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2048,6 +2048,7 @@
Pathfinder Options… Options Pathfinder…
Pathfinders: Pathfinders :
Paths Tracés
Path Length Longueur des tracés
Paths: {paths} Anchors: {anchors} Colors: {colors} Tracés : {paths} Points d’ancrage : {anchors} Couleurs : {colors}
Pattern Motif
Pattern Editing Modification du motif
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2512,6 +2512,7 @@
Pathfinder Options… Útvonalkezelő beállításai…
Pathfinders: Útvonalkezelők:
Paths Útvonalak
Path Length Útvonalak hossza
Paths: {paths} Anchors: {anchors} Colors: {colors} Útvonalak: {paths} Horgonypontok: {anchors} Színek: {colors}
Pattern Mintázat
Pattern Brush Options Mintázatecset beállításai
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2053,6 +2053,7 @@
Pathfinder Options… Opzioni elaborazione tracciati…
Pathfinders: Elaborazioni tracciati:
Paths Tracciati
Path Length Lunghezza dei tracciati
Paths: {paths} Anchors: {anchors} Colors: {colors} Tracciati: {paths} Ancoraggi: {anchors} Colori: {colors}
Pattern Motivo
Pattern Editing Modifica motivo
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2111,6 +2111,7 @@
Pathfinder Options… パスファインダーオプション…
Pathfinders: パスファインダー:
Paths パス
Path Length パスの長さ
Paths: {paths} Anchors: {anchors} Colors: {colors} パス:{paths} アンカー:{anchors} カラー:{colors}
Pattern Editing パターン編集
Pattern options are available in pattern editing mode. パターンオプションはパターン編集モードで使用できます。
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2106,6 +2106,7 @@
Pathfinder Options… 패스파인더 옵션…
Pathfinders: 패스파인더:
Paths 패스
Path Length 패스 길이
Paths: {paths} Anchors: {anchors} Colors: {colors} 패스: {paths} 앵커: {anchors} 색상: {colors}
Pattern Editing 패턴 편집
Pattern options are available in pattern editing mode. 패턴 옵션은 패턴 편집 모드에서 사용할 수 있습니다.
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2727,6 +2727,7 @@ theme Appearance Wygląd
Width Profile Profil szerokości
Objects Obiekty
Paths Ścieżki
Path Length Długość ścieżek
Add Guide Dodaj linię pomocniczą
Edit Selection Edytuj zaznaczenie
Recall Selection Przywołaj zaznaczenie
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2049,6 +2049,7 @@
Pathfinder Options… Параметры обработки контуров…
Pathfinders: Обработка контуров:
Paths Контуры
Path Length Длина контуров
Paths: {paths} Anchors: {anchors} Colors: {colors} Контуры: {paths} Опорные точки: {anchors} Цвета: {colors}
Pattern Узор
Pattern Editing Редактирование узора
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2045,6 +2045,7 @@
Pathfinder Options… Параметри обробки контурів…
Pathfinders: Обробка контурів:
Paths Контури
Path Length Довжина контурів
Paths: {paths} Anchors: {anchors} Colors: {colors} Контури: {paths} Опорні точки: {anchors} Кольори: {colors}
Pattern Візерунок
Pattern Editing Редагування візерунка
Can't render this file because it contains an unexpected character in line 718 and column 40.
+1
View File
@@ -2305,6 +2305,7 @@
Pathfinder Options… Tùy chọn Pathfinder…
Pathfinders: Pathfinder:
Paths Đường dẫn
Path Length Độ dài đường dẫn
Paths: {paths} Anchors: {anchors} Colors: {colors} Đường dẫn: {paths} Điểm neo: {anchors} Màu: {colors}
Pattern Họa tiết
Pattern Brush Options Tùy chọn cọ họa tiết
1 # Vietnamese (vi) catalog. Same format as zh-hant.tsv: context <TAB> source <TAB> translation
2305
2306
2307
2308
2309
2310
2311
+1
View File
@@ -1936,6 +1936,7 @@
Pathfinder Options… 路径查找器选项…
Pathfinders: 路径查找器:
Paths 路径
Path Length 路径长度
Paths: {paths} Anchors: {anchors} Colors: {colors} 路径:{paths} 锚点:{anchors} 颜色:{colors}
Pattern 图案
Pattern Editing 图案编辑
Can't render this file because it contains an unexpected character in line 2 and column 73.
+1
View File
@@ -2026,6 +2026,7 @@
Pathfinder Options… 路徑管理員選項…
Pathfinders: 路徑管理員:
Paths 路徑
Path Length 路徑長度
Paths: {paths} Anchors: {anchors} Colors: {colors} 路徑:{paths} 錨點:{anchors} 顏色:{colors}
Pattern 圖樣
Pattern Editing 圖樣編輯
Can't render this file because it contains an unexpected character in line 6 and column 47.
+4 -2
View File
@@ -2422,8 +2422,10 @@ result carries the same files as a zip (`{name: "<name>.zip", dataBase64}`, entr
`document.info {selectionOnly?, category?, format?: "text"}` adds `sections` (`[{id, title, rows: [[label, value]]}]`:
document, objects, graphicStyles, spotColors, patterns, gradients, symbols, fonts, fontDetails, linkedImages,
embeddedImages); `format: "text"` returns the plain-text report Document Info › Save… (`docInfo.save {path?}`) and
the package report write.
embeddedImages) and `pathLength` (pt: the total length of the paths, compound paths' pieces included and guides left
out, which objects lists as Path Length in the document's units, say for a cut line or an LED strip along the letters);
`format: "text"` returns the plain-text report Document Info › Save… (`docInfo.save {path?}`) and the package report
write.
```json
{"name":"run_command","arguments":{"command":"file.package","params":{"folder":"/tmp/handoff","copyFonts":false}}}