乳膠範例

乳膠範例

我在 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

結果

lua代碼

將其保存在文件中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 圖片時,我“重建”了稍後用於每一行的字串。

有一些問題我沒有解決(我不知道如何解決):

  1. 文本中的連字破壞了演算法,因為產生的字形沒有 ASCII 等效項。這就是為什麼我寫“Fit”而不是“fit”,以避免“fi”連字。
  2. 基於同樣的原因,可能不允許使用重音字元(未測試)
  3. 顯然 tikz 會幹擾 TeX 裝箱機制,因為如果我嘗試在 tikz 環境中建立盒子,則不會產生任何盒子。這就是為什麼我必須在進入 tikz 之前「準備」盒子。
  4. 可能還有更多問題尚未發現(沒有經過太多測試)

相關內容