epix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ePiX-devel] Recent recoding


From: Andrew D. Hwang
Subject: [ePiX-devel] Recent recoding
Date: Thu, 11 Jan 2007 12:19:56 -0500 (EST)

Here's a summary of the changes to ePiX in the past week. Not everything works yet, and (since the term starts next Wednesday rather than the week after) I need to spend a day or two on other things. However, I Really Hope (and reasonably expect) the code to work as described below within the next week.

The internal implementations compile, and I'm in the process of writing the user-level code in the new framework. Nothing has been tested yet, but since large chunks come from ePiX2 (where they seemed to work) I'm cautiously optimistic that the remaining work will progress smoothly.

None of the code has been uploaded anywhere, but I'm happy to distribute it privately if anyone is interested. For now, there are no guarantees on anything but the user interface (call syntax, and most of the semantics) from Version 1.0.22: Internal details are theoretically subject to change.

--Andy

Andrew D. Hwang                 address@hidden
Department of Math and CS       http://mathcs.holycross.edu/~ahwang
College of the Holy Cross       (508) 793-2458 (Office: 320 Swords)
Worcester, MA, 01610-2395       (508) 793-3530 (fax)


Design of ePiX-1.0.23
=====================

ePiX-1.0.23 (a pre-release of ePiX-1.1) shares the user interface of
ePiX-1.0.22, but differs completely in implementation. A figure is
still built up command-by-command from the input file, but commands'
actions are stored as internal data structures, then written to the
output file in one step at the end of the file. Four goals guided the
recoding. In decreasing order of importance:

1. Make old files compile with the same meaning.

2. Organize the code to minimize cross-dependencies between files, and
   to make the code more maintainable, or at least understandable by
   others.

   Provide small, (relatively) flexible classes instead of complex
   single-purpose functions. (The old path::draw() functions exemplify
   the depths to which the code had sunk.)

   Strive to name these classes systematically and provide standard
   interfaces. Some classes (Color et. al., Camera) were retrofitted
   almost verbatim from ePiX2, while others (length, screen, picture,
   and format, for example) borrowed heavily from ePiX2.

3. Hide or encapsulate global data, preferring the "initialize on
   first use" idiom. Hide implementation details that users aren't
   supposed to use. (Files such as globals.h, Labels.h, and output.h
   contained very little of use to the user.)

   Functions that used to accept EPIX_NUM_PTS or EPIX_INFTY as default
   arguments are instead provided in multiple forms, to avoid exposing
   internal constants in user header files.

4. Incorporate (some of) ePiX2 in a "usable" library as a way of
   better understanding how the core functionality ought to be
   structured to facilitate high-level coding.


Global State
============

Drawing falls into three categories: textual, path, and filling. The
attributes controlled by declaration-style commands fall into five
categories. Each is accessed through a void function that returns a
static reference to the corresponding data structure.

(i) paint_style.h, the_paint_style().

  The visual attributes are color and line width (conceptually a
  "pen"), fill style (solid or none) and color, line style (solid,
  dashed, dotted, as well as associated attributes such as dash
  length)

(ii) label_style.h, the_label_style().

  This class controls text color, mask color, label padding and border
  pen (for boxed labels), alignment, font face and size, and rotation
  angle.

(iii) arrowheads.h, the_arrowhead_style().

  Arrowhead width, ratio (length to width), camber, and filling.

(iv) clipping.h, the_clip_box().

  Clipping is now automatic, but there should be no discernible change
  of behavior: Users needn't know about clipping at all, except to
  resize the_clip_box().

(v) angle_units.h, the_angle_style().

  Radians (default), degrees, and revolutions.


Picture Description
===================

The screen class is an abstract rectangle in which figure elements,
known as "tiles", are drawn. A complete figure corresponds to the
picture class, which comprises two screens, unitlength and true
offsets, and some internal bookkeeping data (such as a list of all
colors that appear). Most of this data is public; the alternatives
were to write an enormous interface, or to make dozens of functions
friends of the picture class. As a concession to encapsulation, the
picture class is a wrapper; the implementation (where the public data
lives) is invisible to the user.

The first screen, the_canvas, corresponds to (and is controlled
exactly like) the bounding_box. The second screen is the_page, and
represents the picture box. There is a static picture reference,
the_picture(), which plays the role of "the global picture" that
corresponds to the input file.

A picture can be initialized in one command:

  picture(P(a,c), P(b,d), "4in x 6cm");

is the same as

  bounding_box(P(a,c), P(b,d));
  unitlength("1in");
  picture(4, 2.3622); // height units converted to width units

The old-style commands are retained, but I hope/expect the new form to
catch on.


Picture Representation
======================

There are (going to be) five kinds of tile:

(i) glyph, for labels and markers (tile0.*)

(ii) outline, for unfilled paths (tile1.*)

(iii) [unnamed], for arrows

(iv) plate, for filled paths (tile2.*)

(v) [command?], for attribute-setting commands such as linewidth and
  color declarations.


Every object-creating command builds a 3-D data structure, clips it according to the clip box and the camera position (it is no longer possible to see objects behind the camera!), maps it to a tile via the camera (which also performs color filtering), and adds the tile to a screen. At any point in an input file, one screen is "active". By default, the_picture().the_canvas is active. A sub-picture is drawn by creating and activating another screen, then "pasting" the screen onto a given region of the_canvas.

The screen class (also a wrapper for the actual implementation) is in
user space, naturally. A screen has a "crop mask" (rectangles and
ellipses are implemented), and can be cropped to the mask. There are
two decorations, border (drawn by a pen) and backing (solid color).
Backing is intended to facilitate insets, including graph legends, but
theoretically could be used to draw flow charts (one screen per node!)
et. al.


Output
======

When the "end()" command is issued, the_canvas is affinely scaled onto
the_page, labels' offsets and dashed line lengths are computed, and
the list of tiles is passed to an output format (eepic is implemented,
PSTricks will be soon), which writes the_page's contents to stdout or
to a specified file. A single run of epix can now write multiple files
if there's some reason to do so. (One must take care not to direct the
output to the filename epix generates!)


The User Interface
==================

The user interface comprises (exactly) the following:

* Attribute-setting commands

* Markers and text labels

* Curve-like objects (lines and polygons, arcs, ellipses, splines)

* Coordinate grids and plotting, including data plotting

* Miscelleneous drawing (e.g., spherical plotting)

* Geometric objects (circle, segment, sphere, plane)

* Page markup

The first six are included in the existing interface, and work almost
exactly as before. The differences are:

* clip() has no effect, as clipping is always active.

* The global reference the_camera() should be used in favor of the
  object "camera". (If it's not a burden on users, I'd prefer to
  replace "camera" by "camera()", but it's easy to code either way.)

* The global variables x_min, etc. are accessible through xmin(),
  etc. As with the camera, I'd sort of like to use x_min() and force
  users to change immediately. (Andrew Sterian sensibly made this
  change to Pyepix years ago.)


Source Code Organization
========================

Starred files are essentially unchanged from ePiX-1.0.22. Capitalized
file names (and classes therein) come from ePiX2.


---(A)---
active_screen.h
  The active_screen() object

angle_units.h
  Angular mode state

arrowheads.h
  Arrowhead style state


---(C)---
camera.h
  The Camera (back-ported from ePiX2)

circle.h [*]
  The circle object class

clipping.h
  The clip_box

Color.h
  The Color interface. COlor models are implemented in the files

  Color_CMY.h
  Color_CMYK.h
  Color_Gray.h
  Color_Neutral.h
  Color_RGB.h
  Color_Sep.h (Cyan/Magenta/Yellow/Black layers for separation)

Color_Utils.h
  Miscellaneous functions for Color manipulation

constants.h
  The parts of globals.h users don't need to see

cropping.h
  Whether or not cropping is active, and what to do if it is

curves.h [*]
  Lines, simple polygons, arcs, ellipses, splines


---(D)--- dataplot.h [*]
  Data plotting (many new features since last "official" version)

deriv.h
  A difference quitient template that doesn't belong in functions.h

domain.h [*]
  Plot ranges


---(E)---
edge_data.h
  Template class for representing paths

eepic.h
  The eepic output format

enums.h
  The parts of globals that users need

errors.h [*]
  Warning functions


---(F)---
format.h
  The output format interface

frame.h [*]
  Orthonormal bases

functions.h [*]
  Miscellaneous functions for plotting, etc.


---(G)---
geometry.h [*]
  Spherical and hyperbolic geometry


---(H)---
halfspace.h
  A helper class for clipping


---(L)---
label_data.h
  Formerly Labels.h, but will an improved design

label_style.h
  Visual attributes of textual elements

length.h
  True length manipulation


---(M)---
map.h [*]
  Template wrappers for plotting


---(O)---
object.h
  The common interface for circle, plane, segment, and sphere


---(P)---
paint_style.h
  Visual attributes for (un)filled paths

pair_map.h
  Affine mappings between screens

pairs.h [*]
  The basic 2-d class

path_data.h
  The implementation of path

path.h [*]
  Same interface, totally refurbished backend

picture_data.h
  The implementation of picture

picture.h
  The user interface of picture

plane.h [*]
  The plane class

plot_algorithms.h [*]
  Plotting templates

plots.h [*]
  Plotting commands

polyhedron.h [*]
  Collections of edges that can be cut by a plane; not well-implemented


---(S)---
screen_data.h
  The implementation of screen

screen.h
  The user interface of screen

screen_mask.h
  Crop regions

segment.h [*]
  The segment object class

sphere.h [*]
  The sphere object class

state_data.h
  Wrapper header that includes five "style" headers

state.h
  User-space global functions for manipulating the drawing state

surface.h [*]
  Shaded syrface plotting


---(T)---
tile0.h
  The glyph class (0-dimensional tile)

tile1.h
  The outline class

tile2.h
  The plate class

tile.h
  The tile interface

triples.h [*]
  The basic 3-d class

utils.h
  Functions useful for writing an output file




reply via email to

[Prev in Thread] Current Thread [Next in Thread]