diff options
Diffstat (limited to 'Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex')
-rw-r--r-- | Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex new file mode 100644 index 00000000000..422d7d8d0a2 --- /dev/null +++ b/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-gd-binding-layer.tex @@ -0,0 +1,289 @@ +% Copyright 2010-2011 by Renée Ahrens +% Copyright 2010-2011 by Olof Frahm +% Copyright 2010-2011 by Jens Kluttig +% Copyright 2010-2011 by Matthias Schulz +% Copyright 2010-2011 by Stephan Schuster +% Copyright 2011 by Jannis Pohlmann +% Copyright 2011 by Till Tantau +% +% This file may be distributed and/or modified +% +% 1. under the LaTeX Project Public License and/or +% 2. under the GNU Free Documentation License. +% +% See the file doc/generic/pgf/licenses/LICENSE for more details. + + +\section{The Binding Layer} + +\label{section-gd-binding-layer} + +\ifluatex\else This section of the manual can only be typeset using Lua\TeX.\expandafter\endinput\fi + +\subsection{Overview} + +This section explains how the \emph{binding} of the graph drawing +system to a particular display layer works. Let me stress +that all of this is important only for readers who +\begin{itemize} +\item either wish to write new display system (see + Section~\ref{section-gd-display-layer}) +\item or wish to know more about how the graph drawing system works on + the pure \pgfname\ layer (this is were the binding occurs). +\end{itemize} + +\emph{Bindings} are used to encapsulate the details of the +communication between the graph drawing system and a display system +(see Section~\ref{section-gd-display-layer} for an introduction to +display systems). + +Consider a display system that communicates with the graph drawing +system. At some point, the display system would like to run an +algorithm to lay out a graph. To achieve this, it will call different +functions from the class |InterfaceToDisplay| and the effect of this +is that a representation of the to-be-drawn graph is constructed +internally and that the appropriate algorithms are run. All of this is +in some sense independent of the actual display system, the class +|InterfaceToDisplay| offers the same standard interface to all display +systems. + +At some point, however, the graph drawing system may need to ``talk +back'' to the display system. For instance, once the graph has been +laid out, to trigger the actual rendering of the graph, the graph +drawing system must ``tell'' the display layer where the vertices +lie. For some display systems this is easy: if the display system +itself is written in Lua, it could just access the syntactic digraph +directly. However, for systems like \tikzname\ or systems written in +another language, the graph drawing system needs a set of functions +that it can call that will tell the display system what is going +on. This is were bindings come in. + +The class |Binding| is an interface that defines numerous methods that +will be called by the graph drawing system in different situations (see +the documentation below for details). For instance, there is a +function |renderVertex| that is called by the graph drawing system +whenever a vertex should be rendered by the display system. The class +is really just an interface in the sense of object-oriented +programming. For each display system you need to create a subclass of +|Binding| like |BindingToPGF| or |BindingToASCII| that implement the +methods declared by |Binding|. The number of methods that need to be +implemented depends on the display system. + +In the following, you will find the documentation of the |Binding| +class in Section~\ref{section-gd-binding-doc}. Following this, we +first have a quick look at how the |BindingToPGF| works and then go +over a simple example of a binding to a more or less imaginary +display system. This example should help readers interested in +implementing their own bindings. + + +\subsection{The Binding Class and the Interface Core} +\label{section-gd-binding-doc} + +\includeluadocumentationof{pgf.gd.bindings.Binding} +\includeluadocumentationof{pgf.gd.interface.InterfaceCore} + + +\subsection{The Binding To PGF} + +\includeluadocumentationof{pgf.gd.bindings.BindingToPGF} + + +\subsection{An Example Binding Class} + +\label{section-gd-binding-layer-example} + +In the present section a complete binding is presented to an imaginary +``\textsc{ascii} art display system'' is presented. The idea is that +this display system will depict graphs using just normal letters and +spaces so that, when the text is typeset in a monospace font, a +visualization of the graph results. For instance: + +\bigskip +\noindent +\begin{minipage}[t]{.5\textwidth} +\emph{Graph rendered by |BindingToPGF|:} +\medskip + +\tikz [anchor=base]\graph [layered layout,level distance=2.35cm,sibling +distance=1.2cm,edges={rounded corners,>=spaced stealth'}] { + Alice; + Bob; + Charly; + Dave; + Eve; + Fritz; + George; + Alice -> Bob; + Alice -> Charly; + Charly -> Dave; + Bob -> Dave; + Dave -> Eve; + Eve -> Fritz; + Fritz -> Alice; + George -> Eve; + George -> Fritz; + Alice -> George; +}; +\end{minipage}% +\begin{minipage}[t]{.49\textwidth} +\emph{Graph rendered by |BindingToASCII|:} + +\begin{verbatim} + Alice + ....... + .. . . . + ... . . . + ... .. . .. + .. . . . + Charly Bob . . + .. . . . + . . . . + . . . . + .. . . . + .. . . + Dave George . + .. . ... . + . . .. . + . . ... + .. . . ... + .. . .. + Eve . .. + .. . .. + . . . + . . . + .. . .. + ... + Fritz +\end{verbatim} +\end{minipage} +\bigskip + +The binding will reside in a file |BindingToASCII.lua|, whose contents +is detailed below, and which is used by calling the |bind| function of +|InterfaceToDisplay|, see its documentation for details. + +The binding's code starts with some initializations: + +\begin{codeexample}[code only] +-- File BindingToASCII.lua + +-- Imports +local lib = require "pgf.gd.lib" + +-- Subclass the Binding class: +local BindingToASCII = lib.class { base_class = require "pgf.gd.bindings.Binding" } +\end{codeexample} + +The interesting code is the code for +``rendering'' a graph. The graph drawing system will invoke the +binding's methods |renderStart| and |renderStop| to signal that the +graph drawing algorithms have finished and that the vertices and edges +can now be drawn. + +In our \textsc{ascii} renderer, we use a two-dimensional field holding +characters that severs as the ``drawing canvas''. At the beginning of +the rendering, we initialize it with blanks: + +\begin{codeexample}[code only] +local canvas + +function BindingToASCII:renderStart() + canvas = {} + -- Clear the canvas + for x=-30,30 do + canvas [x] = {} + for y=-30,30 do + canvas[x][y] = ' ' + end + end +end +\end{codeexample} + +In order to ``render'' a vertex, the graph drawing system will call +the |renderVertex| method. The binding of \tikzname\ does a lot of +complicated things in this method to retrieve the underlying node's +box from internal table and to somehow reinstall the box in \TeX's +output stream; for our \textsc{ascii} binding things are much simpler: +We simply put the vertex's name at the canvas position corresponding +to the vertex's |pos| coordinate. Note that this simple version of an +\textsc{ascii} renderer does not try to scale things; thus, array out +of bounds might occur here. + +\begin{codeexample}[code only] +function BindingToASCII:renderVertex(v) + canvas [math.floor(v.pos.x)][math.floor(v.pos.y)] = v.name +end +\end{codeexample} + +The rendering of edges is a more complicated process. Given two +vertices, we put dots at the canvas positions between them; provided +there are no vertices (so edges are behind the nodes). Here is the +essential part of the code (for the complete code, have a look at +|pgf/gd/examples/BindingToASCII.lua|): + + +\begin{codeexample}[code only] +function BindingToASCII:renderEdge(e) + local function connect (p,q) + -- Connect the points p and q + local x1, y1, x2, y2 = math.floor(p.x+0.5), math.floor(p.y+0.5), math.floor(q.x+0.5), math.floor(q.y+0.5) + ... + local delta_x = x2-x1 + local delta_y = y2-y1 + ... + local slope = delta_y/delta_x + for i=x1,x2 do + local x,y = i, math.floor(y1 + (i-x1)*slope + 0.5) + + if canvas[x][y] == " " then + canvas[x][y] = '.' + end + end + ... + end + + -- Iterate over all points on the path from tail to head: + local p = e.tail.pos + for i=1,#e.path do + connect(p, e.tail.pos + e.path[i]) + p = e.tail.pos + e.path[i] + end + connect(p, e.head.pos) +end +\end{codeexample} + + +The methods |renderVertex| and |renderEdge| will be called once for +each vertex and edge of the to-be-rendered graph. At the end, the +|renderStop| method is called. In our case, this method will output +the canvas using |print|. A slight complication arises when node names +are longer than just one character. In this case, the following code +``centers'' them on their coordinate and makes sure that they do not +get overwritten by the dots forming edges: + +\begin{codeexample}[code only] +function BindingToASCII:renderStop() + for y=10,-30,-1 do + local t = {} + for x=-30,30 do + local s = canvas[x][y] + for i=1,#s do + pos = x+30+i-math.floor(#s/2) + if not t[pos] or t[pos] == " " or t[pos] == "." then + t[pos] = string.sub(s,i,i) + end + end + end + print(table.concat(t)) + end +end +\end{codeexample} + +At the end, we need to return the created object: + +\begin{codeexample}[code only] +return BindingToASCII +\end{codeexample} + + |