Handwriting → PDF
손글씨 샘플로부터 실제 .ttf 폰트를 만들고, 이를 사용해 텍스트를 작성자 손글씨처럼 보이는 PDF로 렌더링합니다. 모든 작업은 로컬에서 실행되며, 샘플이 기기를 떠나는 일은 절대 없습니다.
사용자에게 처음에 반드시 알려야 할 엄중한 사실: 이것은 사진 한 장으로 중국어 3,000자를 창조해내는 AI가 아닙니다. 폰트는 샘플에 실제로 쓰인 문자만 포함할 수 있습니다. 따라서: 로마자 텍스트는 약 60–100자의 작성된 문자가 필요하고, 중국어 텍스트는 문서에 사용된 모든 고유 문자가 필요합니다 (몇 백 자는 일반적이고, 수천 자는 비현실적입니다). 누락된 문자는 중립적인 손글씨 대체 폰트로 그려지며 보고됩니다 — 절대 조용히 만들어내지 않습니다.
0. 도구 위치 확인
스킬 디렉터리는 이 SKILL.md 파일이 들어 있는 폴더입니다. CLI는 다음 런처를 통해 호출합니다:
- Windows:
<skill>\bin\hwpdf.cmd <명령어> ... - macOS/Linux:
<skill>/bin/hwpdf <명령어> ...
런처가 없으면 먼저 설치하거나(<skill>\install.ps1 (Windows), <skill>/install.sh (기타)), 또는 의존성이 이미 설치되어 있을 때 python <skill>/scripts/hwpdf.py <명령어> ...를 실행합니다. 다른 모든 작업 전에 hwpdf doctor가 status ok를 출력해야 합니다. 그렇지 않으면 설치 프로그램을 실행하고 의존성 오류를 보고해야 하며, 임시로 해결하지 마십시오.
1. 입력 방식 선택
| 상황 | 방식 |
|---|---|
| 기본값: 사용자가 실제 손글씨 문서를 원함 | A. 연습지 (최고 품질, 완전 자동 셀 매핑) |
| 사용자가 이미 손글씨가 포함된 PDF를 제공함 | D. PDF 입력 — 먼저 임베디드 폰트를 시도, 실패하면 텍스트 레이어에서 글리프 수집 |
| 사용자가 이미 손글씨 사진 한 장을 보냈고 더 쓰기를 원하지 않음 | B. 자유 형식 사진 (에이전트가 잘라낸 글리프에 레이블 지정) |
사용자가 이미 자신의 .ttf/.otf 파일을 가지고 있음 | C. 폰트만 — 4단계로 건너뛴 후 프로필 저장 |
무엇을 생성하기 전에 문서 텍스트를 요청하세요: 연습지는 문서가 사용하는 문자만 필요하므로, 짧은 텍스트는 짧은 연습지로 이어집니다.
방식 A — 연습지 (권장)
- 대상 텍스트를 UTF-8 파일(예:
hw/doc.txt)에 저장한 후 다음 실행:
이 명령은hwpdf template --text-file hw/doc.txt -d hwhw/template.pdf(및hw/template.json)를 생성합니다. 페이지당 30개 셀, 30개의 고유 문자마다 한 페이지씩 생성됩니다. 사용자에게 정확히 다음을 알리세요:- 100% / 실제 크기로 인쇄 ("용지에 맞춤" 절대 안 됨);
- 모든 밝은 회색 글리프를 진한 펜(0.5mm 이상)으로 따라 그리기 — 볼펜은 너무 가벼움;
- 네 개의 검은색 모서리 사각형을 보이게 하고 표시하지 않기;
- 각 페이지를 위에서 균일한 조명으로 촬영하고, 프레임을 채우며, 파일을 보내기.
- 사진을 페이지 순서대로 스캔:
모서리 사각형에서 원근 및 작은 회전이 보정됩니다. 출력:hwpdf scan hw/page1.jpg hw/page2.jpg -d hwhw/glyphs.json및hw/glyphs/*.png. 셀이 "누락"으로 반환되면 글리프가 작성되지 않았거나 너무 희미한 것입니다 — 어떤 문자인지 알리고 해당 셀만 다시 촬영할 것을 제안하세요. - 폰트 빌드:
hwpdf font -d hw --family "Alex Hand" -o hw/font.ttf - 렌더링 전 커버리지 확인:
0이 아닌 종료 코드 /hwpdf coverage --font hw/font.ttf --text-file hw/doc.txtmissing목록은 해당 문자에 대한 글리프가 없음을 의미합니다. 해당 문자만을 위한 작은 두 번째 시트를 작성하고 병합하여 해결:
그렇지 않으면 중립 대체를 수락하고 명시적으로 알립니다.hwpdf template --chars "<누락된 문자>" -d hw2 hwpdf scan hw2/page1.jpg -d hw --append hwpdf font -d hw -o hw/font.ttf - 렌더링:
hwpdf render --font hw/font.ttf --text-file hw/doc.txt -o hw/letter.pdf --size 12 --paper ruled - 결과를 확인하세요. PDF 페이지를 PNG로 렌더링하고 시각적으로 검사:
판단: 획이 너무 가늘거나/굵은지, 줄 간격이 너무 좁은지, 문자가 충돌하거나 여백 밖으로 나가는지, 명백히 잘못된 것이 있는지.hwpdf preview --pdf hw/letter.pdf -d hw/preview --dpi 150--size,--leading,--jitter,--weight(폰트 재빌드),--paper none|ruled|grid로 수정.
방식 D — 사용자가 손글씨가 포함된 PDF를 제공하는 경우
작동할 때 가장 빠른 경로입니다. PDF에 이미 모양이 포함되어 있기 때문입니다.
- 임베디드 폰트 추출 시도 (최상: 전체 글리프 세트, 다시 그릴 필요 없음):
좋은 출력 = 실제 문자 맵이 있는(hwpdf extract-font --pdf user.pdf -d hwmapped> 20)hw/fonts/디렉터리의.ttf/.otf파일. 보고서에 "subset/cid"라고 나오면 건너뜁니다. - 그렇지 않고, PDF에 텍스트 레이어가 있는 경우(문자를 선택할 수 있을 때), 렌더링된 페이지에서 글리프를 수집합니다 — 텍스트 레이어가 레이블을 제공하고, 래스터가 잉크를 제공합니다:
hwpdf pdf-specimen --pdf user.pdf -d hw # --font-name "<font family>"를 추가하면 해당 폰트만 유지 hwpdf font -d hw --family "Alex Hand" -o hw/font.ttf - 그렇지 않으면 스캔 이미지입니다:
hwpdf rasterize --pdf user.pdf -d hw/pages→ 페이지 이미지에 방식 B 적용, 또는 연습지(방식 A) 요청. - 결과를 프로필로 저장(아래 5단계)한 후 렌더링.
방식 B — 자유 형식 사진
hwpdf segment hw/photo.jpg -d hw→hw/contact.png(번호가 매겨진 썸네일) +hw/crops/.hw/contact.png를 열고 번호를 읽습니다.hw/labels.json을 다음과 같이 작성:{"0":"A","1":"b",...}, 또는hwpdf label -d hw --pair "0=A 1=B 2=''"사용 (""는 점, 얼룩, 페이지 가장자리 또는 두 획으로 그려진 문자의 조각과 같은 블롭을 버립니다).hwpdf font -d hw --labels hw/labels.json -o hw/font.ttf, 그런 다음 위의 4–6단계.
연속/필기체 및 다획 CJK 문자는 이 방식을 오류하기 쉽게 만듭니다. 결과가 나빠 보이면 방식 A로 전환하고 이유를 설명하세요.
방식 C — 사용자가 이미 폰트를 가지고 있는 경우
hwpdf coverage 및 hwpdf render --font <해당 파일>로 건너뛰고 프로필을 저장합니다.
프로필 — 안정적이고 재사용 가능한 방법
프로필은 출력물의 모양을 재현하는 데 필요한 모든 것을 고정합니다: 폰트 파일(SHA-256과 함께 프로필에 복사됨), 기본값, 그리고 바로 붙여넣을 수 있는 프롬프트.
hwpdf profile save --name alex --font hw/font.ttf --source "사용자 손글씨 pdf"
hwpdf profile list
hwpdf render --profile alex --text-file letter.txt -o letter.pdf
- 프로필은
~/.handwriting-pdf/profiles/<name>/디렉터리에 저장됩니다 (profile.json,font.ttf,PROMPT.md).HWPDF_PROFILE_DIR을 설정하여 위치를 변경할 수 있습니다. PROMPT.md는 사용자를 위해 작성됩니다: 어떤 에이전트나 기계에 붙여넣으면 동일한 폰트와 동일한 레이아웃 기본값을 호출합니다.- 모양을 반복적으로 개선하려면? 한 번에 하나씩 변경 — 렌더링,
preview, 비교, 그런 다음hwpdf profile save --name alex --font hw/font.ttf --size ... --paper ...로 새 기본값으로 만듭니다.font --weight 1은 더 굵은 획을 다시 빌드합니다. 변경 사항이 유지되도록 이후에 프로필을 다시 저장하세요. - PDF에서 빌드된 프로필은 해당 PDF에 나타난 문자만 포함합니다. 전체 문서를 약속하기 전에
hwpdf coverage --font <프로필 폰트> --text-file <새 문서>로 확인하세요.
합성 — 사용자가 쓰지 않은 문자 (실험적)
문서에는 거의 항상 사용자가 쓰지 않은 문자가 필요합니다. 중국어에서는 이것이 예외가 아니라 표준입니다. 두 가지 방법을 정직함의 순서대로 나열합니다:
- 중립 대체 (기본값, 예측 가능):
render --fallback auto는 시스템 손글씨 폰트를 선택합니다. 페이지는 사용자의 손글씨와 인쇄체 또는 중립 손글씨를 혼합하며,render는 이 방식으로 그려진 모든 문자를 보고합니다. - 합성 추론 (
hwpdf synth, 아직 실험적): 사용자 스타일의 측정 가능한 부분(기울기, 획 두께, x-높이, 글리프 너비)을 빌려 시스템 골격 글리프에 찍어내어 전체 문자 집합을 포함하는 두 번째 폰트를 빌드합니다.
hwpdf synth doctor # 사용 가능한 엔진과 누락된 사항 확인
hwpdf synth build --style hw/font.ttf --charset common3500 -o hw/synth.ttf
hwpdf synth specimen --font hw/synth.ttf --real hw/font.ttf -o hw/sheet.png # 먼저 검사
hwpdf synth verify --font hw/synth.ttf --charset common3500 # 커버리지 / 누락 확인
hwpdf synth eval --font hw/synth.ttf --real hw/font.ttf -o hw/report.md # 보고서용 숫자
hwpdf profile save --name alex --font hw/font.ttf --synth-font hw/synth.ttf
hwpdf render --profile alex --text-file doc.txt -o out.pdf # 합성으로 빈칸 채움
엔진: stylefit (분석 기반 — 다운로드 불필요, GPU 불필요, 결정적; 중국어 글리프는 시스템 산세리프 골격을 유지하고 사용자의 기울기/두께만 반영) 및 stub (테스트 픽스처, 스타일 전송 아님). 확산 엔진 diff-font는 라이선스가 해결되지 않은 가중치가 필요합니다 (PLAN.md §8 S4) — synth doctor가 실제로 그렇게 말합니다.
명확히 설명하세요: 사용자가 쓴 문자는 그대로 재현됩니다. 추론된 문자는 "인쇄된 골격에 사용자의 기울기와 두께를 적용한 것"입니다. 추론된 절반이 "사용자처럼 보인다"고 사용자에게 말하지 마십시오. 배송 전에 <font>.json 파일의 meta.gate (rejected는 0이어야 함)와 샘플을 확인하세요.
규칙
- 로컬 전용. 샘플, 폰트 또는 출력물을 업로드하지 마십시오. API 호출 금지.
- 사용자 자신의 손글씨만. 타인의 손글씨, 서명 또는 레터헤드를 모방하는 것을 거부하고, 서명 / 계약서 / 증명서 / 공문서 생성을 거부하세요 — 간략히 설명하고 (위조, 사기, 증거 규칙) 대신 일반적인 타자 문서를 제안하세요.
- 품질을 절대 조작하지 마십시오. 폰트에 40개의 글리프가 있으면 40이라고 말하세요. 대체 폰트가 페이지의 절반을 그렸다면 그렇게 말하세요. 누락된 문자를 그대로 보고하십시오.
- 도구를 탓하기 전에 다시 촬영을 요청하세요: 흐릿하거나, 그림자가 지거나, 모서리가 잘리거나, 격자선이 덮인 사진이 가장 흔한 실패 원인입니다.
- 작업 디렉터리(
hw/)를 유지하세요 — 사용자가 나중에 문자를 추가하고 폰트를 다시 빌드할 수 있습니다.
명령어 참조
| 명령어 | 목적 |
|---|---|
hwpdf doctor | 의존성 + 시스템 폰트 확인 |
hwpdf template --chars "abc" / --text-file doc.txt -d DIR | 연습지 PDF + 메타데이터 |
hwpdf scan IMG... [-d DIR] [--rotate 90] [--append] | 촬영된 시트 → 글리프 마스크 (append = 기존 작업에 병합) |
hwpdf extract-font --pdf in.pdf -d DIR | PDF에서 임베디드 폰트 추출 (최상의 경우: 전체 TTF) |
hwpdf pdf-specimen --pdf in.pdf -d DIR [--font-name F] | PDF의 텍스트 레이어 + 래스터에서 레이블이 있는 글리프 수집 |
hwpdf rasterize --pdf in.pdf -d DIR [--dpi 300] | 스캔된 PDF → 페이지 PNG |
hwpdf segment IMG... [-d DIR] [--thresh N] [--deskew] | 자유 형식 사진 → 블롭 + 콘택트 시트 |
hwpdf label -d DIR --order "ABC" / --pair "0=A 1=B" | 블롭을 문자에 매핑 |
hwpdf font -d DIR [--labels f] [--family NAME] [--weight -2..2] [--smooth 0..2] -o out.ttf | 폰트 빌드 |
hwpdf coverage --font f --text-file doc.txt | 누락된 문자 확인 |
hwpdf render --font f --text-file doc.txt -o out.pdf [--size 12] [--leading 1.8] [--paper ruled] [--jitter 1] [--ink "#1a1c24"] [--fallback auto|none|path] | PDF 렌더링 (--font system:cjk / system:latin = 내장 손글씨 폰트, 사용자 샘플이 없고 손글씨 느낌만 원할 때 사용) |
hwpdf render --profile NAME --text-file doc.txt -o out.pdf | 저장된 프로필의 폰트 + 기본값을 사용하여 PDF 렌더링 |
hwpdf profile save/list/show/remove ... | 재사용 가능한 손글씨 프로필 고정 / 검사 (PROMPT.md 작성) |
hwpdf preview --pdf out.pdf -d DIR [--dpi 150] | PDF 페이지 → 시각적 검토용 PNG |
hwpdf synth doctor / build / specimen / verify / charsets | 선택적 추론 엔진: 작성된 부분 집합에서 전체 문자 집합 폰트 생성 (합성 섹션 참조) |
hwpdf selftest -d DIR [--messy] | 종단 간 합성 스모크 테스트 |
제한 사항 (해당될 때 명시)
- 문자당 하나의 글리프: 연결된 필기체 없음, 발생 간 자연스러운 변형 없음, 압력/잉크 질감 없음. 간격 지터는 시뮬레이션되지만 글리프 모양은 그렇지 않습니다.
- CJK: 폰트는 작성된 문자만 포함합니다. 페이지당 30개 셀; 300자 편지는 10페이지 연습지가 필요합니다.
hwpdf synth build --charset common3500이 지름길이지만, 추론된 CJK는 사용자의 기울기를 가진 시스템 산세리프 골격일 뿐, 실제 붓놀림이 아닙니다. - PDF 텍스트 레이어는 생성된 폰트의 실제 텍스트입니다 (검색/복사 가능).
- 사진에는 연습지의 네 개의 검은색 모서리 사각형이 모두 보여야 합니다.
자세한 내용: references/workflow.md · references/troubleshooting.md