easyrender-0.1.0.0: Graphics/EasyRender.hs
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleContexts #-}
-- | This module provides efficient functions for rendering vector
-- graphics to a number of formats, including EPS, PostScript, and
-- PDF. It provides an abstraction for multi-page documents, as well
-- as a set of graphics primitives for page descriptions.
--
-- The graphics model is similar to that of the PostScript and PDF
-- languages, but we only implement a subset of their functionality.
-- Care has been taken that graphics rendering is done efficiently and
-- as lazily as possible; documents are rendered \"on the fly\",
-- without the need to store the whole document in memory.
--
-- The provided document description model consists of two separate
-- layers of abstraction:
--
-- * /drawing/ is concerned with placing marks on a fixed surface, and
-- takes place in the 'Draw' monad;
--
-- * /document structure/ is concerned with a sequence of pages, their
-- bounding boxes, and other meta-data. It takes place in the
-- 'Document' monad.
module Graphics.EasyRender (
-- * Types
-- ** Coordinates
X,
Y,
-- ** Color
Color(..),
-- ** Fonts
Basefont(..),
Font(..),
nominalsize,
text_width,
-- ** Alignment
Alignment,
align_left,
align_center,
align_right,
-- * The Document monad
-- $DOCUMENTMODEL
Document,
newpage,
newpage_defer,
endpage,
-- * The Draw monad
-- $DRAWINGMODEL
Draw,
-- ** Path construction commands
-- $PATHCONSTRUCTION
newpath,
moveto,
lineto,
curveto,
closepath,
arc,
arc_append,
oval,
rectangle,
-- ** Painting commands
stroke,
fill,
fillstroke,
-- ** Text commands
textbox,
-- ** Graphics parameters
-- $GRAPHICSPARAMETERS
setlinewidth,
setcolor,
-- ** Coordinate system
-- $COORDINATESYSTEM
translate,
scale,
-- ** Comments
comment,
-- ** Block structure
-- $BLOCKSTRUCTURE
block,
-- * Backends
-- $BACKENDS
RenderFormat(..),
render_stdout,
render_file,
render_string,
-- * Customization
-- $CUSTOMIZATION
-- ** Custom drawing commands
-- $CUSTOMCOMMANDS
draw_subroutine,
custom_ps,
custom_pdf,
custom_ascii,
-- ** Customization interface
Custom(..),
custom,
-- ** Customized rendering functions
-- $CUSTOMRENDER
render_custom_stdout,
render_custom_file,
render_custom_string,
) where
import Graphics.EasyRender.Internal
-- $DOCUMENTMODEL
--
-- Document description takes place in the 'Document' monad. A basic
-- multi-page document has the following structure:
--
-- > document :: Document ()
-- > document = do
-- > newpage x y $ do
-- > <<<drawing commands>>>
-- > newpage x y $ do
-- > <<<drawing commands>>>
-- > ...
--
-- Here, each 'newpage' command describes one page of the
-- document. The parameters /x/ and /y/ specify the dimensions of the
-- page bounding box. They are expressed in units of PostScript
-- points, i.e., multiples of 1/72 inch.
--
-- Sometimes the bounding box for a page is not known until after the
-- page content has been generated. For this purpose, we also provide
-- the following alternative to the 'newpage' command:
--
-- > newpage_defer $ do
-- > <<<drawing commands>>>
-- > endpage x y
--
-- It works just like the 'newpage' command, except that the bounding
-- box is given at the end.
-- $DRAWINGMODEL
--
-- The description of the visible content of a page take place in the
-- 'Draw' monad. It takes the form of a sequence of drawing commands,
-- for example:
--
-- > moveto 10 10
-- > lineto 10 100
-- > lineto 100 100
-- > lineto 100 10
-- > closepath
-- > stroke
--
-- The graphics model is similar to that of the PostScript and PDF
-- languages. The basic concept is that of a /path/, which is a
-- sequence of straight and curved line segments. Paths are first
-- constructed using /path construction commands/, and then painted
-- using /painting commands/, depending on a set of current
-- /graphics parameters/ and a current /coordinate system/.
--
-- We also provide block structure. Changes to the graphics state
-- (color, coordinate system, etc.) that are done within a block are
-- local to the block.
--
-- > block $ do
-- > <<drawing commands>>
-- $PATHCONSTRUCTION
--
-- During path construction, there is a notion of /current path/ and
-- /current point/. A path may consist of zero or more connected
-- subpaths, and each subpath is either open or closed.
-- $GRAPHICSPARAMETERS
--
-- The painting commands rely on a set of graphics parameters. The
-- graphics parameters are initially set to default values, and can be
-- altered with the following commands.
-- $COORDINATESYSTEM
--
-- Coordinates, lengths, widths, etc, are all interpreted relative to
-- a /current coordinate system/. The initial coordinate system of
-- each page has the origin in the lower left corner, with each unit
-- equaling one PostScript point (1/72 inch). The following commands
-- can be used to change the current coordinate system.
-- $BLOCKSTRUCTURE
--
-- Drawing operations can be grouped into blocks with the 'block'
-- operator. Changes to the graphics parameters and coordinate system
-- are local to the block. It is undefined whether changes to the
-- current path made within a block persist after the end of the block
-- (they do in PDF, but not in PostScript). Therefore, path
-- construction should not be broken up across end-of-block boundaries.
-- $CUSTOMIZATION
--
-- The document and drawing abstractions provided by this module are
-- purposely kept general-purpose, and do not include
-- application-specific features. However, we provide a mechanism by
-- which applications can provide customized drawing commands and
-- other custom features.
-- $CUSTOMCOMMANDS
--
-- It is sometimes useful to use customized drawing commands. For
-- example, an application that draws many rectangles might like to
-- define a custom 'rectangle' function for appending a rectangle to
-- the current path. Of course this can be defined as an ordinary
-- Haskell function, using elementary drawing commands:
--
-- > my_rect :: X -> Y -> X -> Y -> Draw ()
-- > my_rect x0 y0 x1 y1 = do
-- > moveto x0 y0
-- > lineto x0 y1
-- > lineto x1 y1
-- > lineto x1 y0
-- > closepath
--
-- However, sometimes it is nice to make use of specialized abilities
-- of individual backends. For example, PDF already has a built-in
-- rectangle drawing command, and PostScript has the ability to define
-- custom subroutines within the document text. Using these features
-- can decrease the size of the generated documents.
--
-- We therefore provide a facility for defining new drawing commands
-- with backend-specific implementations. For example, a more general
-- version of the above 'my_rect' function can be defined as
-- follows:
--
-- > my_rect :: X -> Y -> X -> Y -> Draw ()
-- > my_rect x0 y0 x1 y1 = draw_subroutine alt $ do
-- > moveto x0 y0
-- > lineto x0 y1
-- > lineto x1 y1
-- > lineto x1 y0
-- > closepath
-- > where
-- > alt = [
-- > custom_ps $ printf "%f %f %f %f rect\n" x0 y0 x1 y1,
-- > custom_pdf $ printf "%f %f %f %f re\n" x0 y0 (x1-x0) (y1-y0),
-- > custom_ascii $ printf "My_rect %f %f %f %f\n" x0 y0 x1 y1
-- > ]
--
-- The idea is to provide a default definition in terms of primitive
-- drawing commands, as well as a list of various backend specific
-- definitions. In the case of PostScript subroutines, the PostScript
-- file must then also be supplied with a definition for the /rect/
-- subroutine, which can be done with the command 'render_ps_custom':
--
-- > my_ps_defs = "/rect { ... } bind def\n"
-- >
-- > my_render_ps = render_ps_custom custom { ps_defs = my_ps_defs }
--
-- Note that the 'draw_subroutine' customization mechanism is entirely
-- optional. Its purpose is to generate shorter output for some
-- backends; if it is omitted, the file may be be longer but should
-- look the same.
-- $BACKENDS
--
-- The following commands can be used to render documents to various
-- available formats. The available formats are PostScript, PDF, EPS,
-- and an ASCII-based debugging format. Output can be written to
-- standard output, to a file, or to a string.
-- $CUSTOMRENDER
--
-- The following are versions of the generic rendering functions that
-- also take a customization data structure as an additional
-- parameter.