
tikz의 경로를 따라 텍스트 정렬에 문제가 있습니다. 나는 사용자 정의 모양을 만들고 다음과 같은 방법으로 그 안에 경로를 따라 텍스트를 썼습니다.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.text}
\begin{document}
\begin{tikzpicture}
% shape
\draw (70:3) arc (70:110:3)
-- (110:5) arc (110:70:5)
-- cycle;
\path[
postaction={
decorate,
decoration={
text along path,
text align = center,
text={Gershon Daly Bonifacy Yaw}
}
}
]
(105:4.5) arc (105:75:4.5)
(105:4.0) arc (105:75:4.0)
(105:3.5) arc (105:75:3.5);
\end{tikzpicture}
\end{document}
결과는 꽤 괜찮으나 작은 문제가 있습니다. 이것은 출력이다없이중앙 정렬:
그리고 이건~와 함께중앙 정렬:
내 문제는 경로가 아닌 모양의 중심선을 기준으로 올바른 줄 바꿈(단어 중간에 줄을 끊지 않음)과 정렬을 원한다는 것입니다.
나는 경로를 따라 텍스트를 렌더링할 때 모든 문자가 서로 다르게 래핑되고 \hbox
개별적으로 올바른 정도로 바뀌는 것을 알고 있습니다.
어떤 제안이 있으십니까?
업데이트:
~ 안에이것응답 경로는 텍스트가 경로에 맞는 경우에만 장식됩니다. 적합한 텍스트로만 경로를 장식하고 나머지 텍스트는 다른 경로에 남겨 두는 유사한 접근 방식이 있을 수 있습니까?
업데이트 2:
텍스트가 설명된 대로 왼쪽 들여쓰기 상태를 재정의하는 경로에 맞지 않으면 텍스트를 숨길 수 있습니다.위에서 언급한 답변:
\makeatletter
\pgfkeys{
/pgf/decoration/omit long text/.code={%
\expandafter\def\csname pgf@decorate@@text along path@left indent@options\expandafter\expandafter\expandafter\endcsname\expandafter\expandafter\expandafter{\csname pgf@decorate@@text along path@left indent@options\endcsname,switch if less than=\pgf@lib@dec@text@width to final}%
},
}
\makeatother
내 생각은 텍스트 조판을 건너뛰는 것(최종 상태로 전환)뿐만 아니라 텍스트가 조판되지 않았음을 의미하는 플래그도 설정하여 텍스트 길이를 줄이고 데코레이션을 다시 호출할 수 있도록 하는 것입니다.
답변1
내 아이디어(OP 질문에 대한 설명)에 따라 LuaTeX로 몇 가지 실험을 수행했습니다. 이는 예비 결과입니다.
라텍스의 예
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{decorations.text}
\directlua{dofile("testing.lua")}
\begin{document}
\sffamily
% Before entering tikzpicture
\directlua{PrepareText({{105,75,4.5}, {105,75,4}, {105,75,3.5}},
"Gershon Daly Bonifacy Yaw")}
\begin{tikzpicture}
\draw (70:3) arc (70:110:3)
-- (110:5) arc (110:70:5)
-- cycle;
\directlua{TypeInArcs()}
\end{tikzpicture}
%
% A second example
\directlua{PrepareText({{105,75,4.5}, {105,75,4}, {105,75,3.5}},
"This is another longer test, which does not Fit")}
\begin{tikzpicture}
\draw (70:3) arc (70:110:3)
-- (110:5) arc (110:70:5)
-- cycle;
\directlua{TypeInArcs()}
\end{tikzpicture}
%
% Third example
\directlua{PrepareText({{105,75,4.5}, {105,75,4}, {105,75,3.5}, {105,75,3}},
"This is another longer test, which now does Fit")}
\begin{tikzpicture}
\draw (70:2.5) arc (70:110:2.5)
-- (110:5) arc (110:70:5)
-- cycle;
\directlua{TypeInArcs()}
\end{tikzpicture}
\end{document}
결과
다음으로 컴파일한 후lualatex
루아 코드
파일에 저장하십시오 testing.lua
.
function GetLinesFromBox()
local lines,i,j,l,d,list,words
lines = {}; j = 1;
d=node.types();
list = tex.box[0].head
node.unprotect_glyphs(list)
for l in node.traverse(list) do
if (d[l.id]=="hlist") then
words = {}; i = 1
for l in node.traverse(l.head) do
if (d[l.id]=="glyph") then
words[i] = string.char(l.char)
i=i+1
end
if (d[l.id]=="glue") then
words[i] = " "
i=i+1
end
end
lines[j] = table.concat(words,"")
j=j+1
end
end
return lines
end
function ComputeLengthArc(start_, end_, radius)
return (radius*(math.abs(start_-end_)*2*math.pi/360))
end
global_arcs = {}
global_text = ""
function PrepareText(arcs, text)
local j,l
global_arcs = arcs
global_text = text
tex.print("\\setbox0=\\vbox{\\centering\\parshape ", #arcs)
for j=1,#arcs do
l = ComputeLengthArc(arcs[j][1], arcs[j][2], arcs[j][3] )
tex.print("0cm "..l.."cm ")
end
tex.print("\\noindent ".. text .. "}")
end
function TypeInArcs()
local lines,j
lines = GetLinesFromBox()
for j=1,#global_arcs do
if lines[j]~=nil then
tex.sprint("\\path[ postaction = { decorate, decoration = {")
tex.sprint(" text along path,")
tex.sprint(" text align = center,")
tex.sprint(" text={"..lines[j].."}")
tex.sprint("} } ]")
tex.sprint("("..global_arcs[j][1]..":"..global_arcs[j][3]..
") arc ("..global_arcs[j][1]..":"..global_arcs[j][2]..":"..global_arcs[j][3]..");")
end
end
end
설명 및 주의사항
이것은 단지 개념 증명일 뿐입니다. 알고리즘은 매우 순진합니다. 나는 TeX의 상자 0에 텍스트를 조판했지만 parshape
각 줄에 적절한 길이를 사용했습니다. 그런 다음 Lua의 결과 노드를 검사합니다. 각 노드는 hbox
선이고, glyph
해당 상자 안의 각 노드는 문자이고, 각 노드 glue
는 공백이라고 가정합니다. 이렇게 하면 나중에 tikz 그림을 그릴 때 각 줄에 사용할 문자열을 "재구성"합니다.
내가 해결하지 못한 몇 가지 문제가 있습니다(방법을 모르겠습니다).
- 텍스트의 합자는 ASCII에 해당하지 않는 문자 모양을 생성하므로 알고리즘을 손상시킵니다. 이것이 제가 "fi" 합자를 피하기 위해 "fit" 대신 "Fit"을 쓴 이유입니다.
- 같은 이유로 악센트 부호가 있는 문자는 허용되지 않습니다(테스트되지 않음).
- 분명히 tikz는 TeX 권투 메커니즘을 방해합니다. 왜냐하면 tikz 환경 내부에 상자를 만들려고 하면 상자가 생성되지 않기 때문입니다. 이것이 내가 tikz에 들어가기 전에 상자를 "준비"해야 하는 이유입니다.
- 아마도 아직 발견되지 않은 더 많은 문제가 있을 것입니다(많이 테스트되지 않음)