\documentclass[12pt,letterpaper,dvipdfm]{article}

% \usepackage{amsmath}
% \usepackage{amsfonts}
\usepackage[letterpaper,hmargin=1in]{geometry}
%\usepackage[letterpaper,left=2cm,right=8cm,bottom=3cm,top=3cm,marginparwidth=4cm]{geometry}
%\usepackage{natbib}
\usepackage{graphicx}
\usepackage{url}
\usepackage{natbib}
\usepackage{color}
\usepackage{paralist}           % compactitem
\definecolor{red}{rgb}{1,0,0}
\newcommand{\FIXME}[1]{{\color{red}\{FIXME: #1\}}}
\usepackage{hyperref}


\usepackage{fancyhdr}
\pagestyle{fancy}
\lhead{cl-cairo2 tutorial} \rhead{Tam\'as K Papp}
\cfoot{\thepage}

\renewcommand\floatpagefraction{.9}
\renewcommand\topfraction{.9}
\renewcommand\bottomfraction{.9}
\renewcommand\textfraction{.1}

\usepackage{listings}
\lstset{
  language=Lisp,
  extendedchars=true,
  basicstyle=\ttfamily,
  stringstyle=\ttfamily\slshape,
  commentstyle=\slshape,
%  numbers=left,
%  stepnumber=5,
%  numbersep=6pt,
%  numberstyle=\footnotesize,
  breaklines=true,
%  frame=single,
  columns=fullflexible,
  literate={-}{}{0\discretionary{-}{}{-}},
}

\begin{document}

\title{Tutorial for the cl-cairo2 package}
\author{Tam\'as K Papp}
\date{\today}
\maketitle

\section{Introduction}
\label{sec:introduction}

\href{http://cairographics.org/}{Cairo} is a 2D graphics library with
support for multiple output devices.  The \lstinline!cl-cairo2!
package provides Common Lisp bindings for the Cairo API.\footnote{Alternatives
are \href{http://www.cliki.net/cl-cairo}{cl-cairo}, written by Lars
Nostdal and others (this project appears to be dormant), and Christian
Haselbach's \href{http://www.cliki.net/cffi-cairo}{cffi-cairo}.}

\lstinline!cl-cairo2! is written with the following principles in mind:

\begin{description}
\item[CFFI bindings are generated by SWIG.]  This ensures that API
  changes are caught easily and makes it easier to follow them.
  The bindings to C functions are not exported directly.
\item[It attempts to make the interface more Lisp-like.]  The Cairo
  API is written in C, which has no garbage collection or condition
  handling, and has little support for sophisticated dynamic data
  structures.  However, the Lisp user should not worry about reference
  counting and pointer arithmetic.  Instead of merely providing the C
  wrappers, cl-cairo2 aims to provide an interface conforming to the
  style of Lisp better.
\item[Condition handling.]  In the Cairo API, an error is signaled by
  changing the state of the object, which the user is supposed to
  query periodically.  The functions in cl-cairo2 do this
  automatically, and use Common Lisp's powerful condition facility to
  signal errors.\footnote{This feature is not fully developed yet:
    currently a warning is signalled for all errors.  The framework is
    in place, I just need to decide which errors require user
    intervention, etc.}
\end{description}

This tutorial introduces cl-cairo2, but is not an introduction to
Cairo itself.  If you are not familiar with Cairo, it is recommended
that your read the
\href{http://www.tortall.net/mu/wiki/CairoTutorial}{Cairo Tutorial for
  Python (and other) Programmers}.

\section{Installation and loading}
\label{sec:installation-loading}

cl-cairo2 uses ASDF.  Please refer to the
\href{http://www.cliki.net/asdf}{ASDF} and
\href{http://www.cliki.net/ASDF-Install}{ASDF-Install} manuals on how
to install packages.  You need to have the latest Cairo API installed.
On Debian systems, you just need to install the \verb!libcairo2!
package.  You don't need the header files or SWIG unless you plan to
regenate the SWIG bindings.

Once installed, you can load cl-cairo2 with
\begin{lstlisting}
(asdf:operate 'asdf:load-op :cl-cairo2)
\end{lstlisting}

\section{Getting started}
\label{sec:getting-started}


Most Cairo drawing operations are performed on a \emph{context}.
Think of the context as a combination of a canvas which remembers pen
strokes (the current path), color, line width, line style, and other,
more complicated settings that determine what gets drawn where.  When
you build a path (which you want to fill with a color/pattern, stroke
with a given line style, or even save), all of this happens in a
context.

All \verb!cl-cairo2! functions that use a context take it as
their last optional argument.  If not given, these functions use
\lstinline!*context*!, a special variable that stores the default
context.

Contexts are created from \emph{surfaces} --- which, at this point,
should be thought of as the bare canvas itself (think of PDF,
PostScript, of PNG files).  Contexts are created from surfaces.  All
Cairo objects, including contexts and surfaces, are implemented in
CLOS wrappers, and can be closed (\emph{destroyed}) with
\lstinline!destroy!.

When the context is created from a surface, the reference count (in
the internals of Cairo) of the latter is incremented.  You can
immediately destroy the surface: it will not be destroyed (ie the file
will not be closed) until you destroy the context.\footnote{The file
  will also be closed if the wrapper object is garbage collected.
  However, you should not rely on this, as calling the garbage
  collector is not portable.}  The following code draws a white
diagonal line on a blue background, using a Postscript file -- the
result is shown in Figure~\ref{fig:example}.

\lstinputlisting[firstline=13,lastline=27]{example.lisp}

\begin{figure}[htbp]
  \centering
  \includegraphics{example.epsi}
  \caption{white diagonal line on a blue background}
  \label{fig:example}
\end{figure}

Unless you need the surface itself for something else, you should use
the \lstinline!create-*-context! convenience commands provided by
cl-cairo2.  For example, the first three lines of the code above would
be replaced by
\begin{lstlisting}
(setf *context* (create-ps-context "example.ps" 200 100))
\end{lstlisting}
Unlike the original Cairo API, surfaces and contexts in
\lstinline!cl-cairo2! remember their width and height.  Use the
generic functions \lstinline!get-width! and \lstinline!get-height! to
extract these.

When you want to write the output into a bitmap file (for example, in
PNG format), you first need to create an \emph{image surface}, then
write this to the bitmap file when you are done.  The macro
\lstinline!with-png-file! will take care of these details: use it like
\begin{lstlisting}
(with-png-file ("example.png" 'format-rgb24 200 100)
  ;; drawing commands
  ...)
\end{lstlisting}

This example above highlights another feature of cl-cairo2: constants
(such as the format specifier \lstinline!rgb24!) are exported as
simple names from the cl-cairo2 package.  Internal functions in the
package map these to the enum constants used by Cairo.  cl-cairo2 uses
lookup tables (assoc lists) for this purpose, which are defined in
\verb!tables.lisp!.  Cairo constants
\texttt{CAIRO\_\textsl{PROPERTY}\_\textsl{SOMETHING}} usually map to
the Lisp symbol \lstinline!property-something!, and can only be used
in setting or querying \texttt{PROPERTY}.  For example,
\verb!CAIRO_FORMAT_RGB24!  is mapped to \lstinline!format-rgb24!, and
using it for some other property will create an error.

Likewise, names of the Lisp function are easy to deduce from the name
of the C function in the Cairo API: just drop the \verb!cairo_! prefix
and convert all underscores (\verb!_!) to dashes (\lstinline!-!).  The
exceptions to this rule (and the explanations) are given in
Table~\ref{tab:naming}.

\begin{table}[htbp]
  \centering
  \begin{tabular}{p{11cm}|c}
    Cairo API name (explanation) & cl-cairo2 name\\\hline
    \verb!cairo_fill! (would conflict with \lstinline!cl:fill!) 
    & \lstinline!fill-path! \\
    \verb!cairo_identity_matrix! (would
    conflict with matrix algebra packages)& \lstinline!reset-trans-matrix! \\
    \verb!cairo_matrix_init_identity! & use \lstinline!(make-trans-matrix)!\\
    \verb!cairo_matrix_transform_distance! 
    & \lstinline!transform-distance!\\
    \verb!cairo_matrix_transform_point! &
    \lstinline!transform-point!\\
    \verb!cairo_matrix_*! & \lstinline!trans-matrix-*!
  \end{tabular}
  % \caption{Function names different from the Cairo API}
  \label{tab:naming}
\end{table}



\section{Implementation notes}
\label{sec:implementation-notes}

\subsection{General}
\label{sec:general}

The package contains some helper functions, most notably
\lstinline{deg-to-rad}, which converts degrees to radians.  Cairo
functions use the latter.

\subsection{Surfaces}
\label{sec:surfaces}

See the beginning of \verb!surface.lisp! for helper macros used
internally to define wrappers for the SWIG-generated CFFI interface
(neither the interface not these macros are exported).
\lstinline!with-alive-surface! checks if the pointer for a surface
object is nil, and \lstinline!check-surface-pointer-status! queries
the status of the surface after executing \lstinline!body!.
\lstinline!with-surface! is a combination of the two, and
\lstinline!new-surface-with-check! makes a new surface object from a
pointer, checking its status first.

Currently, only Postscript, PDF, SVG and image surfaces (which can be
written to PNG files) are supported.

Drawing in X11 windows is implemented using the
\lstinline!x11-context! class --- see Section~\ref{sec:xlib-context}
for more information.

\subsection{Contexts}
\label{sec:contexts}

Contexts are represented as the class \lstinline!context!, which
currently only has one slot, a pointer to the context.  When contexts
are destroyed, this is set to \lstinline!nil!.  As mentioned above,
the default context is \lstinline!*context*!, and it is the default
for the last (optional) argument of each function.

The macro \lstinline!with-context! is similar to
\lstinline!with-surface! above (it executes the body with pointer
pointing to the object and then checks error status).  The functions
\lstinline!define-with-default-context! defines a function acting on a
context given a list of arguments and exports this function.
\lstinline!define-flexible! is similar, but allows a more flexible
function body.

Functions that are not implemented yet include
\begin{compactitem}
  \item \lstinline!cairo-get-target!
  \item \lstinline!push-group-with-content!
  \item \lstinline!get-group-target!
  \item \lstinline!set-source!, \lstinline!set-source-surface!,
    \lstinline!get-source!
  \item \lstinline!mask!, \lstinline!mask-surface!
\end{compactitem}
I doubt that Lisp users need \lstinline!get/set-user-data! or
\lstinline!get-reference-count!.  Let me know if you do.

Since version 0.2.3, you can use colors from
\href{http://www.cliki.net/cl-colors}{cl-colors} with the generic
function \lstinline!set-source-color!, for example,
\begin{lstlisting}
  (set-source-color +darkolivegreen+)
\end{lstlisting}


\subsection{Paths}
\label{sec:paths}

Almost all drawing operations of Cairo rely on the construction of
paths.  While basic paths can be constucted in a context, paths can be
saved, modified and reused independently.  At the moment, cl-cairo2
does not support these path operations:
\begin{compactitem}
  \item\lstinline!copy-path!
  \item\lstinline!copy-path-flat!
  \item\lstinline!path-destroy!
  \item\lstinline!append-path!
\end{compactitem}
This is because I decided to follow the recommendation of
\href{http://www.cairographics.org/manual/bindings-path.html}{relevant
  section} of the Cairo API Manual, and implement paths and related
manipulators in a way that doesn't require the user to traverse
structures of C pointers.  This is not done yet.

\lstinline!glyph-path! (see Section~\ref{sec:text} for discussion
about glyphs) is not implemented either.

\subsection{Text}
\label{sec:text}

Text operations are very basic at the moment (refer to
\verb!text.lisp! for an enumeration of what is missing).  You can
select font face and size using commands like
\begin{lstlisting}
  (select-font-face "Arial" 'font-slant-italic 'font-weight-bold)
  (select-font-size 12)
\end{lstlisting}
and use \lstinline!(show-text "hello world")! to draw it.  You can
control text placement by using \lstinline!text-extents! and
recalculating the position --- see \verb!example.lisp! for examples
(in Section~\ref{sec:examples}).  Note that Cairo functions accept
text in UTF-8 format: you should convert your strings to UTF-8 if you
plan to use non-ASCII characters.

The long-term goal is to use CLOS for font selection, following the
recommendations
\href{http://www.cairographics.org/manual/bindings-fonts.html}{here}.
Also, proper handling of glyphs would be a nice thing, but would
require other libraries (eg \href{http://www.pango.org/}{Pango}) for
converting text to glyphs.

\subsection{Transformations}
\label{sec:transformations}

cl-cairo2 defines the structure \lstinline!trans-matrix! with the
slots \lstinline!xx!, \lstinline!yx!, \lstinline!xy!, \lstinline!yy!,
\lstinline!x0!, \lstinline!y0!.  The defaults for these slots give you
the identity matrix.

All the functions that use transformation matrices use this structure.
Consequently, \verb!cairo_matrix_init! has no corresponding function
in cl-cairo2: you can construct a translation matrix using
\lstinline!make-trans-matrix!.

Some functions are renamed, see Table~\ref{tab:naming}.  Generally,
functions which manipulate \lstinline!trans-matrix! stuctures start
with \lstinline!trans-matrix-!, and other a few other functions have
been renamed to avoid conflicts with linear algebra packages.

\subsection{Xlib Contexts}
\label{sec:xlib-context}

The xlib context is not part of cairo -- it is a bit of glue code that
uses cairo's X11 surface on a pixmap, and displays this pixmap when
needed (when X11 asks for the window contents to be redrawn or when
cairo draws on the pixmap).

In cl-cairo2, each window maps to a context.  The surface is not
exposed to the user, who is only allowed to see the context.  This
makes memory management and proper cleanup easier.  For example, you
can create an \lstinline!xlib-context! with
\begin{lstlisting}
(setf *context* (create-xlib-context 500 400
                                         :display-name "localhost:0"
                                         :window-name "my pretty drawing"))
\end{lstlisting}
If you give \lstinline!nil! for \lstinline!display-name!, Xlib fill
probably figure out a reasonable default, usually from your
\verb!$DISPLAY! environment variable.

The X11 event loop runs in a separate thread, so you need a Lisp
implementation that supports threads.  

When the context \lstinline!destroy!ed, the window is closed.  This
works the other way too: when the window is closed, the context is
destroyed.  The windows are double-buffered using a pixmap on the X11
server, therefore redrawing exposed windows is fast.  However, this
implementation precludes the resizing of the window.

Example code can be found in \verb!tutorial/x11-example.lisp!.  The
current implementation is not optimized for speed (the whole window is
redrawn all the time) but it is fast enough.  If you draw a lot of
objects at the same time, it is suggested that you suspend
synchronizing with the X-window server using
 \lstinline!(sync-lock context)!.
  When you are done, you can call \lstinline!(sync-unlock context)!, which will automatically sync the buffer and the window.
You can nest calls to \lstinline!sync-lock!  and
\lstinline!sync-unlock!, and if you want to restore syncing
unconditionally, use \lstinline!sync-reset!, which also performs
syncing too.  These are generic functions which do nothing for other
contexts.



\subsection{To Do}
\label{sec:todo}

The list below reflects my priorities.  If you need something, please
let me know.
\begin{itemize}
\item patterns (should be easy)
\item Win32 surfaces (I can't do it, I don't use Windows)
\item CLOS integration for fonts (as suggested
  \href{http://www.cairographics.org/manual/bindings-fonts.html}{here})
\end{itemize}

Things I don't plan on doing, but will be happy to incorporate if
somebody does it:
\begin{itemize}
\item Pango and/or glyph handling
\end{itemize}


\section{Examples}
\label{sec:examples}

Below is an extended example, which can be found in
\texttt{example.lisp}.  Figures~\ref{fig:text}--\ref{fig:hearts} show
the results.

\lstinputlisting{example.lisp}

\begin{figure}[htbp]
  \centering
  \includegraphics[height=8cm]{text.epsi}
  \caption{text.pdf}
  \label{fig:text}
\end{figure}

\begin{figure}[htbp]
  \centering
  \includegraphics[height=8cm]{lissajous.epsi}
  \caption{lissajous.pdf}
  \label{fig:lissajous}
\end{figure}

\begin{figure}[htbp]
  \centering
  \includegraphics[natwidth=12cm, natheight=9cm]{hearts.png}
  \caption{hearts.png}
  \label{fig:hearts}
\end{figure}

\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
