NAME

PostScript::Graph::Style - style settings for postscript objects

SYNOPSIS

Simplest

Each time a new object is created the default style will be slightly different.

    use PostScript::Graph::File;
    use PostScript::Graph::Style;

    my $file = new PostScript::Graph::File();
    my $seq = new StyleSequence();
    
    while (...) {
	my $style = new PostScript::Graph::Style(
		sequence => $seq,
		point	 => {}
	    );
	$style->write($file);
	
	$file->add_to_page( <<END_OF_CODE );
	    % code using point variables...
	    
	    % setting colour or grey shade
	    gpaperdict begin
		pocolor gpapercolor
	    end

	    % choosing a line width
	    powidth setlinewidth
	    
	    % scaled relative to point sizing
	    0 ppsize rlineto
	    
	    % showing the chosen point shape
	    100 200 ppshape
    END_OF_CODE
    }
    

Typical

It is possible to control how each new object varies.

    my $seq = new StyleSequence();
    $seq->setup( "red", [0, 1, 0.2, 0.8, 0.4, 0.6] );
	    
    my $file = new PostScript::Graph::File();
    while (...) {
	my $style = new PostScript::Graph::Style(
	    sequence => $seq,
	    auto     => [ qw(dashes red shape) ], 
	    bar      => {},
	);
	$style->write($file);
	
	... postscript using bar variables ...
    }
    

Some of the styles may be overriden.

    my $style = new PostScript::Graph::Style(
		sequence => $seq,
		auto     => [qw(red green blue)],
		color    => 1,
		line     => {
		    width        => 4,
		    outer_dashes => [],
		    outer_color  => [1, 0, 0],
		},
	    );

Or the automatic default feature can be supressed and some or all details specified directly.

    my $style = new PostScript::Graph::Style(
		auto  => "none",
		point => {
		    shape => "circle",
		    size  => 12,
		},
	    );

All options

    my $style = new PostScript::Graph::Style(
	sequence     => $seq,
	auto	     => [qw(red green blue)],
	changes_only => 0,
	same	     => 1,

	line => {
	    color	 => [0, 1, 0],
	    inner_color  => [1, 1, 0],
	    outer_color  => 0,
	    dashes	 => [3, 3],
	    inner_dashes => [5, 2, 5, 10],
	    outer_dashes => [],
	    width	 => 2,
	    inner_width  => 2,
	    outer_width  => 2.5,
	},

	point => {
	    size         => 8,
	    shape        => "diamond",
	    color	 => [0, 1, 0],
	    inner_color  => [1, 1, 0],
	    outer_color  => 0,
	    width	 => 2,
	    inner_width  => 2,
	    outer_width  => 2.5,
	},

	bar => {
	    color	 => [0, 1, 0],
	    inner_color  => [1, 1, 0],
	    outer_color  => 0,
	    width	 => 2,
	    inner_width  => 2,
	    outer_width  => 2.5,
	},
    );

DESCRIPTION

This module is designed as a supporting part of the PostScript::Graph suite. For top level modules that output something useful, see

PostScript::Graph::Bar
PostScript::Graph::Stock
PostScript::Graph::XY

Style settings are provided for objects placed on a graph. Lines on the same graph need to be distinguishable from each other. Each line would have a PostScript::Graph::Style object holding its settings. Passing each line a reference to the same StyleSequence object makes the styles vary. This can either use the defaults of be controlled to every last detail.

Settings are provided for three types of object. A line is any unfilled path, a bar is any filled path while a point is a filled path that may contain holes.

They all have outer and inner components. The inner component provides the main shape and colour, while the outer 'edge' is provided to insulate this from any background colour. Lines may be whole or broken and a variety of builtin shapes is provided. By default, repeated calls to new return styles that differ from one another although like everything else this can be under detailed user control if required.

The settings are only useful once they have been written out to a PostScript::Graph::File object using write. The following functions return values set in the constructor. See "new" for more details.

bar_outer_color()
bar_outer_width()
bar_inner_color()
bar_inner_width()

color()

line_outer_color()
line_outer_width()
line_outer_dashes()
line_inner_color()
line_inner_width()
line_inner_dashes()

point_size()
point_shape()
point_outer_color()
point_outer_width()
point_inner_color()
point_inner_width()

same()
sequence()

Style Generation

Although it is possible to specify styles directly, mostly the style just needs to be different from the last one. These dynamic defaults provide around 3600 variations which should be suitable for most cases. The values themselves can be replaced if desired. Permutations of these are then generated on demand and the permutation order is also under user control.

StyleSequence new

Whenever a new PostScript::Graph::Style object is created, it uses certain defaults. These defaults can be made to vary if a sequence is declared as one of the options. This should be the value returned from:

my $seq = new StyleSequence();

reset()

Starts the sequence of defaults again.

setup( key, array )

The defaults provided by the StyleSequence are chosen from arrays which may be redefined using this method. Note that it is a StyleSequence method and NOT a PostScript::Graph::Style method, and should typically be called directly after the StyleSequence object is created.

Example

use PostScript::Graph::Style;

my $seq = new StyleSequence();
$seq->setup( "red", [0, 0.5, 1] );

array is always an array reference as in the example. key may be one of the following.

red	    green   blue
yellow  mauve   cyan
gray    shape   size
dashes  width

Mostly, their arrays contain integers (0 to 1.0 for colours). The exceptions are dashes, shape and possibly gray.

See "inner_dashes" for details on the arrays required for dashes. Suitable values for shape can be one of these entries, taken from the default array.

    my $seq = new StyleSequence();
    $seq->setup( "shape",
	[ qw(cross plus dot circle square diamond) ]);

<gray> allows the user to define custom colour sequences. The 'color' style option must be set for this, see "color". If the gray array is filled with decimals between 0 and 1 (inclusive), the result is varying shades of grey. However, it is also possible to use arrays of red-green-blue colours:

    my $seq = new StyleSequence();
    $seq->setup( "gray",
	[ [ 0, 0, 0 ],	    # white
	  [ 0, 0, 1 ],	    # blue
	  [ 0, 1, 0 ],	    # green
	  [ 0, 1, 1 ],	    # cyan
	  [ 1, 0, 0 ],	    # red
	  [ 1, 0, 1 ],	    # mauve
	  [ 1, 1, 0 ],	    # yellow
	  [ 1, 1, 1 ], ]);  # black

    my $gs = new PostScript::Graph::Style(
		auto  => [qw(gray)],
		color => 0,
		bar   => {},
	    );

The full range of colours may be used provided that the 'same' style option has not been set. By default each line, point and bar are outlined in the complementary colour to the background, making them stand out.

More than one variable can be set of course. For example the following would ensure lines with 15 shades of red-orange-yellow, if 'auto' was set to some combination of red, blue and green.

my $seq = new StyleSequence();
$seq->setup("red", [ 0.2, 1, 0.4, 0.8, 0.6 ]);
$seq->setup("green", [ 0, 0.8, 0.4 ]);
$seq->setup("blue", [ 0 ]);

Class Methods

default()

Return a fallback StyleSequence. Note that this is possibly called by many, unrelated objects, so the sequences generated may not be predictable or even useful.

CONSTRUCTOR

new( [options] )

options can either be a list of hash keys and values or a single hash reference. In both cases the hash must have the same structure. There are a few principal keys and most of these refer to hashes holding a group of options.

It is essential that the settings to be specified are indicated, so at least one of line, point or bar is given, even if the hashes are empty. Otherwise no style settings will actually be output.

Global settings

These are mainly concerned with how the defaults are generated for each new PostScript::Graph::Style object.

auto

This can either be the string "none" or a list of features. The list of features only makes sense if sequence is also given.

The first feature mentioned will vary fastest from one style to the next while the last varies slowest. Any features not mentioned will not be varied. See "Style Generation" for how to change the defaults for these features.

red	    green   blue
yellow  mauve   cyan
gray    dashes  width
shape   size

Example 1

    $ps = new PostScript::Graph::Style(
	    auto => [qw( dashes shape )],
	    bar  => {},
	);
	

Setting auto to the string 'none' (instead of the array) prevents the automatic generation of defaults, as does setting every option directly.

Calling new again with the same options returns the next set of defaults.

Whenever auto is given a new list, the dynamic defaults are reset.

If nothing is given, the behaviour depends on whether this is the first call to new or a repeated call. If auto is not present or no list is given when the dynamic defaults are first initialized, all non-colour values are assumed.

changes_only

Set this to 0 if you need every style parameter written out to postscript. If this is 1, only the changes from the previous style settings are added to the file. (Default: 1)

color

Set this to 0 to use shades of grey for monochrome printers.

This also must be set to 0 to cycle through user defined colours. See "Style Generation" for how to set those. This switch actually determines whether the colour value is taken from the gray array or a composite of the red, green and blue arrays. So putting the custom colours into 'gray' and setting color to 0 reads these. The internal postscript code handles each format interchangeably, so the result is coloured gray!

same

By default, the outer colour is the complement of the background (see "outer_color"). Setting this to 1 makes the outer colour the same as the background.

sequence

This identifies a sequence of default values. If this is not defined (but 'auto' is not 'none'), a new sequence would be created with each call resulting in the same style every time.

Graphic settings

The options described below belong within line, bar or point sub-hashes unless otherwise mentioned. For example, referring to the descriptions for color and size:

line  => { color => ... }	    valid
point => { color => ... }	    valid

line  => { size => ... }	    NOT valid
point => { size => ... }	    valid

The sub-hashes are significant. They should be present if that feature is to be used, even if the sub-hash is empty. Otherwise, no postscript values of that type will be defined.

All color options within these sub-hashes take either a single greyscale decimal or a reference to an array holding decimals for red, green and blue components. All decimals should be between 0 and 1.0 inclusive.

color       => 1		    white
outer_color => 0		    black
inner_color => [1, 0, 0]	    red

Example 2

    $ps = new PostScript::Graph::Style(
	    auto  => "none",
	    line  => {
		width       => 2,
		inner_color => [ 1, 0.6, 0.4 ],
	    }
	    point => {
		shape       => "diamond",
		size        => 12,
		color       => [ 1, 0.8, 0.8 ],
		inner_width => 2,
		outer_width => 1,
	    }
	);
   

color

A synonym for inner_color. See "new".

dashes

Set both inner and outer dash patterns. See "inner_dashes".

inner_color

The main colour of the line or point. See "new".

inner_dashes

This array ref holds values that determine any dash pattern. They are repeated as needed to give the size 'on' then 'off'. Examples are the best way to describe this.

inner_dashes => []		-------------------------
inner_dashes => [ 3 3 ]	---   ---   ---   ---   -
inner_dashes => [ 5 2 1 2 ]	-----  -  -----  -  -----

Only available for lines.

inner_width

The size of the central portion of the line. Although this can be set of points, size is more likely to be what you want. Probably should be no less than 0.1 to be visible - 0.24 on a 300dpi device or 1 on 72dpi. (Default: 0.5)

When used in conjunction with inner_dashes, setting inner and outer widths to the same value produces a two-colour dash.

outer_color

Colour for the 'edges' of the line or point. To be visible outer_width must be greater than <inner_width>. (Default: -1)

Note that the default is NOT a valid postscript value (although gpapercolor handles it fine. See "gpapercolor" in PostScript::Graph::Paper. If default_bgnd() is called later, it fills all colours marked thus with a background colour now known.

outer_dashes

If this is unset, inner lines alternate with the outer colour. To get a dashed line, this should be the same value as inner_dashes. (Default: "[]")

Only available for lines.

outer_width

Total width of the line or point, including the border (which may be invisible, depending on colour). The edge is only visible if this is at least 0.5 greater than inner_width. 2 or 3 times inner_width is often best. (Default: 1.5)

When using the circle point shape, this should be quite small to allow the line to be visible inside the circle.

shape

This string specifies the built-in shape to use for points. Suitable values are "plus", "cross", "dot", "circle", "square" and "diamond". (Default: "dot")

Only available for points.

size

Width across the inner part of a point shape. (Default: 5)

Not available for lines.

width

Set the inner line width. The outer width is also set to twice this value.

OBJECT METHODS

write( ps )

Write style settings to the PostScript::Graph::File object. This is a convenient way of setting all the postscript variables at the same time as it calls each of the line, point and bar variants below.

All of the postscript variables are set if the constructor option changes_only was set to 0. Otherwise, only those values that are different from the previous style are written out.

See "POSTSCRIPT CODE" for a list of the variables set.

background( grey | arrayref [, same] )

The default outer colour setting (-1) is interpreted as 'use complement to graphpaper background'. Of course, it is not possible to bind that until the graphpaper object exists. Calling this function sets all outer colour values to be a complement of the colour given, unless same is set to non-zero. If not given, same takes on the value given to the constuctor or 0 by default.

POSTSCRIPT CODE

PostScript variables

These are set within the 'gstyledict' dictionary. All ...color variables are either a decimal or an array holding red, green and blue values. They are best passed to "gpapercolor" in PostScript::Graph::Paper.

   PostScript	Perl method
   ##########	###########
   locolor	line_outer_color
   lowidth	line_outer_width
   lostyle	line_outer_dashes
   licolor	line_inner_color
   liwidth	line_inner_width
   listyle	line_inner_dashes

   ppshape	point_shape
   ppsize	point_size
   pocolor	point_outer_color
   powidth	point_outer_width
   picolor	point_inner_color
   piwidth	point_inner_width
   
   bocolor	bar_outer_color
   bowidth	bar_outer_width
   bicolor	bar_inner_color
   biwidth	bar_inner_width

Setting Styles

Once write has been called to update the postscript variables, the graphic environment must be set to use them. The GraphStyle resource provides a number of functions for this.

line_inner

Sets the colour, width and dash pattern for a line.

line_outer

Sets the colour, width and dash pattern for a line's edge.

point_inner

Sets the colour and width for a point.

point_outer

Sets the colour and width for a point's edge.

bar_inner

Sets the colour and width for a bar.

bar_outer

Sets the colour and width for a bar's edge.

Drawing Functions

The functions which draw the shapes all remove 'x y' from the stack. They use a variable 'ppsize' which should be the total width of the shape.

make_plus
make_cross
make_dot
make_circle
make_square
make_diamond

BUGS

Using the compound colours yellow, mauve and cyan with other colours can have unpredictable results.

Using an auto colour with 'color => 0' fails to produce shades of grey.

AUTHOR

Chris Willmot, chris@willmot.org.uk

SEE ALSO

PostScript::Graph::File, PostScript::Graph::Paper, PostScript::Graph::Key, PostScript::Graph::XY.