
Changes from grid_4.1.* to grid_4.2.0:
-------------------------------------

1.  New 'vpPath' argument to grid.grep() so that we can ask for
    matching grobs WITH vpPaths WITHOUT having to ask for matching
    viewports, e.g., grid.grep("path", vpPath=TRUE).

    The value of 'vpPath' defaults to the value of 'viewports', so ...

    grid.grep("path", viewports=TRUE)

    ... behaves as before.

2.  New grid.group(), grid.define(), and grid.use() functions for
    defining and using "isolated groups" (on supported devices).
    These can be used to draw content in isolation before combining
    the content with the main image, to apply compositing operators
    other than "over", and to apply affine transformations to
    content.

3.  New grid.stroke(), grid.fill(), and grid.fillStroke() functions
    for defining a path (based on a grob) and then stroking and/or
    filling that path.

4.  viewport(clip) can now be a path, from as.path().  This defines a
    clipping path and allows the fill rule for the path to be
    specified.

5.  Text and raster content can now be included in patterns,
    (clipping) paths, and masks (and groups).  (On supported devices.)

6.  The fixed limit on the number of patterns, clipping paths, and/or
    masks on Cairo-based devices has been removed.

7.  Fix for reinitialising gpar settings when pushViewport() then
    grid.newpage() WITHOUT up/popViewport().

8.  Clipping paths and masks are turned off (initially) when resolving
    a pattern.

9.  Stricter rules to disallow pattern, clipping path, mask, group, or
    path within clipping path or path.

10. Fix for replayPlot() of an "empty" 'grid' "plot"
    (where recordPlot() was called with 'grid' loaded, 
     but with no 'grid' drawing performed).

    Bug 18237 (Thanks to Kevin Ushey for bug report).


Changes from grid_4.0.* to grid_4.1.0:
-------------------------------------

1.  Bug fix for grid.curve() with vertical or horizontal "curve".
    Thanks to Patrick Breheney for the report.

2.  Bug fix for grid.pack(side="[left|top]").
    Thanks to Deepayan Sarkar for the report.

3.  New editViewport() function.

4.  gpar(fill) can now be a linearGradient() or radialGradient() or 
    pattern().

5.  viewport(clip) can now be a grob (that defines a clipping path).

6.  New viewport(mask) argument that can be "none", "inherit", or
    a grob (that defines a mask).


Changes from grid_3.6.* to grid_4.0.0:
-------------------------------------

1.  upViewport() or popViewport() now correctly reverts to previous
    gpar() settings.  

    It used to always revert to previous viewport gpar() settings, 
    but that is wrong if we are coming out of a viewport that 
    is a 'childrenvp' of a gTree and the gTree has gpar() settings
    (in that case we should revert to the gTree gpar() settings).

    Reported by Nicolas Coutin.

2.  Internal reimplementation of units, thanks to Thomas Lin Pedersen,
    which makes operations on units MUCH faster.

    Only user-visible change is printing of results of unit arithmetic,
    which now always looks like a call to sum(), and a new unit.psum()
    function.

    Internally, there are now just "simpleUnit" and "unit" (no more
    "unit.arithmetic" and "unit.list").


Changes from grid_3.5.* to grid_3.6.0:
-------------------------------------

1.  New functions deviceLoc() and deviceDim().

2.  Improve handling of graphics devices in grid.grabExpr().
    Should now work when multiple graphics devices already open
    (e.g., within 'knitr' document).

3.  Fix bug in grid.layout() when viewport has negative width/height
    (e.g., due to being sized in "native" units within viewport
     with flipped scales).

    Thanks to report by Silas Dean.

4.  Add 'wrap.grob' argument to grid.grab() and grid.grabExpr()
    to allow wrapping of grobs as well as viewports (if both
    'wrap' and 'wrap.grob' are TRUE.

    Also, no longer check for duplicate grob names at top-level
    if 'wrap' is TRUE.

    Also, do not start new page if 'wrap' is TRUE.

    Thanks to report from John Bullock.

5.  Exported makeContent.default() (so that
    external packages can do more stuff with grobs)

6.  New 'pathId' and 'pathId.lengths' arguments for grid.path()
    to allow multiple paths to be drawn at once.

    Contributed by Thomas Lin Pedersen.

7.  New grobCoords() and grobPoints() functions to calculate points 
    along the perimeter (or length) of a grob.

8.  Internal changes to graphical parameter setting to speed things
    up a bit.  
    
    Contributed by Thomas Lin Pedersen.


Changes from grid_3.4.* to grid_3.5.0:
-------------------------------------

1.  Fix for current.vpTree() so that it puts you back in the right
    place in the viewport tree if there are nested viewports with
    the same name (e.g., pushViewport(vp, vp)).

    Reported by Prem Thomas.

2.  Added 'device' (and 'width' and 'height') arguments to grid.grabExpr()

    Suggestion from Claus Wilke.


Changes from grid_3.3.* to grid_3.4.0:
-------------------------------------

1.  Added format() method for units, so, for example, the number of 
    digits printed for numeric values can be controlled.

    grid.show.layout() now uses format() for annotating layout
    widths and heights.

2.  More robust handling of NA values in graphical parameter settings
    that affect text.  NA values for fontsize, lineheight, cex, and
    fontfamily are ignored, i.e., inherited from parent drawing context.
    A mixture of NA and non-NA generates an error.

3.  Improved support for calcStringMetric() function (and
    stringAscent() and stringDescent() and grobAscent() and
    grobDescent()) so that text encoding is now handled.

    Reported by Hakon Malmedal and Hadley Wickham.


Changes from grid_3.2.* to grid_3.3.0:
-------------------------------------

1.  Added "pseudonym" units to check made in absolute.size() so that,
    for example, absolute.size(unit(1, "in")) works properly
    (reported by Baptiste Auguie).

2.  Registered absolute.units() methods in NAMESPACE, so that, for
    example, a call to absolute.size(unit(1,"npc") + unit(2,"mm"))
    works outside of 'grid' (reported by Baptiste Auguie).

3.  Refactored grid.draw() so that grid.draw(NULL) now works 
    (by doing nothing).  Reported by Hadley Wickham.

4.  Modified grid.ls() so that it returns nothing if there are no
    active devices (rather than opening a new device).
  
5.  Modified grid.grep() so that it returns an empty list (rather than
    throwing an error) when the 'grid' display list is empty.

6.  Added subassignment methods for unit objects
    (e.g., x <- unit(1:3, "cm"); x[2] <- unit(.5, "npc"))

    Thanks to Baptiste Auguie for code suggestions.


Changes from grid_3.1.* to grid_3.2.0:
-------------------------------------

1.  Fixed evaluation of "pure null" units (by making evaluation recursive).
    Previously, for example, a unit list with a unit list as its first
    component would evaluate to NA.  This typically only affects layouts 
    in grid.

    Problem reported by Baptiste Auguie.

2.  Fixed problem in validDetails.beziergrob(), which used to fail if
    you tried to specify 'id.lengths'

3.  Fixed bug in downViewport() when descending more than one
    viewport.  It was possible for this to end up with the wrong
    clipping region (because if you ended up in a viewport that
    inherited its clipping region from a parent, that clipping region
    was not enforced).


Changes from grid_3.0.* to grid_3.1.0:
-------------------------------------

1.  New current.rotation() function.

2.  vpPath() and gPath() now automatically expand any embedded path 
    separators in their input.

3.  New functions depth(), for determining the depth of a viewport 
    hierarchy or path, and explode(), for expanding a path into
    its components.

4.  New function grid.grep()
    (based on ideas and code from Simon Potter).

5.  The grid.force() function now accepts an explicit grob to (draw 
    and) force or a gPath to force a specific already-drawn grob.
    Ditto the grid.revert() function.

6.  New current.parent() function to return parent of current viewport.

7.  New resolveRasterSize() function.

8.  Made 'vp' argument of current.viewport() defunct.

9.  Deprecated functions made defunct: 
    grid.grob, grid.arrows, arrowsGrob, grid.convert, grid.convertX,
    grid.convertY, grid.convertWidth, grid.convertHeight,
    grid.collection, push.viewport, pop.viewport, viewport.transform,
    draw.details, convertNative.

10. Down viewports are now recorded on the display list as full-depth
    strict vpPaths even when downViewport() is called with non-strict
    vpPath (which can produce a down viewport of greater depth than
    the depth of the vpPath).

11. Exported generic forceGrob().

12. Bug fix for recording viewport pushes on the graphics engine display
    list (reported by the friendly folks from RStudio).

    The bug could be tickled by copying a grid scene from one graphics
    device to another and then attempting to navigate within 
    viewports on the original graphics device.

13. Better defenses against division-by-zero in unit resolution/conversion
    (see ./DivByZero.txt).


Changes from grid_3.0.0 to grid_3.0.1:
-------------------------------------

1.  Added str() method for "unit.arithmetic"
    Reported by Andreas Leha.


Changes from grid_2.15.0 to grid_3.0.0:
--------------------------------------

1.  Bug fix for showViewport() when the viewport is a
    "vpStack" and one of the components of the stack
    is NOT just a simple viewport (e.g., when one of
    the components of the "vpStack" is a "vpStack").

2.  Bug fix for grid.ls(viewports = TRUE) when listing a
    "vpStack" and one of the components of the stack
    is NOT just a simple viewport (e.g., when one of
    the components of the "vpStack" is a "vpStack").

3.  Added support for "vpPaths" within a "vpStack",
    "vpList", or "vpTree" (i.e., mixing of viewports
    and "vpPaths").

4.  New functions grid.reorder() and reorderGrob() to  
    modify the order in which the children of a gTree 
    are drawn.

5.  Bug fix for grid.ls() to report children of a gTree
    in the correct order.

6.  New makeContext() and makeContent() "hook" functions
    to allow alternative method for creating custom grobs.

7.  Standard behaviour for grobs is now to use upViewport()
    rather than popViewport() on the 'vp' slot.

8.  New grid.force() function to provide access to grobs 
    that are generated only at drawing time (for grobs that 
    use the new makeContent() hook).

9.  New grid.revert() function to revert the effect of 
    grid.force().

10. Implementation of "xaxis", "yaxis", "frame", "cellGrob",
    "roundrect", "beziergrob", "curve", and "functiongrob"
    changed to use makeContext() and makeContent() hooks.

11. New grid.delay() and delayGrob() functions;  analogues
    of grid.record() and recordGrob() that are implemented
    via makeContent() hooks.


Changes from grid_2.14.0 to grid_2.15.0:
---------------------------------------

1.  Added calcStringMetric() function.

2.  Added "strascent" and "strdescent" units, plus 
    stringAscent() and stringDescent() convenience functions.

3.  Added "grobascent" and "grobdescent" units, plus 
    grobAscent() and grobDescent() convenience functions.

    The "ascent" of a grob is equivalent to its height by default,
    but ascentDetails() methods can be written 
    (e.g., text grobs are different).

    The "descent" of a grob is zero by default,
    but descentDetails() methods can be written 
    (e.g., text grobs are different).

4.  Fix for xsplinePoints() so that it copes with xspline grob
    with non-NULL 'id' AND so that it takes the 'vp' and 'gp'
    settings into account.

5.  Added grid.bezier() function to draw Bezier curve
    (using an X-spline approximation).

    Also added bezierPoints() function.

6.  Added grid.DLapply() function.


Changes from grid_2.12.0 to grid_2.13.0:
---------------------------------------

1.  Added grid.function() for drawing lines to represent functions.

2.  Fixed bug in calculation of x, y, width, and height of segments
    grobs.

3.  Fixed bug in grid.grab(wrap = TRUE) when the scene includes 
    downViewport()s.

4.  Added showGrob() function.


Changes from grid_2.11.0 to grid_2.12.0:
---------------------------------------

1.  Neither width nor height need to be specified in 
    grid.raster().  The image aspect ratio will be used
    to calculate an appropriate image size for the 
    current viewport.

2.  Added [x|y|width|height]Details() methods for "rastergrob"s

3.  "roundrect" grobs now obey their 'just' setting
    (bug reported by Beau Benjamin Bruce)

4.  Added grid.path() for rendering paths with holes.


Changes from grid_2.10.0 to grid_2.11.0:
---------------------------------------

1.  Added xsplinePoints() function to return the (x, y) 
    locations that an Xspline would be drawn through.
    Useful for, e.g., clipping an Xspline against a
    boundary.

2.  Added grid.raster() function for rendering raster images.

3.  Added grid.cap() function for capturing output on
    current graphics device as a raster image.

4.  Fixed PROTECT() bug in grid.rect() PR#14199
    Thanks to Andrew Runnalls for the bug report.

5.  Fixed multiple problems in rep.unit() and unit subsetting.
    Motivated by PR#14170.  Thanks to Bert Gunter.
    

Changes from grid_2.9.0 to grid_2.10.0:
--------------------------------------

1.  Added showViewport() function for displaying viewport trees
    graphically.

2.  Fixed bug in unit() indexing;  negative integer indices now work.

3.  Modified behaviour of editGrob() and addGrob() so that they 
    return the original grob if the specified gPath does not exist,
    and issue a warning (if new argument 'warn' is TRUE).
    

Changes from grid_2.8.0 to grid_2.9.0:
-------------------------------------

1.  Copied grid.roundRect() from 'RGraphics' package into 'grid'.

    Renamed to grid.roundrect() and also used roundrectGrob()
    rather than roundRect(), partly for more consistent naming,
    partly to avoid namespace collision until original functions
    get removed from 'RGraphics' package.

2.  Fixed bug in grid.curve() when curve is horizontal or vertical
    straight line.

3.  Exposed is.grob() and valid.just() via the NAMESPACE.

4.  Fixed bug in downViewport(), which meant that unsuccessful
    downViewport()s were still being recorded on the graphics
    engine display list.  This could cause interesting results
    when a window is resized (i.e., when the display list is 
    replayed).  

    Bug reported by Felix Andrews.

5.  Added some pseudonyms for come units.  For example, it is now
    possible to specify just "in" instead of "inches".


Changes from grid_2.7.0 to grid_2.8.0:
-------------------------------------

1.  Added grid.null() and nullGrob();  grob that is guaranteed
    to have zero-width, zero-height, and draw nothing.

    Useful as zero-size placeholder AND as invisible reference
    point for other grobs to draw relative to.

2.  Fixed bug in listing, via grid.ls(), of frame grobs.  If the frame
    had a vpPath in its 'vp' component, you got an error from vpStack().

    Problem reported by Hadley Wickham.

3.  Fixed a bug in grid.ls() when attempting to list the display list
    following the removal of a grob (i.e., so that there were NULLs
    in the display list).

    Problem reported by Felix Andrews.


Changes from grid_2.6.0 to grid_2.7.0:
-------------------------------------

1.  Grid will no longer complain about clipping to a rotated
    viewport if the rotation is a multiple of 90 degrees.

    Prompted by report from Gustaf Rydevik.

2.  Open Xsplines must have zero shape for first and last
    control point, but this was not being enforced correctly
    for the case where there were multiple Xsplines in a
    single grid.xspline() call (i.e., with use of 'id' or
    'id.length').  The problem can be seen with this code
    (most curves do not connect to the first control point
    [there are also subtle errors in the curve shapes]):

        grid.newpage()
        pushViewport(viewport(w=.5, h=.5))
        grid.xspline(x=outer(c(0, .5, 1, .5), 5:1/5),
                     s=1,
                     y=outer(c(.5, 1, .5, 0), 5:1/5),
                     id.lengths=rep(4, 5),
                     gp=gpar(col=1:5, lwd=3))
        grid.rect()

3.  Frame grobs have been improved so that all of the viewports
    that are generated during the drawing of a frame (and its
    cells) are left on the display list (previously, they were
    popped).

    This has implications particularly for ggplot[2] because
    it means that it is now possible to downViewport() to 
    viewports created during the drawing of a ggplot[2] plot
    to, for example, add further annotations to the plot.

4.  Small fixes to grid.ls():

    - viewports pushed by cellGrobs within frames are now
      shown by grid.ls()

    - fixed warning (bug really) when display list contains
      only one grob (and padPrefix() is called).


Changes from grid_2.5.0 to grid_2.6.0:
-------------------------------------

1.  Added grid.gedit() as convenience wrapper for grid.edit()
    based on usage patterns of Hadley Wickham when working with
    'ggplot' package.

    Ditto, grid.gget() and grid.gremove().

2.  Improved implementation of 'id' and 'id.lengths' arguments
    for drawing multiple polygons/polylines/xsplines to gain 
    order 2 speed improvement.  

    Problem independently reported by Luke Tierney, Deepayan Sarkar and
    Vilmos Prokaj.

3.  Bug fixes for grid.remove(), especially for grep=TRUE and global=TRUE
    (i.e., removing all grobs from DL where the name matches a pattern).

    Also some fixes to grid.remove() error messages when no match found.

    Bug reports from Hadley Wickham.

4.  New function grid.ls() for listing grob trees and viewport trees
    (including both grob trees and viewport trees interlaced).

    Useful for exploring current grob/viewport tree, explaining
    grob/viewport trees, and programming on or debugging 
    grob/viewport trees.


Changes from grid_2.4.0 to grid_2.5.0:
-------------------------------------

1.  Added 'open' argument to grid.curve().  This allows, for example,
    filling the segment of a circle.

2.  Fixed bug in arrow() function:  segfault produced if either 
    'ends' or 'type' argument are given as NULL.  Thanks to
    Sebastien Luque for the report.


Changes from grid_2.3.0 to grid_2.4.0:
-------------------------------------

1.  Bug fix for colour used when drawing a rectangle in a
    rotated viewport (reported by Olaf Burger).

2.  Removed 'units.per.obs' argument from grid.lines() and 
    grid.segments() 

    (This is a bug fix;  should have been removed long ago).

3.  Added extra check on 'data' argument of unit(), which means
    that if you supply a non-NULL value where the 'unit' is
    not "str[width|height]" or "grob[x|y|width|height]", you
    get an error.  This may impact on existing code.

4.  Radii in grid.circle() are now silently converted to their
    absolute value (negative values used to trigger an error).

5.  New function grobName() for generating unique (within-session)
    grob names (based on class of grob).

    Also, modified default naming of grobs to be based on class
    of grob.  This should not impact on existing code because
    noone should be depending on the default names generated by grid.


Changes from grid_2.2.0 to grid_2.3.0:
-------------------------------------

1.  Bug fix for stringWidth() and stringHeight() with mathematical 
    annotation.

    These used to always convert the argument to "character".
    Now they let language objects (e.g., expressions) pass through.

2.  New grid.xspline() function to draw X-splines (a general curve
    approximated or interpolated relative to control points).

3.  New 'arrow' argument to grid.line.to(), grid.lines(), and
    grid.segments().  This provides a new way to specify arrow
    heads on either end of a line.

    grid.arrows() has been deprecated.

    NOTE: that the new 'arrow' arguments have been added BEFORE
    the name, gp and vp arguments so existing code that specifies
    any of these arguments *by position* (not by name) will fail.

4.  Added "[" (subset) methods for "gpar" objects.

5.  New grobX() and grobY() functions for producing units 
    describing a location on the boundary of a grob.

6.  Units produced by grobX() and grobY() make use of new 
    xDetails() and yDetails() generic functions to calculate the 
    boundary of a grob.  Methods for these functions are provided
    for all grid graphical primitives.

7.  Bug fix for grid.polygon() when 'x' is not just a simple unit
    (e.g., it is unit arithmetic);  'index' was being calculated
    incorrectly so not all of polygon would be drawn or, if 
    'id' or 'id.length' were used, only a single polygon would
    be drawn (with unexpected shape).

8.  New grid.curve() primitive for drawing a curve between two
    locations.  

    Together with new grobX() and grobY() provides support for
    drawing simple node-and-edge graphs and flow diagrams.

9.  New grid.clip() primitive for setting the clipping region
    (more accurately, the clipping rectangle).  Has effect until
    the next grid.clip() or when the current viewport is popped.

10. New dim.layout() method for layout objects.  Allows easy
    access to dimensions of layout via nrow() and ncol().

11. unit.rep() deprecated in favour of unit method(s) for rep() function.

12. unit.length() deprecated in favour of unit method(s) for length() function.

13. New grid.polyline() primitive.  Just like grid.lines() except has
    'id' and 'id.lengths' arguments.

    These work like the corresponding arguments in grid.polygon() and
    grid.xspline(), allowing multiple polylines to be drawn from a
    single grid.polyline() call.

14. Fixed drawing of top-level gList objects so that they 
    (actually the grobs in the gList) are recorded on the 
    grid display list.

    Allowed a gList to be component of a gList 
    (the gList constructor merges sub-gList into resulting gList).

    Added subset method for gList objects 
    (so that result is still a gList).

15. Bug fix for grid.rect() and grid.circle() with gpar(lty="blank").
    (problem was actually in the graphics engine).
    
    Reported by John Braun (private correspondence).


Changes from grid_2.1.0 to grid_2.2.0:
-------------------------------------

1.  current.vpPath() now exported.

2.  Grid now uses the 'fg' and 'bg' settings (if any) for
    graphics devices to set the initial graphical parameter
    settings of the top-level viewport (i.e., the 'gp' arg
    of viewport[ROOT]).

3.  Fixed bug in evaluation of grobWidth(polygonGrob()).
    The C function L_locnBounds was not exported AND
    the widthDetails.polygon method was not exposed properly
    via the NAMESPACE.

    Reported in private correspondence by Deepayan Sarkar.

    Also corrected export of heightDetails, validDetails, and	
    widthDetails for arrows, circle, polygon, points, rect, and
    segments primitives.


Changes from grid_2.0.1 to grid_2.1.0:
------------------------------------

1.  preDrawDetails(), drawDetails(), and postDrawDetails() 
    methods are now recorded on the graphics engine
    display list.   This means that calculations within these 
    methods are now run when a device is resized or
    when output is copied from one device to another.  A simple
    example (the rectangle remains 1inch wide when resizing the
    device -- it does not in previous versions) ...

        testgrob <- grob(cl="test")
	drawDetails.test <- function(x, recording) {
	  w <- convertWidth(unit(1, "inches"), "npc")
	  grid.rect(width=w)
	}
	grid.draw(testgrob)

2.  Fixed bug in grid.text() when "rot" argument has length 0.
    (privately reported by Emmanuel Paradis)

3.  New getNames() function to return just the names of all top-level
    grobs on the display list.

4.  Recording on the grid display list is turned off within 
    preDrawDetails(), drawDetails(), and postDrawDetails() methods.

    This means that you do not need to worry about specifying
    recording=FALSE within these methods.
    
5.  Grid should recover better from errors or user-interrupts
    during drawing (i.e., not leave you in a strange viewport
    or with strange graphical parameter settings).

6.  New function grid.refresh() to redraw the grid display list.

7.  New function grid.record() to capture calculations
    with grid graphics output.  For example ...

        grid.record({
                      w <- convertWidth(unit(1, "inches"), "npc")
	              grid.rect(width=w)
                    },
                    list())

8.  grobWidth and grobHeight ("grobwidth" and "grobheight" units)
    for primitives (text, rects, etc, ...) are now
    calculated based on a bounding box for the relevant grob.

    These used to be calculated assuming a grob was scalar
    rather than vector.  For example, the following now behaves
    much more sensibly ...

        txt <- textGrob(c("This is a repeat", "This is a repeat"),
	                y=1:2/3, rot=45)
        grid.draw(txt)
        grid.rect(width=grobWidth(txt), height=grobHeight(txt))

    NOTE: this has changed the calculation of the size of a scalar
    rect (or circle or lines) so that, for example, something like ...

        grid.pack(frame, rectGrob())

    ... needs to become ...

        grid.pack(frame, rectGrob(), 
                  width=unit(1, "null"), height=unit(1, "null"))

    ... if you just want a rectangle that fills the space available.

9.  New arguments "warn" and "wrap" for function grid.grab()
    
    If warn>0 will warn if know (or, if warn>1,  if even suspect) 
    that the grab has not faithfully captured the output.  

    If wrap=TRUE, will capture output by wrapping all non-grobs
    on the display list in grobs.  Resulting gTree is less 
    elegant and harder to work with, but should always faithfully
    capture output.

10. New function grid.grabExpr() which captures the output from
    an expression (i.e., not from the current scene) without
    doing any drawing (i.e., no impact on the current scene).

11. upViewport() now (invisibly) returns the path that it goes up
    (suggested by Ross Ihaka).

    This makes it possible to do things like ...

        upPath <- upViewport(n)
	...
	downViewport(upPath)

    ... (i.e., navigate up and then back down to where you came from).

12. The "gamma" gpar has been deprecated (this is a device property
    not a property of graphical objects;  suggested by Ross Ihaka).

13. New "lex" gpar;  a line width multiplier.
    The final line width is calculated as ...

        gpar("lex")*gpar("lwd")

    ... and the multiplier is cumulative (like cex) ...

      grid.rect(height=0.5, width=0.5, 
                gp=gpar(lwd=16))                # lex = 1
      pushViewport(viewport(gp=gpar(lex=0.5)))
      grid.rect(height=0.5, width=0.5, 
                gp=gpar(lwd=16, col="red"))     # lex = 0.5
      pushViewport(viewport(gp=gpar(lex=0.5)))
      grid.rect(height=0.5, width=0.5, 
                gp=gpar(lwd=16, col="green"))   # lex = 0.25!

    This (along with cex) provides support for "zooming" a grid scene.

14. grid.text() now handles any language object as mathematical
    annotation (instead of just expressions).  For example ...

      grid.text(call("sin", pi))
 
15. plotViewport() has default value for "margins" argument (that match
    the default value for par(mar)).

16. The "extension" argument to dataViewport() can now be vector, 
    in which case the first value is used to extend the xscale and
    the second value is used to extend the y scale.
    (suggested by Ross Ihaka).

17. All "just" arguments (for viewports, layouts, rectangles, text)
    can now be numeric values (typically between 0 [left] and 1 [right])
    as well as character values ("left", "right", ...).

    For rectangles and text, there are additional "hjust" and "vjust"
    arguments which allow numeric vectors of justification in
    each direction (e.g., so that several pieces of text can have 
    different justifications).  If these are specified, they
    override the "just" argument.
    (suggested by Ross Ihaka)

18. New "edits" argument for grid.xaxis() and grid.yaxis() to
    allow specification of on-the-fly edits to axis children
    (when at == NULL, so children are generated on-the-fly).

19. applyEdit(x, edit) returns x if target of edit (i.e., child
    specified by a gPath) cannot be found.

20. Fix for calculation of length of max/min/sum unit.  Length is
    now (correctly) reported as 1 (was reported as length of first arg).

21. Viewport names can now be any string (they used to have to be a
    valid R symbol).

    The documentation now says that grob names can be any string
    (they always could be, but the documentation said they had to
     be a valid R symbol)

22. The "label" argument for grid.xaxis() and grid.yaxis() can now 
    also be a language object or string vector, in which case it 
    specifies custom labels for the tick marks.


Changes from grid_2.0.0 to grid_2.0.1:
------------------------------------

1.  Fixed bug in grid.newpage();  it was not starting new page
    on first grid call if there was already traditional graphics
    output on the device (i.e., the device was "dirty" but not 
    "grid dirty").

2.  Fixed bug in grid.grab() when no viewports have been pushed.


Changes from grid_1.9.0 to grid_2.0.0:
------------------------------------

1.  Calculation of number of circles to draw in circleGrob now
    looks at length of y and r as well as length of x.

2.  Calculation of number of rectangles to draw in rectGrob now
    looks at length of y, w, and h as well as length of x.

3.  All primitives (rectangles, lines, text, ...) now handle 
    non-finite values (NA, Inf, -Inf, NaN) for locations and
    sizes.

    Non-finite values for locations, sizes, and scales of
    viewports result in error messages.

    There is a new vignette("nonfinite") which describes this
    new behaviour.

4.  Fixed (unreported) bug in drawing circles.  Now checks that
    radius is non-negative.

5.  downViewport() now reports the depth it went down to find a 
    viewport.  Handy for "going back" to where you started, e.g., ...

      depth <- downViewport("vpname")
      <draw stuff>
      upViewport(depth)

6.  The "alpha" gpar() is now combined with the alpha channel of
    colours when creating a gcontext as follows:

      finalAlpha = gpar("alpha")*(R_ALPHA(col)/255)

    This means that gpar(alpha=) settings now affect internal
    colours so grid alpha transparency settings now are sent to
    graphics devices.

    The alpha setting is also cumulative.  For example, ...
      
      grid.rect(width=0.5, height=0.5, 
                gp=gpar(fill="blue"))              # alpha = 1
      pushViewport(viewport(gp=gpar(alpha=0.5)))
      grid.rect(height=0.25, gp=gpar(fill="red"))  # alpha = 0.5
      pushViewport(viewport(gp=gpar(alpha=0.5)))
      grid.rect(width=0.25, gp=gpar(fill="red"))   # alpha = 0.25 !

7.  Editing a gp slot in a grob is now incremental.  For example ...

      grid.lines(name="line")
      grid.edit("line", gp=gpar(col="red")) # line turns red
      grid.edit("line", gp=gpar(lwd=3)) # line becomes thick AND STAYS red
      
8.  The "cex" gpar is now cumulative.  For example ...
      
      grid.rect(height=unit(4, "char")) # cex = 1
      pushViewport(viewport(gp=gpar(cex=0.5)))
      grid.rect(height=unit(4, "char")) # cex = 0.5
      pushViewport(viewport(gp=gpar(cex=0.5)))
      grid.rect(height=unit(4, "char")) # cex = 0.125 !!!

9.  New childNames() function to list the names of children
    of a gTree.

10. The "grep" and "global" arguments have been implemented for 
    grid.[add|edit|get|remove]Grob() functions.

    The "grep" argument has also been implemented for the
    grid.set() and setGrob().

11. New function grid.grab() which creates a gTree from the 
    current display list (i.e., the current page of output can
    be converted into a single gTree object with all grobs
    on the current page as children of the gTree and all the 
    viewports used in drawing the current page in the childrenvp
    slot of the gTree).

12. New "lineend", "linejoin", and "linemitre" gpar()s:

      line end can be "round", "butt", or "square".
      line join can be "round", "mitre", or "bevel".
      line mitre can be any number larger than 1
        (controls when a mitre join gets turned into a bevel join;  
         proportional to angle between lines at join;
	 very big number means that conversion only happens for lines
	 that are almost parallel at join).

13. New grid.prompt() function for controlling whether the user is
    prompted before starting a new page of output.

    Grid no longer responds to the par(ask) setting in the "graphics"
    package.


Changes from grid_1.9.0 to grid_1.9.1:
------------------------------------

1.  Fixed (unreported) bug in internal calculation of unitArithmetic
    object when op = * and numeric operand longer than unit operand

2.  Fixed (unreported) bug in creation of unitArithmetic objects
    when numeric operand is integer.  All numeric operands are now
    coerced to real.


Changes from grid_1.8.0 to grid_1.9.0:
------------------------------------

1.  Renamed push/pop.viewport() to push/popViewport().

2.  Added upViewport(), downViewport(), and seekViewport() to 
    allow creation and navigation of viewport tree 
    (rather than just viewport stack).

3.  Added id and id.lengths arguments to grid.polygon() to allow
    multiple polygons within single grid.polygon() call.

4.  Added vpList(), vpStack(), vpTree(), and current.vpTree()
    to allow creation of viewport "bundles" that may be pushed
    at once (lists are pushed in parallel, stacks in series).

    current.vpTree() returns the current viewport tree.

5.  Added vpPath() to allow specification of viewport path
    in downViewport() and seekViewport().
    
    See ?viewports for an example of its use.

    NOTE: it is also possible to specify a path directly,
    e.g., something like "vp1::vp2", but this is only
    advised for interactive use (in case I decide to change the
    separator :: in later versions).

6.  Added "just" argument to grid.layout() to allow justification
    of layout relative to parent viewport *IF* the layout is not
    the same size as the viewport.  There's an example in
    help(grid.layout).

7.  Allowed the "vp" slot in a grob to be a viewport name or a
    vpPath.  The interpretation of these new alternatives is to
    call downViewport() with the name or vpPath before drawing the
    grob and upViewport() the appropriate amount after drawing the
    grob.  Here's an example of the possible usage:

        pushViewport(viewport(w=.5, h=.5, name="A"))
	grid.rect()
	pushViewport(viewport(w=.5, h=.5, name="B"))
	grid.rect(gp=gpar(col="grey"))
	upViewport(2)
	grid.rect(vp="A", gp=gpar(fill="red"))
	grid.rect(vp=vpPath("A", "B"), gp=gpar(fill="blue"))

8.  Added engine.display.list() function.  This allows the user to
    tell grid NOT to use the graphics engine display list and to handle
    ALL redraws using its own display list (including redraws after
    device resizes and copies).

    This provides a way to avoid some of the problems with resizing
    a device when you have used grid.convert(), or the gridBase package,
    or even base functions such as legend().

    There is a document discussing the use of display lists in grid
    on the grid web site 
    (http://www.stat.auckland.ac.nz/~paul/grid/grid.html)

9.  Changed the implementation of grob objects.  They are no longer 
    implemented as external references.  They are now regular R objects
    which copy-by-value.  This means that they can be saved/loaded
    like normal R objects.  In order to retain some existing grob
    behaviour, the following changes were necessary:

    - grobs all now have a "name" slot.  The grob name is used to
      uniquely identify a "drawn" grob (i.e., a grob on the display
      list).  
    - grid.edit() and grid.pack() now take a grob name as the first
      argument instead of a grob.  (Actually, they take a gPath -
      see below)
    - the "grobwidth" and "grobheight" units take either a grob
      OR a grob name (actually a gPath - see below).  Only in the 
      latter case will the unit be updated if the grob "pointed to"
      is modified.

    In addition, the following features are now possible with grobs:

    - grobs now save()/load() like any normal R object.
    - many grid.*() functions now have a *Grob() counterpart.  The
      grid.*() version is used for its side-effect of drawing 
      something or modifying something which has been drawn;  the
      *Grob() version is used for its return value, which is a grob.
      This makes it more convenient to just work with grob objects without
      producing any graphical output (by using the *Grob() functions).
    - there is a gTree object (derived from grob), which is a grob 
      which can have children.  A gTree also has a "childrenvp" slot
      which is a viewport which is pushed and then "up"ed before the
      children are drawn;  this allows the children of a gTree to 
      place themselves somewhere in the viewports specified in the
      childrenvp by having a vpPath in their vp slot. 
    - there is a gPath object, which is essentially a concatenation
      of grob names.  This is used to specify the child of (a child of ...)
      a gTree.
    - there is a new API for creating/accessing/modifying grob objects:
      grid.add(), grid.remove(), grid.edit(), grid.get() (and their
      *Grob() counterparts can be used to add, remove, edit, or extract
      a grob or the child of a gTree.  NOTE: the new grid.edit() API
      is incompatible with the previous version.

10. Added stringWidth(), stringHeight(), grobWidth(), and grobHeight()
    convenience functions (they produce "strwidth", "strheight",
    "grobwidth", and "grobheight" unit objects, respectively).

11. Allowed viewports to turn off clipping altogether.  Possible settings
    for viewport clip arg are now:

      "on"      = clip to the viewport (was TRUE)
      "inherit" = clip to whatever parent says (was FALSE)
      "off"     = turn off clipping 

    Still accept logical values (and NA maps to "off")


Changes from grid_1.8.0 to grid_1.8.1:
------------------------------------

1.  I have effectively disabled the "mystrwidth", "mystrheight",
    "mychars", and "mylines" units.  These are now identical in
    behaviour to the equivalent units without the "my".

    Another way to look at it is that I have modified the behaviour
    of "lines", "chars", "strwidth", and "strheight" so that they
    ALWAYS obey the latest gpar settings (including any gpar 
    settings in a grob).  

    Some examples ...

    This text is sized AND positioned in terms of a fontsize of 6:

      grid.text("small text and small lines", y=unit(2, "lines"), 
                gp=gpar(fontsize=6))

    This text is 6 pt in size, but is positioned in terms of the
    (default on X11) fontsize 12:

      push.viewport(viewport(y=unit(2, "lines")))
      grid.text("small test and big lines", gp=gpar(fontsize=6))
      pop.viewport()

2.  Fixed a bug in the calculation of "grobwidth" and "grobheight"
    units.  The following code demonstrates the problem (the black
    rectangle should snugly bound the grey rectangles):

      grid.newpage()
      # Create a frame with fontsize=6
      gf <- grid.frame(layout=grid.layout(10, 10,
                       widths=unit(rep(1, 10), "strwidth",
                         as.list(rep("o", 10))),
                       heights=unit(rep(1, 10), "strheight",
                         as.list(rep("o", 10)))),
                     gp=gpar(fontsize=6))
      # Add a rect to the frame
      for (i in 1:10)
        grid.place(gf, grid.rect(gp=gpar(col="grey"), draw=FALSE),
                   col=i, row=i)
      grid.draw(gf)
      # Now draw a rect around the frame
      grid.rect(width=unit(1, "grobwidth", gf),
                height=unit(1, "grobheight", gf))

3.  Fixed a bug in the implementation of the "cex" gpar.  This is now
    used correctly in the transformation code in unit.c

    The bug was demonstrated by the following simple example
    (the second set of points should be twice the radius of the
    first set of points):

      grid.newpage()
      push.viewport(viewport())
      grid.points()
      grid.points(gp = gpar(cex = 2))
      
    Another demonstration from the original bug report from David Hinds:

      xyplot(1:4~1:4, cex=1:4, pch=1)

4.  Fixed a bug in multiplication of scalar by unit object, when the
    scalar has length > 1.  The following example demonstrates
    the problem:

      grid.segments(x0=1:3/4, y0=0.1, x1=1:3/4,
                    y1=1:3/4*unit(1, "npc"))

    This should behave the same as:

      grid.segments(x0=1:3/4, y0=0.1, x1=1:3/4,
                    y1=unit(1:3/4, "npc"))
      

Changes from grid_0.7-4 to grid_1.8.0:
------------------------------------

1.  grid.text() now checks that the rot argument is numeric and finite.

2.  dataViewport() checks for is.null(<arg>) rather than missing(<arg>)
    and has renamed arguments x and y to xData and yData.

    All to avoid confusion with specifying x= and y= in the ... argument.

    This also fortuitously fixed a bug in dataViewport where the 
    calculation of the x-range was partially dependent on the y-range(!)

    Thanks to Russell Norvell for spotting and reporting the bug.

3.  unit() checks that units argument is character mode.

    Fix for bug (first reported by Achim Zeileis) produced by, 
    for example ...

	unit(1, 2)

4.  The function absolute.units() was recursive and now uses a loop.

    Fixes the following problem (from Deepayan Sarkar):

        gf <- grid.frame(layout = grid.layout(nrow=1, ncol=1), draw = FALSE)
        grob.rect <- grid.rect(x = 1:99/100, y = 1:99/100,
                               h = rep(.01, 100), w = rep(.05, 100),
                               gp = gpar(col = terrain.colors(100)),
                               draw = FALSE)
        grid.pack(frame = gf, row = 1, col = 1,
                  grob = grob.rect,
                  draw = FALSE)
        grid.draw(gf)  # Fails with stack overflow

5.  There is now a grid.locator() function for interactively selecting
    locations within the current grid viewport with a mouse.

6.  There is a new grid.convert() function for converting between
    different coordinate systems.  

    The convertNative() function has been deprecated.

7.  The default "top-level" viewport that is generated by grid
    now has its "native" coordinate system set to the "native"
    coordinate system of the device.  For example, "native"
    units at the top-level correspond to points on a PostScript
    device, pixels on an X11 device, and so on.

    For example, try the following:

        library(grid)
	x11()
	grid.rect(x=10, y=10, width=10, height=10,
                 default.units="native")

    This may cause consternation if you ever plot grid.points()
    at the top-level because the default units for grid.points()
    are "native" ... I consider this an unlikely occurrence.

8.  Added a new gpar called "alpha" for specifying transparency.
    This is supposed to be a number from 1 (opaque) to 0 (transparent).
    No R devices will take any notice of this whatsoever as yet.

9.  Modified "xaxis" and "yaxis" grobs so that they extend the 
    "collection" class.  This means that, when a new generic function
    is created, it may be possible to write methods just for the 
    collection class and not also separate xaxis and yaxis methods.

10. Modified unit subsetting so that logical indices work.  
    For example ...

        unit(1:4, "npc")[1:4 == 3]

11. Fixed detaching/reloading of grid package (was causing an error).
 
12. There is a new grid.arrows() primitive.  

    See the help file for example usage.

13. Grid is now a base package (hence version number leap!)


Changes from grid_0.7-3 to grid_0.7-4:
------------------------------------

1.  Fixed the bug in the bug-fix in item 7. below.


Changes from grid_0.7-2 to grid_0.7-3:
------------------------------------

1.  Properly removed "origin" settings from viewports.

2.  Modified grid.pretty() slightly so that it would respond
    sensibly/usefully to things like ...

        grid.pretty(c(10, 0))

    A side-effect of this is that the following sort of viewport
    scale specifications become sensible/useful ...

        push.viewport(viewport(layout=grid.layout(1, 2)))
        push.viewport(viewport(layout.pos.col=1))
        push.viewport(viewport(w=.8, h=.8,
                               xscale=c(10,0)))
        grid.points(1:10, 1:10/11)
        grid.xaxis()
        grid.yaxis()
        pop.viewport(2)
        push.viewport(viewport(layout.pos.col=2))
        push.viewport(viewport(w=.8, h=.8,
                               yscale=c(10,0)))
        grid.points(1:10/11, 1:10)
        grid.xaxis()
        grid.yaxis()
        pop.viewport(3)

3.  Fixed the calculation of number of "vertices" in grid.lines so that
    it is the maximum of length(x) and length(y).

    Used to be calculated solely on length(x).

4.  Grid now throws an error if you try to create a unit of length 0.

    This to fix a bug reported by Bud Gibson, the essence of which was ...

        grid.points(size=unit(numeric(0), "mm"))

5.  The default value of the "at" argument for grid.xaxis() and
    grid.yaxis() is NULL (was NA;  NA was inconsistent with other
    default argument settings and basically a dumb idea)

6.  Grid now throws an error if you try to create a gpar object with
    an element of length 0.

    This is to fix a bug reported by Michael Friendly (and diagnosed by
    Brian Ripley), the essence of which was ...

         grid.lines(gpar(fontsize=numeric(0)))

7.  grid.text() now converts its label argument to a string.

    This is to fix a bug where "grobwidth" or "grobheight" would 
    segfault if given a text grob for which the label was not a string.
    (The fix involved including a check for "mystrwidth" and "mystrheight"
     units in valid.data).

    The bug could be produced by ...
    
        grid.rect(w=unit(1, "grobwidth", data=grid.text(5)))
    

Changes from grid_0.7-1 to grid_0.7-2:
-------------------------------------

1.  Fixed some generic/method incompatibilities (pointed out by Kurt).


Changes from grid_0.7 to grid_0.7-1:
------------------------------------

1.  Fixed a bug where layout matrix respect was not being applied to
    the correct cell.  For example, the following caused the cell
    1,3 to be respected rather than 1,2 ...

	lt.resp <- matrix(0, 2, 3)
	lt.resp[1,2] <- 1
	grid.show.layout(grid.layout(2, 3, respect = lt.resp))

    Reported by Deepayan Sarkar.


Changes from grid_0.6 to grid_0.7:
------------------------------------

1.  The web pages for grid have moved to ...
   
	http://www.stat.auckland.ac.nz/~paul/grid/grid.html

2.  Mathematical annotation is now available in grid.

    Wherever grid expects a string, an expression may be used instead.
    This covers not only producing mathematical annotation output,
    but also correctly calculating width and height of expressions,
    and checking for overlapping expressions.

3.  If you try to save/load a grid grob, it will now fail gracefully
    rather than seg faulting.

4.  If you save a display list containing grid output, then detach
    grid, then try to run the display list again, it will now fail 
    gracefully rather than seg faulting.

5.  All gpar() settings can now be vectors.  Well, they could always
    be vectors, but now values other than the first one will have an
    effect.  This will not happen in all contexts, for example, 
    viewports will only take notice of the first value in each setting,
    but for graphics functions where multiple items can be output,
    multiple settings may be sensibly given.  Some examples are:

    # multiple points with different colours
    grid.points(1:10/11, 1:10/11, gp=gpar(col=1:10))

    # multiple segments with different colours
    grid.segments(1:10/11, 0, 1:10/11, 1, gp=gpar(col=1:10))

    # multiple points with different sizes
    grid.points(1:10/11, 1:10/11, size=unit(1:10, "mm"))

    # multiple pieces of text with different font sizes
    grid.text(1:10, x=1:10/11, gp=gpar(fontsize=10:20))

    # multiple rects with different lineheights (and height is in "lines")
    grid.rect(width=.05, x=1:10/11,
              height=unit(1, "mylines"),
              gp=gpar(lineheight=1:10))

6.  (Because of a fix to R/src/main/engine.c ...)
    Multiple-line text (i.e., text with "\n"s in it) is now correctly
    spaced vertically (i.e., takes notice of the current value of 
    "fontsize").
    
    NOTE, however, that multiple-line text still takes no notice of the
    current value of "lineheight".

7.  Fixed a bug in grid.layout().  It was the case that, if you 
    entered widths or heights which were not unit objects, they
    were not converted properly to unit objects.

8.  Modified the defaulting of "just" arguments when a single value
    is provided.  See the new example in grid.text.

9.  Fixed a bug where grid.points(pch=NULL) would cause a crash.
    This now defaults pch to the value 1.

10. Added "fontfamily" and "fontface" gpar() settings.  The fontfamily
    setting will mostly be ignored until devices are modified to take
    notice of the extra information, BUT this can be used NOW to 
    specify a Hershey Font family (on all devices).  The fontface 
    setting is designed to take over from the old "face" setting,
    but the latter is retained for backward compatibility.


Changes from grid_0.5-1 to grid_0.6:
------------------------------------

1.  Some internal changes to speed up creation of unit objects.  
    This may have a noticeable effect on drawing legends and anything 
    that relies on grid frames (e.g., "key"s in lattice).

2.  A couple of bug fixes for "grobwidth" and "grobheight" units.
    Symptoms were legends not being allocated the correct amount of 
    space.

    Thanks to Deepayan Sarkar and Peter Kleiweg for help diagnosing
    the bug and testing the fix.

3.  Added plotViewport() and dataViewport() 
    convenience function for creating a 
    viewport that has the typical layout of an R plot.

4.  Altered viewport() function so that layout.pos.row and layout.pos.col
    can be specified as a sequence and only the range() of that 
    sequence is used.

5.  Removed most documentation from the package to reduce the download
    size.  The user's guide and changes file are included with the
    tar ball, but the other documents are only available via 
    http://www.stat.auckland.ac.nz/PEOPLE/paul/grid/grid.html

    Also changed the format of the user's guide from postscript to pdf.

6.  Fixed bug in unit.length where the length of a unit.arithmetic object
    was calculated incorrectly if the length() of the scalar multiplier
    was longer than the unit.length() of the unit object being multiplied.

7.  Allowed character settings for pch in grid.points()

8.  The crash on Windows platforms when plot history is turned on
    has been fixed in R version 1.5.  

    This fix means that grid_0.6 will only run on R version >= 1.5.0

9.  Added handling of NULL values for gpar elements.  Except for col
    and fill, this now means the same as specifying no setting at all
    for the element -- previous behaviour was a segfault.


Changes from grid_0.5 to grid_0.5-1:
------------------------------------

1.  Fix for some grid bugs.
    
    The problems were:
	(i)   grid output could not be saved in metafile format 
	(ii)  non-grid output could not be saved in metafile format when
	      grid was loaded
	(iii) empty page at start of grid postscript output
	(iv)  empty page at start of non-grid postscript output when
	      grid was loaded
	(v)   copying grid output from x11 to postscript (dev.copy)
	      produced blank pages in postscript

    These problems were due to two things in grid:
	(i)  grid created a new page whenever a new device was started.
	(ii) grid created a new page whenever the display list was
	     replayed (e.g., when a device was resized or the output
	     was copied from one device to another)

    Grid now only creates a new page the first time grid output is
    produced on a device AND only creates a new page for replaying
    the display list IF there has already been grid output on the device.


Changes from grid_0.2 to grid_0.5:
----------------------------------

1.  R has a new device API and a new graphics engine.  Grid uses these.

    This means that this version will NOT work on R versions before 1.4.0

    Another known "bug" is that this version of grid will crash R if
    used in Windows with plot history recording turned on (although
    "add"ing individual grid "plots" to the plot history should still
    work).
    
2.  Added "mystrwidth" and "mystrheight" units;  basically these just
    complete the set of units which depend on font, fontsize, and/or 
    lineheight and therefore may refer to the current viewport settings
    of these parameters OR to the current settings of the grob being
    drawn.

3.  Added unit.rep function (the base rep() function is not generic
    so I could not simply write a rep.unit method).

4.  Added new gpar, "gamma", for gamma-correction of colours
    (defaults to 1).  NOTE that only windows devices will currently
    respond to on-the-fly changes in gamma.

5.  Added "clip" flag to viewports.  If "clip" is TRUE, then output
    is clipped to the viewport.

    Clipping obeys only the most recent viewport clip setting.
    For example, if you clip to viewport1, then clip to viewport2,
    the clipping region is determined wholly by viewport2, the
    size and shape of viewport1 is irrelevant (until viewport2
    is popped of course).

    If a viewport is rotated (because of its own "angle" setting
    or because it is within another viewport which is rotated) then
    the "clip" flag is ignored.
  
6.  The functions grid.start() and grid.stop() have been removed.
    grid automatically "registers" with devices.

7.  Grid no longer automatically opens a device when it is loaded.
    Instead, a device is created, if there are none open, when the
    first drawing occurs or when the first viewport is pushed.

8.  Added new functions unit.pmin() and unit.pmax() which are unit
    versions of pmax() and pmin()

9.  Added new function grid.place() which provides a simpler 
    interface to grid.pack() and is useful for using grid "frame"s
    as just a convenient way of defining a layout and sticking 
    things in it.


Changes from grid_0.1 to grid_0.2:
----------------------------------

1. Fixed bug in rotating viewports;  this should be more reliable now.

2. Added grid.line.to() and grid.move.to().  These allow drawing BETWEEN
   different coordinate systems.  See example in inst/doc/demo3.ps.

3. Added some more demonstrations to the doc directory.

4. Added more test code to the tests directory.

5. Added "grobwidth" and "grobheight" units.  See the document
   grid/inst/doc/advanced/parentchild.ps

6. Added more detailed documentation to grid/inst/doc/advanced.  This
   stuff is not as friendly for the reader, but may be useful if you're
   tearing your hair out wondering why some strange effect is occurring.

7. Changed frames and packing to use the new "grobwidth" and "grobheight"
   units.  This fixes some problems with frames and packing.

8. Fixed a bug where the gpar settings for "fontsize" and "lineheight"
   _within a grob_ would not affect the location or size of the grob
   if they were specified in "lines" or "char" units.

   This required adding new "mylines" and "mychar" units (alternative
   suggestions for names welcome !) so that you can specify whether
   a grob's a location/size is in terms of the current viewport's
   fontsize and lineheight ("lines" and "char") or in terms of its own
   fontsize and lineheight ("mylines" and "mychar").

9. Added grid.polygon() and grid.circle() primitives

10. Added newpage=TRUE argument to grid.start() so that you can restart
    grid graphics mode without having to move to a new page.

    For example, try ...

	postscript()
	grid.start()
	grid.polygon()
	grid.stop()
	grid.start() # moves to new page
	grid.circle()
	grid.stop()
	grid.start(newpage=FALSE) # does NOT move to new page
	grid.rect()
	grid.stop()
	dev.off()

11. Changed interface for pop.viewport().  This now just takes a
    number of viewports to pop, which defaults to 1.  
    For example ...

        push.viewport(viewport())
	pop.viewport(current.viewport())

    ... becomes ...
    
        push.viewport(viewport())
	pop.viewport()

    ... and ...

        vp1 <- viewport()
	vp2 <- viewport()
	push.viewport(vp1, vp2)
	pop.viewport(vp2, vp1)

    ... becomes ...

        vp1 <- viewport()
	vp2 <- viewport()
	push.viewport(vp1, vp2)
	pop.viewport(2)
	
12. Speed-up of pushing and popping viewports.  This will probably not
    be noticeable in normal usage, but makes a big difference for 
    frames and packing.

Changes from lattice_0.2 to grid_0.1:
-------------------------------------

0. Change of package name from "lattice" to "grid" (!!!!)

   This means that most user functions have changed from l<something>
   to grid.<something>

1. Slight speed up of grid.push.viewport and grid.pop.viewport.

2. Added sum() method for units.

   For example, try ...

       grid.rect(w=sum(unit(c(.25,.25), "npc")))
       grid.rect(w=sum(unit(c(.25,.25), "npc"), unit(1, "cm")), border="red")

3. Changed the usage of grid.edit() slightly.  If you want to specify 
   several new values at once, you must use grid.prop.list() rather
   than just list().  For example, for a single new value use ...

       grid.edit(<grob>, col="red")

   ... as before, but for multiple new values use ...

       grid.edit(<grob>, grid.prop.list(col="red", lty="dashed"))

   ... rather than ...
   
       grid.edit(<grob>, list(col="red", lty="dashed"))

4. Added a new grid.frame() grob.  This acts a bit like a simple 
   grid.collection() BUT controls the placement of its children.  
   You add children using the grid.pack() function.

5. All viewports and grobs now have a "gp" slot which contains a
   "gpar" object.  This is a list of graphical parameters, which 
   replaces the specification of individual graphical parameters
   for each different type of grob.  

   For example, instead of the old ...
   
       grid.rect(w=.8, h=.8, border="red")

   ... we have the new ...

       grid.rect(w=.8, h=.8, gp=gpar(border="red"))

   This may seem like a loss (because you have to type more stuff),
   and it is a loss, but the (hopefully greater) win is that (i) you only
   have one parameter for all graphical settings, for example, ...

       grid.rect(w=.8, h=.8, gp=gpar(border="red", lwd=3))

   ... and (ii) this applies for all grobs, for example, ...

       grid.text("hi", gp=gpar(col="red", fontsize=10))

   ... and (iii) you can add more graphical parameters with minimal fuss,
   for example, ...

       grid.text("hi", gp=gpar(col="red", fontsize=10, new.par=whatever))

   ... and (iv) its easier to automate things (see below).

   Graphical parameter settings are "permanent" so, for example, if
   an axis sets the colour to "red" then all of its children are
   drawn in "red" unless they set colour to something else.

   For example, try ...

       grid.multipanel(vp = grid.viewport(0.5, 0.5, 0.8, 0.8, 
                                          gp=gpar(fontsize=20)))

   ... and notice that all of the components of the multipanel take
   notice of the fontsize setting of the parent viewport (except the
   axis labels because they explicitly set the fontsize to 20 themselves).

   The setting of graphical parameters is automated;  
   if you have a slot called "gp" in your grob, Lattice will
   set the graphical parameters in that slot before calling
   draw.details() and unset the parameters afterwards.

6. The pushing and popping of "local" viewports has been automated.
   If you have a slot called "vp" in your grob, Lattice will call
   grid.push.viewport() on that slot before calling draw.details() 
   and grid.pop.viewport() afterwards.

7. "collection" grobs and "[x|y]axis" grobs no longer pass editing
   operations down to their children.  

   This was mainly (only ?) for sharing graphical parameter settings
   and that duty is now performed by the gpar stuff in point 5 above.

   This is a good thing because there are some cases where passing
   down editing operations could cause serious damage.  For example, 
   consider what would have happened if you had edited the "vp" slot
   of a collection grob (!)

