fix: 标题换行计算使用原始font_size,与CSS预览一致
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2m35s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 3m2s
AI Code Review / AI Code Review (pull_request) Successful in 4m5s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m16s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m50s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 4m38s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 4m44s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m39s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 5m54s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 3m57s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 7m27s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m4s
CI/CD Pipeline / CI Gate (pull_request) Successful in 26s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 3m0s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 4m0s
CI/CD Pipeline / Production Browser E2E (pull_request) Failing after 482h43m38s
CI/CD Pipeline / Build Production Worker Image (pull_request) Failing after 482h43m40s
CI/CD Pipeline / Build Production Web Image (pull_request) Failing after 482h43m40s
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 482h48m32s
CI/CD Pipeline / Canary Release to Production (pull_request) Failing after 482h43m39s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 482h48m33s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 482h51m6s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 482h51m6s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 482h51m8s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 482h51m10s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 482h51m10s
CI/CD Pipeline / Deploy Production (pull_request) Failing after 483h17m38s
CI/CD Pipeline / Build Production API Image (pull_request) Failing after 483h17m39s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 483h22m32s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 483h25m5s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 483h25m9s

- 移除 _wrap_title_text 中对 _compensate_ass_fontsize 的调用
- 换行计算直接使用 font_size,1.35x补偿仅用于ASS Fontsize渲染
- 修复 font_size=113 时每行字数从6个变为8个,与CSS预览一致
- 新增3个测试验证换行逻辑正确性

Fixes #任务C
This commit is contained in:
xiaoxia
2026-08-27 12:34:23 +08:00
parent 1330b436dc
commit 8edc124b89
2 changed files with 45 additions and 3 deletions
+3 -3
View File
@@ -224,8 +224,8 @@ def _wrap_title_text(
if available_width <= 0:
return text
# 换行宽度必须与实际渲染(补偿后的 ASS Fontsize)一致,否则换行位置会错位
ass_font_size = _compensate_ass_fontsize(font_size)
# 换行计算使用原始 font_size,与 CSS 预览一致;1.35x 补偿仅用于 ASS Fontsize 渲染
# 先按已有 \N 分段,每段独立自动换行,最后用 \N 拼回
segments = text.split("\\N")
@@ -238,7 +238,7 @@ def _wrap_title_text(
for ch in seg:
# CJK 字符按全角估算,其他按半角
char_width = float(ass_font_size) if ord(ch) > 0x2E80 else ass_font_size * 0.55
char_width = float(font_size) if ord(ch) > 0x2E80 else font_size * 0.55
if current_width + char_width > available_width and current_line:
lines.append(current_line)
@@ -15,6 +15,7 @@ from packages.domain.ass_subtitle_builder import (
TITLE_MARGIN_BOTTOM,
TITLE_MARGIN_SIDE,
TITLE_MARGIN_TOP,
_wrap_title_text,
build_ass_content,
build_ass_style,
escape_ass_text,
@@ -579,3 +580,44 @@ class TestConstants:
assert isinstance(TITLE_MARGIN_TOP, int)
assert isinstance(TITLE_MARGIN_BOTTOM, int)
assert isinstance(TITLE_MARGIN_SIDE, int)
# ============================================================
# _wrap_title_text 换行逻辑验证
# ============================================================
class TestWrapTitleTextFontSizeConsistency:
"""验证换行计算使用原始 font_size,与 CSS 预览一致。"""
def test_font_size_113_uses_original_not_compensated(self):
"""font_size=113 时,每行应容纳8个字(113px字宽),而非6个字(153px字宽)。"""
# 标题"永康拾掇脚阔头"共7个字
# 可用宽度 = 1080 - 60 - 60 = 960px
# 用 font_size=113:char_width=113,960/113 ≈ 8.5,每行8个字
# 7个字 < 8个字,应该在一行内
title = "永康拾掇脚阔头"
result = _wrap_title_text(title, video_width=1080, font_size=113, margin_l=60, margin_r=60)
# 不应该有换行
assert "\\N" not in result
assert result == title
def test_long_title_wraps_correctly(self):
"""长标题应该按 font_size 字宽正确换行。"""
# 16个中文字,每行8个字,应该换行为2行
title = "永康拾掇脚阔头来一个笑一个哈哈哈"
result = _wrap_title_text(title, video_width=1080, font_size=113, margin_l=60, margin_r=60)
# 应该有一个换行
assert result.count("\\N") == 1
# 每行8个字
lines = result.split("\\N")
assert len(lines) == 2
assert len(lines[0]) == 8
assert len(lines[1]) == 8
def test_mixed_cjk_and_ascii(self):
"""混合中英文时,英文按半角宽度计算。"""
# "测试test" = 2个中文(2*113=226) + 4个英文(4*113*0.55=248.6) = 474.6px
title = "测试test"
result = _wrap_title_text(title, video_width=1080, font_size=113, margin_l=60, margin_r=60)
# 总宽度474.6px < 960px,应该在一行内
assert "\\N" not in result