V'-2/V'-4 수정: 표 행 수 계산 + footer 최소 높이 + 이미지 비율
- V'-2: 표 공간 계산에 V'-4(결론 위까지 채움) 높이 반영 → Kei에게 정확한 행 수 전달 (1행 → 5행) - V'-2: 이미지 높이를 실제 비율로 계산 (sub_layout 고정값 대신) → 200/2.73 = 73px (기존 172px → 공간 100px 확보) - footer 최소 높이: design tokens 기반 동적 계산 → weight 0.05일 때 26px → 53px 보장 - assemble_stage2: 이미지 높이도 실제 비율 반영 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -716,19 +716,39 @@ async def generate_slide(
|
||||
popup = next((p for p in popups if pr in p.get("title", "")), None)
|
||||
if not popup:
|
||||
continue
|
||||
# 공란 계산: after(updated_containers) 기준
|
||||
after_ci = updated_containers.get(role)
|
||||
after_h = after_ci.height_px if after_ci else float(text_sc["height_px"])
|
||||
# after 높이에서 제목+keymsg+padding 제외 → 텍스트 영역
|
||||
# 공란 계산: V'-4 적용 후 높이 (결론 바로 위까지 채움)
|
||||
from src.fit_verifier import _load_design_tokens as _ldt_v2
|
||||
_v2_tokens = _ldt_v2()
|
||||
_v2_slide_h = _v2_tokens.get("slide_height", 720)
|
||||
_v2_pad = _v2_tokens["spacing_page"]
|
||||
_v2_header_h = _v2_tokens.get("header_height", 66)
|
||||
_v2_gap = _v2_tokens["spacing_block"]
|
||||
_v2_gap_small = _v2_tokens["spacing_small"]
|
||||
_v2_concl_ci = updated_containers.get("결론") or next((ci for r, ci in updated_containers.items() if ci.zone == "footer"), None)
|
||||
_v2_concl_h = _v2_concl_ci.height_px if _v2_concl_ci else 53
|
||||
_v2_ft_top = _v2_slide_h - _v2_pad - _v2_concl_h - _v2_gap
|
||||
_v2_column_bottom = _v2_ft_top - _v2_gap
|
||||
_v2_bg_ci = next((ci for r, ci in updated_containers.items() if ci.zone == "body" and r != role), None)
|
||||
_v2_bg_h = _v2_bg_ci.height_px if _v2_bg_ci else 0
|
||||
_v2_core_top = _v2_pad + _v2_header_h + _v2_gap + _v2_bg_h + _v2_gap_small
|
||||
after_h = _v2_column_bottom - _v2_core_top # 결론 위까지의 실제 본심 높이
|
||||
keymsg_h = 0
|
||||
for sc in role_scs:
|
||||
if sc.get("name") == "keymsg":
|
||||
keymsg_h = float(sc.get("height_px", 0))
|
||||
title_h = (fs + 1) * 1.5 + 4
|
||||
content_area_h = after_h - 16 - title_h - keymsg_h - 8 # pad*2 + gap
|
||||
# 이미지 높이: 실제 비율로 계산
|
||||
svg_sc = next((sc for sc in role_scs if sc.get("name") == "svg"), None)
|
||||
img_h = 0
|
||||
if svg_sc:
|
||||
svg_w = float(svg_sc.get("width_px", 200))
|
||||
img_ratio = next((img.get("ratio", 1) for img in (context.slide_images or []) if img.get("b64")), 1)
|
||||
img_h = svg_w / img_ratio if img_ratio > 0 else float(svg_sc.get("height_px", 0))
|
||||
text_lines = len([l for l in st_text.split("\n") if l.strip() and not l.strip().startswith("[팝업:") and not l.strip().startswith("[이미지:") and not l.strip().lstrip("• ").startswith("출처:")])
|
||||
text_h_used = text_lines * fs * 1.55
|
||||
available_h = content_area_h - text_h_used
|
||||
# 표 공간 = 전체 - 제목 - max(이미지,텍스트) - keymsg - padding
|
||||
upper_h = max(img_h, text_h_used)
|
||||
available_h = after_h - 16 - title_h - upper_h - keymsg_h - 8
|
||||
available_w = float(text_sc["width_px"])
|
||||
if available_h < fs * 3:
|
||||
continue # 공간 부족하면 건너뜀
|
||||
|
||||
@@ -400,6 +400,12 @@ def calculate_container_specs(
|
||||
# 비중 비율로 높이 할당
|
||||
ratio = weight / total_weight
|
||||
height_px = max(min_block_h, int(available * ratio))
|
||||
# footer는 최소 높이 보장 (font_size * line_height + padding)
|
||||
if zone_name == "footer":
|
||||
from src.fit_verifier import _load_design_tokens as _ldt_footer
|
||||
_ft = _ldt_footer()
|
||||
_footer_min = int(14 * _ft.get("line_height_ko", 1.7) + _ft["spacing_page"])
|
||||
height_px = max(_footer_min, height_px)
|
||||
|
||||
# 블록 내부 제약 계산 — topic당 높이로 판단
|
||||
topic_count = max(1, len(topic_ids))
|
||||
|
||||
Reference in New Issue
Block a user