summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/macos-package.sh64
1 files changed, 59 insertions, 5 deletions
diff --git a/scripts/macos-package.sh b/scripts/macos-package.sh
index 3255898..ebe9e2a 100755
--- a/scripts/macos-package.sh
+++ b/scripts/macos-package.sh
@@ -48,6 +48,27 @@ sha256() {
printf '%s\n' "${output%% *}"
}
+utf8_char_count() {
+ # 不依赖 locale 的 UTF-8 码点计数:只数每个码点的首字节
+ # (ASCII <128,或 110xxxxx/1110xxxx/11110xxx 前导字节),续字节 10xxxxxx 忽略。
+ printf '%s' "$1" | od -An -t u1 | awk '
+ { for (i = 1; i <= NF; i++) { b = $i; if (b < 128 || (b >= 192 && b < 248)) n++ } }
+ END { print n + 0 }'
+}
+
+png_dimensions() {
+ # 从 PNG IHDR 读取宽高(大端 4 字节,偏移 16/20),只依赖 od。
+ local bytes size
+ bytes="$(od -An -t u1 -j 16 -N 8 "$1" | tr -s ' ' '\n' | sed '/^$/d' | paste -sd' ')"
+ read -r b0 b1 b2 b3 b4 b5 b6 b7 <<< "$bytes"
+ if [[ -z "${b7:-}" ]]; then
+ return 1
+ fi
+ printf '%s %s\n' \
+ "$(( b0 * 16777216 + b1 * 65536 + b2 * 256 + b3 ))" \
+ "$(( b4 * 16777216 + b5 * 65536 + b6 * 256 + b7 ))"
+}
+
write_launcher() {
local launcher_path="$1"
cat > "$launcher_path" <<'EOF'
@@ -276,17 +297,50 @@ for rid in osx-arm64 osx-x64; do
exit 1
fi
done
+ # CJK 清单不再硬编码行数:与图集网格自洽(16 列,行数覆盖字符数且无空行),
+ # 并校验非空、每行恰 1 个字符、字符唯一,避免图集增长后打包悄悄过期。
+ if [[ ! -s "$app_dir/Contents/MacOS/Assets/cjk-glyphs.txt" ]]; then
+ printf 'BLOCKED: packaged CJK manifest for %s is empty\n' "$rid" >&2
+ exit 1
+ fi
mapfile -t cjk_manifest_lines < "$app_dir/Contents/MacOS/Assets/cjk-glyphs.txt"
- if [[ "${#cjk_manifest_lines[@]}" -ne 188 ]]; then
- printf 'BLOCKED: packaged CJK manifest for %s contains %s lines; expected 188\n' "$rid" "${#cjk_manifest_lines[@]}" >&2
+ if [[ "${#cjk_manifest_lines[@]}" -eq 0 ]]; then
+ printf 'BLOCKED: packaged CJK manifest for %s is empty\n' "$rid" >&2
exit 1
fi
- for cjk_manifest_line in "${cjk_manifest_lines[@]}"; do
- if [[ ${#cjk_manifest_line} -ne 1 ]]; then
- printf 'BLOCKED: packaged CJK manifest for %s contains a line that is not one character\n' "$rid" >&2
+ declare -A cjk_seen_characters=()
+ for index in "${!cjk_manifest_lines[@]}"; do
+ cjk_manifest_line="${cjk_manifest_lines[$index]}"
+ if [[ "$(utf8_char_count "$cjk_manifest_line")" -ne 1 ]]; then
+ printf 'BLOCKED: packaged CJK manifest for %s line %s is not one character\n' "$rid" "$((index + 1))" >&2
exit 1
fi
+ if [[ "${cjk_seen_characters[$cjk_manifest_line]+present}" ]]; then
+ printf 'BLOCKED: packaged CJK manifest for %s has a duplicate character on line %s\n' "$rid" "$((index + 1))" >&2
+ exit 1
+ fi
+ cjk_seen_characters[$cjk_manifest_line]=1
done
+ cjk_character_count="${#cjk_manifest_lines[@]}"
+ cjk_cell_pixels=24
+ cjk_expected_columns=16
+ if ! read -r cjk_atlas_width cjk_atlas_height < <(png_dimensions "$app_dir/Contents/MacOS/Assets/cjk-glyph-atlas.png"); then
+ printf 'BLOCKED: cannot read packaged CJK atlas dimensions for %s\n' "$rid" >&2
+ exit 1
+ fi
+ cjk_columns=$(( cjk_atlas_width / cjk_cell_pixels ))
+ cjk_rows=$(( cjk_atlas_height / cjk_cell_pixels ))
+ cjk_capacity=$(( cjk_columns * cjk_rows ))
+ if (( cjk_columns != cjk_expected_columns )); then
+ printf 'BLOCKED: packaged CJK atlas for %s has %s columns; expected %s\n' \
+ "$rid" "$cjk_columns" "$cjk_expected_columns" >&2
+ exit 1
+ fi
+ if (( cjk_capacity < cjk_character_count || cjk_capacity - cjk_character_count >= cjk_columns )); then
+ printf 'BLOCKED: packaged CJK atlas grid %sx%s (%s cells) is inconsistent with manifest %s characters for %s\n' \
+ "$cjk_columns" "$cjk_rows" "$cjk_capacity" "$cjk_character_count" "$rid" >&2
+ exit 1
+ fi
if ! file -b "$app_dir/Contents/MacOS/LivingVillage.Desktop" >> "$mach_o_report"; then
printf 'BLOCKED: failed to inspect bundled apphost for %s\n' "$rid" >&2