
스크립트에 다음이 필요한 문서가 있습니다.복잡한 텍스트 레이아웃나는 이것이 XeTeX에서 작동한다고 믿습니다. 그러나 나는 놀라운 결과를 얻었습니다.
\documentclass{article}
\usepackage{fontspec}
\tracinglostchars=2 % https://tex.stackexchange.com/a/41235/48
\def\testtext{R ಶ್ರೀವತ್ಸ \quad Rಶ್ರೀವತ್ಸ}
\begin{document}
\fontspec{Arial Unicode MS} \testtext
\fontspec{Noto Sans Kannada} \testtext
\fontspec{Noto Serif Kannada} \testtext
\fontspec{Kedage} \testtext
\end{document}
이것 으로 컴파일하면 xelatex
다음이 제공됩니다.
스크립트를 읽을 수 없는 분들을 위해 왼쪽에 있는 것(입력에 R ಶ್ರೀವತ್ಸ
R 뒤에 공백이 있는 경우)은 올바른 반면, 오른쪽에 있는 것(입력에는 동일한 텍스트가 있지만 R 뒤에 공백이 없음)은 다음과 같습니다. 아니다.
출력의 "상자"를 이해합니다. 이는 선택한 칸나다어 글꼴에 R 문자가 없기 때문입니다. (이 효과에 대한 메시지는 덕분에 터미널에 인쇄됩니다 \tracinglostchars=2
.)
질문: 공백을 생략하면 왜 출력이 잘못되나요? 그리고 공간이 없어도 어떻게 하면 제대로 작동하게 할 수 있을까요?
내가 이해하는 바에 따르면 XeTeX에서는 텍스트 레이아웃(일명 텍스트 렌더링, 일명 텍스트 모양 지정)이 HarfBuzz 라이브러리에서 제공됩니다. HarfBuzz는 다른 많은 응용 프로그램에서 사용되며 이 텍스트를 잘 처리할 수 있어야 합니다. LuaTeX에서는 시스템 종속성을 피하고 모든 것을 자체적으로 구현하려고 합니다(Lua 코드에서). 이는 아마도 텍스트 레이아웃의 복잡성을 과소평가할 수 있으며 어떤 경우에도 LuaTeX는 현재 Devanagari 및 Malayalam 이외의 인도어 스크립트를 전혀 지원하지 않습니다. 따라서 lualatex
위 파일은 다음과 같이 생성됩니다.
(적어도 내가 이해하는 것은 지속적으로 잘못된 것입니다!)
편집하다: 아래 @cfr의 답변 덕분에 실제 문제를 해결하기 위해 무엇을 해야 하는지 알 수 있습니다. 글꼴을 로드할 때 스크립트를 지정합니다(예: \fontspec{Noto Sans Kannada}[Script=Kannada]
또는 그녀의 답변에서 더 나은 방법). 따라서 문제를 해결하는 것이 가능합니다. 남은 유일한 질문은 다음과 같습니다.무슨 일이야?
그리고 그만한 가치가 있는 문제를 재현하는 최소한의 일반 XeTeX 파일이 있습니다( 가 xetex
아닌 로 컴파일 xelatex
).
\font\notosansnone="Noto Sans Kannada"
% \font\notosanskndt="Noto Sans Kannada:script=knd2"
\font\notosansknda="Noto Sans Kannada:script=knda"
\def\testtext{R ಶ್ರೀ Rಶ್ರೀ}
{\notosansnone \testtext} (No script)
% {\notosanskndt \testtext} (knd2)
{\notosansknda \testtext} (knda)
\bye
답변1
첫 번째 또는 마지막 글꼴이 없습니다. 그러나 Polyglossia는 나에게 올바르게 작동합니다. (올바른 글꼴 구성으로도 작동할 것이라고 생각하지만 결국에는 이것이 원하는 것이기 때문에 이렇게 했습니다.)
\documentclass{article}
\usepackage{polyglossia}
\setmainlanguage{kannada}
\setotherlanguage[variant=british]{english}
\newfontfamily\kannadafont{Noto Serif Kannada}[Script=Kannada]
\newfontfamily\kannadafontsf{Noto Sans Kannada}[Script=Kannada]
\tracinglostchars=2 % https://tex.stackexchange.com/a/41235/48
\def\testtext{R ಶ್ರೀವತ್ಸ \quad Rಶ್ರೀವತ್ಸ}
\begin{document}
% \fontspec{Arial Unicode MS} \testtext
\testtext
\sffamily \testtext
% \fontspec{Kedage} \testtext
\end{document}
답변2
(이 모든 것의 결과로 내가 이해한 것을 공유합니다.)
솔루션
첫째, 문제에 대한 해결책은 다음과 같습니다.
- 처럼@cfr의 답변및 매뉴얼
[Script=Kannada]
에 설명된 대로 이 글꼴을 사용해야 한다고 지적했습니다 . 그리고 이를 사용하면 모든 것이 예상대로 작동합니다. 공백이 있든 없든 전체 텍스트가 칸나다어 스크립트에 적절하게 렌더링됩니다.fontspec
polyglossia
- 또한 우리는 실제로 칸나다어 스크립트로 렌더링된 R과 같은 칸나다어가 아닌 문자를 원하지 않습니다. 같은 다른 스크립트 문자는
R
다른 언어 또는 최소한 다른 글꼴로 표시되어야 합니다(방법은 아래 참조). 이것).
그렇다면 이것은 XeTeX나 XeTeX가 사용하는 일부 라이브러리의 버그입니까? 아니요, 사용자 오류라고 말하고 싶습니다. 그럼에도 불구하고 단어 사이에 공백이 있을 때(스크립트를 지정할 필요 없이) 모든 것이 잘 작동한다는 사실은 아마도 이러한 사용자 오류를 더 많이 발생시킬 수 있습니다.
설명
공간에 따른 동작의 불일치를 설명하는 것은 무엇입니까(무슨 일이 일어나고 있나요?)? 그리고 이 동작을 XeTeX에서 변경할 수 있나요? 내가 찾은 것은 다음과 같습니다.
텍스트 레이아웃을 위해 XeTeX에서 사용하는 라이브러리, 즉하프버즈(Firefox, Chrome, LibreOffice 등에서 사용됩니다.하프버즈(Harfbuzz)란 무엇입니까?hb-view
) 에는 글꼴과 텍스트 문자열로 호출할 수 있는 명령줄 프로그램이 함께 제공됩니다 . 이를 통해 다음과 같은 결과를 얻습니다.
hb-view NotoSansKannada-Regular.ttf "ಶ್ರೀ"
그리고--script=knda
:hb-view NotoSansKannada-Regular.ttf " ಶ್ರೀ"
그리고--script=knda
:hb-view NotoSansKannada-Regular.ttf "Rಶ್ರೀ"
그리고--script=knda
hb-view NotoSansKannada-Regular.ttf "R ಶ್ರೀ"
그리고--script=knda
이것이 보여주는 것은 다음과 같은 경우 출력이 정확하다는 것입니다.어느 하나공백이 아닌 첫 번째 문자는 올바른 스크립트에서 나온 것입니다.또는스크립트는 명시적으로 지정됩니다.
따라서 XeTeX에서 나타나는 동작("Rಶ್ರೀ"과 "R ಶ್ರೀ"의 차이점)은 무엇으로 설명됩니까?@울리케 피셔에서 지적했다XeTeX 동반자:
XeTeX의 접근 방식은 다음과 같습니다.
조판 프로세스는 너비를 결정하기 위해 API를 통해 시스템 라이브러리에 너비를 얻은 일련의 문자(단어)를 수집합니다.
XeTeX 단락은 다음의 시퀀스입니다.단어다음으로 구분된 노드접착제.
따라서 XeTeX의 조판 엔진은 글리프가 아닌 단어를 배치하고 후자는 글꼴 렌더링 엔진에 의해 그려집니다.
(위의 "시스템 라이브러리"와 "글꼴 렌더링 엔진"은 이제 HarfBuzz입니다(덕분에칼레드 호스니); 예전에는 중환자실이었어요.) 그래서
"Rಶ್ರೀವತ್ಸ"을 사용하면 XeTeX는 HarfBuzz에게 전체 문자열을 하나의 단위로 렌더링하도록 요청합니다. 이는 원하는 스크립트의 문자로 시작하지도 않고 스크립트를 올바르게 지정하지도 않았기 때문에 실패합니다(위의 hb-view 실험에서 볼 수 있듯이).
"R ಶ್ರೀವತ್ಸ"을 사용하면 XeTeX는 HarfBuzz에게 두 단어 각각에 대해 별도로 요청하며, 이 경우 두 번째 단어는 올바른 스크립트의 문자로 시작하기 때문에 (스크립트를 지정하지 않았더라도) 올바르게 렌더링됩니다.
그래도 그러한 추측에 의존하지 않고 스크립트를 명시적으로 지정하는 것이 가장 좋습니다.
두 스크립트로 작업하기
두 스크립트가 모두 원활하게 작동하도록 하려면 R과 같은 문자가 다른 언어로 되어 있음을 지정해야 합니다. . \textenglish{R}ಶ್ರೀವತ್ಸ
대신에 작성하여 이를 수행할 수 있습니다 Rಶ್ರೀವತ್ಸ
. 입력을 변경하고 싶지 않다면 다음을 사용하여 이를 수행할 수 있는 방법이 있습니다.ucharclasses
패키지.
어떤 이유로 작동하게 할 수 없어서 그냥 수동으로 했습니다(참고:의 예texdoc xetex
그리고우편의 저자로부터 ucharclasses
, 예를 들어 언급된 대로 255가 4095로 변경되었습니다.이 답변):
\documentclass{article}
\usepackage{fontspec}
\usepackage{polyglossia}
\newfontfamily\kannadafont{Noto Serif Kannada}[Script=Kannada]
\newfontfamily\englishfont{Georgia}
\setdefaultlanguage{kannada}
\setotherlanguage{english}
\XeTeXinterchartokenstate = 1 % Enable the character classes functionality
\newXeTeXintercharclass \CharEnglish
\XeTeXcharclass `R = \CharEnglish
\XeTeXinterchartoks 0 \CharEnglish = {\selectlanguage{english}}
\XeTeXinterchartoks 4095 \CharEnglish = {\selectlanguage{english}}
\XeTeXinterchartoks \CharEnglish 0 = {\selectlanguage{kannada}}
\XeTeXinterchartoks \CharEnglish 4095 = {\selectlanguage{kannada}}
\begin{document}
R ಶ್ರೀವತ್ಸ \quad Rಶ್ರೀವತ್ಸ
\end{document}
R
이는 영어 문자( 위에만 해당)와 단어 경계(4095) 또는 일반(영어로 지정되지 않음) 문자(0) 사이를 이동할 때마다 언어를 변경합니다 .
원본 문서의 경우 모든 영어 문자를 처리하기 위해 다음과 같은 작업을 수행하는 루프를 작성했습니다.
\XeTeXcharclass `R = \CharEnglish
알파벳의 모든 대문자와 소문자에 대해:
\newcount\tmpchar
\tmpchar = `A
\loop
\ifnum \tmpchar < `[ % [ comes just after Z
\XeTeXcharclass \tmpchar = \CharEnglish
\XeTeXcharclass \lccode \tmpchar = \CharEnglish
\advance \tmpchar by 1
\repeat