fix(mxl-compile,mxl-decompile): прозрачность у ссылочной картинки

Атрибут прозрачности живёт не только у картинки с данными: платформа пишет
<picture t="false" ref="v8ui:Имя"/>, причём t перед ref. Компилятор в этой
ветке его терял, декомпилятор не читал — в «Бухгалтерии предприятия» на
8.3.27 таких записей 67.

Заодно уточнена картина по конфигурациям: t="false" стоит у 11 135 картинок
БП, значения true не бывает нигде — включённую прозрачность платформа
выражает координатами пикселя, и вместе с t они не встречаются.
This commit is contained in:
Nick Shirokov
2026-08-15 20:30:15 +03:00
parent ce66b03586
commit 20bb45fb9e
8 changed files with 47 additions and 32 deletions
@@ -1,4 +1,4 @@
# mxl-compile v1.48 — Compile 1C spreadsheet from JSON
# mxl-compile v1.49 — Compile 1C spreadsheet from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -1612,7 +1612,7 @@ if ($def.pictures) {
}
if (-not $entry.Ref -and -not $entry.Data -and
($entry.Transparent -or $entry.PixelX)) {
[Console]::Error.WriteLine("pictures[$($pr.Name)]: 'transparent' and 'transparentPixel' require 'data'")
[Console]::Error.WriteLine("pictures[$($pr.Name)]: 'transparent' and 'transparentPixel' require 'ref' or 'data'")
exit 1
}
$pictureEntries += $entry
@@ -2572,13 +2572,15 @@ $picIdx = 0
foreach ($pic in $pictureEntries) {
X "`t<picture>"
X "`t`t<index>$picIdx</index>"
# Прозрачность записывается перед ссылкой и не зависит от того, где лежит картинка:
# в БП 8.3.27 таких ссылочных записей 67.
$attr = if ($pic.Transparent) { " t=`"$($pic.Transparent)`"" } else { '' }
if ($pic.PixelX) { $attr += " tx=`"$($pic.PixelX)`" ty=`"$($pic.PixelY)`"" }
if ($pic.Ref) {
X "`t`t<picture ref=`"$(Esc-Xml $pic.Ref)`"/>"
X "`t`t<picture$attr ref=`"$(Esc-Xml $pic.Ref)`"/>"
} elseif (-not $pic.Data) {
X "`t`t<picture/>"
} else {
$attr = if ($pic.Transparent) { " t=`"$($pic.Transparent)`"" } else { '' }
if ($pic.PixelX) { $attr += " tx=`"$($pic.PixelX)`" ty=`"$($pic.PixelY)`"" }
# Данные платформа переносит по строкам тем же переводом, что и весь файл, —
# в отличие от блоба настроек элемента управления, где перенос голый LF.
$parts = @("$($pic.Data)" -split "`r?`n")
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# mxl-compile v1.48 — Compile 1C spreadsheet from JSON
# mxl-compile v1.49 — Compile 1C spreadsheet from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import hashlib
@@ -1567,7 +1567,7 @@ def main():
entry['PixelX'] = str(int(pic_def['transparentPixel'].get('x', 0)))
entry['PixelY'] = str(int(pic_def['transparentPixel'].get('y', 0)))
if not entry['Ref'] and not entry['Data'] and (entry['Transparent'] or entry['PixelX']):
print(f"pictures[{pic_name}]: 'transparent' and 'transparentPixel' require 'data'", file=sys.stderr)
print(f"pictures[{pic_name}]: 'transparent' and 'transparentPixel' require 'ref' or 'data'", file=sys.stderr)
sys.exit(1)
picture_entries.append(entry)
picture_names[pic_name] = len(picture_entries)
@@ -2424,14 +2424,16 @@ def main():
for pic_i, pic in enumerate(picture_entries):
lines.append('\t<picture>')
lines.append(f'\t\t<index>{pic_i}</index>')
# Прозрачность записывается перед ссылкой и не зависит от того, где лежит картинка:
# в БП 8.3.27 таких ссылочных записей 67.
attr = f' t="{pic["Transparent"]}"' if pic['Transparent'] else ''
if pic['PixelX']:
attr += f' tx="{pic["PixelX"]}" ty="{pic["PixelY"]}"'
if pic['Ref']:
lines.append(f'\t\t<picture ref="{esc_xml(pic["Ref"])}"/>')
lines.append(f'\t\t<picture{attr} ref="{esc_xml(pic["Ref"])}"/>')
elif not pic['Data']:
lines.append('\t\t<picture/>')
else:
attr = f' t="{pic["Transparent"]}"' if pic['Transparent'] else ''
if pic['PixelX']:
attr += f' tx="{pic["PixelX"]}" ty="{pic["PixelY"]}"'
# Данные платформа переносит по строкам тем же переводом, что и весь файл, —
# в отличие от блоба настроек элемента управления, где перенос голый LF.
parts = str(pic['Data']).replace('\r\n', '\n').split('\n')
@@ -1,4 +1,4 @@
# mxl-decompile v1.27 — Decompile 1C spreadsheet to JSON
# mxl-decompile v1.28 — Decompile 1C spreadsheet to JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -283,14 +283,16 @@ foreach ($picNode in $root.SelectNodes("d:picture", $ns)) {
# System.Xml переводы строк в тексте не нормализует, а lxml нормализует: без этой
# замены порты дали бы разный JSON на одном и том же файле.
$entry["data"] = ($inner.InnerText -replace "`r`n", "`n").Trim()
if ($inner.HasAttribute('t')) { $entry["transparent"] = ($inner.GetAttribute('t') -ceq 'true') }
# Пиксель прозрачного цвета: координата внутри самой картинки (проверено —
# это не её размеры). В корпусе встречается без атрибута t.
if ($inner.HasAttribute('tx')) {
$entry["transparentPixel"] = [ordered]@{
x = [int]$inner.GetAttribute('tx')
y = [int]$inner.GetAttribute('ty')
}
}
# Прозрачность живёт и у ссылочной картинки (в БП 8.3.27 таких записей 67), поэтому
# читаем её вне ветвления. Пиксель прозрачного цвета — координата внутри картинки.
if ($entry.Count -gt 0 -and $inner.HasAttribute('t')) {
$entry["transparent"] = ($inner.GetAttribute('t') -ceq 'true')
}
if ($entry.Count -gt 0 -and $inner.HasAttribute('tx')) {
$entry["transparentPixel"] = [ordered]@{
x = [int]$inner.GetAttribute('tx')
y = [int]$inner.GetAttribute('ty')
}
}
$picturesOut[$name] = $entry
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# mxl-decompile v1.27 — Decompile 1C spreadsheet to JSON
# mxl-decompile v1.28 — Decompile 1C spreadsheet to JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -446,13 +446,13 @@ def main():
entry["ref"] = inner.get("ref")
elif (inner.text or "").strip():
entry["data"] = (inner.text or "").strip()
if inner.get("t") is not None:
entry["transparent"] = inner.get("t") == "true"
# Пиксель прозрачного цвета: координата внутри самой картинки (проверено —
# это не её размеры). В корпусе встречается без атрибута t.
if inner.get("tx") is not None:
entry["transparentPixel"] = OrderedDict([("x", int(inner.get("tx"))),
("y", int(inner.get("ty") or 0))])
# Прозрачность живёт и у ссылочной картинки (в БП 8.3.27 таких записей 67), поэтому
# читаем её вне ветвления. Пиксель прозрачного цвета — координата внутри картинки.
if entry and inner.get("t") is not None:
entry["transparent"] = inner.get("t") == "true"
if entry and inner.get("tx") is not None:
entry["transparentPixel"] = OrderedDict([("x", int(inner.get("tx"))),
("y", int(inner.get("ty") or 0))])
pictures_out[name] = entry
picture_key[pic_i] = name
+5
View File
@@ -744,6 +744,11 @@ AARnQUlBAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAA</picture>
в корпусе встречается `tx="97" ty="83"` при картинке 368×117, то есть Конфигуратор углом
не ограничен.
Прозрачность не привязана к тому, где лежит картинка: `t` пишется и у ссылочной записи, причём
ПЕРЕД `ref``<picture t="false" ref="v8ui:Имя"/>`. В «Бухгалтерии предприятия» на 8.3.27 таких
записей 67, а `t="false"` стоит у 11 135 картинок; значения `true` у этого атрибута не бывает
ни в одной проверенной конфигурации — включённую прозрачность выражают `tx`/`ty`.
## Рисунки
Рисунок — объект поверх сетки: картинка, фигура, надпись, диаграмма. Лежит в `<drawing>`
@@ -6,5 +6,5 @@
"areas": [{ "rows": [["Бланк"]] }]
},
"params": { "outputPath": "Template.xml" },
"expectError": "pictures[пусто]: 'transparent' and 'transparentPixel' require 'data'"
"expectError": "pictures[пусто]: 'transparent' and 'transparentPixel' require 'ref' or 'data'"
}
@@ -4,9 +4,9 @@
"columns": 2,
"pictures": {
"пусто": {},
"значок": { "ref": "v8ui:Стоп48", "transparent": false },
"точка": {
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==",
"transparent": true,
"transparentPixel": { "x": 3, "y": 5 }
}
},
@@ -43,7 +43,7 @@
<autoSize>false</autoSize>
<pictureSize>Stretch</pictureSize>
<zOrder>1</zOrder>
<pictureIndex>2</pictureIndex>
<pictureIndex>3</pictureIndex>
</drawing>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
@@ -58,6 +58,10 @@
</picture>
<picture>
<index>1</index>
<picture t="true" tx="3" ty="5">iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==</picture>
<picture t="false" ref="v8ui:Стоп48"/>
</picture>
<picture>
<index>2</index>
<picture tx="3" ty="5">iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg==</picture>
</picture>
</document>