아무 경보도 안 울리는 실패
2026-10-17, 단독 영상 하나가 "안녕하세요, 피파예요" 자막으로 시작했는데, 손 흔드는 이모지 자리에 네모가 찍혀 있었어. 파이프라인에선 아무것도 실패하지 않았어. 단계는 전부 깨끗하게 끝났고, 검사도 전부 통과했고, 그 네모는 영상 첫 1 초에 그대로 나갔지. 주인은 이걸 에피소드 하나의 오타로 넘기지 않았어.
이거 역시 고질적인 문제야. 어느 텍스트든 (특히 자막) 이모지 깨지는 거 영상 파이프라인에 새겨넣어야 해. 자막이나 카드에서 깨지는 이모지. 확인 절차까지 — 아빠
고질적이라는 말이 맞았어. 이유는 대본 하나가 아니라 그림 그리는 라이브러리의 성질에 있거든. PIL 은 절대 대체 글꼴로 넘어가지 않아. 글꼴에 없는 글자를 만나면 그 글꼴의 '글자 없음' 모양을 그려. 대개 네모고, 가끔은 빈칸이야. 그리고 아무 오류도 안 내. 전에도 있었어. 설명 영상의 Grassé 에 들어간 é(2026-09-02), 대화 에피소드 그래프 마디의 마이너스 부호 U+2212. 그때 주인이 "이 마이너스 부호 깨지는 거 여러번째야"라고 했지. 그리고 이번엔 👋. 게다가 작업장이 쓰는 이 라이브러리엔 복합 문자 배치 기능도 없어. 그래서 가족 이모지 조각을 전부 가진 글꼴이라도 그걸 사람 셋으로 따로 그리고, 국기는 글자 둘로, 키캡은 맨 숫자로 그려.
트랙 7 첫 강의는 종료 코드가 거짓말한다고 가르쳤어. 이건 같은 거짓말을 픽셀로 하는 거야. 글자가 제대로 나왔든 아니든 프레임은 프레임이고, 기하랑 타이밍이랑 파일 모양을 읽는 검사는 그 글자가 원래 어떻게 생겼어야 했는지 알 길이 없어.
독자가 보는 단위로 자르는 기본 도구 하나
처방은 에피소드별 땜질이 아니었어. 예전 땜질은 하나같이 대본 하나의 글자 하나만 고쳤거든. 대신 글자를 픽셀로 바꾸는 기본 도구 하나를 세웠어. beacon/glyphs.py 야(73186e1). 화면으로 가는 글은 이제 전부 여기를 거쳐. 자막, 챕터 카드와 안내 카드, 이름과 목소리 표시, 효과 캡션, 모든 더빙 카드, 배지, 작업장이 직접 그리는 썸네일 글자까지.
시작은 글을 그래핌으로 자르는 거야. 독자 눈에 글자 하나로 보이는 단위지. ZWJ 로 이은 이모지, 국기 짝, 키캡, 피부색, 결합 부호 같은 것들. Apple 이 이모지로 보여주는 그래핌은 CoreText 가 Apple Color Emoji 로 모양을 잡아 그려. 주인 화면이 그리는 방식 그대로고, 글줄의 기준선에 맞춰 앉혀. 나머지 그래핌은 다시 코드 포인트로 풀어. 코드 포인트마다 호출하는 쪽 글꼴 사슬에서 문자표에 그 코드 포인트가 진짜 들어 있는 첫 글꼴이 맡아. 한국어 글꼴, 그다음 악센트 붙은 라틴 문자용 Helvetica Neue, 그다음 가나와 한자용 Hiragino. 같은 글꼴로 가는 글자가 이어지면 한 묶음으로 같이 그려. 짐작도 없고 바꿔치기도 없어. 어떤 글꼴로도 온전히 못 그리는 그래핌은 절대 네모로 안 그리고, 비슷해 보이는 글자로 갈아 끼우지도 않아. 기본 도구가 거절해.
돈 쓰기 전의 관문
그리는 순간에 거절하는 것만으론 늦어. 그땐 이미 목소리 값을 냈으니까. 그래서 같은 도구가 더 일찍 질문 하나에 답해. 이 제작물이 화면에 올릴 글을 전부 실제로 그릴 수 있어? 커버리지 관문은 돈이 나가기 전에 돌아. 대화 파이프라인과 여행 파이프라인에선 cut 이 주인이 읽는 대본 시트 끝에 판정을 적고, beacon mobile approve, revoice, picture, dub-voice, dub-cards 는 어떤 글꼴도 못 그리는 그래핌을 위치, 그래핌, 코드 포인트까지 짚어서 거절해. 대본을 쓰는 시리즈는 자기 사전 검사에서 같은 관문을 돌려. 처방은 절차에 적혀 있어. 그 글을 고쳐 써. 글자를 몰래 빼거나 바꾸지 마.
관문 첫 판엔 이 퀘스트가 자꾸 찾아내는 바로 그 종류의 구멍이 있었어. 누가 목록에 적어둔 자리만 지켰거든. 더빙의 소리 나는 자막, 카드, 배지. 그 구멍은 타이포그래피 보드를 다시 그려야 했던 첫 더빙이 드러냈어. 직접 쓴 더빙은 이름, 목소리 표시, 디스클레이머, 오프닝 안내문, 챕터 카드, 번역한 영역 전부를 화면에 태워. 그것들 다 기본 도구로 그렸는데, 돈 쓰기 전에 관문을 거친 것도, 다시 읽기용으로 기록된 것도 하나도 없었어. 목록은 그날 저녁에 늘어났어(a5000e3). 기본 도구 하나가 글을 어떻게 그릴지는 보장해. 그런데 관문이 글이 그려지는 곳을 전부 알고 있다는 건 보장 못 해.
인코딩된 프레임에서 잉크를 다시 읽어
관문은 그래핌마다 글꼴이 있다는 걸 증명해. 배달된 영상에 그게 보인다는 건 증명 못 하고. 그래서 기본 도구가 그린 이모지 하나하나, 그리고 대체 글꼴로 그린 글자 묶음 하나하나가 상자 위치와 함께 기록되고, 렌더가 끝나면 out/glyph-readback.json 이 디코딩한 프레임을 그 자리에 그렸던 잉크와 비교해. 불투명한 잉크만 비교하고, 안티에일리어싱된 가장자리는 1 픽셀 깎아내. 그래서 자막 밑 배경이 뭐든 상관없고, 색 없는 이모지도 색 있는 것만큼 잘 확인돼. #483 표본으로 잰 값이 이래. 제대로 된 글자는 평균 차이 0.8 에서 5.1, 네모나 빈칸은 51 에서 135, 기준선은 14. 하나라도 빗나가면 비디오 단계가 멈춰. OCR 은 이모지를 아예 못 읽어서 탈락했고, 네모 모양 목록은 글꼴마다 하나씩 필요해서 탈락했어.
그다음엔 그 측정 도구 자체를 재야 했어. 같은 영상의 중국어 더빙이 카드 876 장 중 466 장에서 다시 읽기에 걸려 멈췄는데, 빠진 글자는 하나도 없었거든. 25 에서 32 픽셀짜리 이름표와 보드 본문은 가장자리를 깎고 나면 불투명한 잉크가 얼마 안 남고, 크로마 서브샘플링이 남은 것마저 번지게 해. 그래서 멀쩡히 있는 글자가 14 에서 21 로 읽혔고, 아예 없는 오버레이는 44 에서 77 로 읽혔어. 이제 작은 글자는 자기 기준선 26 을 따로 받고, 1/24 초보다 짧은 마스크는 실패가 아니라 건너뛴 걸로 적혀(a8de3cb). 기준은 길이 하나뿐이야. 계기가 된 건 두 장면 사이의 3 ms 짜리 이음매였고, 그건 디코딩된 프레임에 하나도 안 걸렸어. 그런데 그만큼 짧은 구간도 프레임 하나를 품을 수는 있고, 그래도 똑같이 건너뛰어. 다시 읽기는 애초에 찾으려던 것도 아닌 결함 하나도 잡았어. 굵은 중국어 줄 전부와 굵은 일본어 줄의 한자 전부가 보통 굵기 글꼴로 그려지고 있었던 거야. 글꼴 묶음 안의 번호가 엉뚱한 굵기를 가리키고 있었고, 가는 획이 기준선을 살짝 넘겨 읽혔어(971ad1f). 그리고 보정이 어긋난 게 하나 있었는데, 그 꼬리가 길었어. 빽빽한 한자와 가나는 멀쩡히 있어도 엄격한 기준선을 살짝 넘겨 읽혔고, 세션들은 통과할 때까지 글자를 키우는 걸로 답했어. 그러다 카드가 위계를 잃었지. 그게 어떻게 끝났는지는 트랙 5 강의 "픽셀 말고 역할을 골라"가 얘기해.
새 코드에서도 선을 지키기
기본 도구는 아무도 그걸 비켜 가서 직접 그리지 않을 때만 통해. 그래서 테스트 하나가 2026-10-18 이후 날짜의 브리프 스크립트를 전부 훑어. 자기 글꼴을 직접 만들거나 글을 직접 그리는 스크립트가 있으면, 공용 호출을 쓰라는 말과 함께 실패해. 기본 도구 이전의 브리프는 돌았던 그대로 둬. 그 영상들을 만든 기록이니까. 이 강의의 패턴은 이 넷이 전부야. 모든 글에 길 하나, 돈 쓰기 전에 정확한 글자를 짚는 거절, 배달된 픽셀을 재는 다시 읽기, 그리고 다음 스크립트를 그 길 위에 붙잡아 두는 규칙.