Das Latex-Beispiel

Das Latex-Beispiel

Ich habe einige Probleme mit der Textausrichtung entlang des Pfads in Tikz. Ich habe eine benutzerdefinierte Form erstellt und darin Text entlang des Pfads folgendermaßen geschrieben:

\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}

Das Ergebnis ist ziemlich gut, aber es gibt kleine Probleme. Dies ist die Ausgabeohnezentrale Ausrichtung:

ohne Ausrichtung

und das istmitzentrale Ausrichtung:

mit Ausrichtung

Mein Problem besteht darin, dass ich einen korrekten Zeilenumbruch (kein Zeilenumbruch in der Mitte des Wortes) und eine Ausrichtung relativ zur Mittellinie der Form und nicht des Pfads möchte.

Ich weiß, dass beim Rendern von Text entlang eines Pfads jeder Buchstabe anders umbrochen \hboxund separat im richtigen Winkel gedreht wird.

Irgendwelche Vorschläge?

AKTUALISIEREN:

InDasDer Antwortpfad wird nur dann dekoriert, wenn der Text in den Pfad passt. Vielleicht gibt es einen ähnlichen Ansatz, um den Pfad nur mit angepasstem Text zu dekorieren und den Rest des Textes den anderen Pfaden zu überlassen?

UPDATE 2:

Ich kann Text verbergen, wenn der Text nicht in den Pfad passt, indem ich den linken Einzug neu definiere, wie in angegebenoben erwähnte Antwort:

\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

Meine Idee besteht darin, nicht nur den Textsatz zu überspringen (zum Endzustand zu wechseln), sondern auch einige Flags zu setzen, die bedeuten, dass der Text nicht gesetzt ist, sodass ich die Textlänge verringern und die Verzierung erneut aufrufen kann.

Antwort1

Meiner Idee folgend (in einem Kommentar zur Frage des OP) habe ich einige Experimente mit LuaTeX durchgeführt. Dies sind die vorläufigen Ergebnisse.

Das Latex-Beispiel

\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}

Das Ergebnis

Nach dem Kompilieren mitlualatex

Ergebnis

Der Lua-Code

Speichern Sie es in einer Datei 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

Erläuterungen und Vorbehalte

Dies ist nur ein Proof of Concept. Der Algorithmus ist sehr naiv. Ich setze den Text in Feld 0 von TeX, aber mit parshapeden entsprechenden Längen für jede Zeile. Dann untersuche ich die resultierenden Knoten von Lua und gehe davon aus, dass jeder hboxeine Zeile, jeder glyphin diesem Feld ein Zeichen und jeder glueein Leerzeichen ist. Auf diese Weise „rekonstruiere“ ich die Zeichenfolge, die später beim Zeichnen des Tikz-Bildes für jede Zeile verwendet werden soll.

Es gibt einige Probleme, die ich nicht gelöst habe (ich weiß nicht wie):

  1. Ligaturen im Text unterbrechen den Algorithmus, da sie Glyphen erzeugen, die kein ASCII-Äquivalent haben. Aus diesem Grund habe ich „Fit“ statt „fit“ geschrieben, um die Ligatur „fi“ zu vermeiden.
  2. Aus dem gleichen Grund sind vermutlich auch keine Akzentzeichen erlaubt (nicht getestet)
  3. Anscheinend stört Tikz den TeX-Boxing-Mechanismus, denn wenn ich versuche, die Box in der Tikz-Umgebung zu erstellen, wird keine Box erstellt. Aus diesem Grund muss ich die Box „vorbereiten“, bevor ich Tikz öffne.
  4. Wahrscheinlich noch weitere Probleme, die noch nicht gefunden wurden (nicht ausreichend getestet)

verwandte Informationen