글꼴 시스템(NFSS / 인코딩)

\textbf\sffamily로 서체를 바꾸면 내부에서는 무엇이 일어날까요? 이 페이지는 서체 명령 뒤쪽의 작동 방식을 다룹니다. LaTeX는 하나의 글꼴을 서로 독립적인 다섯 속성(NFSS)으로 지정하고, 입력 문자를 실제 글리프에 대응시키는 인코딩을 통해 조판합니다. 명령 목록은 별도 페이지에 맡기고, 여기서는 \selectfont로 확정하는 저수준 선택 방법, OT1 / T1 / TU 같은 인코딩의 차이, 그리고 pdfLaTeX에서 왜 \usepackage[T1]{fontenc}를 쓰는지 깊이 살펴봅니다.

NFSS: 글꼴은 다섯 속성으로 결정된다

LaTeX2e의 글꼴 선택은 NFSS(New Font Selection Scheme, 새 글꼴 선택 방식)라는 체계에 기반합니다. 그 핵심은 어떤 텍스트 글꼴도 다섯 속성으로 완전히 결정된다는 생각입니다. fntguide(LaTeX2e 글꼴 선택 안내서)는 이 다섯 속성을 encoding, family, series, shape, size라고 정합니다.

  • 인코딩 — 글꼴 안에서 문자가 놓이는 순서(입력 문자와 글리프 슬롯의 대응). 본문에서는 OT1(TeX text)과 T1(TeX extended text, 이른바 Cork)이 대표적입니다. 다음 절에서 자세히 다룹니다.
  • 패밀리 — 글자의 골격을 공유하는 글꼴 모음. 코드는 Computer Modern Roman이 cmr, 그 Sans가 cmss, Typewriter가 cmtt입니다. 상용 글꼴에서는 Times가 ptm, Helvetica가 phv, Courier가 pcr입니다.
  • 시리즈 — 굵기와 폭을 합친 축입니다. m(medium = 기본), b(bold), bx(bold extended), c(condensed), sb(semi-bold) 등이 있습니다.
  • 셰이프 — 글자의 모양입니다. n(직립/로마체), it(이탤릭), sl(기울임/oblique), sc(대문자와 작은 대문자). 드물게 ui(인위적으로 세운 직립 이탤릭)도 있습니다.
  • 크기 — 디자인 크기입니다. 10pt 같은 치수이며, 단위를 생략하면 pt로 간주합니다.

핵심은 series가 굵기와 폭을 하나로 합친 축이라는 점입니다. 표준 표기에서 굵기는 ul부터 ub(ultra light에서 ultra bold), 폭은 uc부터 ux(ultra condensed에서 ultra expanded)까지입니다. 둘을 이어 붙여 하나의 값으로 만들되, m은 굵기와 폭이 모두 medium일 때 한 글자만 남기는 경우를 제외하고 생략합니다. 그래서 “굵은 표준 폭”은 b, “굵은 넓은 폭”은 bx, “표준 굵기 좁은 폭”은 c가 됩니다.

이 다섯 가지를 encoding/family/series/shape/size로 늘어놓은 표기가 LaTeX 내부에서의 글꼴 공식 이름입니다. 예를 들어 OT1/cmr/m/n/10은 “OT1 인코딩의 Computer Modern Roman, 보통 굵기, 직립, 10포인트”를 뜻합니다. overfull box 경고에 \OT1/cmr/m/n/10 같은 형태로 나타나는 것이 바로 이 다섯 속성입니다. 평소 사용하는 \textbf 같은 고수준 명령은 이 다섯 속성 중 하나를 다시 쓰는 조작에 지나지 않습니다.

저수준 선택자와 \selectfont

고수준 명령 아래에는 속성을 하나씩 지정하는 저수준 선택자가 있습니다. \fontencoding{T1}, \fontfamily{ptm}, \fontseries{b}, \fontshape{it}, \fontsize{12}{14}입니다. 하지만 중요한 규칙이 있습니다. 이들은 설정만 해서는 효과가 없고, \selectfont를 호출해야 비로소 반영됩니다. fntguide는 글꼴 매개변수를 설정한 뒤 이어지는 텍스트 전에 즉시 \selectfont 명령을 두어야 한다고 경고합니다.

latex
% 正しい:設定 → \selectfont → テキスト / Correct: set, then \selectfont, then text
\fontfamily{ptm}\fontseries{b}\selectfont Some text.

% 誤り:設定とテキストの間に文字を挟んではいけない / Wrong: no text between a setting and \selectfont
\fontfamily{ptm} Some \fontseries{b}\selectfont text.

속성을 한꺼번에 지정하는 지름길이 \usefont{encoding}{family}{series}{shape}입니다. 이는 대응하는 \font... 명령들을 나열하고 \selectfont를 붙인 것과 같으며, 크기는 현재 값을 이어받습니다. 특정 글꼴을 이름으로 한 번만 부르고 싶을 때 편리합니다. 또한 \fontencoding을 바꾼 경우에도 확정하려면 역시 뒤에 \selectfont가 필요합니다.

이 속성들을 직접 쓸 일은 드뭅니다. \textbf는 내부에서 \fontseries를, \sffamily\fontfamily를 호출하기 때문입니다. 명령 목록과 명령형/선언형의 구분은 “Font style commands” 페이지에 정리되어 있습니다. 저수준을 만지는 경우는 특정 글꼴을 이름으로 지정하거나 새 글꼴을 클래스나 패키지에 연결할 때로 제한됩니다.

기본값 매크로: \rmdefault와 그 동료들

\textrm이나 \rmfamily어떤 패밀리를 고르는지는 하드코딩되어 있지 않고 매크로에 보관됩니다. 세 가지가 있는데, \rmdefault(로마체), \sfdefault(산세리프), \ttdefault(타자기체)이며 article 클래스의 기본값은 각각 cmr, cmss, cmtt입니다. 그래서 본문 글꼴을 Times, Helvetica, Courier로 바꾸고 싶은 설계자는 명령을 다시 쓰지 않고 이 매크로를 교체합니다.

latex
% 文書全体の3ファミリを差し替える / Re-point the three families for the whole document
\renewcommand{\rmdefault}{ptm}  % roman   → Times
\renewcommand{\sfdefault}{phv}  % sans    → Helvetica
\renewcommand{\ttdefault}{pcr}  % mono    → Courier

본문 글꼴 자체는 \encodingdefault / \familydefault / \seriesdefault / \shapedefault 네 가지로 결정되며, 기본값은 OT1, \rmdefault, m, n입니다. \familydefault\rmdefault를 가리키므로 \rmdefault를 바꾸면 본문 글꼴이 바뀝니다. 굵은 글자의 굵기는 \bfdefault(기본 bx)가 가지고 있으며, 많은 PostScript 글꼴처럼 굵은 글자에 bx가 없는 글꼴을 쓸 때는 이를 b로 낮춰야 할 수 있습니다.

글꼴 인코딩: 입력에서 글리프로

글꼴 인코딩이란 글꼴 안에서 글리프가 놓이는 순서, 즉 입력된 문자를 글꼴의 어느 슬롯(글리프)에 대응시킬지에 대한 약속입니다. 다섯 속성 중 첫 번째이면서도 \textbf 같은 저자용 명령이 준비되어 있지 않은 유일한 속성이기도 합니다. fntguide가 말하듯, 인코딩 전환은 fontenc 같은 패키지가 제공하는 것이기 때문입니다.

본문에서 알아야 할 핵심은 다음과 같습니다. OT1은 Knuth의 원래 7비트 “TeX text” 인코딩(기본값)입니다. 128자만 들어가므로 éñ 같은 악센트 문자는 기본 문자와 악센트 기호의 합성(\accent)으로 만들어집니다. 이 합성이 문제입니다. 악센트가 붙은 단어는 하이픈 처리되지 않고, PDF에서 복사해 붙여넣을 때도 깨집니다. T1(“TeX extended text”, 1990년 Cork의 TUG 회의에서 유래해 Cork 인코딩이라고도 함)은 8비트 256글리프 인코딩으로, 악센트 문자를 독립된 하나의 글리프로 가집니다. 이를 통해 서유럽 및 일부 동유럽 언어가 올바르게 하이픈 처리되고 복사 붙여넣기도 정상적으로 됩니다.

TU(TeX Unicode)는 시스템에 설치된 OpenType 글꼴을 Unicode 코드 포인트로 직접 쓰기 위한 인코딩이며, XeLaTeX와 LuaLaTeX의 기본값입니다. fontspec이 이를 자동으로 설정하므로 Unicode 엔진에서는 TU를 명시적으로 쓸 일이 거의 없습니다. 그 밖에 용도별로 T2A(키릴 문자), LGR(그리스 문자, 현재 그리스어에서 주로 쓰이는 인코딩), TS1(Text Companion, 저작권 기호나 통화 기호처럼 본문에서 쓰는 기호 글리프 모음으로 textcomp가 처리)이 있습니다. 수식용으로는 OML(수식 이탤릭), OMS(수식 기호), OMX(대형 수식 기호)가 배정되어 있습니다.

인코딩내용비트 폭 / 비고
OT1Knuth의 원래 “TeX text”(기본값)7비트; 악센트는 합성 → 하이픈 불가
T1TeX extended text(Cork); 서유럽 언어8비트 256글리프; 악센트가 단일 글리프 → 하이픈 가능
TUTeX Unicode; OpenType 글꼴 직접 사용Xe/LuaLaTeX 기본값; fontspec이 설정
T2A키릴 문자8비트(T2B / T2C도 있음)
LGR그리스 문자현재 그리스어의 표준 256글리프 인코딩
TS1Text Companion(텍스트 기호)저작권, 통화 기호 등; textcomp가 처리

입력 인코딩과 글꼴 인코딩

헷갈리기 쉬운 두 가지를 구분해 둡니다. 입력 인코딩은 소스 .tex 파일의 바이트열을 어떤 문자로 읽을지(UTF-8 등)에 대한 약속이며, 역사적으로는 inputenc 패키지가 담당했습니다. 글꼴 인코딩은 그렇게 읽은 문자를 출력 글꼴의 어느 글리프에 흘려 넣을지에 대한 약속이며, fontenc가 담당합니다. 입구(inputenc)와 출구(fontenc)의 관계로 생각하면 됩니다.

현대 pdfLaTeX에서는 소스 문자를 UTF-8이 기본으로 읽기 때문에 inputenc를 명시적으로 읽어들일 필요가 거의 없어졌습니다. 하지만 글꼴 인코딩은 여전히 지정할 가치가 있습니다. fontencpdfLaTeX용 패키지이며, XeLaTeX나 LuaLaTeX를 사용할 때는 대신 fontspec을 사용합니다(Unicode 엔진에서는 TU가 기본이므로 이 문제 자체가 거의 생기지 않습니다).

pdfLaTeX에서는 T1 읽어들이기

pdfLaTeX로 문서를 조판한다면 프리앰블에 \usepackage[T1]{fontenc}를 쓰는 것이 정석입니다. 이는 문서의 글꼴 인코딩을 T1로 바꾸어 OT1 기본값의 폐해, 즉 악센트가 붙은 단어가 하이픈 처리되지 않고 PDF에서 복사하면 깨지는 문제를 없앱니다. fontenc 문서도 이것이 프랑스어, 독일어, 이탈리아어, 폴란드어 등 넓은 서유럽 언어를 지원하며, 악센트 문자가 있는 단어도 LaTeX가 하이픈 처리하고 출력을 복사해 붙여넣을 수 있다고 설명합니다.

fontenc 옵션에 여러 인코딩을 나열하면 마지막에 적은 것이 기본값이 됩니다(\encodingdefault가 그것으로 설정됨). 예를 들어 그리스어를 섞는 문서라면 \usepackage[LGR,T1]{fontenc}처럼 써서 본문 기본값은 T1로 유지하고 필요할 때 LGR로 전환합니다.

document.tex
\documentclass{article}
\usepackage[T1]{fontenc}   % フォントエンコーディングを T1 に / font encoding -> T1
% pdfLaTeX では入力は UTF-8 が既定(inputenc は通常不要)
% Input is UTF-8 by default on pdfLaTeX (inputenc usually unneeded)
\begin{document}
% T1 ならアクセント付きの語も正しくハイフネーションされる
% With T1, accented words hyphenate correctly
Na\"ive r\"esum\"e, \"uberfl\"ussig, Stra\ss{}e.
\end{document}

저수준 선택자의 실제 예

마지막으로 하나의 문서에서 저수준 선택자와 \usefont의 사용법을 확인합니다. \usefont는 다섯 속성 중 네 가지(encoding, family, series, shape)를 한 번에 주고 그 자리에서 확정하며, \fontfamily + \selectfont는 속성을 개별적으로 설정한 뒤 확정합니다. 둘 다 그룹 { }로 감싸면 효과가 그 범위에 한정됩니다.

document.tex
\documentclass{article}
\usepackage[T1]{fontenc}
\begin{document}
% \usefont で 4 属性を一括指定 / \usefont sets four attributes at once
{\usefont{T1}{ptm}{b}{it} Bold italic Times}

% 低水準セレクタを個別に設定し \selectfont で確定
% Set selectors individually, then commit with \selectfont
{\fontfamily{phv}\fontseries{b}\selectfont Bold Helvetica}

% サイズだけ変える(baselineskip は現在値を流用)
% Change only the size (reuse the current baselineskip)
{\fontsize{14}{\f@baselineskip}\selectfont Fourteen point}
\end{document}

여기서 {\usefont{T1}{ptm}{b}{it} ...}는 “T1 인코딩의 Times, 굵은 이탤릭”을 선택합니다. 그룹을 벗어나면 원래 글꼴로 돌아갑니다. \fontsize의 두 번째 인수에 내부 매크로 \f@baselineskip을 넘기는 것은 행간을 바꾸지 않고 글자 크기만 바꾸기 위한 관용구입니다(내부 매크로를 직접 다시 쓰면 안 되지만, 읽어서 넘기는 것은 괜찮습니다).