03번 B' 정상 동작: 가로 3단 카드 + overflow 해소 + 하단 균형

- block_assembler B': 카드 3개 이상 + 이미지 없음 → 가로(row) 배치
- block_assembler B': section title이 카드 제목, D1은 카드 내 bold 불릿
- block_assembler: overflow:auto → overflow:hidden, [핵심요약:] 마커 필터
- block_assembler: \x01 바이트 수정
- pipeline: Selenium 실측 기반 zone 간 재배분 (allocated-scrollHeight로 slack 계산)
- pipeline: surplus 최대 50%만 이전 (하단 최소 공간 보장)
- pipeline: bottom_left/bottom_right → Selenium bottom zone 매핑
- kei_client: 상단은 팝업 대상 제외, 하단에서만 팝업 분리

결과: 02번/03번 모두 overflow 없이 정상 출력

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 10:32:14 +09:00
parent bc7c08e575
commit b13df8b176
4 changed files with 79 additions and 1319 deletions

View File

@@ -588,14 +588,40 @@ async def generate_slide(
)
fit_analysis = redistribute(fit_analysis, containers_dict)
# Type B: zone 간 재배분
# Type B: Selenium 실측 기반 zone 간 재배분
if context.analysis.layout_template in ("B", "B'"):
deficit_roles = [(r, rf.shortfall_px) for r, rf in fit_analysis.roles.items() if rf.shortfall_px > 0]
surplus_roles = [(r, abs(rf.shortfall_px)) for r, rf in fit_analysis.roles.items() if rf.shortfall_px < -8]
# Selenium 측정에서 실제 overflow/여유를 가져옴
zone_to_roles = {}
for role, ci in updated_containers.items():
# Selenium CSS 클래스 매핑: bottom_left/bottom_right → bottom
z = ci.zone
if z in ("bottom_left", "bottom_right"):
z = "bottom"
if z not in zone_to_roles:
zone_to_roles[z] = []
zone_to_roles[z].append(role)
deficit_roles = []
surplus_roles = []
for zn, zd in filled_measurement.get("zones", {}).items():
excess = zd.get("excess_px", 0)
scroll_h = zd.get("scrollHeight", 0)
roles_in_zone = zone_to_roles.get(zn, [])
if excess > 0:
for r in roles_in_zone:
deficit_roles.append((r, float(excess)))
elif roles_in_zone:
# 실제 콘텐츠(scrollHeight)와 할당 높이 차이로 여유 계산
allocated = sum(updated_containers[r].height_px for r in roles_in_zone if r in updated_containers)
slack = allocated - scroll_h
if slack > 8:
for r in roles_in_zone:
surplus_roles.append((r, float(slack)))
if deficit_roles and surplus_roles:
total_deficit = sum(d for _, d in deficit_roles)
total_surplus = sum(s for _, s in surplus_roles)
transferable = min(total_deficit, total_surplus)
# surplus의 최대 50%만 이전 — 하단 최소 공간 보장
transferable = min(total_deficit, total_surplus * 0.5)
if transferable > 0:
for role, deficit in deficit_roles:
share = transferable * (deficit / total_deficit)