Merge pull request #2150 from AyberkA0/docinfo-path-length

Document Info: Objects gives the paths' total length (#1958)
This commit is contained in:
BFlat
2026-10-16 04:32:34 +07:00
committed by GitHub
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}}}