카드 하나를 대여섯 번 그린 일
더빙은 주인의 마스터를 그림으로 그대로 써(이 트랙 여섯 번째 강의). 새 언어로 다시 그리는 건 말이 실린 글자뿐이야. 피파 자신의 방송 카드, 그리고 모바일 영상 더빙에선 화자 이름, 합성 음성 표시, 자막, 오프닝 안내, 장 제목 글자까지. 나머지 픽셀은 전부 주인의 마스터야. 모바일 영상을 더빙하기 시작하고 첫 두 주 동안, 카드 영역마다 글자 크기, 굵기, 행간, 여백이 따로 붙어 있었어. 그때그때 번역하던 세션이 적어 넣은 값이고, 렌더러는 받은 대로 그렸지. 하나하나의 선택이 틀린 건 아니었어. 문제는 세션마다 그걸 전부 처음부터 다시 정했다는 거야. 한 더빙의 중국어, 일본어 카드는 다섯 번, 여섯 번 그려졌어. 다음 더빙은 언어마다 세 번씩 그려졌고, 주인이 세션 로그를 찍은 스크린샷과 함께 렌더 도중에 멈춰 세웠어. 스크린샷 속 세션은 금색 제목보다 커져 버린 자막을 보고 서열을 되돌리는 중이었어. 영어 시트까지 다시 채워서 이미 올라간 영어 영화의 영역이 밀릴 판이었고, 또 한 번 렌더하려고 글자를 50 px 로 키우는 중이었지.
주인의 판정은 카드 하나가 아니라 빠진 규칙을 겨냥했어.
한번 룰로 정하면? 저렇게 계속 실수를 하는 건 룰이 없다는 건데. 세션마다 처음부터 다시 한다는 거거든 — 아빠
정본은 하나, 다형성 세금은 자식이 내
판정은 모양까지 같이 왔어. 주인의 루트 클래스 원칙이야. 정본은 하나 두고, 다른 게 필요한 자식은 꼭 필요한 것만 재정의해서 그 값을 치르고, 나머지는 물려받아. beacon/card_type.py 는 더빙 캔버스 크기 1920×1080 에 맞춘 뿌리 척도 Latin 을 정의해. 역할은 여덟 개야. headline, lead, subtitle, body, cell-head, cell, label, caption. 역할마다 서열, 굵기, 명목 크기(그려질 수 있는 최대 크기), 줄어들 수 있는 바닥, 행간, 여백, 기본 잉크가 붙어. English 는 아무것도 안 바꾸는 자식이야. CJK 는 딱 하나, caption 의 바닥만 바꾸는 자식이고, Chinese, Japanese, Korean 은 그걸 물려받아. 언어를 하나 더하는 건 코드 붙은 클래스 하나를 더하는 거야. 숫자도 모듈 안에서 지어낸 게 아냐. 2026-10-08 부터 2026-10-19 까지 올라간 더빙에서 주인이 이미 받아들인 카드들의 값을 읽어 왔어. 세션끼리 엇갈린 곳에선 가운데를 잡고, 서열 사이에 눈에 보이는 간격을 남겼고.
글자를 키워온 측정
이 모듈에서 제일 배울 게 많은 건 중국어, 일본어 자식이 안 바꾸는 거야. 크기와 행간은 뿌리 그대로야. 판정 전 더빙들에서 중국어, 일본어 글자를 키운 건 전부 같은 원인이었고, 그 원인은 읽는 사람의 필요가 아니었어. 렌더가 끝나면 작업장은 자기 프레임을 다시 읽어서, 그린 잉크와 인코딩된 영상 속 잉크를 견줘(트랙 6 에 새로 붙은 강의 '어떤 글자도 네모로 타지 않아'가 그 계기 얘기야). 제목 크기의 한자는 멀쩡히 있는데도 엄격한 선 14 를 살짝 넘겼어. 어느 제목 서체는 14.3, 37 px 보통 굵기 한자는 15.4 에서 16.6, 42 px 굵은 한자는 14.03 에서 15.02. 정말로 빠진 글자는 44 에서 77, 네모는 51 에서 135 가 나와. 세션들은 멀쩡한 글자가 높게 읽히자 엄격한 선을 통과할 때까지 글자를 키우는 걸로 답했어. 카드가 서열을 잃은 경로가 그거야. 고친 건 계기 쪽이야. 획이 빽빽한 문자는 화면 높이의 56/1080 까지 느슨한 작은 글자 기준을 써.
그렇다고 그 선이 그냥 틀렸던 것도 아냐. 그래서 배울 거리야. 2026-10-18 에 가는 중국어 획이 14.6, 15.3 으로 그 선에 걸리면서 진짜 버그 하나가 드러났어. 굵은 글자용 서체 번호가 글꼴 묶음 안의 보통 굵기를 가리키고 있어서, 굵은 한자 줄이 전부 굵은 숫자, 굵은 가나 옆에 보통 굵기로 그려지고 있었던 거야. 문턱 가까이 앉은 계기는 진짜 결함과 멀쩡한 작업을 같이 잡아. 사람들이 그 값을 보고 제품을 바꾸기 시작하면, 먼저 그 값이 어느 쪽인지부터 물어.
크기는 기계가 정해
이제 영역은 마스터가 정한 것만 말해. 원래 잉크가 어디 앉아 있는지(bounds), 바탕과 잉크 색, 마스터 자체의 글자 안쪽 여백, 줄바꿈, 정렬, 글머리표. 그리고 role 을 이름으로 불러. font_size, weight, line_height, padding, paragraph_gap 을 직접 적은 영역은 거절돼. 재서 확인한 예외는 reason 을 단 override 에 살고, 실행할 때마다 출력되고 카드 잠금에 남아. 그다음 배치가 더빙 전체에 대해 크기를 한 번에 정해. 영역마다 자기 역할 범위 안에서 글이 들어가는 가장 큰 크기를 가져. 먼저 한 줄로, 안 되면 줄을 바꿔서. 바닥 밑으로 내려가야 하면 멈추고, 영역, 상자, 역할, 바닥을 짚으면서 '번역을 줄여'라고 말해. 한 카드 안에서 같은 역할은 한 크기로 그려. 그 역할의 영역들이 필요로 하는 크기 중 가장 작은 걸로. 서열은 불변 조건이야. 같은 카드에서 높은 서열은 낮은 서열보다 최소 2 px 커야 하고, 낮은 쪽이 양보해. 양보하다 자기 바닥 밑으로 내려가야 하면 실행은 멈추고, 위쪽 줄을 줄이라고 말해.
절차는 이걸 한 줄로 적어. 글자를 키우지 말고 번역을 줄여. 카드엔 마스터가 정한 방이 있고, 말이 그 방에 들어가야 해. 여섯 번째 강의가 말소리 한 줄 한 줄에 건 제약이랑 똑같아.
경계는 얼고, 올라간 언어는 다시 안 그려
언어를 처음 렌더하면 dub/<language>/card-lock.json 이 생겨. 영역마다 경계, 역할, 크기, 그리고 이유를 단 예외 전부. 나중 실행이 이미 그린 영역의 경계를 옮기면 멈춰. 경계는 마스터의 기하 구조고, 글자를 맞추는 수단이 절대 아니니까. 잘못 잰 영역은 거절 로그에 이유를 적고 잠금을 지워야만 풀려. 업로드 기록이 있는 언어는 아예 다시 안 그려. 거길 고치는 건 개정이야(트랙 4 에 새로 붙은 강의 '고친 판은 갈아 끼우지 않고 뒤를 이어'). 스크린샷 속 세션이 영어 시트를 다시 채우던 그 일이 이제는 그대로 거절돼.
문자 고유의 규칙도 따라왔어
척도를 정하고 나니, 아무도 고르지 않았는데 CJK 글자가 틀려 있던 다른 길들이 드러났어. 줄바꿈은 금칙을 따라. 닫는 부호나 작은 가나로는 줄을 시작하지 않아(보드는 2026-10-17, 자기만의 탐욕적 줄바꿈을 따로 쓰던 오프닝 안내는 2026-10-26). 2026-10-26 부터는 닫는 부호가 여럿 이어지면 앞 글자랑 통째로 같이 내려가고, 그 글자 바로 앞에 여는 괄호가 있으면 그것도 같이 내려가. 다만 여는 괄호 검사는 이렇게 끌어내릴 때만 돌아. 평범한 글자 앞에서 줄이 끊기면 여는 괄호가 줄 끝에 그대로 남을 수 있어. 그 변경의 커밋 메시지는 줄 끝에 여는 괄호를 절대 안 남긴다고 적었지만, 그 말은 이 경우에만 맞아. CJK 자막에서 숫자는 통째로 남고, 구분 기호에서 안 끊겨(2026-10-13). 그리고 글리프 관문은 이제 소리 내 읽는 자막만이 아니라 더빙이 태우는 모든 면을 봐(2026-10-17). 이름, 목소리 표시, 안내, 장 카드, 영역 하나하나까지. 전부 측정으로 찾았고, 모든 언어가 거쳐 그리는 코드 한 곳에서 한 번 고쳤어.
판정이 요구한 증명은 손보지 않은 렌더였어. 예전 더빙 둘을 중국어, 일본어로 다시 렌더했어. 카드 3 장에 영역 18 개, 카드 12 장에 영역 24 개. 한 번씩만 돌렸고, 되읽기 실패는 없었어. 자막이 제목보다 컸던 그 카드는 모든 언어에서 제목 38 위에 자막 33 으로 나왔고.