diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2017-12-08 18:57:06 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2017-12-08 18:57:06 (GMT) |
commit | 90a861b642f765d5657ab827aedabe3920ff9333 (patch) | |
tree | 88b93d468ca1feed91ef2958f46f3f74f1418aac /ast/plot.c | |
parent | fba23129f50db253ed3fbbaa23d6e342bf86068e (diff) | |
download | blt-90a861b642f765d5657ab827aedabe3920ff9333.zip blt-90a861b642f765d5657ab827aedabe3920ff9333.tar.gz blt-90a861b642f765d5657ab827aedabe3920ff9333.tar.bz2 |
upgrade AST
Diffstat (limited to 'ast/plot.c')
-rw-r--r-- | ast/plot.c | 32074 |
1 files changed, 0 insertions, 32074 deletions
diff --git a/ast/plot.c b/ast/plot.c deleted file mode 100644 index 368cb73..0000000 --- a/ast/plot.c +++ /dev/null @@ -1,32074 +0,0 @@ -/* -*class++ -* Name: -* Plot - -* Purpose: -* Provide facilities for 2D graphical output. - -* Constructor Function: -c astPlot -f AST_PLOT - -* Description: -* This class provides facilities for producing 2D graphical output. -* A Plot is a specialised form of FrameSet, in which the base -* Frame describes a "graphical" coordinate system and is -* associated with a rectangular plotting area in the underlying -* graphics system. This plotting area is where graphical output -* appears. It is defined when the Plot is created. -* -* The current Frame of a Plot describes a "physical" coordinate -* system, which is the coordinate system in which plotting -* operations are specified. The results of each plotting operation -* are automatically transformed into graphical coordinates so as -* to appear in the plotting area (subject to any clipping which -* may be in effect). -* -* Because the Mapping between physical and graphical coordinates -* may often be non-linear, or even discontinuous, most plotting -* does not result in simple straight lines. The basic plotting -* element is therefore not a straight line, but a geodesic curve -c (see astCurve, astGenCurve and astPolyCurve). A Plot also provides facilities for -c drawing markers or symbols (astMark), text (astText) and grid lines -c (astGridLine). It is also possible to draw curvilinear axes with -c optional coordinate grids (astGrid). -f (see AST_CURVE, AST_GENCURVE and AST_POLYCURVE). A Plot also provides facilities -f for drawing markers or symbols (AST_MARK), text (AST_TEXT) and grid -f lines (AST_GRIDLINE). It is also possible to draw curvilinear axes -f with optional coordinate grids (AST_GRID). -* A range of Plot attributes is available to allow precise control -* over the appearance of graphical output produced by these -c functions. -f routines. -* -* You may select different physical coordinate systems in which to -* plot (including the native graphical coordinate system itself) -* by selecting different Frames as the current Frame of a Plot, -* using its Current attribute. You may also set up clipping (see -c astClip) to limit the extent of any plotting you perform, and -f AST_CLIP) to limit the extent of any plotting you perform, and -* this may be done in any of the coordinate systems associated -* with the Plot, not necessarily the one you are plotting in. -* -* Like any FrameSet, a Plot may also be used as a Frame. In this -* case, it behaves like its current Frame, which describes the -* physical coordinate system. -* -* When used as a Mapping, a Plot describes the inter-relation -* between graphical coordinates (its base Frame) and physical -* coordinates (its current Frame). It differs from a normal -* FrameSet, however, in that an attempt to transform points which -* lie in clipped areas of the Plot will result in bad coordinate -* values (AST__BAD). - -* Inheritance: -* The Plot class inherits from the FrameSet class. - -* Attributes: -* In addition to those attributes common to all FrameSets, every -* Plot also has the following attributes: -* -* - Abbrev: Abbreviate leading fields? -* - Border: Draw a border around valid regions of a Plot? -* - Clip: Clip lines and/or markers at the Plot boundary? -* - ClipOp: Combine Plot clipping limits using a boolean OR? -* - Colour(element): Colour index for a Plot element -* - DrawAxes(axis): Draw axes for a Plot? -* - DrawTitle: Draw a title for a Plot? -* - Escape: Allow changes of character attributes within strings? -* - Edge(axis): Which edges to label in a Plot -* - Font(element): Character font for a Plot element -* - Gap(axis): Interval between linearly spaced major axis values -* - Grf: Select the graphics interface to use. -* - Grid: Draw grid lines for a Plot? -* - Invisible: Draw graphics in invisible ink? -* - LabelAt(axis): Where to place numerical labels for a Plot -* - LabelUnits(axis): Use axis unit descriptions in a Plot? -* - LabelUp(axis): Draw numerical Plot labels upright? -* - Labelling: Label and tick placement option for a Plot -* - LogGap(axis): Interval between logarithmically spaced major axis values -* - LogPlot(axis): Map the plot onto the screen logarithmically? -* - LogTicks(axis): Space the major tick marks logarithmically? -* - MajTickLen(axis): Length of major tick marks for a Plot -* - MinTickLen(axis): Length of minor tick marks for a Plot -* - MinTick(axis): Density of minor tick marks for a Plot -* - NumLab(axis): Draw numerical axis labels for a Plot? -* - NumLabGap(axis): Spacing of numerical axis labels for a Plot -* - Size(element): Character size for a Plot element -* - Style(element): Line style for a Plot element -* - TextLab(axis): Draw descriptive axis labels for a Plot? -* - TextLabGap(axis): Spacing of descriptive axis labels for a Plot -* - TickAll: Draw tick marks on all edges of a Plot? -* - TitleGap: Vertical spacing for a Plot title -* - Tol: Plotting tolerance -* - Width(element): Line width for a Plot element - -* Functions: -c In addition to those functions applicable to all FrameSets, the -c following functions may also be applied to all Plots: -f In addition to those routines applicable to all FrameSets, the -f following routines may also be applied to all Plots: -* -c - astBBuf: Begin a new graphical buffering context -c - astBorder: Draw a border around valid regions of a Plot -c - astBoundingBox: Returns a bounding box for previously drawn graphics -c - astClip: Set up or remove clipping for a Plot -c - astCurve: Draw a geodesic curve -c - astEBuf: End the current graphical buffering context -c - astGenCurve: Draw a generalized curve -c - astGetGrfContext: Get the graphics context for a Plot -c - astGrfPop: Retrieve previously saved graphics functions -c - astGrfPush: Save the current graphics functions -c - astGrfSet: Register a graphics routine for use by a Plot -c - astGrid: Draw a set of labelled coordinate axes -c - astGridLine: Draw a grid line (or axis) for a Plot -c - astMark: Draw a set of markers for a Plot -c - astPolyCurve: Draw a series of connected geodesic curves -c - astRegionOutline: Draw the outline of an AST Region -c - astText: Draw a text string for a Plot -f - AST_BBUF: Begin a new graphical buffering context -f - AST_BORDER: Draw a border around valid regions of a Plot -f - AST_BOUNDINGBOX: Returns a bounding box for previously drawn graphics -f - AST_CLIP: Set up or remove clipping for a Plot -f - AST_CURVE: Draw a geodesic curve -f - AST_EBUF: End the current graphical buffering context -f - AST_GENCURVE: Draw a generalized curve -f - AST_GETGRFCONTEXT: Get the graphics context for a Plot -f - AST_GRFPOP: Retrieve previously saved graphics functions -f - AST_GRFPUSH: Save the current graphics functions -f - AST_GRFSET: Register a graphics routine for use by the Plot class -f - AST_GRID: Draw a set of labelled coordinate axes -f - AST_GRIDLINE: Draw a grid line (or axis) for a Plot -f - AST_MARK: Draw a set of markers for a Plot -f - AST_POLYCURVE: Draw a series of connected geodesic curves -f - AST_REGIONOUTLINE: Draw the outline of an AST Region -f - AST_TEXT: Draw a text string for a Plot - -* Graphical Elements: -* The colour index, character font, character size, line style and -* line width used for plotting can be set independently for -* various elements of the graphical output produced by a Plot. -* The different graphical elements are identified by appending the -* strings listed below as subscripts to the Plot attributes -* Colour(element), Font(element), Size(element), Style(element) -* and Width(element). These strings are case-insensitive and -* unambiguous abbreviations may be used. Elements of the graphical -* output which relate to individual axes can be referred to either -* independently (e.g. "(Grid1)" and "(Grid2)" ) or together (e.g. -* "(Grid)"): -* -c - Axes: Axis lines drawn through tick marks using astGrid -f - Axes: Axis lines drawn through tick marks using AST_GRID -c - Axis1: Axis line drawn through tick marks on axis 1 using astGrid -f - Axis1: Axis line drawn through tick marks on axis 1 using AST_GRID -c - Axis2: Axis line drawn through tick marks on axis 2 using astGrid -f - Axis2: Axis line drawn through tick marks on axis 2 using AST_GRID -c - Border: The Plot border drawn using astBorder, astGrid or astRegionOutline -f - Border: The Plot border drawn using AST_BORDER, AST_GRID or AST_REGIONOUTLINE -c - Curves: Geodesic curves drawn using astCurve, astGenCurve or astPolyCurve -f - Curves: Geodesic curves drawn using AST_CURVE, AST_GENCURVE or AST_POLYCURVE -c - Grid: Grid lines drawn using astGridLine or astGrid -f - Grid: Grid lines drawn using AST_GRIDLINE or AST_GRID -c - Grid1: Grid lines which cross axis 1, drawn using astGridLine or astGrid -f - Grid1: Grid lines which cross axis 1, drawn using AST_GRIDLINE or AST_GRID -c - Grid2: Grid lines which cross axis 2, drawn using astGridLine or astGrid -f - Grid2: Grid lines which cross axis 2, drawn using AST_GRIDLINE or AST_GRID -c - Markers: Graphical markers (symbols) drawn using astMark -f - Markers: Graphical markers (symbols) drawn using AST_MARK -c - NumLab: Numerical axis labels drawn using astGrid -f - NumLab: Numerical axis labels drawn using AST_GRID -c - NumLab1: Numerical labels for axis 1 drawn using astGrid -f - NumLab1: Numerical labels for axis 1 drawn using AST_GRID -c - NumLab2: Numerical labels for axis 2 drawn using astGrid -f - NumLab2: Numerical labels for axis 2 drawn using AST_GRID -c - Strings: Text strings drawn using astText -f - Strings: Text strings drawn using AST_TEXT -c - TextLab: Descriptive axis labels drawn using astGrid -f - TextLab: Descriptive axis labels drawn using AST_GRID -c - TextLab1: Descriptive label for axis 1 drawn using astGrid -f - TextLab1: Descriptive label for axis 1 drawn using AST_GRID -c - TextLab2: Descriptive label for axis 2 drawn using astGrid -f - TextLab2: Descriptive label for axis 2 drawn using AST_GRID -c - Ticks: Tick marks (both major and minor) drawn using astGrid -f - Ticks: Tick marks (both major and minor) drawn using AST_GRID -c - Ticks1: Tick marks (both major and minor) for axis 1 drawn using astGrid -f - Ticks1: Tick marks (both major and minor) for axis 1 drawn using AST_GRID -c - Ticks2: Tick marks (both major and minor) for axis 2 drawn using astGrid -f - Ticks2: Tick marks (both major and minor) for axis 2 drawn using AST_GRID -c - Title: The Plot title drawn using astGrid -f - Title: The Plot title drawn using AST_GRID - -* Copyright: -* Copyright (C) 1997-2006 Council for the Central Laboratory of the -* Research Councils -* Copyright (C) 2009 Science & Technology Facilities Council. -* All Rights Reserved. - -* Licence: -* This program is free software: you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation, either -* version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General -* License along with this program. If not, see -* <http://www.gnu.org/licenses/>. - -* Authors: -* DSB: D.S. Berry (Starlink) -* RFWS: R.F. Warren-Smith (Starlink) - -* History: -* 18-SEP-1996 (DSB): -* Original version. -* 25-FEB-1997 (RFWS): -* Tidied all public prologues. -* 18-AUG-1997 (DSB): -* Changes made to ensure that the first label on each axis is -* never abbreviated, and to avoid segmentation violation when NumLab -* is set to zero. -* 1-SEP-1997 (DSB): -* astGetGap changed so that it returns the default value which will -* be used (instead of AST__BAD) if no value has been set for Gap. -* The Border attribute modified so that it is off (zero) by default. -* 19-SEP-1997 (DSB): -* o Check that something has been plotted before using the bounding -* box to determine title and label positions. -* o Fixed bug which caused a tick mark at the pole to be draw at -* a random angle. -* o The size of the increment used to determine the tangent to a grid -* line at the position to a label has been reduced to make sure the -* labls are drawn parallel to grid line. -* o Correct the logic for catering with reversed axes when determining -* the displacement of a label's reference point from the associated -* axis. -* o Corrected logic which determined if two numerical labels overlap. -* o Corrected logic for determining when to abbreviate numerical -* labels. -* o Use of strtok replaced by local function FindWord. -* o Correct logic which determines which side of the axis to draw -* tick marks when using interior labelling. -* o If the base Frame of the FrameSet supplied to astPlot has more -* than 2 axes, then use a sub-frame formed from the first two axes, -* instead of simply reporting an error. -* o If the current Frame of the Plot supplied to astGrid or -* astBorder has more than 2 axes, then use a sub-frame formed from -* the first two axes, instead of simply reporting an error. -* o Default for Border is now to draw the border if exterior -* Labelling is used, but not to draw it if interior labelling is -* used. -* o Public astGet function now returns actual used values for all -* attributes. Protected astGetXyz functions still return the requested -* value (which may differ from the used value), or the "unset" value -* if no value has been set for the attribute. -* o The defaults for Edge now depend on Labelling. If exterior -* labelling was requested but cannot be produced using defaults of -* Edge(1)=Bottom and Edge(2)=Left, then these default Edge values -* are swapped. If exterior labelling is still not possible, the -* original default Edge values are re-instated. -* o Unset attributes which use dynamic defaults are now flagged as -* "unhelpful" in the dump function. -* o Added attribute Escape which allows text strings to include -* escape sequences (see function GrText). This attribute and -* associated functionality is currently not available for use, search -* for all occurences of ENABLE-ESCAPE for instructions on how to -* enable the facilities. -* o Strings now used instead of integers to represent "choice" -* attributes externally (eg Edge and Labelling). -* 24-NOV-1997 (DSB): -* o Fixed bug in function Grid which caused units to be included in -* SkyFrame axis labels by default. -* o Replaced calls to DrawText by calls to astGText, and replaced -* references to "U" and "D" justifications by "T" and "B". This -* stops labels drifting to the bottom left when GAIA zooms. -* 23-MAR-1998 (DSB): -* Added extra checks on global status into routine Grid to avoid -* segmentation violations occuring due to null pointers being used. -* 10-JUN-1998 (DSB): -* Modify DrawTicks so that ticks are drawn closer to singularities -* than previously. Also normalise this constraint to the screen size -* rather than the length of a major tick mark. -* 28-OCT-1998 (DSB): -* o Added method astPolyCurve. -* o Extract the Current Frame from the Plot prior to using Frame -* methods such as astOffset, astNorm, etc. -* o PlotLabel modified to ensure labels are abbreviated even if -* they are next to the "root" label (i.e. the label with most -* trailing zeros). -* o Modified description of Width attribute. Width no longer gives -* the absolute line width in inches. Instead it is a scale factor, -* where 1.0 corresponds to a "typical thin line" on the device. -* o Modified LabelUnits attribute so that the default value is zero -* for SkyAxes and non-zero for other Axes. -* 10-DEC-1998 (DSB): -* Modified all calls to the "pow" maths function to avoid using -* literal constants as arguments. This seems to cause segmentation -* violations on some systems. -* 16-JUL-1999 (DSB): -* Fixed memory leaks in EdgeCrossings and EdgeLabels. -* 16-SEP-1999 (DSB): -* Avoid writing out clipping limits if they are undefined. -* 12-OCT-1999 (DSB): -* o Modified use of the NumLab attribute so that setting it to zero -* does not prevent exterior labels from being produced. -* o Allow length of tick marks to be specified separately for -* both axes. -* 13-OCT-2000 (DSB): -* o Purge zero length sections from CurveData structures. -* o Increase tolerance for edge labels from 0.0005 to 0.005. -* 9-JAN-2001 (DSB): -* o Change argument "in" for astMark and astPolyCurve from type -* "const double (*)[]" to "const double *". -* o Check success of astReadString before using the returned -* pointer. -* o Change method for choosing default LabelAt values to ignore -* values which produce no visible labels. -* 10-JAN-2001 (DSB): -* o Modified FindMajTick to choose the size of fillable holes in -* the axis range on the basis of the number of ticks on the axis. -* This avoids holes being visible in the displayed tick marks when -* using very small gaps. -* 22-MAY-2001 (DSB): -* Added a check when using interior labelling, to ensure that the -* most appropriate edges are used for text labels. -* 13-JUN-2001 (DSB): -* Added public method astGenCurve, astGrfSet, astGrfPop, astGrfPush. -* Made DrawAxes attribute axis specific. -* 4-JUL-2001 (DSB): -* The Crv function used to have a restriction that if *any* -* subsection was very short, then *none* of the subsections were -* subdivided. This meant that long subsections which needed -* subdividing were not subdivided if there was also a very short -* subsection. To get round this problem the restriction was changed -* to "if *all* subsections are very short then none are divided. -* This was implemented by changing dl2_min to dl2_max, and adding -* a check for very short segments (which are then not sub-divided). -* 16-AUG-2001 (DSB): -* Remove the check for very short segments introduced above, as it -* caused south pole tan projection to include some spurious lines. -* 20-SEP-2001 (DSB): -* - Initialize baseframe to NULL in astInitPlot (prevents segvios). -* - Modified astInitPlot to allow the "frame" argument to the astPlot -* constructor to be a Plot. -* 10-JAN-2002 (DSB): -* - Added axis-specific graphical elements "axis1", "axis2", etc. -* - FullForm returns a match without ambiguity if the test string -* matches an option exactly, including length. -* 31-JAN-2002 (DSB): -* - Added RejectOOB to reject tick marks which are not in their primary -* domain. -* 14-FEB-2002 (DSB): -* - Relaxed the conditions for equality within the EQUALS macro. -* Guard aginst no ticks being found. -* 18-FEB-2002 (DSB): -* - Make a permanent copy of any old axis format string in TickMarks. -* Previously a mere pointer into the astGet string buffer was stored, -* which could be over-written after many calls to astGet. -* - If a user specifies an axis format, use it whether or not it -* results in any identical adjacent labels. -* 4-MAR-2002 (DSB): -* - Made fairly extesive changes to the creation and use of tick -* mark values in order to circumvent problems with CAR projections, -* and "1 to many" mappings (such as 2D cartesian->polar). The -* policy now is that axis normalization is only performed when -* necessary (i.e. to create labels for display, etc). Tick mark -* values are stored and handled as non-normalized values as much as -* possible. -* 13-JUN-2002 (DSB): -* Modified Norm1 to prevent major tick value from being removed if -* the supplied reference value is out of bounds, resulting in the -* Mapping producing bad values -* 14-JUN-2002 (DSB): -* Re-wrote PlotLabels to improve abbreviation of labels and the -* choice of which labels not to print. -* 14-AUG-2002 (DSB): -* - Added method astBoundingBox. -* - Added attribute Invisible. -* - Correct handling of "axis specific" plot elements cuch as -* (Axis1), (Axis2), etc. -* 12-SEP-2002 (DSB): -* - Modified Map1 to remove slow normalization method (it is now -* faster but the changes result in some longer-than-needed grids -* lines when (e.g.) plotting pixel coordins in Polar coords). -* - Modified Axlot so that SkyFrames positions which are out of -* their normal ranges are not rejected by Map1. -* 10-OCT-2002 (DSB): -* grfAttrs:Modified to test element attributes explicitly using the -* relevant TestUse<attr> functions, instead of relying on the -* "GetUse<attr>" function returning the NO<attr> constant if not set. -* - Modified Axplot so that SkyFrames positions which are out of -* their normal ranges are not rejected by Map1. -* - Only use tick marks which are within the axis range given by the -* Bottom and Top Axis attributes. -* - Norm1: If the normalized current frame coords are bad, do not -* reinstate the original unnormalized values. For instance, current -* Frame values which are outside the valid domain of the projection -* should result in bad values when normalized, not the original -* good values. The original comment stated "If the normalization -* produced bad coords (e.g. as may happen if the supplied refernce -* value corresponds to a point on the line through the tick mark -* which is outside the valid region of the mapping) leave the original -* tick mark values unchanged". -* - GetTicks: Limit maxticks to be no less than 8. -* 8-JAN-2003 (DSB): -* - Changed private InitVtab method to protected astInitPlotVtab -* method. -* - Use private IsASkyFrame method in place of astIsASkyFrame. -* - Modify PlotLabels to excluding exponents when counting trailing -* zeros, and also to pad trailing fields with trailing zeros up to -* the max number of decimal places when estimating label priorities. -* - Modified Overlap to ensure that axis labels are speced by at -* least two spaces. -* 22-JAN-2003 (DSB): -* - Modified PlotLabels so that labels are rejected in a regular -* pattern rather than semi-random. -* - Modified the way PlotLabels abbreviates leading fields. -* - Introdued the skipbad parameter for the Crv function, in order -* to provide some degree of protection against the Crv algorithm -* skipping over small sections of valid coordinates (such as when -* a curve crosses the plot very close to a corner of the plot). -* 25-MAR-2003 (DSB): -* - Modified FindMajTicks to avoid losing tick marks when dealing -* with high precision data. -* 8-AUG-2003 (DSB): -* - Modified PlotLabels to ensure that the root label for the -* second axis is not omitted due to it overlapping a label from -* the first axis (a different root label is now chosen if this would -* be the case). -* - Modify FindMajTicks to avoid tick marks which should be at -* exactly zero being placed at some very small non-zero axis value. -* 22-OCT-2003 (DSB): -* - DrawTicks modified to correctly reset graphical attributes and -* pass on to the next axis if an axis has zero length major and minor -* tick marks. -* 9-JAN-2004 (DSB): -* DrawGrid: Report error if no grid curves can be drawn. -* AxPlot: Initialise returned CDATA structure before checking argument -* validity. -* GetTicks: Calculate the reference value on the other axis using -* function "Typical" rather than simply using the man of the supplied -* values (the supplied values may be clustered around 0 and 2*PI if the -* field is centred on the origin, resulting in the mean being at about -* 1.PI and therefore inappropriate). -* 13-JAN-2004 (DSB): -* - Added LogPlot attribute, and the facility for mapping the base -* coordinate system logarithmically onto the plotting area instead of -* linearly. -* - Added LogTicks attribute, and the facility for spacing the -* major tick marks logarithmically instead of linearly. -* - Added LogGap attribute, and the facility for storing separate -* gap sizes for linear and log tick spacing. -* 15-JAN-2004 (DSB): -* - Added LogLabel attribute. -* - Re-instated the inclusion of escape sequences in strings (see -* function GrText). -* 12-FEB-2004 (DSB): -* - RightVector: Corrected usage of chh and chv. -* - GQch and GScales: Check that values returned by grf module are -* usable. -* - DrawAxis: Extend axis section by one section (if possible) at -* each end (overcomes problems where the axis does not reach a pole). -* - DrawAxis: Check axis does not extend beyond a pole. -* - Labels: Correct logic of loop which plots interior labels -* (previously it missed out labels if there were only 3) -* - Allow for some rounding error in FindMajTicks when comparing an -* axis value with a loweror upper axis limit. -* 19-FEB-2004 (DSB): -* - Reduced the dynamic range restriction for log ticks from 2 decades -* to 1. -* - Temporarily clear any error status before re-instating the -* original Format in TickMarks. -* - Add LogTicks to the GetAttrib function so that the value of the -* LogTicks attribute can be got by the public. -* - Modify Crv to include a check that he vector scale has not -* changed much between adjacent segments. -* - Modify Crv so that a segment is only subdivided if at least -* half of the subsegments are longer than the shortest significant -* length. Also put a restriction on subdivision so that -* subdivision only occurs if the bounding box of the segment being -* sub-divided is smaller than the bounding box of its parent -* segment. -* 27-FEB-2004 (DSB): -* - Reduce the default Tol value from 0.001 to 0.01 in order to -* speed up curve drawing.. -* - Use 0.1*Tol in Boundary because the boundary tracing algorithm -* seems to produce much worse visible errors than it should do for a -* given Tol. -* 2-MAR-2004 (DSB): -* - Corrected handling of bounding boxes in Crv so that -* subdivision is allowed if the bounding box shrinks on only 1 axis -* (previously required shrinkage on both axes but this fails if -* all the points are on a horizontal or vertical line). -* - Modified FindMajTicks to use a better algorithm for finding an -* appropriate nfill value (previously logplot=1 axes could have -* unfilled holes at the high end). -* - Modified GetTicks so that FindMajTicks is not called -* repeatedly with the same gap size. -* - Modify AxPlot/Map1 so that the axis curve is sampled logarithmically -* if the corresponding axis is mapped logarithmically. -* 10-MAR-2004 (DSB): -* - Modified Typical to give less weight to vaalues close to the -* edges of the range covered by the plotting area. -* - Increased minimum angle between curve and edge required to -* create an edge label from 3 degs to 5 degs. -* - Modified PlotLabels to ignore duplicate adjacent labels which -* determining overlap of labels. -* 17-MAR-2004 (DSB): -* - Modified Typical to give normal weight to edge bins in -* histogram if these bins contain all the counts. -* - Modified DrawTicks to add extra minor ticks below first major -* tick value and above last major tick value. -* - Norm1 can reject usable tick mark values because of an -* inappropriate value being used on the other axis (i.e. one for -* which the position is undefined in grapics coords). Therfoer -* Norm1 has been modified to use 3 different reference values -* in an attempt to find one which gives good axis values. -* 25-AUG-2004 (DSB): -* - Correct handling of "fmt" pointer in TickMarks function (identified -* and reported by Bill Joye). -* 14-SEP-2004 (DSB): -* - In EdgeLabels change definition of "distinct labels". Used to -* be that labels were distinct if they had different formatted -* labels. Now they are distinct if they have different floating -* point numerical values. Fixes a bug reported by Micah Johnson. -* - TickMarks re-structured to optimise the precision (no. of digits) -* even if a value has been assigned for the Format attribute, but only -* if the format specifier includes a wildcard precision specifier. For -* instance, to get graphical separators a format must be specified -* which included the "g" flag. As things were, this would prevent -* the optimisation of the digits value. Can now use "dms.*g" to -* allow the number of digits to be optimised. -* 29-SEP-2004 (DSB): -* - In FindMajTicks, begin the process of increasing "nfill" from -* a value of zero rather than one (in many cases no filling is -* needed). -* - In GetTicks (linear tick marks section) ensure that 10 -* *different* gap sizes are used before giving up. Previously, the -* 10 tests could include duplicated gap values. -* 8-NOV-2004 (DSB): -* - In Norm1, try more alternative "other axis" values before -* accepting that a tick mark value cannot be normalised. -* 2-FEB-2005 (DSB): -* - Avoid using astStore to allocate more storage than is supplied -* in the "data" pointer. This can cause access violations since -* astStore will then read beyond the end of the "data" area. -* 15-MAR-2005 (DSB): -* - Modified GridLines to use appropriate algorithm for choosing -* start of grid lines in cases where one axis has logarithmic tick -* spacing and the other has linear tick spacing. -* 21-MAR-2005 (DSB): -* - Added the Clip attribute. -* 12-JUL-2005 (DSB): -* - Modified AxPlot so that Map1 only normalises if neither axis -* is a SkyAxis. Previously it normalised if either axis was not a -* SkyAxis. -* 7-DEC-2005 (DSB): -* Free memory allocated by calls to astReadString. -* 18-JAN-2006 (DSB) -* Add Abbrev attribute. -* 14-FEB-2006 (DSB) -* Correct EdgeLabels to use gap size rather than EQUAL macro when -* comparing label values. -* 17-FEB-2006 (DSB) -* Added escape sequences "%h+" and "%g+". -* 21-MAR-2006 (DSB) -* Added extra status checks in TickMarks. -* 18-MAY-2006 (DSB) -* Trans: use correct PointSet when tranforming to arbitrary -* clipping frame. -* 26-MAY-2006 (DSB) -* Added LabelAt to TestAttrib. -* 2-JUN-2006 (DSB) -* - In MAKE_GET2, return the set value if a value has been set -* without recalculating the defaults. -* - Fix bug that could cause segvio in Grid if clipping is used. -* 5-JUN-2006 (DSB) -* Do not change the box returned by astBoundBox as a consequence -* of calling astGetAttrib. -* 19-JUN-2006 (DSB) -* Changed the default line 0.0 from zero to 1.0. -* 22-JUN-2006 (DSB) -* Include axis textual labels and title in the bounding box -* created by AST_GRID and returned by AST_BOUNDINGBOX. -* 26-JUN-2006 (DSB) -* Set the Direction attribute in the base Frame of a Plot if an -* axis is reversed. -* 29-JUN-2006 (DSB) -* - Guard against astGap calls that reach a minimum gap size. -* - Sort out splitting of long axis labels (such as date/time -* strings produced by TimeFrames). -* 30-JUN-2006 (DSB) -* If abbreviating labels, display the last field for identical -* neighbours rather than the whole value. -* 10-JUL-2006 (DSB) -* Make astStripEscapes public so it can be used by the NDF library. -* 7-AUG-2006 (DSB) -* Increase the number of attempts to find a new gap size from 5 to -* 25 in GetTicks. -* 24-OCT-2006 (DSB) -* Add the ForceExterior attribute so that SPLAT can have external -* axes even if there are no usable horizontal axis ticks (as requested -* by PWD). Currently this attribute is not included in the public -* documentation, as it may cause problems. If it seems to work OK -* then it can be made public. -* 25-JAN-2006 (DSB) -* Do not draw ticks marks that start outside the bounds of the -* axis they are labelling. -* 27-FEB-2007 (DSB) -* - Change nominal Crv_scerr value from 5.0 to 1.5 (this avoids gaps -* in HPX grid plots being bridged by grid lines). -* - Double the dimension of the grid used by GoodGrid to avoid -* missing the pointy bits in a HPX projection. -* 17-MAY-2007 (DSB) -* Exclude corner positions when determining the range of axis -* values covered by the plot. This gives better default gap sizes. -* 11-JUN-2007 (DSB) -* Plug memory leaks. -* 20-JUN-2007 (DSB) -* - Add attribute GrfContext. -* - Pass the GrfContext attribute value to each external grf function. -* External code that uses the astGrfSet function must be changed -* so that the external grf functions registered using astGrfSet -* accept this new parameter. -* 21-JUN-2007 (DSB) -* - Change GrfContext to be an Object rather than an integer. -* 22-JUN-2007 (DSB) -* - Do not dump the GrfContext Object since it may cause an -* infinite dumping loop. -* - Allow a NULL vtab to be supplied when initialising a Plot -* structure. This causes the vtab defined locally within this -* class to be used so that the new object behaves as a simple Plot. -* 25-JUN-2007 (DSB) -* - Free the graphics context object when then the Plot is deleted. -* - Fix memory leak in FullForm. -* - Since the grfcontext object is only used by external code, store -* a public object identifier for it in the Plot structure rather -* than a true C pointer. -* 26-JUN-2007 (DSB) -* Honour the LabelUp attribute value even if labels are drawn -* around the edges of the plot. -* 28-JUN-2007 (DSB) -* - Make all axis attribute arrays 3 elements long rather than 2. -* - Add the protected methods astCopyPlotDefaults and astMirror. -* - Add public method astGetGrfContext, remove astSetGrfContext. -* - Fix memory leak. -* 6-SEP-2007 (DSB): -* Dump and load any user-specified tick mark values. -* 20-OCT-2009 (DSB): -* - Modify SplitValue so that it only splits long values if -* previous long values were split, or if the value contains a -* space. -* - Take account of zero height bounding boxes in UpdateConcat. -* - Correct Dump so that it dumps attributes for all available -* axes (2 for a Plot, 3 for a Plot3D). -* 12-JAN-2010 (DSB): -* Fix various memory leaks. -* 4-MAR-2011 (DSB): -* - Added grf functions BBuf and EBuf. -* - Added public method astBBuf and astEBuf. -* 23-AUG-2011 (DSB): -* - If exterior labelling was requested but would produced too -* few labels, only swap to interior labelling if doing so would -* allow more labels to be drawn (i.e. do not swap to interior if -* it does not gain us anything). -* - Slightly decrease the dynamic range of an axis needed to produce -* logarithmic ticks (this is to avoid problems with round errors). -* 6-OCT-2011 (DSB): -* - Prevent grf qch and scales functions being called lots of times -* during each drawing operation (since the information returned by -* these functions will not change during the course of a single drawing -* operation). -* 11-OCT-2011 (DSB): -* - Combine multiple continuous polylines into a single polyline -* before calling the grf polyline function. Reducing the number of -* calls to the underlying graphics system can make a big difference -* if the graphics system is written in an interpreted language -* such as python. -* - Take account of differing axis scales when rotating vectors by -* 90 degrees. -* 12-OCT-2011 (DSB): -* - Fix the change made yesterday to correct rotation of numerical axis -* rotations. I forgot that the astGText function in the grf module -* expects the up vector in equally scaled coords, not graphics coords. -* - Take account of unequal axis scales when working out the -* length of each grid curve. -* 15-OCT-2011 (DSB): -* Always check that the grf module implements the scales function -* before trying to invoke the scales function. -* 21-MAY-2012 (DSB): -* Correct text strings used to represent the "Labelling" attribute -* within dumps of a Plot. Previously they were reversed. -* 7-JUN-2012 (DSB): -* Speed up plotting of CmpRegion boundaries by splitting the -* CmpRegion up into a set of disjoint Regions, and plotting each -* one separately. -* 16-JUN-2014 (DSB): -* - Prevent seg fault in PlotLabels caused by accessing -* uninitialised "atext" field stored within purged labels. -* - Choose a label with non-negative priority as the fall-back root label. -* 17-APR-2015 (DSB): -* Added method astRegionOutline. -* 20-APR-2015 (DSB): -* Draw Regions with higher accuracy, because Regions (i.e. Polygons) -* can be very non-smooth. -*class-- -*/ - -/* Module Macros. */ -/* ============== */ -/* Set the name of the class we are implementing. This indicates to the header - files that define class interfaces that they should make "protected" - symbols available. */ -#define astCLASS Plot - -/* Values for constants used in this class. */ -#define CRV_NSEG 14 /* No. of curve segments drawn by function Crv */ -#define CRV_NPNT 15 /* CRV_NSEG plus one */ -#define CRV_MXENT 10 /* Max. no. of recursive entries into function Crv */ -#define MAJTICKS_OPT 10 /* Optimum number of major axiss or grid lines */ -#define MAJTICKS_MAX 14 /* Max. number of major ticks or grid lines */ -#define MAJTICKS_MIN 6 /* Min. number of major ticks or grid lines */ -#define EDGETICKS_DIM 100 /* No. of edge samples used to find tick marks */ -#define LEFT 0 /* Id for the left edge of the plotting area */ -#define TOP 1 /* Id for the top edge of the plotting area */ -#define RIGHT 2 /* Id for the right edge of the plotting area */ -#define BOTTOM 3 /* Id for the bottom edge of the plotting area */ -#define NOSTYLE -999 /* A value which represents a null Style value */ -#define NOWIDTH -99.9 /* A value which represents a null Style value */ -#define NOFONT -999 /* A value which represents a null Style value */ -#define NOCOLOUR -999 /* A value which represents a null Style value */ -#define NOSIZE -99.9 /* A value which represents a null Style value */ - -#if defined(THREAD_SAFE) -#define GLOBALS_PROTO , AstGlobals * -#define GLOBALS_ARG , AstGlobals *AST__GLOBALS -#define GLOBALS_NAME , AST__GLOBALS -#else -#define GLOBALS_PROTO -#define GLOBALS_ARG -#define GLOBALS_NAME -#endif - -/* -* -* Name: -* MAKE_CLEAR - -* Purpose: -* Implement a method to clear a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_CLEAR(attr,component,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Clear<Attribute>( AstPlot *this, int axis ) -* -* and an external interface function of the form: -* -* void astClear<Attribute>_( AstPlot *this, int axis ) -* -* which implement a method for clearing a single value in a specified -* multi-valued attribute for an axis of a Plot. - -* Parameters: -* attr -* The name of the attribute to be cleared, as it appears in the function -* name (e.g. LabelAt in "astClearLabelAt"). -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to assign to the component -* to clear its value. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_CLEAR(attr,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Clear##attr( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astClear" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Assign the "clear" value. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astClear##attr##_( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Plot,Clear##attr))( this, axis, status ); \ -} - - -/* -* -* Name: -* MAKE_GET - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_GET(attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static <Type> Get<Attribute>( AstPlot *this, int axis ) -* -* and an external interface function of the form: -* -* <Type> astGet<Attribute>_( AstPlot *this, int axis ) -* -* which implement a method for getting a single value from a specified -* multi-valued attribute for an axis of a Plot. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type Get##attr( AstPlot *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGet" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -type astGet##attr##_( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Plot,Get##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_SET - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a Plot. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_SET(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set<Attribute>( AstPlot *this, int axis, <Type> value ) -* -* and an external interface function of the form: -* -* void astSet<Attribute>_( AstPlot *this, int axis, <Type> value ) -* -* which implement a method for setting a single value in a specified -* multi-valued attribute for a Plot. - -* Parameters: -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. LabelAt in "astSetLabelAt"). -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void Set##attr( AstPlot *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSet" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} \ -\ -/* External interface. */ \ -/* ------------------- */ \ -void astSet##attr##_( AstPlot *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Invoke the required method via the virtual function table. */ \ - (**astMEMBER(this,Plot,Set##attr))( this, axis, value, status ); \ -} - -/* -* -* Name: -* MAKE_TEST - -* Purpose: -* Implement a method to test if a single value has been set in a -* multi-valued attribute for a class. - -* Type: -* Private macro. - -* Synopsis: -* #include "plot.h" -* MAKE_TEST(attr,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static int Test<Attribute>( AstPlot *this, int axis ) -* -* and an external interface function of the form: -* -* int astTest<Attribute>_( AstPlot *this, int axis ) -* -* which implement a method for testing if a single value in a specified -* multi-valued attribute has been set for a class. - -* Parameters: -* attr -* The name of the attribute to be tested, as it appears in the function -* name (e.g. LabelAt in "astTestLabelAt"). -* assign -* An expression that evaluates to 0 or 1, to be used as the returned -* value. This can use the string "axis" to represent the zero-based -* index of the value within the attribute. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_TEST(attr,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static int Test##attr( AstPlot *this, int axis, int *status ) { \ - int result; /* Value to return */ \ -\ -/* Initialise */ \ - result = 0; \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astTest" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Assign the result value. */ \ - } else { \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = 0; \ -\ -/* Return the result. */ \ - return result; \ -} \ -/* External interface. */ \ -/* ------------------- */ \ -int astTest##attr##_( AstPlot *this, int axis, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return 0; \ -\ -/* Invoke the required method via the virtual function table. */ \ - return (**astMEMBER(this,Plot,Test##attr))( this, axis, status ); \ -} - -/* -* -* Name: -* MAKE_GET3 - -* Purpose: -* Implement a method to get a single value in a multi-valued attribute. - -* Type: -* Private macro. - -* Synopsis: -* MAKE_GET3(attr,attr,type,bad_value,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static <Type> Get<Attribute>( AstPlot *this, int axis ) -* -* which implements a method for getting a single value from a specified -* multi-valued attribute for an axis of a Plot. Note, no public -* interface function is created. -* -* The value returned is the value which would actually be used if -* astGrid was called with the current set of Plot attributes. This -* includes calculating any dynamic defaults which would be used, and is -* consequently rather slow. - -* Parameters: -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). The -* string "Used" is added on to the front of the supplied value. -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. This can -* use the string "axis" to represent the zero-based value index. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -* -*/ - -/* Define the macro. */ -#define MAKE_GET3(attr,type,bad_value,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type GetUsed##attr( AstPlot *, int, int *status ); \ -static type GetUsed##attr( AstPlot *this, int axis, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Initialise */ \ - result = (bad_value); \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return result; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astGetUsed" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* If the attribute is set, use its normal accessor. */\ - } else if( astTest##attr( this, axis ) ) {\ - result = astGet##attr( this, axis );\ -\ -/* Otherwise, re-calculate dynamic defaults by going through the motions of \ - drawing the grid. Nothing is actually drawn because we set the protected \ - attribute Ink to zero first. The calculated values are stored in the \ - Plot structure. */ \ - } else { \ - astSetInk( this, 0 ); \ - astGrid( this ); \ - astClearInk( this ); \ -\ -/* Assign the result value. */ \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -* -* Name: -* MAKE_SET3 - -* Purpose: -* Implement a method to set a single value in a multi-valued attribute -* for a Plot. This is identical to MAKE_SET except that no external -* interface function is created. - -* Type: -* Private macro. - -* Synopsis: -* MAKE_SET3(attr,type,component,assign,nval) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void Set<Attribute>( AstPlot *this, int axis, <Type> value ) -* -* which implements a method for setting a single value in a specified -* multi-valued attribute for a Plot. - -* Parameters: - * attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astSetLabel"). The -* string "Used" is added on to the front of the supplied value. -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. -* nval -* Specifies the number of values in the multi-valued attribute. The -* "axis" values supplied to the created function should be in the -* range zero to (nval - 1). If a value of 0 is supplied, the -* value of the Plot's Nin attribute is used instead. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET3(attr,type,component,assign,nval) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void SetUsed##attr( AstPlot *, int, type, int *status ); \ -static void SetUsed##attr( AstPlot *this, int axis, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Validate the axis index. */ \ - if( axis < 0 || axis >= ( nval ? nval : astGetNin( this ) ) ){ \ - astError( AST__AXIIN, "%s(%s): Index (%d) is invalid for attribute " \ - #attr " - it should be in the range 1 to %d.", status, \ - "astSetUsed" #attr, astGetClass( this ), \ - axis + 1, ( nval ? nval : astGetNin( this ) ) ); \ -\ -/* Store the new value in the structure component. */ \ - } else { \ - this->component[ axis ] = (assign); \ - } \ -} - -/* -*+ -* Name: -* MAKE_GET2 - -* Purpose: -* Implement a method to get an attribute value for a class. - -* Type: -* Protected macro. - -* Synopsis: -* MAKE_GET2(class,attr,type,bad_value,assign) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static <Type> GetUsed<Attr>( AstPlot *this ) -* -* which implement a method for getting a specified attribute value for a -* class. Note, no public interface function is created. -* -* The value returned is the value which would actually be used if -* astGrid was called with the current set of Plot attributes. This -* includes calculating any dynamic defaults which would be used, and is -* consequently rather slow. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attr -* The name of the attribute whose value is to be obtained, as it -* appears in the function name (e.g. Label in "astGetLabel"). The -* string "Used" is added on to the front of the supplied value. -* type -* The C type of the attribute. -* bad_value -* A constant value to return if the global error status is set, or if -* the function fails. -* assign -* An expression that evaluates to the value to be returned. - -* Notes: -* - To avoid problems with some compilers, you should not leave any white -* space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_GET2(class,attr,type,bad_value,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static type GetUsed##attr( Ast##class *, int *status ); \ -static type GetUsed##attr( Ast##class *this, int *status ) { \ - type result; /* Result to be returned */ \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return (bad_value); \ -\ -/* If the attribute is set, use its normal accessor. */\ - if( astTest##attr( this ) ) {\ - result = astGet##attr( this );\ -\ -/* Otherwise, re-calculate dynamic defaults by going through the motions of \ - drawing the grid. Nothing is actually drawn because we set the protected \ - attribute Ink to zero first. The calculated values are stored in the \ - Plot structure. */ \ - } else { \ - astSetInk( this, 0 ); \ - astGrid( this ); \ - astClearInk( this ); \ -\ -/* Assign the result value. */ \ - result = (assign); \ - } \ -\ -/* Check for errors and clear the result if necessary. */ \ - if ( !astOK ) result = (bad_value); \ -\ -/* Return the result. */ \ - return result; \ -} - -/* -*+ -* Name: -* MAKE_SET2 - -* Purpose: -* Implement a method to set an attribute value for a class. This -* is identical to astMAKE_SET except that it does not create an -* external interface function, and it does create a private function -* prototype. - -* Type: -* Protected macro. - -* Synopsis: -* MAKE_SET2(class,attr,type,component,assign) - -* Class Membership: -* Defined by the Plot class. - -* Description: -* This macro expands to an implementation of a private member function of -* the form: -* -* static void SetUsed<Attr>( AstPlot *this, <Type> value ) -* -* which implements a method for setting a specified attribute value for a -* class. - -* Parameters: -* class -* The name (not the type) of the class to which the attribute belongs. -* attr -* The name of the attribute to be set, as it appears in the function -* name (e.g. Label in "astSetLabel"). The string "Used" is added -* to the front. -* type -* The C type of the attribute. -* component -* The name of the class structure component that holds the attribute -* value. -* assign -* An expression that evaluates to the value to be assigned to the -* component. - -* Notes: -* - To avoid problems with some compilers, you should not leave -* any white space around the macro arguments. -*- -*/ - -/* Define the macro. */ -#define MAKE_SET2(class,attr,type,component,assign) \ -\ -/* Private member function. */ \ -/* ------------------------ */ \ -static void SetUsed##attr( Ast##class *, type, int *status ); \ -static void SetUsed##attr( Ast##class *this, type value, int *status ) { \ -\ -/* Check the global error status. */ \ - if ( !astOK ) return; \ -\ -/* Store the new value in the structure component. */ \ - this->component = (assign); \ -} - - -/* Header files. */ -/* ============= */ -/* Interface definitions. */ -/* ---------------------- */ -#include "channel.h" /* I/O channels */ -#include "cmpmap.h" /* Compound mapping class */ - -#include "globals.h" /* Thread-safe global data access */ -#include "error.h" /* Error reporting facilities */ -#include "frame.h" /* Coordinate frame descriptions */ -#include "frameset.h" /* Parent FrameSet class */ -#include "grf.h" /* Low-level graphics interface */ -#include "memory.h" /* Memory allocation facilities */ -#include "object.h" /* Base Object class */ -#include "plot.h" /* Interface definition for this class */ -#include "pointset.h" /* Class holding lists of positions */ -#include "keymap.h" /* Hash maps */ -#include "skyaxis.h" /* Sky coordinate axes */ -#include "skyframe.h" /* Sky coordinate frames */ -#include "winmap.h" /* Scale and shift mappings */ -#include "mathmap.h" /* Algebraic mappings */ -#include "wcsmap.h" /* FITS-WCS projectsions */ -#include "unitmap.h" /* Unit mappings */ -#include "permmap.h" /* Axis permutations */ -#include "region.h" /* Frame regions */ -#include "globals.h" /* Thread-safe global data access */ - - -/* Error code definitions. */ -/* ----------------------- */ -#include "ast_err.h" /* AST error codes */ - -/* C header files. */ -/* --------------- */ -#include <ctype.h> -#include <float.h> -#include <math.h> -#include <stddef.h> -#include <stdio.h> -#include <limits.h> -#include <stdlib.h> -#include <string.h> - -/* Module Type Definitions */ -/* ======================= */ -typedef struct LabelList { - double index; - char *text; - double x; - double y; - char *just; - double upx; - double upy; - double val; - int priority; - const char *atext; - int saved_prio; -} LabelList; - -/* Structure to hold static data used internally within the Crv function. */ -typedef struct CrvStatics { - double *pdl2; /* Pointer to next squared segment length */ - double *pdx; /* Pointer to next segment X increment */ - double *pdy; /* Pointer to next segment Y increment */ - double cosang; /* Cosine of angle between adjacent segments */ - double d0; /* Distance to start of first sub-segment */ - double delta; /* Distance between adjacent sub-segments */ - double dl; /* Segment length in graphics coordinates */ - double dll; /* Segment length for previous segment */ - double last_x; /* Graphics X at the end of the previous segment */ - double last_y; /* Graphics Y at the end of the previous segment */ - double limit2; /* Shortest acceptable squared segment length */ - double t1; /* Increment in X */ - double t2; /* Increment in Y */ - double t3; /* Squared segment length */ - double vx; /* X component of unit vector for current segment */ - double vxl; /* X component of unit vector for previous segment */ - double vy; /* Y component of unit vector for current segment */ - double vyl; /* Y component of unit vector for previous segment */ - int *seg0; /* Pointer to current segment OK flag */ - int *segm; /* Pointer to previous segment OK flag */ - int *segp; /* Pointer to next segment OK flag */ - int all_bad; /* Are all supplied positions bad or clipped? */ - int el; /* Total sub-segment count */ - int j; /* Sub-segment index */ - int last_ok; /* Was the previous position defined? */ - int nel; /* Total number of sub-segments */ - int nlong; /* No.of segments longer than limit2 */ - int nseg; /* Number of segments being sub-divided */ - int nshort; /* No.of segments shorter than limit2 */ - -#ifdef CRV_TRACE - int levels[100]; -#endif - -} CrvStatics; - -/* Structure to hold static data used internally within the Crv function. */ -typedef struct GetTicksStatics { - AstFrame *frame; /* Pointer to the current Frame */ - AstMapping *map; /* Pointer to Base->Current Mapping */ - AstPointSet *pset; /* Pointer to a PointSet holding physical coords */ - double **ptr; /* Pointer to physical coordinate values */ - double defgaps[ 2 ]; /* Initial test gaps for each axis */ - double typval[ 2 ]; /* Typical value on each axis */ - double width[ 2 ]; /* Range of used axis values */ - int maxticks; /* Max. number of ticks on each axis */ - int mintick; /* Min. number of ticks on each axis */ - int ngood[ 2 ]; /* No. of good physical values on each axis */ - int bad; /* Were any bad pixels found? */ -} GetTicksStatics; - -/* Structure to hold static data used internally within the EdgeCrossings - function. */ -typedef struct EdgeCrossingsStatics { - AstFrame *frame; /* Pointer to current Frame in Plot */ - AstPointSet *pset1; /* Graphics cooords at edge samples */ - AstPointSet *pset2; /* Physical cooords at edge samples */ - AstPointSet *pset4; /* Graphics cooords at offset edge samples */ - double **ptr1; /* Pointer to graphics coord. data */ - double **ptr2; /* Pointer to physical coord. data */ - double **ptr4; /* Pointer to graphics coord. data */ - double edgehi; /* High bound on varying graphics axis */ - double edgelo; /* Low bound on varying graphics axis */ - double edgeval; /* Constant graphics axis value along edge */ - double limit; /* Three times the RMS step size */ - int dim; /* Extended number of samples */ - int edgeax; /* Graphics axis to which edgeval refers */ - int paxis; /* Axis used in first invocation */ - int pedge; /* Edge used in first invocation */ -} EdgeCrossingsStatics; - - -/* Structure to hold static data used internally within the Map1 - function. */ -typedef struct Map1Statics { - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coord data */ - double *pax; /* Pointer to start of axis data */ - double *ptr2[ 2 ]; /* Pointers to graphics coord data */ - double *work1; /* Pointer to work space */ - double *work2; /* Pointer to work space */ - double axorig; /* Distance offset */ - double axscale; /* Distance scale */ - int neg; /* Negate axis values? */ - int nl; /* No. of points in pset1 and pset2 */ -} Map1Statics; - -/* Structure to hold static data used internally within the Map2 - function. */ -typedef struct Map2Statics { - AstPointSet *pset1; /* PointSet holding graphics coords */ - AstPointSet *pset2; /* PointSet holding physical coords */ - double **ptr2; /* Pointer to physical coord data */ - double *ptr1[ 2 ]; /* Pointers to graphics coord data */ - int nl; /* No. of points in pset1 and pset2 */ -} Map2Statics; - -/* Structure to hold static data used internally within the Map3 - function. */ -typedef struct Map3Statics { - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coord data */ - double *ptr2[ 2 ]; /* Pointers to graphics coord data */ - int nc; /* No. of physical axes */ - int nl; /* No. of points in pset1 and pset2 */ - double *pos; /* Pointer to memory for a single position */ -} Map3Statics; - -/* Structure to hold static data used internally within the Map4 - function. */ -typedef struct Map4Statics { - AstPointSet *pset1; /* PointSet holding distances */ - AstPointSet *pset2; /* PointSet holding physical coords */ - AstPointSet *pset3; /* PointSet holding graphics coords */ - int nl; /* No. of points in pset1 and pset2 */ -} Map4Statics; - -/* Structure to hold static data used internally within the Map5 - function. */ -typedef struct Map5Statics { - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coord data */ - double *ptr2[ 2 ]; /* Pointers to graphics coord data */ - int nl; /* No. of points in pset1 and pset2 */ -} Map5Statics; - -/* Structure to hold information about tick marks for a single axis. */ -typedef struct TickInfo{ - int nmajor; /* No. of major tick marks */ - int nminor; /* No. of minor tick marks */ - double *ticks; /* Pointer to array of major tick mark values */ - double *minticks; /* Pointer to array of minor tick mark values */ - char **labels; /* Pointer to array of major tick mark labels */ - double *start; /* Start pos'n on other axis for each curve section */ - double *length; /* Length on other axis of each curve section */ - int nsect; /* No. of sections in curve */ - char *fmt; /* Pointer to format string used to create labels */ - double gap; /* The gap between major ticks */ -} TickInfo; - -/* Module Variables. */ -/* ================= */ - -/* Address of this static variable is used as a unique identifier for - member of this class. */ -static int class_check; - -/* Pointers to parent class methods which are extended by this class. */ -static void (* parent_removeframe)( AstFrameSet *, int, int * ); -static AstPointSet *(* parent_transform)( AstMapping *, AstPointSet *, int, - AstPointSet *, int * ); -static const char *(* parent_getattrib)( AstObject *, const char *, int * ); -static int (* parent_testattrib)( AstObject *, const char *, int * ); -static void (* parent_clearattrib)( AstObject *, const char *, int * ); -static void (* parent_setattrib)( AstObject *, const char *, int * ); - -#if defined(THREAD_SAFE) -static int (* parent_managelock)( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Strings giving the label for the graphics items corresponding to - AST__BORDER_ID, AST__GRIDLINE_ID, etc. */ -static char *GrfLabels = "Border Curves Title Markers Strings Axis1 Axis2 Axis3 " - "NumLab1 NumLab2 NumLab3 TextLab1 TextLab2 TextLab3 " - "Ticks1 Ticks2 Ticks3 Grid1 Grid2 Grid3 Axes NumLab " - "TextLab Grid Ticks"; - -/* Text values used to represent edges externally. */ -static const char *xedge[4] = { "left", "top", "right", "bottom" }; - -/* Text values used to represent Labelling externally. */ -static const char *xlbling[2] = { "exterior", "interior" }; - -/* Define macros for accessing each item of thread specific global data. */ -#ifdef THREAD_SAFE - -/* Define how to initialise thread-specific globals. */ -#define GLOBAL_inits \ - globals->Class_Init = 0; \ - globals->GrfAttrs_nesting_t = 0; \ - globals->Crv_nent_t = 0; \ - globals->Box_lbnd_t[ 0 ] = FLT_MAX; \ - globals->Box_ubnd_t[ 0 ] = FLT_MIN; \ - globals->Boxp_lbnd_t[ 0 ] = FLT_MAX; \ - globals->Boxp_ubnd_t[ 0 ] = FLT_MIN; \ - globals->Box_lbnd_t[ 1 ] = FLT_MAX; \ - globals->Box_ubnd_t[ 1 ] = FLT_MIN; \ - globals->Boxp_lbnd_t[ 1 ] = FLT_MAX; \ - globals->Boxp_ubnd_t[ 1 ] = FLT_MIN; \ - globals->Boxp_freeze_t = 0; \ - globals->Map1_plot_t = NULL; \ - globals->Map1_map_t = NULL; \ - globals->Map1_frame_t = NULL; \ - globals->Map1_origin_t = NULL; \ - globals->Map1_statics_t = NULL; \ - globals->Map2_plot_t = NULL; \ - globals->Map2_map_t = NULL; \ - globals->Map2_statics_t = NULL; \ - globals->Map3_plot_t = NULL; \ - globals->Map3_map_t = NULL; \ - globals->Map3_frame_t = NULL; \ - globals->Map3_origin_t = NULL; \ - globals->Map3_end_t = NULL; \ - globals->Map3_statics_t = NULL; \ - globals->Map4_plot_t = NULL; \ - globals->Map4_map_t = NULL; \ - globals->Map4_umap_t = NULL; \ - globals->Map4_statics_t = NULL; \ - globals->Map5_plot_t = NULL; \ - globals->Map5_region_t = NULL; \ - globals->Map5_map_t = NULL; \ - globals->Map5_statics_t = NULL; \ - globals->Poly_n_t = 0; \ - globals->Poly_x_t = NULL; \ - globals->Poly_y_t = NULL; \ - globals->Poly_npoly_t = 0; \ - globals->Poly_np_t = NULL; \ - globals->Poly_xp_t = NULL; \ - globals->Poly_yp_t = NULL; \ - globals->Curve_data_t.nbrk = -1; \ - globals->GetAttrib_Buff[ 0 ] = 0; \ - globals->SplitValue_Buff[ 0 ] = 0; \ - globals->StripEscapes_Buff[ 0 ] = 0; \ - globals->Grf_chv_t = AST__BAD; \ - globals->Grf_chh_t = AST__BAD; \ - globals->Grf_alpha_t = 0.0; \ - globals->Grf_beta_t = 0.0; - -/* Create the function that initialises global data for this module. */ -astMAKE_INITGLOBALS(Plot) - -/* Define macros for accessing each item of thread specific global data. */ -#define class_init astGLOBAL(Plot,Class_Init) -#define class_vtab astGLOBAL(Plot,Class_Vtab) -#define grfattrs_nesting astGLOBAL(Plot,GrfAttrs_nesting_t) -#define grfattrs_attrs astGLOBAL(Plot,GrfAttrs_attrs_t) -#define Crv_limit astGLOBAL(Plot,Crv_limit_t) -#define Crv_scerr astGLOBAL(Plot,Crv_scerr_t) -#define Crv_tol astGLOBAL(Plot,Crv_tol_t) -#define Crv_ux0 astGLOBAL(Plot,Crv_ux0_t) -#define Crv_uy0 astGLOBAL(Plot,Crv_uy0_t) -#define Crv_vxl astGLOBAL(Plot,Crv_vxl_t) -#define Crv_vyl astGLOBAL(Plot,Crv_vyl_t) -#define Crv_xhi astGLOBAL(Plot,Crv_xhi_t) -#define Crv_xl astGLOBAL(Plot,Crv_xl_t) -#define Crv_xlo astGLOBAL(Plot,Crv_xlo_t) -#define Crv_yhi astGLOBAL(Plot,Crv_yhi_t) -#define Crv_yl astGLOBAL(Plot,Crv_yl_t) -#define Crv_ylo astGLOBAL(Plot,Crv_ylo_t) -#define Crv_vxbrk astGLOBAL(Plot,Crv_vxbrk_t) -#define Crv_vybrk astGLOBAL(Plot,Crv_vybrk_t) -#define Crv_xbrk astGLOBAL(Plot,Crv_xbrk_t) -#define Crv_ybrk astGLOBAL(Plot,Crv_ybrk_t) -#define Crv_len astGLOBAL(Plot,Crv_len_t) -#define Crv_ink astGLOBAL(Plot,Crv_ink_t) -#define Crv_nbrk astGLOBAL(Plot,Crv_nbrk_t) -#define Crv_nent astGLOBAL(Plot,Crv_nent_t) -#define Crv_out astGLOBAL(Plot,Crv_out_t) -#define Crv_clip astGLOBAL(Plot,Crv_clip_t) -#define Crv_map astGLOBAL(Plot,Crv_map_t) -#define Box_lbnd astGLOBAL(Plot,Box_lbnd_t) -#define Box_ubnd astGLOBAL(Plot,Box_ubnd_t) -#define Boxp_lbnd astGLOBAL(Plot,Boxp_lbnd_t) -#define Boxp_ubnd astGLOBAL(Plot,Boxp_ubnd_t) -#define Boxp_freeze astGLOBAL(Plot,Boxp_freeze_t) -#define Poly_x astGLOBAL(Plot,Poly_x_t) -#define Poly_y astGLOBAL(Plot,Poly_y_t) -#define Poly_n astGLOBAL(Plot,Poly_n_t) -#define Poly_xp astGLOBAL(Plot,Poly_xp_t) -#define Poly_yp astGLOBAL(Plot,Poly_yp_t) -#define Poly_np astGLOBAL(Plot,Poly_np_t) -#define Poly_npoly astGLOBAL(Plot,Poly_npoly_t) -#define Map1_ncoord astGLOBAL(Plot,Map1_ncoord_t) -#define Map1_plot astGLOBAL(Plot,Map1_plot_t) -#define Map1_map astGLOBAL(Plot,Map1_map_t) -#define Map1_frame astGLOBAL(Plot,Map1_frame_t) -#define Map1_origin astGLOBAL(Plot,Map1_origin_t) -#define Map1_length astGLOBAL(Plot,Map1_length_t) -#define Map1_axis astGLOBAL(Plot,Map1_axis_t) -#define Map1_statics astGLOBAL(Plot,Map1_statics_t) -#define Map1_norm astGLOBAL(Plot,Map1_norm_t) -#define Map1_log astGLOBAL(Plot,Map1_log_t) -#define Map2_ncoord astGLOBAL(Plot,Map2_ncoord_t) -#define Map2_plot astGLOBAL(Plot,Map2_plot_t) -#define Map2_map astGLOBAL(Plot,Map2_map_t) -#define Map2_x0 astGLOBAL(Plot,Map2_x0_t) -#define Map2_y0 astGLOBAL(Plot,Map2_y0_t) -#define Map2_deltax astGLOBAL(Plot,Map2_deltax_t) -#define Map2_deltay astGLOBAL(Plot,Map2_deltay_t) -#define Map2_statics astGLOBAL(Plot,Map1_statics_t) -#define Map3_ncoord astGLOBAL(Plot,Map3_ncoord_t) -#define Map3_plot astGLOBAL(Plot,Map3_plot_t) -#define Map3_map astGLOBAL(Plot,Map3_map_t) -#define Map3_frame astGLOBAL(Plot,Map3_frame_t) -#define Map3_origin astGLOBAL(Plot,Map3_origin_t) -#define Map3_end astGLOBAL(Plot,Map3_end_t) -#define Map3_scale astGLOBAL(Plot,Map3_scale_t) -#define Map3_statics astGLOBAL(Plot,Map3_statics_t) -#define Map4_ncoord astGLOBAL(Plot,Map4_ncoord_t) -#define Map4_plot astGLOBAL(Plot,Map4_plot_t) -#define Map4_map astGLOBAL(Plot,Map4_map_t) -#define Map4_umap astGLOBAL(Plot,Map4_umap_t) -#define Map4_statics astGLOBAL(Plot,Map4_statics_t) -#define Map5_plot astGLOBAL(Plot,Map5_plot_t) -#define Map5_region astGLOBAL(Plot,Map5_region_t) -#define Map5_map astGLOBAL(Plot,Map5_map_t) -#define Map5_ncoord astGLOBAL(Plot,Map5_ncoord_t) -#define Map5_statics astGLOBAL(Plot,Map5_statics_t) -#define Curve_data astGLOBAL(Plot,Curve_data_t) -#define getattrib_buff astGLOBAL(Plot,GetAttrib_Buff) -#define splitvalue_buff astGLOBAL(Plot,SplitValue_Buff) -#define stripescapes_buff astGLOBAL(Plot,StripEscapes_Buff) -#define Grf_chv astGLOBAL(Plot,Grf_chv_t) -#define Grf_chh astGLOBAL(Plot,Grf_chh_t) -#define Grf_alpha astGLOBAL(Plot,Grf_alpha_t) -#define Grf_beta astGLOBAL(Plot,Grf_beta_t) - -static pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER; -#define LOCK_MUTEX2 pthread_mutex_lock( &mutex2 ); -#define UNLOCK_MUTEX2 pthread_mutex_unlock( &mutex2 ); - -/* If thread safety is not needed, declare and initialise globals at static - variables. */ -#else - -/* Variables used within astGrfAttrs_ */ -static double grfattrs_attrs[ GRF__NATTR ]; /* Saved attribute values */ -static int grfattrs_nesting = 0; /* Nesting level. */ - -/* Variables used to pass information to the curve drawing functions. See - the prologues of functions Crv and CrvLine for details. */ -static double Crv_limit; -static double Crv_scerr; -static double Crv_tol; -static double Crv_ux0; -static double Crv_uy0; -static double Crv_vxl; -static double Crv_vyl; -static double Crv_xhi; -static double Crv_xl; -static double Crv_xlo; -static double Crv_yhi; -static double Crv_yl; -static double Crv_ylo; -static float *Crv_vxbrk; -static float *Crv_vybrk; -static float *Crv_xbrk; -static float *Crv_ybrk; -static float Crv_len; -static int Crv_ink; -static int Crv_nbrk; -static int Crv_nent = 0; -static int Crv_out; -static int Crv_clip; -static void (*Crv_map)( int, double *, double *, double *, const char *, const char *, int * ); - -/* A cache of information calculated by the grf module. */ -static double Grf_chv = AST__BAD; -static double Grf_chh = AST__BAD; -static float Grf_alpha = 0.0; -static float Grf_beta = 0.0; - -/* The lower and upper bounds of the graphics coordinates enclosing all - lines and numerical labels drawn by astGrid. */ -static float Box_lbnd[ 2 ] = {FLT_MAX, FLT_MAX }; -static float Box_ubnd[ 2 ] = {FLT_MIN, FLT_MIN }; - -/* The lower and upper bounds of the graphics coordinates enclosing all - drawn graphics primatives, maintained by functions GLine, GMark and - DrawText. */ -static float Boxp_lbnd[ 2 ] = {FLT_MAX, FLT_MAX }; -static float Boxp_ubnd[ 2 ] = {FLT_MIN, FLT_MIN }; -static int Boxp_freeze = 0; - -/* Variables used to stored buffered poly lines (see functions Opoly, Bpoly - and Apoly). */ -static float *Poly_x = NULL; -static float *Poly_y = NULL; -static int Poly_n = 0; -static float **Poly_xp = NULL; -static float **Poly_yp = NULL; -static int *Poly_np = NULL; -static int Poly_npoly = 0; - -/* Variables used by function Map1. See the prologue of Map1 for details. */ -static int Map1_ncoord; -static AstPlot *Map1_plot = NULL; -static AstMapping *Map1_map = NULL; -static AstFrame *Map1_frame = NULL; -static const double *Map1_origin = NULL; -static double Map1_length; -static void *Map1_statics = NULL; -static int Map1_axis; -static int Map1_norm; -static int Map1_log; - -/* Variables used by function Map2. See the prologue of Map2 for details. */ -static int Map2_ncoord; -static AstPlot *Map2_plot = NULL; -static AstMapping *Map2_map = NULL; -static double Map2_x0; -static double Map2_y0; -static double Map2_deltax; -static double Map2_deltay; -static void *Map2_statics = NULL; - -/* Variables used by function Map3. See the prologue of Map3 for details. */ -static int Map3_ncoord; -static AstPlot *Map3_plot = NULL; -static AstMapping *Map3_map = NULL; -static AstFrame *Map3_frame = NULL; -static const double *Map3_origin = NULL; -static const double *Map3_end = NULL; -static double Map3_scale; -static void *Map3_statics = NULL; - -/* Variables used by function Map4. See the prologue of Map4 for details. */ -static int Map4_ncoord; -static AstPlot *Map4_plot = NULL; -static AstMapping *Map4_map = NULL; -static AstMapping *Map4_umap = NULL; -static void *Map4_statics = NULL; - -/* Variables used by function Map5. See the prologue of Map5 for details. */ -static AstPlot *Map5_plot = NULL; -static AstMapping *Map5_map = NULL; -static AstRegion *Map5_region = NULL; -static void *Map5_statics = NULL; -static int Map5_ncoord; - -/* A structure which stores information about the breaks in the last curve - drawn using the public methods "astGridLine" and "astCurve". */ -static AstPlotCurveData Curve_data; - -/* Buffers for strings returned by various functions. */ -static char splitvalue_buff[ 200 ]; -static char stripescapes_buff[ AST__PLOT_STRIPESCAPES_BUFF_LEN + 1 ]; -static char getattrib_buff[ 200 ]; - - -/* Define the class virtual function table and its initialisation flag - as static variables. */ -static AstPlotVtab class_vtab; /* Virtual function table */ -static int class_init = 0; /* Virtual function table initialised? */ - -#define LOCK_MUTEX2 -#define UNLOCK_MUTEX2 - -#endif - -/* Macro to reset the cache of values caclulated by the grf module. */ -#define RESET_GRF \ - Grf_chh = AST__BAD; \ - Grf_chv = AST__BAD; \ - Grf_alpha = 0.0; \ - Grf_beta = 0.0; - - -/* Prototypes for Private Member Functions. */ -/* ======================================== */ - -static double GetTol( AstPlot *, int * ); -static int TestTol( AstPlot *, int * ); -static void ClearTol( AstPlot *, int * ); -static void SetTol( AstPlot *, double, int * ); - -static int GetGrid( AstPlot *, int * ); -static int TestGrid( AstPlot *, int * ); -static void ClearGrid( AstPlot *, int * ); -static void SetGrid( AstPlot *, int, int * ); - -static int GetTickAll( AstPlot *, int * ); -static int TestTickAll( AstPlot *, int * ); -static void ClearTickAll( AstPlot *, int * ); -static void SetTickAll( AstPlot *, int, int * ); - -static int GetForceExterior( AstPlot *, int * ); -static int TestForceExterior( AstPlot *, int * ); -static void ClearForceExterior( AstPlot *, int * ); -static void SetForceExterior( AstPlot *, int, int * ); - -static int GetBorder( AstPlot *, int * ); -static int TestBorder( AstPlot *, int * ); -static void ClearBorder( AstPlot *, int * ); -static void SetBorder( AstPlot *, int, int * ); - -static int GetInvisible( AstPlot *, int * ); -static int TestInvisible( AstPlot *, int * ); -static void ClearInvisible( AstPlot *, int * ); -static void SetInvisible( AstPlot *, int, int * ); - -static int GetInk( AstPlot *, int * ); -static int TestInk( AstPlot *, int * ); -static void ClearInk( AstPlot *, int * ); -static void SetInk( AstPlot *, int, int * ); - -static int GetClipOp( AstPlot *, int * ); -static int TestClipOp( AstPlot *, int * ); -static void ClearClipOp( AstPlot *, int * ); -static void SetClipOp( AstPlot *, int, int * ); - -static int GetClip( AstPlot *, int * ); -static int TestClip( AstPlot *, int * ); -static void ClearClip( AstPlot *, int * ); -static void SetClip( AstPlot *, int, int * ); - -static int GetGrf( AstPlot *, int * ); -static int TestGrf( AstPlot *, int * ); -static void ClearGrf( AstPlot *, int * ); -static void SetGrf( AstPlot *, int, int * ); - -static int GetDrawTitle( AstPlot *, int * ); -static int TestDrawTitle( AstPlot *, int * ); -static void ClearDrawTitle( AstPlot *, int * ); -static void SetDrawTitle( AstPlot *, int, int * ); - -static int GetDrawAxes( AstPlot *, int, int * ); -static int TestDrawAxes( AstPlot *, int, int * ); -static void ClearDrawAxes( AstPlot *, int, int * ); -static void SetDrawAxes( AstPlot *, int, int, int * ); - -static int GetAbbrev( AstPlot *, int, int * ); -static int TestAbbrev( AstPlot *, int, int * ); -static void ClearAbbrev( AstPlot *, int, int * ); -static void SetAbbrev( AstPlot *, int, int, int * ); - -static int GetEscape( AstPlot *, int * ); -static int TestEscape( AstPlot *, int * ); -static void ClearEscape( AstPlot *, int * ); -static void SetEscape( AstPlot *, int, int * ); - -static double GetLabelAt( AstPlot *, int, int * ); -static int TestLabelAt( AstPlot *, int, int * ); -static void ClearLabelAt( AstPlot *, int, int * ); -static void SetLabelAt( AstPlot *, int, double, int * ); - -static double GetNumLabGap( AstPlot *, int, int * ); -static int TestNumLabGap( AstPlot *, int, int * ); -static void ClearNumLabGap( AstPlot *, int, int * ); -static void SetNumLabGap( AstPlot *, int, double, int * ); - -static double GetTextLabGap( AstPlot *, int, int * ); -static int TestTextLabGap( AstPlot *, int, int * ); -static void ClearTextLabGap( AstPlot *, int, int * ); -static void SetTextLabGap( AstPlot *, int, double, int * ); - -static double GetCentre( AstPlot *, int, int * ); -static int TestCentre( AstPlot *, int, int * ); -static void ClearCentre( AstPlot *, int, int * ); -static void SetCentre( AstPlot *, int, double, int * ); - -static double GetGap( AstPlot *, int, int * ); -static int TestGap( AstPlot *, int, int * ); -static void ClearGap( AstPlot *, int, int * ); -static void SetGap( AstPlot *, int, double, int * ); - -static int GetLabelling( AstPlot *, int * ); -static int TestLabelling( AstPlot *, int * ); -static void ClearLabelling( AstPlot *, int * ); -static void SetLabelling( AstPlot *, int, int * ); - -static double GetMajTickLen( AstPlot *, int, int * ); -static int TestMajTickLen( AstPlot *, int, int * ); -static void ClearMajTickLen( AstPlot *, int, int * ); -static void SetMajTickLen( AstPlot *, int, double, int * ); - -static double GetLogGap( AstPlot *, int, int * ); -static int TestLogGap( AstPlot *, int, int * ); -static void ClearLogGap( AstPlot *, int, int * ); -static void SetLogGap( AstPlot *, int, double, int * ); - -static double GetTitleGap( AstPlot *, int * ); -static int TestTitleGap( AstPlot *, int * ); -static void ClearTitleGap( AstPlot *, int * ); -static void SetTitleGap( AstPlot *, double, int * ); - -static double GetMinTickLen( AstPlot *, int, int * ); -static int TestMinTickLen( AstPlot *, int, int * ); -static void ClearMinTickLen( AstPlot *, int, int * ); -static void SetMinTickLen( AstPlot *, int, double, int * ); - -static int GetEdge( AstPlot *, int, int * ); -static int TestEdge( AstPlot *, int, int * ); -static void ClearEdge( AstPlot *, int, int * ); -static void SetEdge( AstPlot *, int, int, int * ); - -static int GetLabelUp( AstPlot *, int, int * ); -static int TestLabelUp( AstPlot *, int, int * ); -static void ClearLabelUp( AstPlot *, int, int * ); -static void SetLabelUp( AstPlot *, int, int, int * ); - -static int GetLogPlot( AstPlot *, int, int * ); -static int TestLogPlot( AstPlot *, int, int * ); -static void ClearLogPlot( AstPlot *, int, int * ); -static void SetLogPlot( AstPlot *, int, int, int * ); - -static int GetLogTicks( AstPlot *, int, int * ); -static int TestLogTicks( AstPlot *, int, int * ); -static void ClearLogTicks( AstPlot *, int, int * ); -static void SetLogTicks( AstPlot *, int, int, int * ); - -static int GetLogLabel( AstPlot *, int, int * ); -static int TestLogLabel( AstPlot *, int, int * ); -static void ClearLogLabel( AstPlot *, int, int * ); -static void SetLogLabel( AstPlot *, int, int, int * ); - -static int GetNumLab( AstPlot *, int, int * ); -static int TestNumLab( AstPlot *, int, int * ); -static void ClearNumLab( AstPlot *, int, int * ); -static void SetNumLab( AstPlot *, int, int, int * ); - -static int GetMinTick( AstPlot *, int, int * ); -static int TestMinTick( AstPlot *, int, int * ); -static void ClearMinTick( AstPlot *, int, int * ); -static void SetMinTick( AstPlot *, int, int, int * ); - -static int GetTextLab( AstPlot *, int, int * ); -static int TestTextLab( AstPlot *, int, int * ); -static void ClearTextLab( AstPlot *, int, int * ); -static void SetTextLab( AstPlot *, int, int, int * ); - -static int GetLabelUnits( AstPlot *, int, int * ); -static int TestLabelUnits( AstPlot *, int, int * ); -static void ClearLabelUnits( AstPlot *, int, int * ); -static void SetLabelUnits( AstPlot *, int, int, int * ); - -static int GetStyle( AstPlot *, int, int * ); -static int TestStyle( AstPlot *, int, int * ); -static void ClearStyle( AstPlot *, int, int * ); -static void SetStyle( AstPlot *, int, int, int * ); - -static int GetFont( AstPlot *, int, int * ); -static int TestFont( AstPlot *, int, int * ); -static void ClearFont( AstPlot *, int, int * ); -static void SetFont( AstPlot *, int, int, int * ); - -static int GetColour( AstPlot *, int, int * ); -static int TestColour( AstPlot *, int, int * ); -static void ClearColour( AstPlot *, int, int * ); -static void SetColour( AstPlot *, int, int, int * ); - -static double GetWidth( AstPlot *, int, int * ); -static int TestWidth( AstPlot *, int, int * ); -static void ClearWidth( AstPlot *, int, int * ); -static void SetWidth( AstPlot *, int, double, int * ); - -static double GetSize( AstPlot *, int, int * ); -static int TestSize( AstPlot *, int, int * ); -static void ClearSize( AstPlot *, int, int * ); -static void SetSize( AstPlot *, int, double, int * ); - -static const char *GetAttrib( AstObject *, const char *, int * ); -static int TestAttrib( AstObject *, const char *, int * ); -static void ClearAttrib( AstObject *, const char *, int * ); -static void SetAttrib( AstObject *, const char *, int * ); - -static AstFrameSet *Fset2D( AstFrameSet *, int, int * ); -static AstKeyMap *GetGrfContext( AstPlot *, int * ); -static AstPlotCurveData **CleanCdata( AstPlotCurveData **, int * ); -static AstPlotCurveData **DrawGrid( AstPlot *, TickInfo **, int, const char *, const char *, int * ); -static AstPointSet *DefGap( AstPlot *, double *, int *, double *, int *, const char *, const char *, int * ); -static AstPointSet *GetDrawnTicks( AstPlot *, int, int, int * ); -static AstPointSet *Trans( AstPlot *, AstFrame *, AstMapping *, AstPointSet *, int, AstPointSet *, int, const char *, const char *, int * ); -static AstPointSet *Transform( AstMapping *, AstPointSet *, int, AstPointSet *, int * ); -static TickInfo **CleanGrid( TickInfo **, int * ); -static TickInfo **GridLines( AstPlot *, double *, double *, int *, const char *, const char *, int * ); -static TickInfo *TickMarks( AstPlot *, int, double *, double *, int *, GetTicksStatics **, const char *, const char *, int * ); -static char **CheckLabels2( AstPlot *, AstFrame *, int, double *, int, char **, double, int * ); -static char *FindWord( char *, const char *, const char **, int * ); -static char *GrfItem( int, const char *, int *, int * ); -static const char *JustMB( AstPlot *, int, const char *, float *, float *, float, float, const char *, float, float, float, float, float *, float *, const char *, const char *, int * ); -static const char *SplitValue( AstPlot *, const char *, int, int *, int * ); -static double **MakeGrid( AstPlot *, AstFrame *, AstMapping *, int, int, double, double, double, double, int, AstPointSet **, AstPointSet**, int, const char *, const char *, int * ); -static double GetTicks( AstPlot *, int, double *, double **, int *, double **, int *, int, int *, double *, GetTicksStatics **, const char *, const char *, int * ); -static double GetUseSize( AstPlot *, int, int * ); -static double GetUseWidth( AstPlot *, int, int * ); -static double GoodGrid( AstPlot *, int *, AstPointSet **, AstPointSet **, const char *, const char *, int * ); -static double Typical( int, double *, double, double, double *, int * ); -static int Border( AstPlot *, int * ); -static int Boundary( AstPlot *, const char *, const char *, int * ); -static int BoxCheck( float *, float *, float *, float *, int * ); -static int CGAttrWrapper( AstPlot *, int, double, double *, int, int * ); -static int CGBBufWrapper( AstPlot *, int * ); -static int CGCapWrapper( AstPlot *, int, int, int * ); -static int CGEBufWrapper( AstPlot *, int * ); -static int CGFlushWrapper( AstPlot *, int * ); -static int CGLineWrapper( AstPlot *, int, const float *, const float *, int * ); -static int CGMarkWrapper( AstPlot *, int, const float *, const float *, int, int * ); -static int CGQchWrapper( AstPlot *, float *, float *, int * ); -static int CGScalesWrapper( AstPlot *, float *, float *, int * ); -static int CGTextWrapper( AstPlot *, const char *, float, float, const char *, float, float, int * ); -static int CGTxExtWrapper( AstPlot *, const char *, float, float, const char *, float, float, float *, float *, int * ); -static int CheckLabels( AstPlot *, AstFrame *, int, double *, int, int, char **, double, int * ); -static int ChrLen( const char *, int * ); -static int Compare_LL( const void *, const void * ); -static int Compared( const void *, const void * ); -static int CountGood( int, double *, int * ); -static int Cross( float, float, float, float, float, float, float, float, int * ); -static int CvBrk( AstPlot *, int, double *, double *, double *, int * ); -static int DrawRegion( AstPlot *, AstFrame *, const char *, const char *, int * ); -static int EdgeCrossings( AstPlot *, int, int, double, double *, double **, EdgeCrossingsStatics **, const char *, const char *, int * ); -static int EdgeLabels( AstPlot *, int, TickInfo **, AstPlotCurveData **, int, const char *, const char *, int * ); -static int FindDPTZ( AstFrame *, int, const char *, const char *, int *, int *, int * ); -static int FindMajTicks( AstMapping *, AstFrame *, int, double, double, double , double *, int, double *, double **, int * ); -static int FindMajTicks2( int, double, double, int, double *, double **, int * ); -static int FindString( int, const char *[], const char *, const char *, const char *, const char *, int * ); -static int Fpoly_ecmp( const void *, const void * ); -static int Fpoly_scmp( const void *, const void * ); -static int FullForm( const char *, const char *, const char *, const char *, const char *, int * ); -static int GCap( AstPlot *, int, int, int * ); -static int GVec( AstPlot *, AstMapping *, double *, int, double, AstPointSet **, AstPointSet **, double *, double *, double *, double *, int *, const char *, const char *, int * ); -static int GetUseColour( AstPlot *, int, int * ); -static int GetUseFont( AstPlot *, int, int * ); -static int GetUseStyle( AstPlot *, int, int * ); -static int GraphGrid( int, int, double, double, double, double, double **, int * ); -static int HasEscapes( const char *, int * ); -static int IdFind( int, int, int *, int *, int *, int * ); -static int Inside( int, float *, float *, float, float, int * ); -static int IsASkyAxis( AstFrame *, int, int * ); -static int IsASkyFrame( AstObject *, int * ); -static int Labelat( AstPlot *, TickInfo **, AstPlotCurveData **, double *, const char *, const char *, int * ); -static int Overlap( AstPlot *, int, int, const char *, float, float, const char *, float, float, float **, const char *, const char *, int * ); -static int PopGat( AstPlot *, float *, const char *, const char *, int * ); -static int TestUseColour( AstPlot *, int, int * ); -static int TestUseFont( AstPlot *, int, int * ); -static int TestUseSize( AstPlot *, int, int * ); -static int TestUseStyle( AstPlot *, int, int * ); -static int TestUseWidth( AstPlot *, int, int * ); -static int ToggleLogLin( AstPlot *, int, int, const char *, int * ); -static int TraceBorder( AstPlot *, AstMapping *, double, double, double, double, int, double, int[ 4 ], const char *, const char *, int * ); -static int Ustrcmp( const char *, const char *, int * ); -static int Ustrncmp( const char *, const char *, size_t, int * ); -static int swapEdges( AstPlot *, TickInfo **, AstPlotCurveData **, int * ); -static void AddCdt( AstPlotCurveData *, AstPlotCurveData *, const char *, const char *, int * ); -static void Apoly( AstPlot *, float, float, int * ); -static void AxPlot( AstPlot *, int, const double *, double, int, AstPlotCurveData *, const char *, const char *, int * ); -static void BBuf( AstPlot *, int * ); -static void BoundingBox( AstPlot *, float[2], float[2], int * ); -static void Bpoly( AstPlot *, float, float, int * ); -static void Clip( AstPlot *, int, const double [], const double [], int * ); -static void Copy( const AstObject *, AstObject *, int * ); -static void CopyPlotDefaults( AstPlot *, int, AstPlot *, int, int * ); -static void Crv( AstPlot *this, double *, double *, double *, int, double *, CrvStatics *, const char *, const char *, int * ); -static void CrvLine( AstPlot *this, double, double, double, double, const char *, const char *, int * ); -static void Curve( AstPlot *, const double [], const double [], int * ); -static void CurvePlot( AstPlot *, const double *, const double *, int , AstPlotCurveData *, const char *, const char *, int * ); -static void Delete( AstObject *, int * ); -static void DrawAxis( AstPlot *, TickInfo **, double *, double *, const char *, const char *, int * ); -static void DrawText( AstPlot *, int, int, const char *, float, float, const char *, float, float, float *, float *, float *, const char *, const char *, int * ); -static void DrawTicks( AstPlot *, TickInfo **, int, double *, double *, const char *, const char *, int * ); -static void Dump( AstObject *, AstChannel *, int * ); -static void EBuf( AstPlot *, int * ); -static void Fpoly( AstPlot *, const char *, const char *, int * ); -static void GAttr( AstPlot *, int, double, double *, int, const char *, const char *, int * ); -static void GBBuf( AstPlot *, const char *, const char *, int * )__attribute__((unused)); -static void GEBuf( AstPlot *, const char *, const char *, int * )__attribute__((unused)); -static void GFlush( AstPlot *, const char *, const char *, int * )__attribute__((unused)); -static void GLine( AstPlot *, int, const float *, const float *, const char *, const char *, int * ); -static void GMark( AstPlot *, int, const float *, const float *, int, const char *, const char *, int * ); -static void GQch( AstPlot *, float *, float *, const char *, const char *, int * ); -static void GScales( AstPlot *, float *, float *, const char *, const char *, int * ); -static void GText( AstPlot *, const char *, float, float, const char *, float, float, const char *, const char *, int * ); -static void GTxExt( AstPlot *, const char *, float , float, const char *, float, float, float *, float *, const char *, const char *, int * ); -static void GenCurve( AstPlot *, AstMapping *, int * ); -static void GrfPop( AstPlot *, int * ); -static void GrfPush( AstPlot *, int * ); -static void GrfSet( AstPlot *, const char *, AstGrfFun, int * ); -static void GrfWrapper( AstPlot *, const char *, AstGrfWrap, int * ); -static void Grid( AstPlot *, int * ); -static void GridLine( AstPlot *, int, const double [], double, int * ); -static void InterpEscape( AstPlot *, int, double, float *, float *, float, float, float, float, const char *, float *, double, double, double, double, double, const char *, const char *, int * ); -static void Labels( AstPlot *, TickInfo **, AstPlotCurveData **, double *, double *, const char *, const char *, int * ); -static void LinePlot( AstPlot *, double, double, double, double, int, AstPlotCurveData *, const char *, const char *, int * ); -static void Map1( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map2( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map3( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map4( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Map5( int, double *, double *, double *, const char *, const char *, int * GLOBALS_PROTO ); -static void Mark( AstPlot *, int, int, int, const double *, int, int * ); -static void Mirror( AstPlot *, int, int * ); -static void Norm1( AstMapping *, int, int, double *, double, double, int * ); -static void Opoly( AstPlot *, int * ); -static void PlotLabels( AstPlot *, int, AstFrame *, int, LabelList *, char *, int, float **, const char *, const char *, int * ); -static void PolyCurve( AstPlot *, int, int, int, const double *, int * ); -static void PurgeCdata( AstPlotCurveData *, int * ); -static void PushGat( AstPlot *, float, const char *, const char *, int * ); -static void RegionOutline( AstPlot *, AstRegion *, int * ); -static void RemoveFrame( AstFrameSet *, int, int * ); -static void RightVector( AstPlot *, float *, float *, float *, float *, const char *, const char *, int * ); -static void SaveTick( AstPlot *, int, double, double, int, int * ); -static void SetTickValues( AstPlot *, int, int, double *, int, double *, int * ); -static void Text( AstPlot *, const char *, const double [], const float [], const char *, int * ); -static void TextLabels( AstPlot *, int, int *, const char *, const char *, int * ); -static void Ticker( AstPlot *, int, int, double, double *, double, int, int, EdgeCrossingsStatics **, const char *, const char *, int * ); -static void UpdateConcat( float *, float *, float, float, float, float, float *, float *, float, float, float *, float *, float *, float *, int * ); - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *, int, int, AstObject **, int * ); -#endif - -/* Functions which access class attributes. */ -/* ======================================= */ -/* Implement member functions to access the attributes associated with this - class using the macros defined for this purpose in the "object.h" file. For - a description of each attribute, see the class interface (in the associated - .h file). */ - -/* Tol. */ -/* ---- */ -/* -*att++ -* Name: -* Tol - -* Purpose: -* Plotting tolerance. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute specifies the plotting tolerance (or resolution) -* to be used for the graphical output produced by a Plot. Smaller -* values will result in smoother and more accurate curves being -* drawn, but may slow down the plotting process. Conversely, -* larger values may speed up the plotting process in cases where -* high resolution is not required. -* -* The Tol value should be given as a fraction of the minimum -* dimension of the plotting area, and should lie in the range -c from 1.0e-7 to 1.0. By default, a value of 0.01 is used. -f from 1.0E-7 to 1.0. By default, a value of 0.01 is used. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -/* The plotting tolerance. Has a value of -1.0 when not set yielding a -default value of 0.01. Usable values are in the range 1.0E-7 to 1.0. */ -astMAKE_CLEAR(Plot,Tol,tol,-1.0) -astMAKE_GET(Plot,Tol,double,0.01,(this->tol == -1.0 ? 0.01 : this->tol)) -astMAKE_SET(Plot,Tol,double,tol,astMIN(astMAX(value,1.0E-7),1.0)) -astMAKE_TEST(Plot,Tol,( this->tol != -1.0 )) - -/* Grid. */ -/* ----- */ -/* -*att++ -* Name: -* Grid - -* Purpose: -* Draw grid lines for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether grid lines (a grid of curves marking the "major" values -* on each axis) are drawn across the plotting area. -* -* If the Grid value of a Plot is non-zero, then grid lines will be -* drawn. Otherwise, short tick marks on the axes are used to mark -* the major axis values. The default behaviour is to use tick -* marks if the entire plotting area is filled by valid physical -* coordinates, but to draw grid lines otherwise. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The spacing between major axis values, which determines the -* spacing of grid lines, may be set using the Gap(axis) attribute. -*att-- -*/ -/* If non-zero use lines instead of tick marks in a coordinate grid. Has a -value of -1 when not set yielding a default value of 0. */ -astMAKE_CLEAR(Plot,Grid,grid,-1) -astMAKE_GET(Plot,Grid,int,0,(this->grid == -1 ? 0 : this->grid)) -astMAKE_SET(Plot,Grid,int,grid,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Grid,( this->grid != -1 )) - -MAKE_GET2(Plot,Grid,int,0,this->ugrid) -MAKE_SET2(Plot,Grid,int,ugrid,( value ? 1 : 0 )) - -/* Invisible. */ -/* ---------- */ -/* -*att++ -* Name: -* Invisible - -* Purpose: -* Draw graphics using invisible ink? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of all graphics produced by -* Plot methods by determining whether graphics should be visible or -* invisible. -* -* If the Invisible value of a Plot is non-zero, then all the Plot -* methods which normally generate graphical output do not do so (you -* can think of them drawing with "invisible ink"). Such methods do, -* however, continue to do all the calculations which would be needed to -* produce the graphics. In particular, the bounding box enclosing the -* graphics is still calculated and can be retrieved as normal using -c astBoundingBox. The default value is zero, resulting in all methods -f AST_BOUNDINGBOX. The default value is zero, resulting in all methods -* drawing graphics as normal, using visible ink. - -* Applicability: -* Plot -* All Plots have this attribute. - -*att-- -*/ -/* If non-zero use invisible ink. Has a value of -1 when not set yielding -a default value of 0. */ -astMAKE_CLEAR(Plot,Invisible,invisible,-1) -astMAKE_GET(Plot,Invisible,int,0,(this->invisible == -1 ? 0 : this->invisible)) -astMAKE_SET(Plot,Invisible,int,invisible,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Invisible,( this->invisible != -1 )) - -/* TickAll */ -/* ------- */ -/* -*att++ -* Name: -* TickAll - -* Purpose: -* Draw tick marks on all edges of a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether tick marks should be drawn on all edges of a Plot. -* -* If the TickAll value of a Plot is non-zero (the default), then -* tick marks will be drawn on all edges of the Plot. Otherwise, -* they will be drawn only on those edges where the numerical and -* descriptive axis labels are drawn (see the Edge(axis) -* attribute). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - In some circumstances, numerical labels and tick marks are -* drawn along grid lines inside the plotting area, rather than -* around its edges (see the Labelling attribute). In this case, -* the value of the TickAll attribute is ignored. -*att-- -*/ -/* If non-zero put tick marks on opposite edges. Has a value of -1 when not -set yielding a default value of 1. */ -astMAKE_CLEAR(Plot,TickAll,tickall,-1) -astMAKE_GET(Plot,TickAll,int,1,(this->tickall == -1 ? 1 : this->tickall)) -astMAKE_SET(Plot,TickAll,int,tickall,( value ? 1 : 0 )) -astMAKE_TEST(Plot,TickAll,( this->tickall != -1 )) - -/* ForceExterior */ -/* ------------- */ -/* -*att+ -* Name: -* ForceExterior - -* Purpose: -* Force the use of exterior labelling? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by forcing -f coordinate grid (drawn with the AST_GRID routine) by forcing -* labels and tick marks to be drawn round the edges of the plot -* (rather than across the middle of the plot), even if there appear -* to be insufficient edge crossings to justify the use of exterior -* labelling. -* -* The default value of zero results in the decision about whether to -* use interior or exterior labelling being made purely on the basis -* of the value of the Labelling attribute. If ForceExterior is set to -* a non-zero value, then the Labelling attribute is ignored and exterior -* labelling will always be attempted, even if there appear to be -* insufficient edge labels to justify their use. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The value of this attribute is currently under investigation, and -* so this attribute prologue is currently marked as protected rather -* than public (in order to prevent it being included in the public -* documentation). -*att- -*/ -astMAKE_CLEAR(Plot,ForceExterior,forceexterior,-1) -astMAKE_GET(Plot,ForceExterior,int,0,(this->forceexterior == -1 ? 0 : this->forceexterior)) -astMAKE_SET(Plot,ForceExterior,int,forceexterior,( value ? 1 : 0 )) -astMAKE_TEST(Plot,ForceExterior,( this->forceexterior != -1 )) - -/* -*att++ -* Name: -* Border - -* Purpose: -* Draw a border around valid regions of a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether a border is drawn around regions corresponding to the -c valid physical coordinates of a Plot (c.f. astBorder). -f valid physical coordinates of a Plot (c.f. AST_BORDER). -* -* If the Border value of a Plot is non-zero, then this border will -* be drawn as part of the grid. Otherwise, the border is not drawn -* (although axis labels and tick marks will still appear, unless -* other relevant Plot attributes indicate that they should -* not). The default behaviour is to draw the border if tick marks -* and numerical labels will be drawn around the edges of the -* plotting area (see the Labelling attribute), but to omit it -* otherwise. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -/* If non-zero draw the border. Has a value of -1 when not set, yeilding - a default of 1. */ -astMAKE_CLEAR(Plot,Border,border,-1) -astMAKE_SET(Plot,Border,int,border,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Border,( this->border != -1 )) -astMAKE_GET(Plot,Border,int,1,(this->border == -1 ? 1 : this->border)) - -MAKE_SET2(Plot,Border,int,uborder,( value ? 1 : 0 )) -MAKE_GET2(Plot,Border,int,1,this->uborder) - -/* Clip */ -/* ---- */ -/* -*att++ -* Name: -* Clip - -* Purpose: -* Clip lines and/or markers at the Plot boundary? - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls whether curves and markers are clipped at the -* boundary of the graphics box specified when the Plot was created. A -* value of 3 implies both markers and curves are clipped at the Plot -* boundary. A value of 2 implies markers are clipped, but not curves. A -* value of 1 implies curves are clipped, but not markers. A value of -* zero implies neither curves nor markers are clipped. The default -* value is 1. Note, this attributes controls only the clipping -* performed internally within AST. The underlying graphics system may -* also apply clipping. In such cases, removing clipping using this -* attribute does not guarantee that no clipping will be visible in the -* final plot. -* -c The astClip function -f The AST_CLIP routine -* can be used to establish generalised clipping within arbitrary -* regions of the Plot. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -astMAKE_CLEAR(Plot,Clip,clip,-1) -astMAKE_GET(Plot,Clip,int,0,(this->clip == -1 ? 1 : this->clip)) -astMAKE_TEST(Plot,Clip,( this->clip != -1 )) -astMAKE_SET(Plot,Clip,int,clip,((value>=0&&value<=3)?value:(astError( AST__ATTIN, "astSetClip(Plot): Invalid value %d supplied for Clip attribute", status, value ), this->clip))) - -/* ClipOp */ -/* ------ */ -/* -*att++ -* Name: -* ClipOp - -* Purpose: -* Combine Plot clipping limits using a boolean OR? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls how the clipping limits specified for -c each axis of a Plot (using the astClip function) are -f each axis of a Plot (using the AST_CLIP routine) are -* combined. This, in turn, determines which parts of the graphical -* output will be visible. -* -* If the ClipOp attribute of a Plot is zero (the default), -* graphical output is visible only if it satisfies the clipping -* limits on all the axes of the clipping Frame (a boolean -* AND). Otherwise, if ClipOp is non-zero, output is visible if it -* satisfies the clipping limits on one or more axes (a boolean -* OR). -* -* An important use of this attribute is to allow areas of a Plot -* to be left clear (e.g. as a background for some text). To -* achieve this, the lower and upper clipping bounds supplied to -c astClip should be reversed, and the ClipOp attribute of the -f AST_CLIP should be reversed, and the ClipOp attribute of the -* Plot should be set to a non-zero value. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ -/* If non-zero only 1axis need be within the clipping bounds to avoid a -point being clipped. Otherwise, all axes must be within bounds. */ -astMAKE_CLEAR(Plot,ClipOp,clipop,-1) -astMAKE_GET(Plot,ClipOp,int,0,(this->clipop == -1 ? 0 : this->clipop)) -astMAKE_SET(Plot,ClipOp,int,clipop,( value ? 1 : 0 )) -astMAKE_TEST(Plot,ClipOp,( this->clipop != -1 )) - -/* Grf. */ -/* ---- */ -/* -*att++ -* Name: -* Grf - -* Purpose: -c Use Grf functions registered through astGrfSet? -f Use Grf routines registered through AST_GRFSET? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -c This attribute selects the functions which are used to draw graphics by -c the Plot class. If it is zero, then the functions in the graphics -c interface selected at link-time are used (see the ast_link script). -c Otherwise, functions registered using astGrfSet are used. In this -c case, if a function is needed which has not been registered, -c then the function in the graphics interface selected at link-time is -c used. -f This attribute selects the routines which are used to draw graphics by -f the Plot class. If it is zero, then the routines in the graphics -f interface selected at link-time are used (see the ast_link script). -f Otherwise, routines registered using AST_GRFSET are used. In this -f case, if a routine is needed which has not been registered, -f then the routine in the graphics interface selected at link-time is -f used. - -* The default is to use the graphics interface - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes, assuming a value of -* zero. - -* Notes: -* - The value of this attribute is not saved when the Plot is written -* out through a Channel to an external data store. On re-loading such -c a Plot using astRead, the attribute will be cleared, resulting in the -f a Plot using AST_READ, the attribute will be cleared, resulting in the -* graphics interface selected at link-time being used. - -*att-- -*/ -/* Use Grf routines registered using astGrfSet? Has a -value of -1 when not set yielding a default of 0. */ -astMAKE_CLEAR(Plot,Grf,grf,-1) -astMAKE_GET(Plot,Grf,int,0,(this->grf == -1 ? 0 : this->grf)) -astMAKE_SET(Plot,Grf,int,grf,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Grf,( this->grf != -1 )) - -/* DrawTitle */ -/* --------- */ -/* -*att++ -* Name: -* DrawTitle - -* Purpose: -* Draw a title for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether a title is drawn. -* -* If the DrawTitle value of a Plot is non-zero (the default), then -* the title will be drawn, otherwise it will be omitted. - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes, assuming a value of -* zero. - -* Notes: -* - The text used for the title is obtained from the Plot's Title -* attribute. -* - The vertical placement of the title can be controlled using -* the TitleGap attribute. -*att-- -*/ -/* If non-zero add a title to the grid. Has a value of -1 when not -set yielding a default value of 1. */ -astMAKE_CLEAR(Plot,DrawTitle,drawtitle,-1) -astMAKE_GET(Plot,DrawTitle,int,1,(this->drawtitle == -1 ? 1 : this->drawtitle)) -astMAKE_SET(Plot,DrawTitle,int,drawtitle,( value ? 1 : 0 )) -astMAKE_TEST(Plot,DrawTitle,( this->drawtitle != -1 )) - -/* LabelUp. */ -/* ------- */ -/* -*att++ -* Name: -* LabelUp(axis) - -* Purpose: -* Draw numerical Plot labels upright? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the numerical labels for each axis of a Plot should be -* drawn upright or not. It takes a separate value for each -* physical axis of a Plot so that, for instance, the setting -* "LabelUp(2)=1" specifies that numerical labels for the second -* axis should be drawn upright. -* -* If the LabelUp value of a Plot axis is non-zero, it causes -* numerical labels for that axis to be plotted upright (i.e. as -* normal, horizontal text), otherwise labels are drawn parallel to -* the axis to which they apply. -* -* The default is to produce upright labels if the labels are placed -* around the edge of the plot, and to produce labels that follow the -* axes if the labels are placed within the interior of the plot (see -* attribute Labelling). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - In some circumstances, numerical labels and tick marks are -* drawn around the edges of the plotting area (see the Labelling -* attribute). In this case, the value of the LabelUp attribute is -* ignored. -* - If no axis is specified, (e.g. "LabelUp" instead of -* "LabelUp(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LabelUp(1) value. -*att-- -*/ -/* Are numerical labels to be displayed on each axis? Has a value of -1 when -not set yielding a value of 0 (no) for both axes. */ -MAKE_CLEAR(LabelUp,labelup,-1,0) -MAKE_GET(LabelUp,int,0,( this->labelup[axis] == -1 ? 0 : this->labelup[axis] ),0) -MAKE_TEST(LabelUp,( this->labelup[axis] != -1 ),0) -MAKE_SET(LabelUp,int,labelup,( value ? 1 : 0 ),0) - -/* DrawAxes */ -/* -------- */ -/* -*att++ -* Name: -* DrawAxes(axis) - -* Purpose: -* Draw axes for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether curves representing coordinate axes should be drawn. -* It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "DrawAxes(2)=0" -* specifies that no axis should be drawn for the second axis. -* -* If drawn, these axis lines will pass through any tick marks -* associated with numerical labels drawn to mark values on the -* axes. The location of these tick marks and labels (and hence the -* axis lines) is determined by the Plot's LabelAt(axis) attribute. -* -* If the DrawAxes value of a Plot is non-zero (the default), then -* axis lines will be drawn, otherwise they will be omitted. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - Axis lines are drawn independently of any coordinate grid -* lines (see the Grid attribute) so grid lines may be used to -* substitute for axis lines if required. -* - In some circumstances, numerical labels and tick marks are -* drawn around the edges of the plotting area (see the Labelling -* attribute). In this case, the value of the DrawAxes attribute -* is ignored. -* - If no axis is specified, (e.g. "DrawAxes" instead of -* "DrawAxes(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the DrawAxes(1) value. -*att-- -*/ -/* If non-zero draw a curve through the tick marks. Has a value of -1 - when not set yielding a default value of 1. */ -MAKE_CLEAR(DrawAxes,drawaxes,-1,0) -MAKE_GET(DrawAxes,int,1,( this->drawaxes[axis] == -1 ? 1 : this->drawaxes[axis] ),0) -MAKE_TEST(DrawAxes,( this->drawaxes[axis] != -1 ),0) -MAKE_SET(DrawAxes,int,drawaxes,( value ? 1 : 0 ),0) - -/* Abbrev */ -/* -------- */ -/* -*att++ -* Name: -* Abbrev(axis) - -* Purpose: -* Abbreviate leading fields within numerical axis labels? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether matching leading fields should be removed from adjacent -* numerical axis labels. It takes a separate value for each physical -* axis of a Plot so that, for instance, the setting "Abbrev(2)=0" -* specifies that matching leading fields should not be removed on -* the second axis. -* -* If the Abbrev value of a Plot is non-zero (the default), then -* leading fields will be removed from adjacent axis labels if they -* are equal. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "Abbrev" instead of -* "Abbrev(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the Abbrev(1) value. -*att-- -*/ -MAKE_CLEAR(Abbrev,abbrev,-1,0) -MAKE_GET(Abbrev,int,1,( this->abbrev[axis] == -1 ? 1 : this->abbrev[axis] ),0) -MAKE_TEST(Abbrev,( this->abbrev[axis] != -1 ),0) -MAKE_SET(Abbrev,int,abbrev,( value ? 1 : 0 ),0) - -/* Escape. */ -/* ------- */ -/* -*att++ -* Name: -* Escape - -* Purpose: -* Allow changes of character attributes within strings? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of text strings and numerical -c labels drawn by the astGrid and (for the Plot class) astText functions, -f labels drawn by the AST_GRID and (for the Plot class) AST_TEXT routines, -* by determining if any escape sequences contained within the strings -* should be used to control the appearance of the text, or should -* be printed literally. Note, the Plot3D class only interprets escape -* sequences within the -c astGrid function. -f AST_GRID routine. -* -* If the Escape value of a Plot is one (the default), then any -* escape sequences in text strings produce the effects described -* below when printed. Otherwise, they are printed literally. -* -c See also the astEscapes function. -f See also the AST_ESCAPES function. - -* Escape Sequences: -* Escape sequences are introduced into the text string by a percent -* "%" character. Any unrecognised, illegal or incomplete escape sequences -* are printed literally. The following escape sequences are -* currently recognised ("..." represents a string of one or more -* decimal digits): -* -* %% - Print a literal "%" character. -* -* %^...+ - Draw subsequent characters as super-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the super-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* %^+ - Draw subsequent characters with the normal base-line. -* -* %v...+ - Draw subsequent characters as sub-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the sub-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %v+ - Draw subsequent characters with the normal base-line -* (equivalent to %^+). -* -* %>...+ - Leave a gap before drawing subsequent characters. -* The digits "..." give the size of the gap, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %<...+ - Move backwards before drawing subsequent characters. -* The digits "..." give the size of the movement, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %s...+ - Change the Size attribute for subsequent characters. The -* digits "..." give the new Size as a fraction of the -* "normal" Size, scaled so that a value of "100" corresponds -* to 1.0; -* -* %s+ - Reset the Size attribute to its "normal" value. -* -* %w...+ - Change the Width attribute for subsequent characters. The -* digits "..." give the new width as a fraction of the -* "normal" Width, scaled so that a value of "100" corresponds -* to 1.0; -* -* %w+ - Reset the Size attribute to its "normal" value. -* -* %f...+ - Change the Font attribute for subsequent characters. The -* digits "..." give the new Font value. -* -* %f+ - Reset the Font attribute to its "normal" value. -* -* %c...+ - Change the Colour attribute for subsequent characters. The -* digits "..." give the new Colour value. -* -* %c+ - Reset the Colour attribute to its "normal" value. -* -* %t...+ - Change the Style attribute for subsequent characters. The -* digits "..." give the new Style value. -* -* %t+ - Reset the Style attribute to its "normal" value. -* -* %h+ - Remember the current horizontal position (see "%g+") -* -* %g+ - Go to the horizontal position of the previous "%h+" (if any). -* -* %- - Push the current graphics attribute values onto the top of -* the stack (see "%+"). -* -* %+ - Pop attributes values of the top the stack (see "%-"). If -* the stack is empty, "normal" attribute values are restored. - -* Applicability: -* Plot -* All Plots have this attribute. -*att-- -*/ - -/* Has a value of -1 when not set yeilding a default of 1. */ -astMAKE_GET(Plot,Escape,int,1,(this->escape == -1 ? 1 : this->escape)) -astMAKE_CLEAR(Plot,Escape,escape,-1) -astMAKE_SET(Plot,Escape,int,escape,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Escape,( this->escape != -1 )) - -/* LabelAt(axis). */ -/* -------------- */ -/* -*att++ -* Name: -* LabelAt(axis) - -* Purpose: -* Where to place numerical labels for a Plot - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where numerical axis labels and associated tick marks are -* placed. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "LabelAt(2)=10.0" -* specifies where the numerical labels and tick marks for the -* second axis should be drawn. -* -* For each axis, the LabelAt value gives the value on the other -* axis at which numerical labels and tick marks should be placed -c (remember that Plots suitable for use with astGrid may only -f (remember that Plots suitable for use with AST_GRID may only -* have two axes). For example, in a celestial (RA,Dec) coordinate -* system, LabelAt(1) gives a Dec value which defines a line (of -* constant Dec) along which the numerical RA labels and their -* associated tick marks will be drawn. Similarly, LabelAt(2) gives -* the RA value at which the Dec labels and ticks will be drawn. -* -* The default bahaviour is for the Plot to generate its own -* position for numerical labels and tick marks. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The LabelAt value should use the same units as are used -* internally for storing coordinate values on the appropriate -* axis. For example, with a celestial coordinate system, the -* LabelAt value should be in radians, not hours or degrees. -* - Normally, the LabelAt value also determines where the lines -* representing coordinate axes will be drawn, so that the tick -* marks will lie on these lines (but also see the DrawAxes -* attribute). -* - In some circumstances, numerical labels and tick marks are -* drawn around the edges of the plotting area (see the Labelling -* attribute). In this case, the value of the LabelAt attribute is -* ignored. -*att-- -*/ -/* The constant value on the other axis at which to place labels for - each axis. */ -MAKE_CLEAR(LabelAt,labelat,AST__BAD,0) -MAKE_GET(LabelAt,double,AST__BAD,this->labelat[axis],0) -MAKE_SET(LabelAt,double,labelat,value,0) -MAKE_TEST(LabelAt,( this->labelat[axis] != AST__BAD ),0) - -MAKE_GET3(LabelAt,double,AST__BAD,this->ulblat[axis],0) -MAKE_SET3(LabelAt,double,ulblat,value,0) - -/* Centre(axis). */ -/* ------------ */ -/* A value at which to place a tick mark. Other ticks marks are spaced at -regular distances from this one. AST__BAD is stored if no value is supplied, -resulting in Plot choosing its own value. */ -MAKE_CLEAR(Centre,centre,AST__BAD,0) -MAKE_GET(Centre,double,AST__BAD,this->centre[axis],0) -MAKE_SET(Centre,double,centre,value,0) -MAKE_TEST(Centre,( this->centre[axis] != AST__BAD ),0) - -MAKE_GET3(Centre,double,AST__BAD,this->ucentre[axis],0) -MAKE_SET3(Centre,double,ucentre,value,0) - -/* Ink */ -/* --- */ -/* A protected attribute indicating if astGrid should draw using visible -ink. The unset value is -1, yeilding a default value of 1. */ -astMAKE_CLEAR(Plot,Ink,ink,-1) -astMAKE_GET(Plot,Ink,int,1,(this->ink == -1 ? 1 : this->ink)) -astMAKE_SET(Plot,Ink,int,ink,( value ? 1 : 0 )) -astMAKE_TEST(Plot,Ink,( this->ink != -1 )) - -/* Gap(axis). */ -/* ---------- */ -/* -*att++ -* Name: -* Gap(axis) - -* Purpose: -* Interval between linearly spaced major axis values of a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the linear interval between the "major" axis values of a Plot, at -* which (for example) major tick marks are drawn. It takes a separate -* value for each physical axis of the Plot so that, for instance, -* the setting "Gap(2)=3.0" specifies the difference between adjacent major -* values along the second axis. The Gap attribute is only used when -* the LogTicks attribute indicates that the spacing between major axis -* values is to be linear. If major axis values are logarithmically spaced -* then the gap is specified using attribute LogGap. -* -* The Gap value supplied will usually be rounded to the nearest -* "nice" value, suitable (e.g.) for generating axis labels, before -* use. To avoid this "nicing" you should set an explicit format -* for the axis using the Format(axis) or Digits/Digits(axis) -* attribute. The default behaviour is for the Plot to generate its -* own Gap value when required, based on the range of axis values -* to be represented. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The Gap value should use the same units as are used internally -* for storing coordinate values on the corresponding axis. For -* example, with a celestial coordinate system, the Gap value -* should be in radians, not hours or degrees. -* - If no axis is specified, (e.g. "Gap" instead of "Gap(2)"), -* then a "set" or "clear" operation will affect the attribute -* value of all the Plot axes, while a "get" or "test" operation -* will use just the Gap(1) value. -*att-- -*/ -/* The gap between tick marks on each axis. AST__BAD is stored if no -value has been supplied, resulting in default values being found. */ -MAKE_CLEAR(Gap,gap,AST__BAD,0) -MAKE_SET(Gap,double,gap,value,0) -MAKE_TEST(Gap,( this->gap[axis] != AST__BAD ),0) -MAKE_GET(Gap,double,AST__BAD,this->gap[axis],0) - -MAKE_SET3(Gap,double,ugap,value,0) -MAKE_GET3(Gap,double,AST__BAD,this->ugap[axis],0) - -/* LogGap(axis). */ -/* ---------- */ -/* -*att++ -* Name: -* LogGap(axis) - -* Purpose: -* Interval between major axis values of a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the logarithmic interval between the "major" axis values of a Plot, at -* which (for example) major tick marks are drawn. It takes a separate -* value for each physical axis of the Plot so that, for instance, -* the setting "LogGap(2)=100.0" specifies the ratio between adjacent major -* values along the second axis. The LogGap attribute is only used when -* the LogTicks attribute indicates that the spacing between major axis -* values is to be logarithmic. If major axis values are linearly spaced -* then the gap is specified using attribute Gap. -* -* The LogGap value supplied will be rounded to the nearest power of 10. -* The reciprocal of the supplied value may be used if this is necessary -* to produce usable major axis values. If a zero or negative value is -* supplied, an error will be reported when the grid is drawn. The default -* behaviour is for the Plot to generate its own LogGap value when -* required, based on the range of axis values to be represented. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The LogGap value is a ratio between axis values and is therefore -* dimensionless. -* - If no axis is specified, (e.g. "LogGap" instead of "LogGap(2)"), -* then a "set" or "clear" operation will affect the attribute -* value of all the Plot axes, while a "get" or "test" operation -* will use just the LogGap(1) value. -*att-- -*/ -/* The logarithmic gap between tick marks on each axis. AST__BAD is stored if - no value has been supplied, resulting in default values being found. */ -MAKE_CLEAR(LogGap,loggap,AST__BAD,0) -MAKE_SET(LogGap,double,loggap,value,0) -MAKE_TEST(LogGap,( this->loggap[axis] != AST__BAD ),0) -MAKE_GET(LogGap,double,AST__BAD,this->loggap[axis],0) - -MAKE_SET3(LogGap,double,uloggap,value,0) -MAKE_GET3(LogGap,double,AST__BAD,this->uloggap[axis],0) - -/* LogPlot. */ -/* ------- */ -/* -*att++ -* Name: -* LogPlot(axis) - -* Purpose: -* Map the plot logarithmically onto the screen? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of all graphics produced by -* the Plot, by determining whether the axes of the plotting surface -* are mapped logarithmically or linearly onto the base Frame of the -* FrameSet supplied when the Plot was constructed. It takes a separate -* value for each axis of the graphics coordinate system (i.e. the -* base Frame in the Plot) so that, for instance, the setting -* "LogPlot(2)=1" specifies that the second axis of the graphics -* coordinate system (usually the vertical axis) should be mapped -* logarithmically onto the second axis of the base Frame of the -* FrameSet supplied when the Plot was constructed. -* -* If the LogPlot value of a Plot axis is non-zero, it causes that -* axis to be mapped logarithmically, otherwise (the default) the axis -* is mapped linearly. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The setting of the LogPlot attribute provides the default value -* for the related LogTicks attribute. By selecting suitable values for -* LogPlot and LogTicks, it is possible to have tick marks which are evenly -* spaced in value but which are mapped logarithmically onto the screen -* (and vice-versa). -* - An axis may only be mapped logarithmically if the visible part of -* the axis does not include the value zero. The visible part of the -* axis is that part which is mapped onto the plotting area, and is -* measured within the base Frame of the FrameSet which was supplied when -* the Plot was constructed. Any attempt to set LogPlot to a non-zero value -* will be ignored (without error) if the visible part of the axis -* includes the value zero -* - If no axis is specified, (e.g. "LogPlot" instead of -* "LogPlot(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LogPlot(1) value. -*att-- -*/ -/* Are plot axes to be mapped logarithmically? Has a value of -1 when -not set yielding a value of 0 (no) for both axes. */ -MAKE_GET(LogPlot,int,0,( this->logplot[axis] == -1 ? 0 : this->logplot[axis] ),0) -MAKE_TEST(LogPlot,( this->logplot[axis] != -1 ),0) - -/* LogTicks. */ -/* ------- */ -/* -*att++ -* Name: -* LogTicks(axis) - -* Purpose: -* Space the major tick marks logarithmically? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the major tick marks should be spaced logarithmically or -* linearly in axis value. It takes a separate value for each physical -* axis of the Plot so that, for instance, the setting "LogTicks(2)=1" -* specifies that the major tick marks on the second axis should be -* spaced logarithmically. -* -* If the LogTicks value for a physical axis is non-zero, the major -* tick marks on that axis will be spaced logarithmically (that is, -* there will be a constant ratio between the axis values at adjacent -* major tick marks). An error will be reported if the dynamic range of -* the axis (the ratio of the largest to smallest displayed axis value) -* is less than 10.0. If the LogTicks value is zero, the major tick marks -* will be evenly spaced (that is, there will be a constant difference -* between the axis values at adjacent major tick marks). The default is -* to produce logarithmically spaced tick marks if the corresponding -* LogPlot attribute is non-zero and the ratio of maximum axis value -* to minimum axis value is 100 or more. If either of these conditions -* is not met, the default is to produce linearly spaced tick marks. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The setting of the LogTicks attribute does not affect the mapping -* of the plot onto the screen, which is controlled by attribute LogPlot. -* By selecting suitable values for LogPlot and LogTicks, it is possible to -* have tick marks which are evenly spaced in value but which are mapped -* logarithmically onto the screen (and vica-versa). -* - An error will be reported when drawing an annotated axis grid if -* the visible part of the physical axis includes the value zero. -* - If no axis is specified, (e.g. "LogTicks" instead of -* "LogTicks(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LogTicks(1) value. -*att-- -*/ -/* Are ticksto be spaced logarithmically? Has a value of -1 when - not set, yeielding a default value equal to the corresponding - LogPlot value. */ -MAKE_CLEAR(LogTicks,logticks,-1,0) -MAKE_GET(LogTicks,int,0,( this->logticks[axis] == -1 ? astGetLogPlot(this,axis) : this->logticks[axis] ),0) -MAKE_TEST(LogTicks,( this->logticks[axis] != -1 ),0) -MAKE_SET(LogTicks,int,logticks,( value ? 1 : 0 ),0) - -MAKE_SET3(LogTicks,int,ulgtk,value,0) -MAKE_GET3(LogTicks,int,0,this->ulgtk[axis],0) - -/* LogLabel. */ -/* -------- */ -/* -*att++ -* Name: -* LogLabel(axis) - -* Purpose: -* Use exponential format for numerical axis labels? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the numerical axis labels should be in normal decimal form -* or should be represented as 10 raised to the appropriate power. -* That is, an axis value of 1000.0 will be drawn as "1000.0" if -* LogLabel is zero, but as "10^3" if LogLabel is non-zero. If -* graphical escape sequences are supported (see attribute Escape), -* the power in such exponential labels will be drawn as a small -* superscript instead of using a "^" character to represent -* exponentiation. -* -* The default is to produce exponential labels if the major tick -* marks are logarithmically spaced (see the LogTicks attribute). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "LogLabel" instead of -* "LogLabel(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the LogLabel(1) value. -*att-- -*/ -/* Are labels to be drawn as 10**x? Has a value of -1 when not set, yeielding - a default value equal to the corresponding LogTicks value. */ -MAKE_CLEAR(LogLabel,loglabel,-1,0) -MAKE_GET(LogLabel,int,0,( this->loglabel[axis] == -1 ? astGetLogTicks(this,axis) : this->loglabel[axis] ),0) -MAKE_TEST(LogLabel,( this->loglabel[axis] != -1 ),0) -MAKE_SET(LogLabel,int,loglabel,( value ? 1 : 0 ),0) - -MAKE_SET3(LogLabel,int,ulglb,value,0) -MAKE_GET3(LogLabel,int,0,this->ulglb[axis],0) - -/* MajTickLen. */ -/* ----------- */ -/* -*att++ -* Name: -* MajTickLen(axis) - -* Purpose: -* Length of major tick marks for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the length of the major tick marks drawn on the axes of a Plot. -* It takes a separate value for each physical axis of the Plot so -* that, for instance, the setting "MajTickLen(2)=0" specifies the -* length of the major tick marks drawn on the second axis. -* -* The MajTickLen value should be given as a fraction of the -* minimum dimension of the plotting area. Negative values cause -* major tick marks to be placed on the outside of the -* corresponding grid line or axis (but subject to any clipping -* imposed by the underlying graphics system), while positive -* values cause them to be placed on the inside. -* -* The default behaviour depends on whether a coordinate grid is -* drawn inside the plotting area (see the Grid attribute). If so, -* the default MajTickLen value is zero (so that major ticks are -* not drawn), otherwise the default is +0.015. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "MajTickLen" instead of -* "MajTickLen(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the MajTickLen(1) value. - -*att-- -*/ -/* Fractional length of major tick marks. Has a value of AST__BAD when not -set yielding a default value of 0.015. */ -MAKE_CLEAR(MajTickLen,majticklen,AST__BAD,0) -MAKE_SET(MajTickLen,double,majticklen,value,0) -MAKE_TEST(MajTickLen,( this->majticklen[axis] != AST__BAD ),0) -MAKE_GET(MajTickLen,double,0.0,( this->majticklen[axis] == AST__BAD ? 0.015 : this->majticklen[axis]),0) - -MAKE_SET3(MajTickLen,double,umjtkln,value,0) -MAKE_GET3(MajTickLen,double,0.0,this->umjtkln[axis],0) - -/* TitleGap. */ -/* --------- */ -/* -*att++ -* Name: -* TitleGap - -* Purpose: -* Vertical spacing for a Plot title. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where the title of a Plot is drawn. -* -* Its value gives the spacing between the bottom edge of the title -* and the top edge of a bounding box containing all the other parts -* of the annotated grid. Positive values cause the title to be -* drawn outside the box, while negative values cause it to be drawn -* inside. -* -* The TitleGap value should be given as a fraction of the minimum -* dimension of the plotting area, the default value being +0.05. - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes since it does not draw -* a Title. - -* Notes: -* - The text used for the title is obtained from the Plot's Title -* attribute. -*att-- -*/ -/* Fractional gap between titile and top edge. Has a value of AST__BAD when -not set yielding a default value of 0.05. */ -astMAKE_CLEAR(Plot,TitleGap,titlegap,AST__BAD) -astMAKE_GET(Plot,TitleGap,double,0.0,( this->titlegap == AST__BAD ? 0.05 : this->titlegap)) -astMAKE_SET(Plot,TitleGap,double,titlegap,value) -astMAKE_TEST(Plot,TitleGap,( this->titlegap != AST__BAD )) - -/* MinTickLen. */ -/* ----------- */ -/* -*att++ -* Name: -* MinTickLen(axis) - -* Purpose: -* Length of minor tick marks for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the length of the minor tick marks drawn on the axes of a Plot. -* It takes a separate value for each physical axis of the Plot so -* that, for instance, the setting "MinTickLen(2)=0" specifies the -* length of the minor tick marks drawn on the second axis. -* -* The MinTickLen value should be given as a fraction of the -* minimum dimension of the plotting area. Negative values cause -* minor tick marks to be placed on the outside of the -* corresponding grid line or axis (but subject to any clipping -* imposed by the underlying graphics system), while positive -* values cause them to be placed on the inside. -* -* The default value is +0.007. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The number of minor tick marks drawn is determined by the -* Plot's MinTick(axis) attribute. -* - If no axis is specified, (e.g. "MinTickLen" instead of -* "MinTickLen(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the MinTickLen(1) value. - -*att-- -*/ -/* Fractional length of minor tick marks. Has a value of AST__BAD when not -set yielding a default value of 0.007. */ -MAKE_CLEAR(MinTickLen,minticklen,AST__BAD,0) -MAKE_SET(MinTickLen,double,minticklen,value,0) -MAKE_TEST(MinTickLen,( this->minticklen[axis] != AST__BAD ),0) -MAKE_GET(MinTickLen,double,0.0,( this->minticklen[axis] == AST__BAD ? 0.007 : this->minticklen[axis]),0) - -/* Labelling. */ -/* ---------- */ -/* -*att++ -* Name: -* Labelling - -* Purpose: -* Label and tick placement option for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the strategy for placing numerical labels and tick marks for a Plot. -* -* If the Labelling value of a Plot is "exterior" (the default), then -* numerical labels and their associated tick marks are placed -* around the edges of the plotting area, if possible. If this is -* not possible, or if the Labelling value is "interior", then they -* are placed along grid lines inside the plotting area. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The LabelAt(axis) attribute may be used to determine the exact -* placement of labels and tick marks that are drawn inside the -* plotting area. -*att-- -*/ -astMAKE_CLEAR(Plot,Labelling,labelling,-9999) -astMAKE_SET(Plot,Labelling,int,labelling,(value?1:0)) -astMAKE_TEST(Plot,Labelling,( this->labelling != -9999 )) -astMAKE_GET(Plot,Labelling,int,0,(this->labelling == -9999 ? 0 : this->labelling)) - -MAKE_SET2(Plot,Labelling,int,ulbling,(value?1:0)) -MAKE_GET2(Plot,Labelling,int,0,this->ulbling) - -/* Edge. */ -/* ----- */ -/* -*att++ -* Name: -* Edge(axis) - -* Purpose: -* Which edges to label in a Plot - -* Type: -* Public attribute. - -* Synopsis: -* String. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* which edges of a Plot are used for displaying numerical and -* descriptive axis labels. It takes a separate value for each -* physical axis of the Plot so that, for instance, the setting -* "Edge(2)=left" specifies which edge to use to display labels for -* the second axis. -* -* The values "left", "top", "right" and "bottom" (or any -* abbreviation) can be supplied for this attribute. The default is -* usually "bottom" for the first axis and "left" for the second -* axis. However, if exterior labelling was requested (see the -* Labelling attribute) but cannot be produced using these default -* Edge values, then the default values will be swapped if this -* enables exterior labelling to be produced. - -* Applicability: -* Plot -* All Plots have this attribute. -* Plot3D -* The Plot3D class ignores this attributes. Instead it uses its -* own RootCorner attribute to determine which edges of the 3D plot -* to label. - -* Notes: -* - In some circumstances, numerical labels will be drawn along -* internal grid lines instead of at the edges of the plotting area -* (see the Labelling attribute). In this case, the Edge attribute -* only affects the placement of the descriptive labels (these are -* drawn at the edges of the plotting area, rather than along the -* axis lines). -*att-- -*/ -/* The edges of the plotting area on which to place numerical labels - for axes 0 and 1. Has a value of -1 when not set yielding a value - of 3 (the bottom edge) for axis 0 and 0 (the left-hand edge) for - axis 1. */ -MAKE_CLEAR(Edge,edge,-1,0) -MAKE_GET(Edge,int,0,( this->edge[axis] == -1 ? (axis?LEFT:BOTTOM) : this->edge[axis] ),0) -MAKE_SET(Edge,int,edge,(abs( value % 4 )),0) -MAKE_TEST(Edge,( this->edge[axis] != -1 ),0) - -MAKE_GET3(Edge,int,0,this->uedge[axis],0) -MAKE_SET3(Edge,int,uedge,(abs( value % 4 )),0) - -/* NumLab. */ -/* -------- */ -/* -*att++ -* Name: -* NumLab(axis) - -* Purpose: -* Draw numerical axis labels for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether labels should be drawn to represent the numerical values -* along each axis of a Plot. It takes a separate value for each -* physical axis of a Plot so that, for instance, the setting -* "NumLab(2)=1" specifies that numerical labels should be drawn -* for the second axis. -* -* If the NumLab value of a Plot axis is non-zero (the default), -* then numerical labels will be drawn for that axis, otherwise -* they will be omitted. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The drawing of associated descriptive axis labels for a Plot -* (describing the quantity being plotted along each axis) is -* controlled by the TextLab(axis) attribute. -* - If no axis is specified, (e.g. "NumLab" instead of -* "NumLab(2)"), then a "set" or "clear" operation will affect the -* attribute value of all the Plot axes, while a "get" or "test" -* operation will use just the NumLab(1) value. -*att-- -*/ -/* Are numerical labels to be displayed on each axis? Has a value of - -1 when not set yielding a value of 1 (yes) for both axes. */ -MAKE_CLEAR(NumLab,numlab,-1,0) -MAKE_GET(NumLab,int,1,( this->numlab[axis] == -1 ? 1 : this->numlab[axis] ),0) -MAKE_TEST(NumLab,( this->numlab[axis] != -1 ),0) -MAKE_SET(NumLab,int,numlab,( value ? 1 : 0 ),0) - -/* NumLabGap. */ -/* --------- */ -/* -*att++ -* Name: -* NumLabGap(axis) - -* Purpose: -* Spacing of numerical labels for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where numerical axis labels are placed relative to the axes they -* describe. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "NumLabGap(2)=-0.01" -* specifies where the numerical label for the second axis should -* be drawn. -* -* For each axis, the NumLabGap value gives the spacing between the -* axis line (or edge of the plotting area, if appropriate) and the -* nearest edge of the corresponding numerical axis -* labels. Positive values cause the descriptive label to be placed -* on the opposite side of the line to the default tick marks, -* while negative values cause it to be placed on the same side. -* -* The NumLabGap value should be given as a fraction of the minimum -* dimension of the plotting area, the default value being +0.01. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "NumLabGap" instead of -* "NumLabGap(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the NumLabGap(1) value. -*att-- -*/ -/* Fractional spacing between numeric labels and axes. Has a value of AST__BAD -when not set yielding a default value of 0.01. */ -MAKE_CLEAR(NumLabGap,numlabgap,AST__BAD,0) -MAKE_GET(NumLabGap,double,0.0,( this->numlabgap[ axis ] == AST__BAD ? 0.01 : this->numlabgap[axis]),0) -MAKE_SET(NumLabGap,double,numlabgap,value,0) -MAKE_TEST(NumLabGap,( this->numlabgap[axis] != AST__BAD ),0) - -/* MinTick. */ -/* -------- */ -/* -*att++ -* Name: -* MinTick(axis) - -* Purpose: -* Density of minor tick marks for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* the density of minor tick marks which appear between the major -* axis values of a Plot. It takes a separate value for each -* physical axis of a Plot so that, for instance, the setting -* "MinTick(2)=2" specifies the density of minor tick marks along -* the second axis. -* -* The value supplied should be the number of minor divisions -* required between each pair of major axis values, this being one -* more than the number of minor tick marks to be drawn. By -* default, a value is chosen that depends on the gap between major -* axis values and the nature of the axis. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If no axis is specified, (e.g. "MinTick" instead of -* "MinTick(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the MinTick(1) value. -*att-- -*/ -/* How many divisions are there between major tick marks? Has a value -of -1 when not set yielding a value of 1 for both axes. */ -MAKE_CLEAR(MinTick,mintick,-1,0) -MAKE_GET(MinTick,int,1,( this->mintick[axis] == -1 ? 1 : this->mintick[axis] ),0) -MAKE_TEST(MinTick,( this->mintick[axis] != -1 ),0) -MAKE_SET(MinTick,int,mintick,( (value < 1)? 1 : value ),0) - -MAKE_GET3(MinTick,int,1,this->umintk[axis],0) -MAKE_SET3(MinTick,int,umintk,( (value < 1)? 1 : value ),0) - -/* TextLab. */ -/* --------- */ -/* -*att++ -* Name: -* TextLab(axis) - -* Purpose: -* Draw descriptive axis labels for a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether textual labels should be drawn to describe the quantity -* being represented on each axis of a Plot. It takes a separate -* value for each physical axis of a Plot so that, for instance, -* the setting "TextLab(2)=1" specifies that descriptive labels -* should be drawn for the second axis. -* -* If the TextLab value of a Plot axis is non-zero, then -* descriptive labels will be drawn for that axis, otherwise they -* will be omitted. The default behaviour is to draw descriptive -* labels if tick marks and numerical labels are being drawn around -* the edges of the plotting area (see the Labelling attribute), -* but to omit them otherwise. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The text used for the descriptive labels is derived from the -* Plot's Label(axis) attribute, together with its Unit(axis) -* attribute if appropriate (see the LabelUnits(axis) attribute). -* - The drawing of numerical axis labels for a Plot (which -* indicate values on the axis) is controlled by the NumLab(axis) -* attribute. -* - If no axis is specified, (e.g. "TextLab" instead of -* "TextLab(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the TextLab(1) value. -*att-- -*/ -/* Are textual labels to be displayed on each axis? Has a value of -1 - when not set yielding a value of 1 (yes) for both axes. */ -MAKE_CLEAR(TextLab,textlab,-1,0) -MAKE_GET(TextLab,int,1,( this->textlab[axis] == -1 ? 1 : this->textlab[axis] ),0) -MAKE_TEST(TextLab,( this->textlab[axis] != -1 ),0) -MAKE_SET(TextLab,int,textlab,( value ? 1 : 0 ),0) - -MAKE_GET3(TextLab,int,1,this->utxtlb[axis],0) -MAKE_SET3(TextLab,int,utxtlb,( value ? 1 : 0 ),0) - -/* TextLabGap. */ -/* ----------- */ -/* -*att++ -* Name: -* TextLabGap(axis) - -* Purpose: -* Spacing of descriptive axis labels for a Plot. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* where descriptive axis labels are placed relative to the axes they -* describe. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "TextLabGap(2)=0.01" -* specifies where the descriptive label for the second axis should -* be drawn. -* -* For each axis, the TextLabGap value gives the spacing between the -* descriptive label and the edge of a box enclosing all other parts -* of the annotated grid (excluding other descriptive labels). The gap -* is measured to the nearest edge of the label (i.e. the top or the -* bottom). Positive values cause the descriptive label to be placed -* outside the bounding box, while negative values cause it to be placed -* inside. -* -* The TextLabGap value should be given as a fraction of the minimum -* dimension of the plotting area, the default value being +0.01. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - If drawn, descriptive labels are always placed at the edges of -* the plotting area, even although the corresponding numerical -* labels may be drawn along axis lines in the interior of the -* plotting area (see the Labelling attribute). -* - If no axis is specified, (e.g. "TextLabGap" instead of -* "TextLabGap(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the TextLabGap(1) value. -*att-- -*/ -/* Fractional spacing between numeric labels and axes. Has a value of AST__BAD -when not set yielding a default value of 0.01. */ -MAKE_CLEAR(TextLabGap,textlabgap,AST__BAD,0) -MAKE_GET(TextLabGap,double,0.0,( this->textlabgap[ axis ] == AST__BAD ? 0.01 : this->textlabgap[axis]),0) -MAKE_SET(TextLabGap,double,textlabgap,value,0) -MAKE_TEST(TextLabGap,( this->textlabgap[axis] != AST__BAD ),0) - -/* LabelUnits. */ -/* ----------- */ -/* -*att++ -* Name: -* LabelUnits(axis) - -* Purpose: -* Use axis unit descriptions in a Plot? - -* Type: -* Public attribute. - -* Synopsis: -* Integer (boolean). - -* Description: -* This attribute controls the appearance of an annotated -c coordinate grid (drawn with the astGrid function) by determining -f coordinate grid (drawn with the AST_GRID routine) by determining -* whether the descriptive labels drawn for each axis of a Plot -* should include a description of the units being used on the -* axis. It takes a separate value for each physical axis of a -* Plot so that, for instance, the setting "LabelUnits(2)=1" -* specifies that a unit description should be included in the -* label for the second axis. -* -* If the LabelUnits value of a Plot axis is non-zero, a unit -* description will be included in the descriptive label for that -* axis, otherwise it will be omitted. The default behaviour is to -* include a unit description unless the current Frame of the Plot -* is a SkyFrame representing equatorial, ecliptic, galactic or -* supergalactic coordinates, in which case it is omitted. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - The text used for the unit description is obtained from the -* Plot's Unit(axis) attribute. -* - If no axis is specified, (e.g. "LabelUnits" instead of -* "LabelUnits(2)"), then a "set" or "clear" operation will affect -* the attribute value of all the Plot axes, while a "get" or -* "test" operation will use just the LabelUnits(1) value. -* - If the current Frame of the Plot is not a SkyFrame, but includes -* axes which were extracted from a SkyFrame, then the default behaviour -* is to include a unit description only for those axes which were not -* extracted from a SkyFrame. -*att-- -*/ -/* Are textual labels to include a string describing the axis units? Has a -value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(LabelUnits,labelunits,-1,0) -MAKE_TEST(LabelUnits,( this->labelunits[axis] != -1 ),0) -MAKE_SET(LabelUnits,int,labelunits,( value ? 1 : 0 ),0) - -MAKE_GET3(LabelUnits,int,1,this->ulbunit[axis],0) -MAKE_SET3(LabelUnits,int,ulbunit,( value ? 1 : 0 ),0) - -/* Style. */ -/* ------ */ -/* -*att++ -* Name: -* Style(element) - -* Purpose: -* Line style for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute determines the line style used when drawing each -* element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Style(border)=2" causes the Plot border to be drawn -* using line style 2 (which might result in, say, a dashed line). -* -* The range of integer line styles available and their appearance -* is determined by the underlying graphics system. The default -* behaviour is for all graphical elements to be drawn using the -* default line style supplied by this graphics system (normally, -* this is likely to give a solid line). - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Style" instead of -* "Style(border)"), then a "set" or "clear" operation will affect -* the attribute value of all graphical elements, while a "get" or -* "test" operation will use just the Style(Border) value. -*att-- -*/ -/* Line styles. Has a value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(Style,style,-1,AST__NPID) -MAKE_GET(Style,int,1,( this->style[axis] == -1 ? 1 : this->style[axis] ),AST__NPID) -MAKE_TEST(Style,( this->style[axis] != -1 ),AST__NPID) -MAKE_SET(Style,int,style,value,AST__NPID) - -/* Font. */ -/* ----- */ -/* -*att++ -* Name: -* Font(element) - -* Purpose: -* Character font for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute determines the character font index used when -* drawing each element of graphical output produced by a Plot. It -* takes a separate value for each graphical element so that, for -* instance, the setting "Font(title)=2" causes the Plot title to -* be drawn using font number 2. -* -* The range of integer font indices available and the appearance -* of the resulting text is determined by the underlying graphics -* system. The default behaviour is for all graphical elements to -* be drawn using the default font supplied by this graphics -* system. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Font" instead -* of "Font(title)"), then a "set" or "clear" operation will -* affect the attribute value of all graphical elements, while a -* "get" or "test" operation will use just the Font(TextLab) -* value. -*att-- -*/ -/* Character fonts. Has a value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(Font,font,-1,AST__NPID) -MAKE_GET(Font,int,1,( this->font[axis] == -1 ? 1 : this->font[axis] ),AST__NPID) -MAKE_TEST(Font,( this->font[axis] != -1 ),AST__NPID) -MAKE_SET(Font,int,font,value,AST__NPID) - -/* Colour. */ -/* ------- */ -/* -*att++ -* Name: -* Colour(element) - -* Purpose: -* Colour index for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Integer. - -* Description: -* This attribute determines the colour index used when drawing -* each element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Colour(title)=2" causes the Plot title to be drawn -* using colour index 2. The synonym "Color" may also be used. -* -* The range of integer colour indices available and their -* appearance is determined by the underlying graphics system. The -* default behaviour is for all graphical elements to be drawn -* using the default colour index supplied by this graphics system -* (normally, this is likely to result in white plotting on a black -* background, or vice versa). -d -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Colour" instead -* of "Colour(title)"), then a "set" or "clear" operation will -* affect the attribute value of all graphical elements, while a -* "get" or "test" operation will use just the Colour(TextLab) -* value. -*att-- -*/ -/* Colours. Has a value of -1 when not set yielding a default of 1. */ -MAKE_CLEAR(Colour,colour,-1,AST__NPID) -MAKE_GET(Colour,int,1,( this->colour[axis] == -1 ? 1 : this->colour[axis] ),AST__NPID) -MAKE_TEST(Colour,( this->colour[axis] != -1 ),AST__NPID) -MAKE_SET(Colour,int,colour,value,AST__NPID) - -/* Width. */ -/* ------ */ -/* -*att++ -* Name: -* Width(element) - -* Purpose: -* Line width for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Floating point. - -* Description: -* This attribute determines the line width used when drawing each -* element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Width(border)=2.0" causes the Plot border to be -* drawn using a line width of 2.0. A value of 1.0 results in a -* line thickness which is approximately 0.0005 times the length of -* the diagonal of the entire display surface. -* -* The actual appearance of lines drawn with any particular width, -* and the range of available widths, is determined by the -* underlying graphics system. The default behaviour is for all -* graphical elements to be drawn using the default line width -* supplied by this graphics system. This will not necessarily -* correspond to a Width value of 1.0. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Width" instead of -* "Width(border)"), then a "set" or "clear" operation will affect -* the attribute value of all graphical elements, while a "get" or -* "test" operation will use just the Width(Border) value. -*att-- -*/ -/* Line widths. Has a value of AST__BAD when not set yielding a - default of 1.0. */ -MAKE_CLEAR(Width,width,AST__BAD,AST__NPID) -MAKE_GET(Width,double,1.0,( this->width[axis] == AST__BAD ? 1.0 : this->width[axis] ),AST__NPID) -MAKE_TEST(Width,( this->width[axis] != AST__BAD ),AST__NPID) -MAKE_SET(Width,double,width,(value!=0.00)?value:(astError(AST__ATTIN,"astSetWidth(Plot):Invalid zero value supplied for Width(%s) attribute", status,GrfItem(axis,NULL,NULL, status )),this->width[axis]),AST__NPID) - -/* Size. */ -/* ----- */ -/* -*att++ -* Name: -* Size(element) - -* Purpose: -* Character size for a Plot element. - -* Type: -* Public attribute. - -* Synopsis: -* Floating Point. - -* Description: -* This attribute determines the character size used when drawing -* each element of graphical output produced by a Plot. It takes a -* separate value for each graphical element so that, for instance, -* the setting "Size(title)=2.0" causes the Plot title to be drawn -* using twice the default character size. -* -* The range of character sizes available and the appearance of the -* resulting text is determined by the underlying graphics system. -* The default behaviour is for all graphical elements to be drawn -* using the default character size supplied by this graphics -* system. - -* Applicability: -* Plot -* All Plots have this attribute. - -* Notes: -* - For a list of the graphical elements available, see the -* description of the Plot class. -* - If no graphical element is specified, (e.g. "Size" instead -* of "Size(title)"), then a "set" or "clear" operation will -* affect the attribute value of all graphical elements, while a -* "get" or "test" operation will use just the Size(TextLab) -* value. -*att-- -*/ -/* Character sizes. Has a value of AST__BAD when not set yielding a default - of 1.0. */ -MAKE_CLEAR(Size,size,AST__BAD,AST__NPID) -MAKE_GET(Size,double,1.0,( this->size[axis] == AST__BAD ? 1.0 : this->size[axis] ),AST__NPID) -MAKE_TEST(Size,( this->size[axis] != AST__BAD ),AST__NPID) -MAKE_SET(Size,double,size,(value!=0.00)?value:(astError(AST__ATTIN,"astSetSize(Plot): Invalid zero value supplied for Size(%s) attribute", status,GrfItem(axis,NULL,NULL, status )),this->size[axis]),AST__NPID) - -/* Member functions. */ -/* ================= */ -static void AddCdt( AstPlotCurveData *cdt1, AstPlotCurveData *cdt2, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* AddCdt - -* Purpose: -* Append one AstPlotCurveData structure to another. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void AddCdt( AstPlotCurveData *cdt1, AstPlotCurveData *cdt2, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* The contents of the structure pointed to by "cdt2" is appended -* to the structure pointed to by "cdt1". - -* Parameters: -* cdt1 -* Pointer to the AstPlotCurveData structure to be modified. -* cdt2 -* Pointer to the AstPlotCurveData structure to be appended to cdt1. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - An error is reported if there is insufficient room in "cdt1" to -* store the information in "cdt2". - -*/ - -/* Local Variables: */ - int nbrk, i, j; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get the total number of breaks described by both structures. */ - nbrk = cdt1->nbrk + cdt2->nbrk; - -/* Report an error if this number of breaks cannot be stored in a AstPlotCurveData - structure. */ - if( nbrk > AST__MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__MXBRK ); - -/* Otherwise, append the information. */ - } else { - -/* Store the index within "cdt1" of the next break to be added. */ - j = cdt1->nbrk; - -/* Add each the position and direction information for each of the breaks - in "cdt2". */ - for( i = 0; i < cdt2->nbrk; i++ ){ - cdt1->xbrk[ j ] = cdt2->xbrk[ i ]; - cdt1->ybrk[ j ] = cdt2->ybrk[ i ]; - cdt1->vxbrk[ j ] = cdt2->vxbrk[ i ]; - cdt1->vybrk[ j ] = cdt2->vybrk[ i ]; - -/* Increment the index of the next break in "cdt1". */ - j++; - } - -/* Update the number of breaks in "cdt1". */ - cdt1->nbrk = nbrk; - -/* Update the length of the curve described by "cdt1". */ - cdt1->length += cdt2->length; - -/* Update the flag indicating if the entire curve is outside the plotting - zone. */ - if( !cdt2->out ) cdt1->out = 0; - - } - -/* Return. */ - return; - -} - -static void Apoly( AstPlot *this, float x, float y, int *status ){ -/* -* Name: -* Apoly - -* Purpose: -* Append a another point to a poly line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Apoly( AstPlot *this, float x, float y, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function appends the supplied point to the current poly line. - -* Parameters: -* x -* The graphics x coordinate. -* y -* The graphics y coordinate. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int ipoint; - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Extend the buffers, and add the supplied point to the end. */ - ipoint = Poly_n++; - Poly_x = astGrow( Poly_x, Poly_n, sizeof(*Poly_x) ); - Poly_y = astGrow( Poly_y, Poly_n, sizeof(*Poly_y) ); - if( astOK ) { - Poly_x[ ipoint ] = x; - Poly_y[ ipoint ] = y; - } - -/* Update the box containing all plotted lines. */ - Box_lbnd[ 0 ] = astMIN( x, Box_lbnd[ 0 ] ); - Box_ubnd[ 0 ] = astMAX( x, Box_ubnd[ 0 ] ); - Box_lbnd[ 1 ] = astMIN( y, Box_lbnd[ 1 ] ); - Box_ubnd[ 1 ] = astMAX( y, Box_ubnd[ 1 ] ); - -} - -static void AxPlot( AstPlot *this, int axis, const double *start, double length, - int ink, AstPlotCurveData *cdata, const char *method, const char *class, int *status ){ -/* -* -* Name: -* AxPlot - -* Purpose: -* Draw a curve with constant axis value. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void AxPlot( AstPlot *this, int axis, const double *start, double length, -* int ink, AstPlotCurveData *cdata, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a section of a curve of the specified length -* with constant value on a specified axis in the current Frame of the -* Plot, starting at the specified position. The algorithm used can handle -* discontinuities in the Mapping between the current Frame and graphics -* coordinates, and information describing any breaks in the curve -* (including the start and end of the curve) are returned in the supplied -* AstPlotCurveData structure. - -* Parameters: -* this -* Pointer to the Plot. -* axis -* The zero-based index of an axis within the current Frame of the Plot. -* The curve has a varying value on this axis. -* start -* A pointer to a an array holding the coordinates of the start of the -* curve within the current Frame of the Plot. -* length -* The length of the section of the curve to be drawn, given as an -* increment along the axis specified by parameter "axis". -* ink -* If zero, the curve is not actually drawn, but information about -* the breaks is still returned. If non-zero, the curve is also drawn. -* cdata -* A pointer to a structure in which to return information about the -* breaks in the curve. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - No curve is draw if the "start" array contains any bad values -* (i.e. values equal to AST__BAD), or if the "length" value is bad, -* or if a NULL pointer is supplied for "cdata". No errors are reported -* in these cases. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - int ok; /* Are all start coords good? */ - int gridid; /* Identifier value for element being drawn */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -#ifdef CRV_TRACE - printf("AXPLOT: axis %d, start (%.*g,%.*g), length %.*g\n", - axis, DBL_DIG, start[0], DBL_DIG, start[1], DBL_DIG, length ); - getchar(); -#endif - - -/* Initialise any supplied cdata structure to hold safe values. */ - if( cdata ){ - cdata->length = 0.0; - cdata->out = 1; - cdata->nbrk = 0; - } - -/* Get the number of axes in the current Frame. */ - naxes = astGetNout( this ); - -/* Check the "start" parameter for bad values. */ - ok = 1; - for( i = 0; i < naxes; i++ ) { - if( start[ i ] == AST__BAD ){ - ok = 0; - break; - } - } - -/* Check the "length" parameter for bad values. */ - if( length == AST__BAD ) ok = 0; - -/* Check that the "cdata" pointer can be used. */ - if( !cdata ) ok = 0; - -/* Only proceed if the parameters are OK, and there has been no error. */ - if( ok && astOK ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - if( axis == 0 ) { - gridid = AST__GRIDLINE2_ID; - } else { - gridid = AST__GRIDLINE1_ID; - } - astGrfAttrs( this, gridid, 1, GRF__LINE, method, class ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the externals used to communicate with the Map1 function... - The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map1_ncoord = naxes; - -/* See if tick marks are logarithmically or linearly spaced. */ - Map1_log = astGetLogTicks( this, axis ); - -/* A pointer to the Plot, the Current Frame and the Mapping. */ - Map1_plot = this; - Map1_frame = astGetFrame( this, AST__CURRENT ); - Map1_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Physical coords at the start of the curve (dist=0). */ - Map1_origin = start; - -/* Length of the curve. */ - Map1_length = length; - -/* The index of the axis which the curve follows. */ - Map1_axis = axis; - -/* Decide whether to omit points not in their normal ranges. */ - Map1_norm = !IsASkyAxis( Map1_frame, 0, status ) && - !IsASkyAxis( Map1_frame, 1, status ); - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map1; - Crv_ink = ink; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata->xbrk; - Crv_ybrk = cdata->ybrk; - Crv_vxbrk = cdata->vxbrk; - Crv_vybrk = cdata->vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map1( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map1 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map1. */ - Map1( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - if( cdata ){ - cdata->length = Crv_len; - cdata->out = Crv_out; - cdata->nbrk = Crv_nbrk; - PurgeCdata( cdata, status ); - } - -/* Annul the Frame and Mapping. */ - Map1_frame = astAnnul( Map1_frame ); - Map1_map = astAnnul( Map1_map ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gridid, 0, GRF__LINE, method, class ); - - } - -/* Return. */ - return; - -} - -static void BBuf( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astBBuf -f AST_BBUF - -* Purpose: -* Begin a new graphical buffering context. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astBBuf( AstPlot *this ) -f CALL AST_BBUF( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function -f This routine -* starts a new graphics buffering context. A matching call to the -c function astEBuf -f routine AST_EBUF -* should be used to end the context. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The nature of the buffering is determined by the underlying -* graphics system (as defined by the current grf module). Each call -c to this function -f to this routine -c to this function -f to this routine -* simply invokes the astGBBuf function in the grf module. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the active GRF BBuf function. */ - GBBuf( this, "astBBuf", astGetClass( this ), status ); - -} - -static int Boundary( AstPlot *this, const char *method, const char *class, int *status ){ -/* -* Name: -* Boundary - -* Purpose: -* Draw a boundary around regions containing valid physical positions. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Boundary( AstPlot *this, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws a boundary around the regions of the plotting -* area which contain valid, unclipped, physical coordinates, but does -* not include the intersections with the edges of the plotting area. -* -* Broadly, the algorithm is as follows: An initial coarse grid is -* created covering the entire plotting area. This grid consists of a -* regular square matrix of points in graphics coordinates, and the -* corresponding physical coordinates. An array of flags is created, -* one for each grid cell, indicating if the boundary passes through the -* cell. This is assumed to be the case if the cell has a mix of good and -* bad corners (i.e corners which have good or bad physical coordinates). -* This assumption does not locate all boundary cells though, since if -* the boundary passes into and out of a cell throught the same edge, -* the corners of the cell will be either all good or all bad. But for -* the moment, we just concentrate on the ones found using this simple -* assumption. For each such cell, a finer grid is then created covering -* the cell, and the boundary is drawn through this fine grid using -* TraceBorder. TraceBorder returns a set of four flags indicating which -* edges of the cell were intersected by the boundary. A check is then -* made on any of the four neighbouring cells into which the curve -* passes. If any of these cells were not flagged as boundary cells using -* the simple assumption described earlier, then they are flagged now -* (with a different flag value). Once all the cells located using the -* simple assumption have been processed, any further cells flagged -* with the new flag value are also processed using TraceBorder in the -* same way. This process is repeated until no extra boundary cells are -* found. - -* Parameters: -* this -* Pointer to a Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A flag indicating if any regions containing invalid physical -* coordinates were found within the plotting area. - -* Notes: -* - This function assumes the physical coordinate Frame is -* 2-dimensional, and it should not be used if this is not the case. -* - A value of zero is returned if an error has already occurred, or -* if this function should fail for any reason. - -*/ - -/* Local Variables: */ - AstFrame *bfrm; /* Pointer to base Plot Frame */ - AstFrame *cfrm; /* Pointer to current Plot Frame */ - AstMapping *map; /* Pointer to Plot mapping (graphics -> physical) */ - AstMapping *rmap; /* Pointer to Plot mapping (graphics -> physical) */ - AstRegion *breg; /* Region mapped into base Plot Frame */ - double blbnd[ 2 ]; /* Lower grid bounds in base frame */ - double bubnd[ 2 ]; /* Upper grid bounds in base frame */ - double dx; /* Plotting area width */ - double dy; /* Plotting area height */ - double power; /* Exponent in pow call */ - double rat; /* Ratio by which to reduce DIM */ - double tol; /* Fractional plotting tolerance */ - int dim; /* No. of points along each edge of coarse grid */ - int edges[ 4 ]; /* Flags indicating edges bisected by boundary */ - int rate_disabled; /* Was the astRate method initially disabled? */ - int ret; /* Any regions containing bad physical coords? */ - -/* Check global status. */ - if( !astOK ) return 0; - -/* Initialise the answer to indicate that no regions containing invalid - physical coordinates have been found. */ - ret = 0; - -/* Get the current Frame from the Plot. */ - cfrm = astGetFrame( this, AST__CURRENT ); - -/* If it is a region, we use a special method, if possible, to trace the - Region boundary. Otherwise, we use a grid tracing method that makes no - assumptions about the nature of the Mapping or Frame. */ - if( !DrawRegion( this, cfrm, method, class, status ) ) { - -/* Each basic element of the boundary drawn by the following algorithm - will be drawn at a multiple of 45 degrees to the horizontal. This can - cause noticable aliasing. For instance, if the border is a straight - line at 50 degrees to the horizontal, it will be drawn at 45 degrees - for long sections, followed by a vertical leap to catch up with where - it should be. Because of this we use a finer tolerance than for other - drawing. */ - tol = 0.25*astGetTol( this ); - -/* Set up the dimension of a coarse grid in graphics coordinates to cover the - whole plotting area. This is chosen to give a finer grid for smaller - plotting tolerances. Note, putting the power as a literal constant in - the call to pow seems to cause a segmentation violation on some systems. */ - power = -0.666666666; - dim = (int) 4*pow( tol, power ) + 10; - if( dim > 400 ) dim = 400; - if( dim < 3 ) dim = 3; - -/* Store the required plotting tolerance as a distance in graphics - coords. */ - dx = fabs( this->xhi - this->xlo ); - dy = fabs( this->xhi - this->xlo ); - tol *= ( ( dx > dy ) ? dx : dy ); - -/* Extract the Mapping from the Plot. */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Select the area covered by the coarse grid. If the current Frame is a - Region, we use the bounding box of Region after being mapped into - graphics coords. */ - if( astIsARegion( cfrm ) ) { - bfrm = astGetFrame( this, AST__BASE ); - -/* Get the Mapping from the current to the base Frame in the Plot, and - remove the effects of any Regions. */ - - astInvert( map ); - rmap = astRemoveRegions( map ); - astInvert( map ); - -/* Map the Region into the GRAPHICS frame. */ - breg = astMapRegion( cfrm, rmap, bfrm ); - astGetRegionBounds( breg, blbnd, bubnd ); - - rmap = astAnnul( rmap ); - bfrm = astAnnul( bfrm ); - breg = astAnnul( breg ); - - rat = ( ( bubnd[ 0 ] - blbnd[ 0 ] )*( bubnd[ 1 ] - blbnd[ 1 ] ) )/ - ( ( this->xhi - this->xlo )*( this->yhi - this->ylo ) ); - rat = sqrt( rat ); - dim = (int) ( rat*dim ); - if( dim < 3 ) dim = 3; - -/* If the current Frame is not a Region, use the whole plot. */ - } else { - blbnd[ 0 ] = this->xlo; - blbnd[ 1 ] = this->ylo; - bubnd[ 0 ] = this->xhi; - bubnd[ 1 ] = this->yhi; - } - -/* Disable the astRate method in order to improve the speed of - evaluating the Mapping in cases where the Mapping includes an - AstRateMap. Note the original value of the flag so that it can be - re-instated at the end. */ - rate_disabled = astRateState( 1 ); - -/* Draw the boundary. */ - ret = TraceBorder( this, map, blbnd[ 0 ], bubnd[ 0 ], blbnd[ 1 ], - bubnd[ 1 ], dim, tol, edges, method, class, status ); - -/* Re-instate the original setting of the "astRate disabled" flag. */ - astRateState( rate_disabled ); - -/* Release the remaining resources. */ - map = astAnnul( map ); - } - cfrm = astAnnul( cfrm ); - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; -} - -static int Border( AstPlot *this_nd, int *status ){ -/* -*++ -* Name: -c astBorder -f AST_BORDER - -* Purpose: -* Draw a border around valid regions of a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c int astBorder( AstPlot *this ) -f RESULT = AST_BORDER( THIS, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws a (line) border around regions of the -* plotting area of a Plot which correspond to valid, unclipped -* physical coordinates. For example, when plotting using an -* all-sky map projection, this function could be used to draw the -* boundary of the celestial sphere when it is projected on to the -* plotting surface. -* -* If the entire plotting area contains valid, unclipped physical -* coordinates, then the boundary will just be a rectangular box -* around the edges of the plotting area. -* -* If the Plot is a Plot3D, this method is applied individually to -* each of the three 2D Plots encapsulated within the Plot3D (each of -* these Plots corresponds to a single 2D plane in the 3D graphics -* system). In addition, if the entire plotting volume has valid -* coordinates in the 3D current Frame of the Plot3D, then additional -* lines are drawn along the edges of the 3D plotting volume so that -* the entire plotting volume is enclosed within a cuboid grid. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astBorder() -f AST_BORDER = LOGICAL -c Zero is returned if the plotting space is completely filled by -f .FALSE. is returned if the plotting space is completely filled by -* valid, unclipped physical coordinates (so that only a -c rectangular box was drawn around the edge). Otherwise, one is -f rectangular box was drawn around the edge). Otherwise, .TRUE. is -* returned. - -* Notes: -c - A value of zero will be returned if this function is invoked -f - A value of .FALSE. will be returned if this function is invoked -c with the AST error status set, or if it should fail for any -f with STATUS set to an error value, or if it should fail for any -* reason. -* - An error results if either the current Frame or the base Frame -* of the Plot is not 2-dimensional or (for a Plot3D) 3-dimensional. -* - An error also results if the transformation between the base -* and current Frames of the Plot is not defined (i.e. the Plot's -* TranForward attribute is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *this; /* Plot with no more than 2 current axes */ - AstPlotCurveData cdata; /* Structure to receive break information */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int inval; /* Were any bad regions found? */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_nd); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astBorder"; - class = astGetClass( this_nd ); - -/* Initialise the bounding box for primitives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this_nd ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Get a Plot with a 2D (or 1D) current Frame. */ - this = (AstPlot *) Fset2D( (AstFrameSet *) this_nd, AST__CURRENT, status ); - -/* Check the current Frame of the Plot is 2-D. */ - naxes = astGetNout( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the current " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__BORDER_ID, 1, GRF__LINE, method, class ); - -/* We first draw the intersections of the regions containing valid - physical coordinates with the edges of the plotting area. First do - the bottom edge. */ - LinePlot( this, this->xlo, this->ylo, this->xhi, this->ylo, - 1, &cdata, method, class, status ); - -/* Now do the right-hand edge. */ - LinePlot( this, this->xhi, this->ylo, this->xhi, this->yhi, - 1, &cdata, method, class, status ); - -/* Now do the top edge. */ - LinePlot( this, this->xhi, this->yhi, this->xlo, this->yhi, - 1, &cdata, method, class, status ); - -/* Now do the left-hand edge. */ - LinePlot( this, this->xlo, this->yhi, this->xlo, this->ylo, - 1, &cdata, method, class, status ); - -/* Now draw a curve following the boundary through the interior of the - plotting area. If the current Frame in the Plot is a Region, we use a - shorter method if possible. If this is not possible, we use a longer - method. */ - inval = Boundary( this, method, class, status ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__BORDER_ID, 0, GRF__LINE, method, class ); - -/* Annul the 2d plot. */ - this = astAnnul( this ); - -/* Return. */ - return inval; - -} - -static void BoundingBox( AstPlot *this, float lbnd[2], float ubnd[2], int *status ){ -/* -*++ -* Name: -c astBoundingBox -f AST_BOUNDINGBOX - -* Purpose: -* Return a bounding box for previously drawn graphics. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astBoundingBox( AstPlot *this, float lbnd[2], float ubnd[2] ) -f CALL AST_BOUNDINGBOX( THIS, LBND, UBND, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function returns the bounds of a box which just encompasess the -f This routine returns the bounds of a box which just encompasess the -* graphics produced by the previous call to any of the Plot methods -* which produce graphical output. If no such previous call has yet -* been made, or if the call failed for any reason, then the bounding box -c returned by this function is undefined. -f returned by this routine is undefined. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c lbnd -f LBND( 2 ) = REAL (Returned) -* A two element array in which is returned the lower limits of the -* bounding box on each of the two axes of the graphics coordinate -* system (the base Frame of the Plot). -c ubnd -f UBND( 2 ) = REAL (Returned) -* A two element array in which is returned the upper limits of the -* bounding box on each of the two axes of the graphics coordinate -* system (the base Frame of the Plot). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - An error results if the base Frame of the Plot is not -* 2-dimensional. -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameSet *fset; /* Pointer to the Plot's FrameSet */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Get a pointer to the FrameSet at the start of the Plot. */ - fset = (AstFrameSet *) this; - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( fset ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "astBoundingBox(%s): Number of axes (%d) in the " - "base Frame of the supplied %s is invalid - this number " - "should be 2.", status, astGetClass( this ), naxes, - astGetClass( this ) ); - } - -/* Return the bounding box. */ - lbnd[ 0 ] = Boxp_lbnd[ 0 ]; - lbnd[ 1 ] = Boxp_lbnd[ 1 ]; - ubnd[ 0 ] = Boxp_ubnd[ 0 ]; - ubnd[ 1 ] = Boxp_ubnd[ 1 ]; - -/* Return. */ - return; - -} - -static int BoxCheck( float *bx, float *by, float *cx, float *cy, int *status ) { -/* -* Name: -* BoxCheck - -* Purpose: -* See if two boxes overlap. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int BoxCheck( float *bx, float *by, float *cx, float *cy, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns a flag indicating if two trapezoidal boxes -* (box "b" and box "c") overlap or not. - -* Parameters: -* bx -* Pointer to an array holding the X coordinates at the 4 corners -* of box "b". -* by -* Pointer to an array holding the Y coordinates at the 4 corners -* of box "b". -* cx -* Pointer to an array holding the X coordinates at the 4 corners -* of box "c". -* cy -* Pointer to an array holding the Y coordinates at the 4 corners -* of box "c". -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the boxes do not overlap or an error has -* already occurred. Otherwise, 1 is returned. - -*/ - -/* Local Variables: */ - float x2; - float y2; - int i; - int ip; - int j; - int jp; - int ret; - -/* Assume the boxes do not overlap. */ - ret = 0; - -/* Check the inherited status. */ - if( !astOK ) return ret; - -/* Check each corner of box b to see if it is inside box c. */ - for( j = 0; j < 4 && ret == 0; j++ ){ - if( Inside( 4, cx, cy, bx[ j ], by[ j ], status ) ) ret = 1; - } - -/* Now check each corner of box c to see if it is inside box b. */ - for( j = 0; j < 4 && ret == 0; j++ ){ - if( Inside( 4, bx, by, cx[ j ], cy[ j ], status ) ) ret = 1; - } - -/* If no overlap has yet been found, we need to see if any of the edges - of the boxes intersect. For instance, in the case of a cross formed by - a vertical rectangle crossing a horizontal rectangle, the above checks - on the corners would not have revealed any overlap. */ - if( !ret ) { - -/* The following code assumes that the corners with indices 0, 1, 2, 3 - are adjacent round the edge of the box. This is the case if the line - joining corners 0 and 1 does not cross the line joining corners 2 and - 3 AND the line joining corners 1 and 2 does not cross the line joining - corners 3 and 0. If either of these conditions is not met swap the - corners around to correct it. First do box b. */ - if( Cross( bx[0], by[0], bx[1], by[1], - bx[2], by[2], bx[3], by[3], status ) ) { - x2 = bx[2]; - y2 = by[2]; - bx[2] = bx[1]; - by[2] = by[1]; - bx[1] = x2; - by[1] = y2; - - } else if( Cross( bx[1], by[1], bx[2], by[2], - bx[3], by[3], bx[0], by[0], status ) ) { - x2 = bx[2]; - y2 = by[2]; - bx[2] = bx[3]; - by[2] = by[3]; - bx[3] = x2; - by[3] = y2; - } - -/* Now do box c. */ - if( Cross( cx[0], cy[0], cx[1], cy[1], - cx[2], cy[2], cx[3], cy[3], status ) ) { - x2 = cx[2]; - y2 = cy[2]; - cx[2] = cx[1]; - cy[2] = cy[1]; - cx[1] = x2; - cy[1] = y2; - - } else if( Cross( cx[1], cy[1], cx[2], cy[2], - cx[3], cy[3], cx[0], cy[0], status ) ) { - x2 = cx[2]; - y2 = cy[2]; - cx[2] = cx[3]; - cy[2] = cy[3]; - cx[3] = x2; - cy[3] = y2; - } - -/* We now check each edge of box b to see if it overlaps any edge of box c. */ - for( j = 0; j < 4 && ret == 0; j++ ) { - -/* This edge of box b starts at the corner with index j. Get the index of the - corner at which the edge ends. */ - jp = j + 1; - if( jp == 4 ) jp = 0; - -/* Check to see if this edge of box b crosses each edge of box c in turn. */ - for( i = 0; i < 4 && ret == 0; i++ ) { - ip = i + 1; - if( ip == 4 ) ip = 0; - - ret = Cross( bx[j], by[j], bx[jp], by[jp], - cx[i], cy[i], cx[ip], cy[ip], status ); - - } - } - } - - return ret; -} - -static void Bpoly( AstPlot *this, float x, float y, int *status ){ -/* -* Name: -* Bpoly - -* Purpose: -* Begin a new poly line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Bpoly( AstPlot *this, float x, float y, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws any current poly line, and then starts a new one -* at the supplied position. - -* Parameters: -* x -* The graphics x coordinate. -* y -* The graphics y coordinate. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int ignore; /* Is the new point the end of the current polyline? */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* See if the new point is co-incident with the end of the current - polyline. If so we assume the current polyline is to be re-started, - rather than starting a new polyline. */ - if( Poly_n > 0 ) { - ignore = ( astEQUALS( Poly_x[ Poly_n - 1 ], x, 1.0E8 ) && - astEQUALS( Poly_y[ Poly_n - 1 ], y, 1.0E8 ) ); - } else { - ignore = 0; - } - -/* If the supplied point is not at the end of the current polyline, draw - any existing poly line. This will empty the buffer. Then add the - supplied point into the buffer. */ - if( !ignore ) { - Opoly( this, status ); - Apoly( this, x, y, status ); - } - -} - - -static int CGCapWrapper( AstPlot *this, int cap, int value, int *status ) { -/* -* -* Name: -* CGCapWrapper - -* Purpose: -* Call a C implementation of the GCap Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGCapWrapper( AstPlot *this, int cap, int value, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GCap -* grf function to enquire or set a graphics attribute value. - -* Parameters: -* this -* The Plot. -* cap -* The capability to be inquired aboue. -* value -* The value ot assign to the capability. -* status -* Pointer to the inherited status value. - -* Returned Value: -* Non-zero if the grf module is capabale of performing the action -* requested by "cap". - -*/ - if( !astOK ) return 0; - return ( (AstGCapFun) this->grffun[ AST__GCAP ] )( astGrfConID(this), cap, value ); -} - -static int CGAttrWrapper( AstPlot *this, int attr, double value, - double *old_value, int prim, int *status ) { -/* -* -* Name: -* CGAttrWrapper - -* Purpose: -* Call a C implementation of the GAttr Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGAttrWrapper( AstPlot *this, int attr, double value, -* double *old_value, int prim, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GAttr -* grf function to enquire or set a graphics attribute value. - -* Parameters: -* this -* The Plot. -* attr -* An integer value identifying the required attribute. The -* following symbolic values are defined in grf.h: -* -* GRF__STYLE - Line style. -* GRF__WIDTH - Line width. -* GRF__SIZE - Character and marker size scale factor. -* GRF__FONT - Character font. -* GRF__COLOUR - Colour index. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by the following values defined in grf.h: -* GRF__LINE -* GRF__MARK -* GRF__TEXT -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGAttrFun) this->grffun[ AST__GATTR ] )( astGrfConID(this), attr, value, old_value, prim ); -} - -static int CGBBufWrapper( AstPlot *this, int *status ) { -/* -* -* Name: -* CGBBufWrapper - -* Purpose: -* Call a C implementation of the GBBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGBBufWrapper( AstPlot *this ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GBBuf -* grf function to start a new graphics context. - -* Parameters: -* this -* The Plot. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGBBufFun) this->grffun[ AST__GBBUF ])( astGrfConID(this) ); -} - -static int CGEBufWrapper( AstPlot *this, int *status ) { -/* -* -* Name: -* CGEBufWrapper - -* Purpose: -* Call a C implementation of the GEBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGEBufWrapper( AstPlot *this ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GEBuf -* grf function to start a new graphics context. - -* Parameters: -* this -* The Plot. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGEBufFun) this->grffun[ AST__GEBUF ])( astGrfConID(this) ); -} - -static int CGFlushWrapper( AstPlot *this, int *status ) { -/* -* -* Name: -* CGFlushWrapper - -* Purpose: -* Call a C implementation of the GFlush Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGFlushWrapper( AstPlot *this ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GFlush -* grf function to flush graphics. - -* Parameters: -* this -* The Plot. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGFlushFun) this->grffun[ AST__GFLUSH ])( astGrfConID(this) ); -} - -static int CGLineWrapper( AstPlot *this, int n, const float *x, - const float *y, int *status ) { -/* -* -* Name: -* CGLineWrapper - -* Purpose: -* Call a C implementation of the GLine Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGLineWrapper( AstPlot *this, int n, const float *x, -* const float *y, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GLine -* grf function to draw a polyline. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* status -* Pointer to the inherited status variable. - -*/ - if( !astOK ) return 0; - return ( (AstGLineFun) this->grffun[ AST__GLINE ])( astGrfConID(this), n, x, y ); -} - -static int CGMarkWrapper( AstPlot *this, int n, const float *x, - const float *y, int type, int *status ) { -/* -* -* Name: -* CGMarkWrapper - -* Purpose: -* Call a C implementation of the GMark Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGMarkWrapper( AstPlot *this, int n, const float *x, -* const float *y, int type, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GMark grf -* function to draw markers. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* type -* An integer which can be used to indicate the type of marker symbol -* required. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGMarkFun) this->grffun[ AST__GMARK ])( astGrfConID(this), n, x, y, type ); -} - -static int CGTextWrapper( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, int *status ) { -/* -* -* Name: -* CGTextWrapper - -* Purpose: -* Call a C implementation of the GText Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGTextWrapper( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GText grf -* function to draw a text string. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* status -* Pointer to the inherited status value. - -*/ - if( !astOK ) return 0; - return ( (AstGTextFun) this->grffun[ AST__GTEXT ])( astGrfConID(this), text, x, y, just, upx, upy ); -} - -static int CGTxExtWrapper( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, float *xb, - float *yb, int *status ) { -/* -* -* Name: -* CGTxExtWrapper - -* Purpose: -* Call a C implementation of the GTxExt Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGTxExtWrapper( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, float *xb, -* float *yb, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GTxExt -* grf function to find the extent of a text string. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* xb -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* yb -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. -* status -* Pointer to the inherited status variable. - -*/ - if( !astOK ) return 0; - return ( (AstGTxExtFun) this->grffun[ AST__GTXEXT ])( astGrfConID(this), text, x, y, just, upx, upy, xb, yb ); -} - -static int CGQchWrapper( AstPlot *this, float *chv, float *chh, int *status ) { -/* -* -* Name: -* CGQchWrapper - -* Purpose: -* Call a C implementation of the GQch Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGQchWrapper( AstPlot *this, float *chv, float *chh, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GQch -* grf function to find the extent of a text string. - -* Parameters: -* this -* The Plot. -* chv -* A pointer to the double which is to receive the height of -* characters drawn vertically. This will be an increment in the X -* axis -* chh -* A pointer to the double which is to receive the height of -* characters drawn vertically. This will be an increment in the Y -* axis -* status -* Pointer to the inherited status value. -*/ - if( !astOK ) return 0; - return ( (AstGQchFun) this->grffun[ AST__GQCH ])( astGrfConID(this), chv, chh ); -} - -static int CGScalesWrapper( AstPlot *this, float *alpha, float *beta, int *status ) { -/* -* -* Name: -* CGScalesWrapper - -* Purpose: -* Call a C implementation of the GScales Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CGScalesWrapper( AstPlot *this, float *alpha, float *beta, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function is a wrapper for a C implementation of the GScales -* grf function to find the extent of a text string. - -* Parameters: -* this -* The Plot. -* alpha -* A pointer to the location at which to return the scale for the -* X axis (i.e. Xnorm = alpha*Xworld). -* beta -* A pointer to the location at which to return the scale for the -* Y axis (i.e. Ynorm = beta*Yworld). -* status -* Pointer to the inherited status value. -*/ - if( !astOK ) return 0; - return ( (AstGScalesFun) this->grffun[ AST__GSCALES ])( astGrfConID(this), alpha, beta ); -} - -static int CheckLabels( AstPlot *this, AstFrame *frame, int axis, - double *ticks, int nticks, int force, char **list, - double refval, int *status ){ -/* -* Name: -* CheckLabels - -* Purpose: -* Create tick mark labels and check that adjacent labels are different. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CheckLabels( AstPlot *this, AstFrame *frame, int axis, double *ticks, -* int nticks, int force, char **list, double refval, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function formats the supplied ticks mark values using the -* astFormat method for the supplied Frame. Unless force is non-zero, it -* then checks all pairs of adjacent labels. If a pair is found which are -* identical then the memory holding the labels is released, and a value -* of zero is returned. Otherwise, a value of one is returned, indicating -* that adjacent labels are all different and the labels are returned. - -* Parameters: -* this -* Pointer to the Plot. -* frame -* Pointer to the Frame. -* axis -* The zero-based index of the axis to which the tick marks refer. -* ticks -* Pointer to an array holding the tick mark values. -* nticks -* The number of tick marks supplied by parameter "ticks". -* force -* If non-zero, then no check for identical adjacent labels is -* performed, and the labels are always considered to be OK. -* list -* Pointer to the start of an array of pointers. Each of the -* elements in this array receives a pointer to a string holding a -* formatted label. Each of these strings should be freed using -* astFree when no longer needed. -* refval -* A value to use for the other axis when normalizing. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if any pairs of identical adjacent labels were found. One -* otherwise. - -* Notes: -* - No error is reported if a pair of identical adjacent labels is -* found. -* - If an error has already occurred, or if this function should -* fail for any reason, a value of zero is returned, and the array of -* pointers identified by "list" is filled with NULL pointers. - - -*/ - -/* Local Variables: */ - const char *label; /* Pointer to formatted tick value */ - double val[ 2 ]; /* Workspace for normalizing */ - int i; /* Tick index */ - int len; /* Number of characters in curent label */ - int ok; /* The returned flag */ - -/* Fill the supplied label list with NULL pointers. */ - if( list ) { - for( i = 0; i < nticks; i++ ) list[ i ] = NULL; - } - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned flag to indicate that all adjacent labels are - different. */ - ok = 1; - -/* Normalize and format the first tick mark value. */ - val[ axis ] = ticks[ 0 ]; - val[ 1 - axis ] = refval; - astNorm( frame, val ); - label = astFormat( frame, axis, val[ axis ] ); - -/* Allocate memory holding a copy of the formatted value, and store a - pointer to this copy in the list of labels. */ - if( label ){ - len = strlen( label ) + 1; - list[ 0 ] = (char *) astStore( NULL, (void *) label, len ); - } else { - ok = 0; - } - -/* Normalize and format each of the tick mark values in this batch. */ - for( i = 1; i < nticks && astOK && ok; i++ ){ - val[ axis ] = ticks[ i ]; - val[ 1 - axis ] = refval; - astNorm( frame, val ); - label = astFormat( frame, axis, val[ axis ] ); - if( label ){ - -/* Unless checks have been supressed, compare this label with the previous - label. If they are identical clear the returned flag. */ - if( !force && !strcmp( label, list[ i - 1 ] ) ) { - ok = 0; - -/* Allocate memory holding a copy of the label, and store a - pointer to this copy in the list of labels. */ - } else { - list[ i ] = (char *) astStore( NULL, (void *) label, strlen( label ) + 1 ); - } - - } else { - ok = 0; - } - - } - -/* If two adjacent labels were identical, or an error occurred, release the - memory used to store the labels. */ - if( !ok || !astOK ){ - for( i = 0; i < nticks; i++ ){ - if( list[ i ] ) list[ i ] = (char *) astFree( (void *) list[ i ] ); - } - } - -/* Ensure a value of zero is returned if an error has occurred. */ - if( !astOK ) ok = 0; - -/* Return the answer. */ - return ok; - -} - -static char **CheckLabels2( AstPlot *this, AstFrame *frame, int axis, - double *ticks, int nticks, char **old_list, - double refval, int *status ){ -/* -* Name: -* CheckLabels2 - -* Purpose: -* Check that labels cannot be shortened. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* char **CheckLabels2( AstPlot *this, AstFrame *frame, int axis, -* double *ticks, int nticks, char **old_list, -* double refval, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function formats the supplied ticks mark values using the -* astFormat method for the supplied Frame. It then compares the labels -* with the corresponding labels supplied in "old_list". If all of the -* new labels are shorter than, or equal in length to, the old labels, -* then memory is allocated to hold the new (shorter) labels, and a -* pointer to this memory is returned. If any new label is longer than -* the corresponding old label, then a NULL pointer is returned. -* -* No check is performed on whether or not there are any identical -* adjacent labels. - -* Parameters: -* this -* Pointer to the Plot. -* frame -* Pointer to the Frame. -* axis -* The zero-based index of the axis to which the tick marks refer. -* ticks -* Pointer to an array holding the tick mark values. -* nticks -* The number of tick marks supplied by parameter "ticks". -* old_list -* Pointer to the start of an array of pointers. Each of the -* elements in this array should hold a pointer to a string holding a -* formatted label. -* refval -* A value to use for the other axis when normalizing. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to an array of pointers. Each of these pointers points to -* a text string holding a shortened label. If a complete set of -* shortened labels could not be found (or if an error occurs), a NULL -* pointer is returned. - -* Notes: -* - The memory holding the returned shortened labels should be -* freed by cthe caller, together with the memory holding the pointers to -* the labels. -* - No error is reported if a pair of identical adjacent labels is -* found. -* - If an error has already occurred, or if this function should -* fail for any reason, a value of NULL is returned. - -*/ - -/* Local Variables: */ - char **list; /* The returned pointer */ - const char *label; /* Pointer to formatted tick value */ - double val[ 2 ]; /* Workspace for normalizing */ - int i; /* Tick index */ - int llen; /* Number of characters in curent label */ - int ok; /* Are the old labels OK to be used? */ - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Allocate memory to hold the pointers to the new labels. */ - list = (char **) astMalloc( sizeof( char * )*(size_t) nticks ); - if( list ) { - -/* Fill this array with NULLs for safety. */ - for( i = 0; i < nticks; i++ ) list[ i ] = NULL; - -/* Initialise a flag to indicate that all the new labels are - shorter than the old labels. */ - ok = 0; - -/* Normalize and format each of the tick mark values in this batch. */ - for( i = 0; i < nticks && astOK; i++ ){ - val[ axis ] = ticks[ i ]; - val[ 1 - axis ] = refval; - astNorm( frame, val ); - label = astFormat( frame, axis, val[ axis ] ); - if( label ){ - -/* Get the length of the new label. */ - llen = strlen( label ); - -/* Compare this label with the corresponding old label. If the new one is - longer than the old one, set the flag and leave the loop. */ - if( llen > strlen( old_list[ i ] ) ) { - ok = 1; - break; - } - -/* Store the new label. */ - list[ i ] = (char *) astStore( NULL, (void *) label, - (size_t) (llen + 1) ); - } - } - -/* If the old labels are to be used, or an error occurred, release the memory - used to store the new labels. */ - if( ok || !astOK ){ - for( i = 0; i < nticks; i++ ){ - if( list[ i ] ) list[ i ] = (char *) astFree( (void *) list[ i ] ); - } - list = (char **) astFree( (void *) list ); - } - - } - -/* Return the answer. */ - return list; - -} - -static int ChrLen( const char *string, int *status ){ -/* -* Name: -* ChrLen - -* Purpose: -* Return the length of a string excluding any trailing white space. - -* Type: -* Private function. - -* Synopsis: -* int ChrLen( const char *string, int *status ) - -* Class Membership: -* Plot - -* Description: -* This function returns the length of a string excluding any trailing -* white space. - -* Parameters: -* string -* Pointer to the string. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The length of a string excluding any trailing white space. - -* Notes: -* - A value of zero is returned if a NULL pointer is supplied, or if an -* error has already occurred. - -*/ - -/* Local Variables: */ - const char *c; /* Pointer to the next character to check */ - int ret; /* The returned string length */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned string length. */ - ret = 0; - -/* Check a string has been supplied. */ - if( string ){ - -/* Check each character in turn, starting with the last one. */ - ret = strlen( string ); - c = string + ret - 1; - while( ret ){ - if( !isspace( (int) *c ) ) break; - c--; - ret--; - } - } - -/* Return the answer. */ - return ret; - -} - -static AstPlotCurveData **CleanCdata( AstPlotCurveData **cdata, int *status ){ -/* -* Name: -* CleanCdata - -* Purpose: -* Release the structures holding curve break information. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPlotCurveData **CleanCdata( AstPlotCurveData **cdata, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function releases the memory used to hold the curve break -* information returned by function DrawGrid, and returns a NULL pointer. - -* Parameters: -* cdata -* Pointer to the information to be freed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A NULL pointer. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. - -*/ - -/* Return if a NULL pointer has been supplied. */ - if( !cdata ) return NULL; - -/* Release each of the two structures in turn (if they exist). */ - (void) astFree( (void *) cdata[ 0 ] ); - (void) astFree( (void *) cdata[ 1 ] ); - -/* Release the memory used to hold the two AstPlotCurveData pointers. */ - (void) astFree( (void *) cdata ); - -/* Return. */ - return NULL; - -} - -static TickInfo **CleanGrid( TickInfo **grid, int *status ){ -/* -* Name: -* CleanGrid - -* Purpose: -* Release the structures holding grid information. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* TickInfo **CleanGrid( TickInfo **grid ) - -* Class Membership: -* Plot member function. - -* Description: -* This function releases the memory used to hold the grid information -* returned by function GridLines, and returns a NULL pointer. - -* Parameters: -* grid -* Pointer to the information to be freed. - -* Returned Value: -* A NULL pointer. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. - -*/ - -/* Local Variables: */ - TickInfo *info; /* Pointer to TickInfo structure being freed */ - int i; /* Axis index */ - int j; /* Tick mark index */ - -/* Return if a NULL pointer has been supplied. */ - if( !grid ) return NULL; - -/* Release each of the TickInfo structures in turn (if they exist). */ - for( i = 0; i < 2; i++ ){ - if( ( info = grid[ i ] ) ){ - -/* Release the memory holding major tick mark values. */ - (void) astFree( (void *) info->ticks ); - -/* Release the memory holding minor tick mark values. */ - (void) astFree( (void *) info->minticks ); - -/* Release the memory holding curve section starting positions. */ - (void) astFree( (void *) info->start ); - -/* Release the memory holding curve section lengths. */ - (void) astFree( (void *) info->length ); - -/* If there are any tick mark labels in the structure... */ - if( info->labels ){ - -/* Release the memory holding each tick mark label. */ - for( j = 0; j < info->nmajor; j++ ){ - (void) astFree( (void *) info->labels[ j ] ); - } - -/* Release the memory holding the pointers to the tick mark labels. */ - (void) astFree( (void *) info->labels ); - -/* Release the memory holding the format specification string. */ - (void) astFree( (void *) info->fmt ); - - } - -/* Release the TickInfo structure. */ - (void) astFree( (void *) info ); - } - } - -/* Release the memory used to hold the two TickInfo pointers. */ - (void) astFree( (void *) grid ); - -/* Return. */ - return NULL; - -} - -static void ClearAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* ClearAttrib - -* Purpose: -* Clear an attribute value for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void ClearAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot member function (over-rides the astClearAttrib protected -* method inherited from the FrameSet class). - -* Description: -* This function clears the value of a specified attribute for a -* Plot, so that the default value will subsequently be used. - -* Parameters: -* this -* Pointer to the Plot. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char label[21]; /* Graphics item label */ - const char *class; /* Pointer to class string */ - int axis; /* Axis number */ - int id1; /* Plot object id */ - int id2; /* Plot object id */ - int id; /* Plot object id */ - int len; /* Length of attrib string */ - int nax; /* Number of base Frame axes */ - int nc; /* No. characters read by astSscanf */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Obtain the length of the "attrib" string. */ - len = strlen( attrib ); - -/* Check the attribute name and clear the appropriate attribute. */ - -/* Edge(axis). */ -/* ------------ */ - if ( nc = 0, - ( 1 == astSscanf( attrib, "edge(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearEdge( this, axis - 1 ); - -/* Grid. */ -/* ----- */ - } else if ( !strcmp( attrib, "grid" ) ) { - astClearGrid( this ); - -/* LabelUp */ -/* ------- */ - } else if ( !strcmp( attrib, "labelup" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLabelUp( this, axis ); - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelup(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLabelUp( this, axis - 1 ); - -/* LogPlot */ -/* ------- */ - } else if ( !strcmp( attrib, "logplot" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogPlot( this, axis ); - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logplot(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogPlot( this, axis - 1 ); - -/* LogTicks */ -/* ------- */ - } else if ( !strcmp( attrib, "logticks" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogTicks( this, axis ); - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logticks(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogTicks( this, axis - 1 ); - -/* LogLabel */ -/* ------- */ - } else if ( !strcmp( attrib, "loglabel" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogLabel( this, axis ); - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loglabel(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogLabel( this, axis - 1 ); - -/* NumLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "numlab" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearNumLab( this, axis ); - -/* NumLab(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearNumLab( this, axis - 1 ); - -/* MinTick. */ -/* ---------- */ - } else if ( !strcmp( attrib, "mintick" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearMinTick( this, axis ); - -/* MinTick(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "mintick(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearMinTick( this, axis - 1 ); - -/* TextLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "textlab" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearTextLab( this, axis ); - -/* TextLab(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearTextLab( this, axis - 1 ); - -/* LabelUnits. */ -/* --------- */ - } else if ( !strcmp( attrib, "labelunits" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLabelUnits( this, axis ); - -/* LabelUnits(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelunits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLabelUnits( this, axis - 1 ); - -/* Style. */ -/* ------ */ - } else if ( !strcmp( attrib, "style" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearStyle( this, id ); - -/* Style(label). */ -/* --------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "style(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearStyle( this, id1 ); - if( nid > 1 ) astClearStyle( this, id2 ); - if( nid > 2 ) astClearStyle( this, id3 ); - -/* Font. */ -/* ----- */ - } else if ( !strcmp( attrib, "font" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearFont( this, id ); - -/* Font(label). */ -/* -------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "font(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearFont( this, id1 ); - if( nid > 1 ) astClearFont( this, id2 ); - if( nid > 2 ) astClearFont( this, id3 ); - -/* Colour. */ -/* ------- */ - } else if ( !strcmp( attrib, "colour" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearColour( this, id ); - -/* Colour(label). */ -/* ---------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "colour(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearColour( this, id1 ); - if( nid > 1 ) astClearColour( this, id2 ); - if( nid > 2 ) astClearColour( this, id3 ); - -/* Color. */ -/* ------ */ - } else if ( !strcmp( attrib, "color" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearColour( this, id ); - -/* Color(label). */ -/* --------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "color(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearColour( this, id1 ); - if( nid > 1 ) astClearColour( this, id2 ); - if( nid > 2 ) astClearColour( this, id3 ); - -/* Width. */ -/* ------ */ - } else if ( !strcmp( attrib, "width" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearWidth( this, id ); - -/* Width(label). */ -/* --------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "width(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - - astClearWidth( this, id1 ); - if( nid > 1 ) astClearWidth( this, id2 ); - if( nid > 2 ) astClearWidth( this, id3 ); - -/* Size. */ -/* ----- */ - } else if ( !strcmp( attrib, "size" ) ) { - for( id = 0; id < AST__NPID; id++ ) astClearSize( this, id ); - -/* Size(label). */ -/* -------------*/ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "size(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, attrib, "astClear", class, status ), - nax, &id1, &id2, &id3, status ); - astClearSize( this, id1 ); - if( nid > 1 ) astClearSize( this, id2 ); - if( nid > 2 ) astClearSize( this, id3 ); - -/* LabelAt(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelat(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLabelAt( this, axis - 1 ); - -/* Centre(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "centre(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearCentre( this, axis - 1 ); - -/* Gap. */ -/* ---- */ - } else if ( !strcmp( attrib, "gap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearGap( this, axis ); - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "gap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearGap( this, axis - 1 ); - -/* LogGap. */ -/* ----------- */ - } else if ( !strcmp( attrib, "loggap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearLogGap( this, axis ); - -/* LogGap(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loggap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearLogGap( this, axis - 1 ); - -/* NumLabGap. */ -/* ---------- */ - } else if ( !strcmp( attrib, "numlabgap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearNumLabGap( this, axis ); - -/* NumLabGap(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearNumLabGap( this, axis - 1 ); - -/* TextLabGap. */ -/* ----------- */ - } else if ( !strcmp( attrib, "textlabgap" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearTextLabGap( this, axis ); - -/* TextLabGap(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearTextLabGap( this, axis - 1 ); - -/* TitleGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "titlegap" ) ) { - astClearTitleGap( this ); - -/* MajTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "majticklen" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearMajTickLen( this, axis ); - -/* MajTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "majticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearMajTickLen( this, axis - 1 ); - -/* MinTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "minticklen" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearMinTickLen( this, axis ); - -/* MinTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "minticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearMinTickLen( this, axis - 1 ); - -/* Labelling. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelling" ) ) { - astClearLabelling( this ); - -/* TickAll. */ -/* -------- */ - } else if ( !strcmp( attrib, "tickall" ) ) { - astClearTickAll( this ); - -/* ForceExterior */ -/* ------------- */ - } else if ( !strcmp( attrib, "forceexterior" ) ) { - astClearForceExterior( this ); - -/* Invisible. */ -/* ---------- */ - } else if ( !strcmp( attrib, "invisible" ) ) { - astClearInvisible( this ); - -/* Border. */ -/* ------- */ - } else if ( !strcmp( attrib, "border" ) ) { - astClearBorder( this ); - -/* ClipOp. */ -/* ------- */ - } else if ( !strcmp( attrib, "clipop" ) ) { - astClearClipOp( this ); - -/* Clip. */ -/* ----- */ - } else if ( !strcmp( attrib, "clip" ) ) { - astClearClip( this ); - -/* Grf. */ -/* ---- */ - } else if ( !strcmp( attrib, "grf" ) ) { - astClearGrf( this ); - -/* DrawTitle. */ -/* ---------- */ - } else if ( !strcmp( attrib, "drawtitle" ) ) { - astClearDrawTitle( this ); - -/* DrawAxes. */ -/* --------- */ - } else if ( !strcmp( attrib, "drawaxes" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearDrawAxes( this, axis ); - -/* Abbrev */ -/* ------ */ - } else if ( !strcmp( attrib, "abbrev" ) ) { - for( axis = 0; axis < nax; axis++ ) astClearAbbrev( this, axis ); - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "drawaxes(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearDrawAxes( this, axis - 1 ); - -/* Abbrev(axis). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "abbrev(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - astClearAbbrev( this, axis - 1 ); - -/* Escape. */ -/* ------- */ - } else if ( !strcmp( attrib, "escape" ) ) { - astClearEscape( this ); - -/* Tol. */ -/* ---- */ - } else if ( !strcmp( attrib, "tol" ) ) { - astClearTol( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_clearattrib)( this_object, attrib, status ); - } -} - -static void ClearLogPlot( AstPlot *this, int axis, int *status ){ -/* -* -* Name: -* ClearLogPlot - -* Purpose: -* Clear the value for a LogPlot attribute - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void ClearLogPlot( AstPlot *this, int axis, int *status ) - -* Class Membership: -* Plot member function - -* Description: -* Assigns the default value to the LogPlot attribute of the specified -* axis, and also re-maps the base Frame of the Plot if necessary. - -* Parameters: -* this -* The Plot. -* axis -* Zero based axis index. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int oldval; /* Original value of the attribute */ - int newval; /* Cleared (default) value of the attribute */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index. */ - if( axis < 0 || axis >= 2 ){ - astError( AST__AXIIN, "astClearLogPlot(%s): Index (%d) is invalid for " - "attribute LogPlot - it should be in the range 1 to 2.", status, - astGetClass( this ), axis + 1 ); - -/* Do nothing if the attribute is not currently set. */ - } else if( astTestLogPlot( this, axis ) ){ - -/* Get the original value of the attribute. clear the value, and then get - the new (default) value. */ - oldval = this->logplot[ axis ]; - this->logplot[ axis ] = -1; - newval = astGetLogPlot( this, axis ); - -/* If the effective value has changed, attempt to remap the axis. If this - fails, re-instate the original value. */ - if( ( oldval != 0 ) != ( newval != 0 ) ) { - if( !ToggleLogLin( this, axis, oldval, "astClearLogPlot", status ) ) { - this->logplot[ axis ] = oldval; - } - } - } -} - -static void Clip( AstPlot *this, int iframe, const double lbnd[], - const double ubnd[], int *status ){ -/* -*++ -* Name: -c astClip -f AST_CLIP - -* Purpose: -* Set up or remove clipping for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astClip( AstPlot *this, int iframe, const double lbnd[], -c const double ubnd[] ) -f CALL AST_CLIP( THIS, IFRAME, LBND, UBND, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function defines regions of a Plot which are to be clipped. -f This routine defines regions of a Plot which are to be clipped. -* Any subsequent graphical output created using the Plot will then -* be visible only within the unclipped regions of the plotting -* area. See also the Clip attribute. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c iframe -f IFRAME = INTEGER (Given) -* The index of the Frame within the Plot to which the clipping -c limits supplied in "lbnd" and "ubnd" (below) refer. Clipping -f limits supplied in LBND and UBND (below) refer. Clipping -* may be applied to any of the coordinate systems associated -* with a Plot (as defined by the Frames it contains), so this -* index may take any value from 1 to the number of Frames in -* the Plot (Nframe attribute). In addition, the values -* AST__BASE and AST__CURRENT may be used to specify the base -* and current Frames respectively. -* -* For example, a value of AST__CURRENT causes clipping to be -* performed in physical coordinates, while a value of AST__BASE -* would clip in graphical coordinates. Clipping may also be -* removed completely by giving a value of AST__NOFRAME. In this -* case any clipping bounds supplied (below) are ignored. -c lbnd -f LBND( * ) = DOUBLE PRECISION (Given) -* An array with one element for each axis of the clipping Frame -c (identified by the index "iframe"). This should contain the -f (identified by the index IFRAME). This should contain the -* lower bound, on each axis, of the region which is to remain -* visible (unclipped). -c ubnd -f UBND( * ) = DOUBLE PRECISION (Given) -* An array with one element for each axis of the clipping Frame -c (identified by the index "iframe"). This should contain the -f (identified by the index IFRAME). This should contain the -* upper bound, on each axis, of the region which is to remain -* visible (unclipped). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - Only one clipping Frame may be active at a time. This function -f - Only one clipping Frame may be active at a time. This routine -* will deactivate any previously-established clipping Frame before -* setting up new clipping limits. -c - The clipping produced by this function is in addition to that -f - The clipping produced by this routine is in addition to that -* specified by the Clip attribute which occurs at the edges of the -* plotting area -c established when the Plot is created (see astPlot). The -f established when the Plot is created (see AST_PLOT). The -* underlying graphics system may also impose further clipping. -* - When testing a graphical position for clipping, it is first -* transformed into the clipping Frame. The resulting coordinate on -* each axis is then checked against the clipping limits (given by -c "lbnd" and "ubnd"). By default, a position is clipped if any -f LBND and UBND). By default, a position is clipped if any -* coordinate lies outside these limits. However, if a non-zero -* value is assigned to the Plot's ClipOp attribute, then a -* position is only clipped if the coordinates on all axes lie -* outside their clipping limits. -* - If the lower clipping limit exceeds the upper limit for any -* axis, then the sense of clipping for that axis is reversed (so -* that coordinate values lying between the limits are clipped -* instead of those lying outside the limits). To produce a "hole" -* in a coordinate space (that is, an internal region where nothing -* is plotted), you should supply all the bounds in reversed order, -* and set the ClipOp attribute for the Plot to a non-zero value. -* - Either clipping limit may be set to the value AST__BAD, which -* is equivalent to setting it to infinity (or minus infinity for a -* lower bound) so that it is not used. -* - If a graphical position results in any bad coordinate values -* (AST__BAD) when transformed into the clipping Frame, then it is -* treated (for the purposes of producing graphical output) as if -* it were clipped. -* - When a Plot is used as a Mapping to transform points -c (e.g. using astTran2), any clipped output points are assigned -f (e.g. using AST_TRAN2), any clipped output points are assigned -* coordinate values of AST__BAD. -* - An error results if the base Frame of the Plot is not -* 2-dimensional. -*-- -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to the clipping Frame */ - AstFrameSet *fset; /* Pointer to the Plot's FrameSet */ - int i; /* Axis index */ - int ifrm; /* The validated frame index */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - ifrm = 0; - -/* Get a pointer to the FrameSet at the start of the Plot. */ - fset = (AstFrameSet *) this; - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( fset ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "astClip(%s): Number of axes (%d) in the " - "base Frame of the supplied %s is invalid - this number " - "should be 2.", status, astGetClass( this ), naxes, - astGetClass( this ) ); - } - -/* If clipping is to be switched on, check the supplied frame index and - bounds. */ - if( iframe != AST__NOFRAME && astOK ) { - -/* Report an error if either of the bounds pointers is NULL.*/ - if( !lbnd ){ - astError( AST__CLPAX, "astClip(%s): A NULL pointer was " - "supplied for the array holding the lower bounds of " - "the clipping volume.", status, astGetClass( this ) ); - } else if( !ubnd ){ - astError( AST__CLPAX, "astClip(%s): A NULL pointer was " - "supplied for the array holding the upper bounds of " - "the clipping volume.", status, astGetClass( this ) ); - } - -/* Validate the clipping frame index. */ - ifrm = astValidateFrameIndex( fset, iframe, "astClip" ); - -/* Get the number of axes in the clipping frame. */ - fr = astGetFrame( this, ifrm ); - naxes = astGetNaxes( fr ); - fr = astAnnul( fr ); - - } - -/* Leave the current clipping information unchanged if an error has - occurred. */ - if( astOK ){ - -/* Remove all clipping information from the Plot. */ - this->clip_lbnd = (double *) astFree( (void *) this->clip_lbnd ); - this->clip_ubnd = (double *) astFree( (void *) this->clip_ubnd ); - this->clip_frame = AST__NOFRAME; - this->clip_axes = 0; - -/* If bounds have been supplied, set up new clipping information. */ - if( iframe != AST__NOFRAME ){ - -/* Store the information. */ - this->clip_frame = ifrm; - this->clip_lbnd = astStore( NULL, lbnd, sizeof(double)*(size_t)naxes ); - this->clip_ubnd = astStore( NULL, ubnd, sizeof(double)*(size_t)naxes ); - this->clip_axes = naxes; - -/* If an error has occurred, remove all clipping information. */ - if( !astOK ){ - this->clip_lbnd = (double *) astFree( (void *) this->clip_lbnd ); - this->clip_ubnd = (double *) astFree( (void *) this->clip_ubnd ); - this->clip_frame = AST__NOFRAME; - this->clip_axes = 0; - -/* Otherwise, replace any bounds of AST__BAD with suitable default - values. */ - } else { - for( i = 0; i < naxes; i++ ){ - if( this->clip_lbnd[ i ] == AST__BAD ) this->clip_lbnd[ i ] = -DBL_MAX; - if( this->clip_ubnd[ i ] == AST__BAD ) this->clip_ubnd[ i ] = DBL_MAX; - } - - } - - } - - } - -/* Return. */ - return; - -} - -static int Compared( const void *elem1, const void *elem2 ){ -/* -* Name: -* Compared - -* Purpose: -* Compare two "double" values. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Compared( const void *elem1, const void *elem2 ) - -* Class Membership: -* Plot method. - -* Description: -* This function compares the two "double" values to which pointers -* are supplied, and returns an integer indicating which is larger, -* checking for AST__BAD values. It is intended for use with the C -* Run-Time-Library sorting function "qsort". - -* Parameters: -* elem1 -* Pointer to the first "double". -* elem2 -* Pointer to the second "double". - -* Returned Value: -* Zero is returned if the values are equal. If the first is larger -* than the second then +1 is returned. Otherwise, -1 is returned. - -* Notes: -* - Values of AST__BAD are considered to be larger than any other -* value (other than another value of AST__BAD). -* - If both values are AST__BAD, then zero is returned. -* - This function executes even if an error has occurred. - -*/ - -/* Local Variables: */ - double *delem1; /* Pointer to the first "double" value */ - double *delem2; /* Pointer to the second "double" value */ - int ret; /* The returned value */ - -/* Get pointers to the two "double" values. */ - delem1 = (double *) elem1; - delem2 = (double *) elem2; - -/* Check the values for equality (including both values being AST__BAD). */ - if( *delem1 == *delem2 ){ - ret = 0; - -/* If the first is bad, then it is considered to be larger than the - second. */ - } else if( *delem1 == AST__BAD ){ - ret = 1; - -/* If the second is bad, then it is considered to be larger than the - first. */ - } else if( *delem2 == AST__BAD ){ - ret = -1; - -/* If the first is larger than the second, return 1. */ - } else if( *delem1 > *delem2 ){ - ret = 1; - -/* If the first is smaller than the second, return -1. */ - } else { - ret = -1; - - } - -/* Return the answer. */ - return ret; - -} - -static int Compare_LL( const void *elem1, const void *elem2 ){ -/* -* Name: -* Compare_LL - -* Purpose: -* Compare two LabelList structures as used by function PlotLabels. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Compare_LL( const void *elem1, const void *elem2 ) - -* Class Membership: -* Plot method. - -* Description: -* This function compares two "LabelList" structures as used by function -* PlotLabels, and returns an integer indicating which has a larger -* "index" value. This function is intended to be used with the C -* Run-Time-Library sorting function "qsort". - -* Parameters: -* elem1 -* Pointer to the first LabelList. -* elem2 -* Pointer to the second LabelList. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero is returned if the values are equal. If the first is larger -* than the second then +1 is returned. Otherwise, -1 is returned. - -* Notes: -* - This function executes even if an error has occurred. - -*/ - -/* Local Variables: */ - LabelList *ll1; /* Pointer to the first LabelList */ - LabelList *ll2; /* Pointer to the second LabelList */ - int ret; /* The returned value */ - -/* Get pointers to the two LabelList structures. */ - ll1 = (LabelList *) elem1; - ll2 = (LabelList *) elem2; - -/* Compare the indices for the two label's. */ - if( ll1->index < ll2->index ){ - ret = -1; - - } else if( ll1->index > ll2->index ){ - ret = 1; - - } else { - ret = 0; - } - -/* Return the answer. */ - return ret; - -} - -static void CopyPlotDefaults( AstPlot *this, int axis, AstPlot *dplot, - int daxis, int *status ){ -/* -*+ -* Name: -* astCopyPlotDefaults - -* Purpose: -* Copy used attribute defaults from one Plot to another. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* void astCopyPlotDefaults( AstPlot *this, int axis, AstPlot *dplot, -* int daxis ) - -* Class Membership: -* Plot method. - -* Description: -* Some of the attributes used by the Plot class have dynamic default -* values that are determined during the process of drawing an annotated -* grid using astGrid. The dynamic default values are stored in a -* separate set of components within the Plot structure. This function -* copies these components from one Plot to another. - -* Parameters: -* this -* Pointer to a Plot containing the values ot be copied. -* axis -* The zero-based index of the axis within "this" for which the -* used defaults are to be copied. -* dplot -* A pointer to another Plot into which the default attribute -* values are to be copied. -* daxis -* The zero based index of the axis within "dplot" which is to -* receive the new values. - -*- -*/ - -/* Check the global status. */ - if( !astOK ) return; - - dplot->ulglb[ daxis ] = this->ulglb[ axis ]; - dplot->ulgtk[ daxis ] = this->ulgtk[ axis ]; - dplot->uloggap[ daxis ] = this->uloggap[ axis ]; - dplot->ugap[ daxis ] = this->ugap[ axis ]; - dplot->ucentre[ daxis ] = this->ucentre[ axis ]; - dplot->uedge[ daxis ] = this->uedge[ axis ]; - dplot->ulblat[ daxis ] = this->ulblat[ axis ]; - dplot->ulbunit[ daxis ] = this->ulbunit[ axis ]; - dplot->umintk[ daxis ] = this->umintk[ axis ]; - dplot->utxtlb[ daxis ] = this->utxtlb[ axis ]; - dplot->umjtkln[ daxis ] = this->umjtkln[ axis ]; - - dplot->ugrid = this->ugrid; - dplot->ulbling = this->ulbling; - dplot->uborder = this->uborder; -} - -static int CountGood( int n, double *data, int *status ){ -/* -* Name: -* CountGood - -* Purpose: -* Coount the number of non-bad values in an array. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int CountGood( int n, double *data, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns the number of elements in the supplied array -* which do not have the value AST__BAD. - -* Parameters: -* n -* The total number of elements in the array. -* data -* Pointer to the start of the array. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of good points in the array. - -* Notes: -* - A value of zero is returned if an error has already occurred. - -*/ - -/* Local Variables: */ - int i; - int ngood; - double *value; - -/* Check global status. */ - if( !astOK ) return 0; - -/* Initialise a pointer to the next array element, and the number of - good elements found so far. */ - value = data; - ngood = 0; - -/* Check each element. */ - for( i = 0; i < n; i++ ){ - if( *(value++) != AST__BAD ) ngood++; - } - -/* Return the answer. */ - return ngood; - -} - -static int Cross( float ax, float ay, float bx, float by, - float cx, float cy, float dx, float dy, int *status ){ -/* -* Name: -* Cross - -* Purpose: -* See if two line segments intersect. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Cross( float ax, float ay, float bx, float by, -* float cx, float cy, float dx, float dy, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function sees if the line segment (A,B) intersects the line -* segment (C,D). - -* Parameters: -* ax, ay -* The coordinates of A. -* bx, by -* The coordinates of B. -* cx, cy -* The coordinates of C. -* dx, dy -* The coordinates of D. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Zero if the line segments do not cross or if an error has already -* occurred, and 1 if they do. - -*/ - -/* Local Variables: */ - int ret; - float m1, m2, denom, num, t1, t2; - -/* Check the inherited status. */ - if( !astOK ) return 0; - -/* Get the fraction of the distance from A to B at which the line AB - intersects the line CD. */ - m1 = dx - cx; - m2 = dy - cy; - denom = (bx - ax)*m2 - (by-ay)*m1; - num = (ay - cy)*m1 - (ax - cx)*m2; - - if( denom != 0.0 ) { - t1 = num / denom; - -/* If the the intersection occurs within the segment of the line between A - and B... */ - if( t1 >= 0.0 && t1 <= 1.0 ){ - -/* ... then get the fraction of the distance from C to D at which the - line CD intersects the line AB. */ - m1 = bx - ax; - m2 = by - ay; - denom = (dx - cx)*m2 - (dy-cy)*m1; - num = (cy - ay)*m1 - (cx - ax)*m2; - - if( denom != 0.0 ) { - t2 = num / denom; - -/* If the the intersection occurs within the segment of the line between C - and D then the line segments intersect. */ - if( t2 >= 0.0 && t2 <= 1.0 ){ - ret = 1; - } else { - ret = 0; - } - -/* If the two lines are parallel, then they do not intersect. */ - } else { - ret = 0; - } - - } else { - ret = 0; - } - - } else { - ret = 0; - - } - - return ret; -} - -static void Crv( AstPlot *this, double *d, double *x, double *y, int skipbad, - double *box, CrvStatics *pstatics, const char *method, - const char *class, int *status ){ -/* -* Name: -* Crv - -* Purpose: -* Draw a curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Crv( AstPlot *this, double *d, double *x, double *y, int skipbad, -* double *box, CrvStatics *pstatics, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a curve parameterised by the distance from some -* starting point. The function pointed to by the external variable -* Crv_map is used to transform distances along the curve into graphics -* coordinates (X,Y). The supplied function parameters defined the -* section of the curve to be drawn. -* -* The algorithm used needs no knowledge about the nature of the mapping -* performed by Crv_map, and can handle discontinuities in the curve. It -* first of all determines if any of the segments of the curve can be -* adequately represented by simply drawing a straight line through the -* supplied end points. This decision is based on several requirements such -* as keeping the angle between adjacent sections low and both ends being -* defined (i.e. X and Y not equal to AST__BAD). Any segments of the curve -* which satisfy the requirements are draw as straight lines. If any of -* the supplied curve segments cannot be drawn in this way, then they are -* split up into a set of evenly-spaced sub-segments and the graphics -* coordinates at the ends of these sub-segments are found using Crv_map. -* This function is then called recursively to draw the sub-segments. This -* recursion is limited in depth by the requirement that all the -* sub-segments must be longer than a specified lower limit. If this is not -* the case, then the curve is assumed to be dis-continuous and and the -* sub-segments are ignored. - -* Parameters: -* d -* Pointer to an array of CRV_NPNT values giving the distance along -* the curve from the starting point to each of CRV_NPNT points. They -* should increase monotonically, and should be in whatever units are -* used by the function pointed to by Crv_map. The curve is drawn from -* d[0] to d[CRV_NPNT]. -* x -* Pointer to an array of CRV_NPNT values giving the graphics X -* coordinate for the positions supplied in the array pointed to by -* parameter "d". -* y -* Pointer to an array of CRV_NPNT values giving the graphics Y -* coordinate for the positions supplied in the array pointed to by -* parameter "d". -* skipbad -* Controls what happens if all the supplied points are bad or -* outside the plotting area. If skipbad is non-zero, then it is -* assumed that the supplied points represent an entirely bad (or -* out of bounds) section of the curve, and this function will -* return without attempt to sub-divide any of the supplied points. -* If skipbad is zero, then it is assumed that we may be able to find -* some good points between the supplied bad points, and therefore -* this function will attempt to sub-divide the supplied points. -* Should be supplied as zero on the initial invocation. -* box -* Pointer to an array of 4 doubles houlding a bounding box within -* which the current segment must reside if it is to be sub-divided. -* Supplied in the order xlo, xhi, ylo, yhi. May be NULL in which -* case, no check is made on the bounding box. -* pstatics -* Pointer to a structure holding values for variables which were -* statically defined within this function prior to the thread-safe -* version of AST. If a NULL pointer is supplied, a new structure -* is created in dynamic memory and initialised. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* External Variables: -* Crv_nent = int (Read/Write) -* The number of recursive entries which have been made into -* this function. This should be set to zero before entering -* this function for the first time. -* Crv_ux0 = double (Read/Write) -* The X component in graphics coordinates of the unit vector -* along the previous segment of the curve. This should be set -* to AST__BAD initially to indicate that the previous section -* is not defined. -* Crv_uy0 = double (Read/Write) -* The Y component of the unit vector along the previous segment. -* Crv_limit = double (Read) -* The square of the maximum acceptable residual between the -* drawn curve and the true curve, in graphics coordinates. -* Crv_scerr = double (Read) -* If the ratio of the lengths of adjacent sub-segments is larger -* than Crv_scerr,then the seub-segments will be sub-divided. Note, -* if either axis is mapped logarithmically onto the screen, then -* there will naturally be large changes in scale. Crv_scerr should -* always be larger than 1.0. -* Crv_map = void (*)( int n, double *dd, double *xx, double *yy, -* const char *method, const char *class ) (Read) -* A pointer to a function which can be called to map "n" distances -* along the curve (supplied in "dd") into graphics coordinates -* (stored in "xx" and "yy"). See function "Map1" as an example. -* Crv_clip = int (Read) -* Should lines be clipped at the edge of the plotting area? - -* Notes: -* - The CRV_TRACE conditional compilation blocks in this function -* provide code which displays the recursive entries made to this -* function (and also pauses on initial entry until return is pressed). -* It is useful for investigating the details of the drawing of a -* curve. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - CrvStatics *statics; /* Pointer to structure holding static values */ - double *dd; /* Pointer to array holding sub-segment distances */ - double *pd; /* Pointer to next sub-segment distance */ - double *px; /* Pointer to next sub-segment x coord. */ - double *py; /* Pointer to next sub-segment y coord. */ - double *xx; /* Pointer to array holding sub-segment x coord.s */ - double *yy; /* Pointer to array holding sub-segment x coord.s */ - double bbox[4]; /* Bounding box for this segment */ - double dl2[ CRV_NSEG ];/* Squred segment lengths */ - double dx[ CRV_NSEG ]; /* X increment along each segment */ - double dy[ CRV_NSEG ]; /* Y increment along each segment */ - int i; /* Segment index */ - int seg_ok[ CRV_NSEG ];/* Flags indicating which segments can be drawn */ - int subdivide; /* Flag indicating if segments can be subdivided */ - -/* Check inherited status */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* If required, allocate memory for a structure to hold the static - variables need by this function. */ - if( ! pstatics ) { - statics = astMalloc( sizeof( CrvStatics ) ); - } else { - statics = pstatics; - } - -/* If this is the first entry, set up the minimum length for a - sub-segment in graphics coordinates. If any segment is less than - this minimum length, then recursion will stop and the curve will - be assumed to be dis-continuous. */ - if( !Crv_nent ) { - statics->limit2 = 20.0*Crv_limit/(CRV_NSEG*CRV_NSEG); - -#ifdef CRV_TRACE - statics->levels[ 0 ] = 0; -#endif - } - - -/* Increment the number of entries into this function. */ - Crv_nent++; - -#ifdef CRV_TRACE - for( i = 0; i < Crv_nent; i++ ) { - printf("%d ",statics->levels[ i ] ); - } - printf("\n"); - - if( getchar() == 'm' ) { - float ffx,ffy; - for( i = 0; i < CRV_NPNT; i++ ) { - ffx = x[i]; ffy = y[i]; - GMark( this, 1, &ffx, &ffy, 2, method, class, status ); - GFlush( this, method, class, status ); - } - } -#endif - -/* ====================================================================== - The first section of this function sets up some arrays holding - information which will be used later on. It looks at each of the segments - joing adjacent tabulated points, and finds and stores the increments in - X and Y along each segment, and the square of the segment length. It - also checks to see if the tabulated points are all bad, or if they are - all good. It also finds the lowest squared segment length. - ======================================================================*/ - -/* Look at the first tabulated point. If it is good, set a flag to indicate - that it can be used, store it as "the previous position" (i.e. the start of - the current segment). Also set a flag ("all_bad") to indicate if all - points looked at so far have been bad, or outside the plotting area. */ - if( *x != AST__BAD && *y != AST__BAD ){ - statics->last_ok = 1; - statics->last_x = *x; - statics->last_y = *y; - statics->all_bad = ( *x < Crv_xlo || *x > Crv_xhi || - *y < Crv_ylo || *y > Crv_yhi ) && Crv_clip; - } else { - statics->last_ok = 0; - statics->all_bad = 1; - } - -/* Initialise the bouding box for the this segment. */ - bbox[ 0 ] = DBL_MAX; - bbox[ 1 ] = -DBL_MAX; - bbox[ 2 ] = DBL_MAX; - bbox[ 3 ] = -DBL_MAX; - -/* Store pointers to the X and Y values for the "current position". This - is the position at the end of the current segment. This is initially - the second tabulated point. */ - px = x + 1; - py = y + 1; - -/* Store pointers to the increments and squared length for the current - segment. */ - statics->pdx = dx; - statics->pdy = dy; - statics->pdl2 = dl2; - -/* Initialise the number of long and short segments. */ - statics->nlong = 0; - statics->nshort = 0; - -/* Loop round each segment. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* If the tabulated point marking the end of the segment is good... */ - if( *px != AST__BAD && *py != AST__BAD ){ - -/* Update the bounding box. */ - if( *px < bbox[ 0 ] ) bbox[ 0 ] = *px; - if( *px > bbox[ 1 ] ) bbox[ 1 ] = *px; - if( *py < bbox[ 2 ] ) bbox[ 2 ] = *py; - if( *py > bbox[ 3 ] ) bbox[ 3 ] = *py; - -/* If the point is within the plotting area, set the "statics->all_bad" flag to - indicate that at least 1 point is within the plotting area. */ - if( !Crv_clip || ( *px >= Crv_xlo && *px <= Crv_xhi && - *py >= Crv_ylo && *py <= Crv_yhi ) ) statics->all_bad = 0; - -/* If the point marking the start of the segment was also good, find and - store the increments and squared length for the segment, incrementing - the pointers ready for the next segment. */ - if( statics->last_ok ){ - statics->t1 = *px - statics->last_x; - statics->t2 = *py - statics->last_y; - statics->t3 = statics->t1*statics->t1 + statics->t2*statics->t2; - *(statics->pdx++) = statics->t1; - *(statics->pdy++) = statics->t2; - *(statics->pdl2++) = statics->t3; - -/* Count the number of segments which are, and are not, shorter than the - minimum significant length. */ - if( statics->t3 > statics->limit2 ) { - statics->nlong++; - } else { - statics->nshort++; - } - -/* If the start was bad, the length of the segment is not defined so store - bad values. */ - } else { - *(statics->pdx++) = AST__BAD; - *(statics->pdy++) = AST__BAD; - *(statics->pdl2++) = AST__BAD; - } - -/* The point at the end of the current segment becomes the point at the - start of the next segment. */ - statics->last_ok = 1; - statics->last_x = *(px++); - statics->last_y = *(py++); - -/* If the tabulated point marking the end of the current segment is bad, - the segment length is undefined so store bad values. */ - } else { - *(statics->pdx++) = AST__BAD; - *(statics->pdy++) = AST__BAD; - *(statics->pdl2++) = AST__BAD; - -/* The point at the end of the current segment becomes the point at the - start of the next segment. */ - statics->last_ok = 0; - px++; - py++; - } - } - -/* ====================================================================== - The next section of this function checks to see lines can be drawn - directly through any of the tabulated points. The flags in "seg_ok" - indicates if this is the case for each segment. - ======================================================================*/ - -/* The unit vector along the previous segment is supplied in external - variables Crv_ux0 and Crv_uy0. These will be AST__BAD if the direction - of the previous segment is undefined. */ - statics->vxl = Crv_ux0; - statics->vyl = Crv_uy0; - -/* The length of the previous segment is initially bad. */ - statics->dll = AST__BAD; - -/* Set up some pointers used to walk through the arrays holding the lengths - of each segment. */ - statics->pdl2 = dl2; - statics->pdx = dx; - statics->pdy = dy; - -/* Check each segment in turn to see if it can be drawn as a single - straight line. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* A segment can only be drawn as a single line if both ends are good - and the distance between them is not zero. */ - if( *statics->pdl2 != AST__BAD && *statics->pdl2 > 0.0 ){ - -/* Get a unit vector in the direction of the current segment. */ - statics->dl = sqrt( *statics->pdl2 ); - statics->vx = *statics->pdx/statics->dl; - statics->vy = *statics->pdy/statics->dl; - -/* If a unit vector in the direction of the previous segment is available, - we check that the angle between the previous segment and the current - segment is not too high. */ - if( statics->vxl != AST__BAD ){ - statics->cosang = statics->vxl*statics->vx + statics->vyl*statics->vy; - -/* If the angle is too high, set a flag to indicate that the segment cannot - be drawn as a single line. Also, set the flag for the previous segment as - well. */ - if( statics->cosang < 0.8 || - ( *statics->pdl2 )*( 1.0 - statics->cosang*statics->cosang ) > Crv_limit ) { - seg_ok[ i ] = 0; - if( i > 0 ) seg_ok[ i - 1 ] = 0; - - -/* If the angle between this segment and the previous segment is not too - high, check that the scale has not changed too much. */ - } else { - -/* If the scale (=vector length) has changed a lot, set a flag to indicate - that the segment cannot be drawn as a single line. Also, set the flag for - the previous segment as well. */ - if( statics->dll != AST__BAD && ( statics->dl < statics->dll/Crv_scerr || statics->dl > statics->dll*Crv_scerr ) ) { - seg_ok[ i ] = 0; - if( i > 0 ) seg_ok[ i - 1 ] = 0; - -/* If the orientation and scale of this segment has not changed much from - the previous segment, the segment can be drawn as a straight line. */ - } else { - seg_ok[ i ] = 1; - } - } - -/* If no unit vector is available for the previous segment, then assume - we are re-starting the curve after a discontinuity. In this case, we - can draw it as a straight line. */ - } else { - seg_ok[ i ] = 1; - } - -/* Save the unit vector along the current segment for use next time. */ - statics->vxl = statics->vx; - statics->vyl = statics->vy; - -/* Save the length if the current segment for use next time. */ - statics->dll = statics->dl; - -/* If the length of the current segment is undefined, or zero, we cannot - draw it as a single line. Also, there is no direction vector to pass - on to the next time, so set them bad. */ - } else { - seg_ok[ i ] = 0; - statics->vxl = AST__BAD; - statics->vyl = AST__BAD; - statics->dll = AST__BAD; - } - -/* Point to the next segment. */ - statics->pdl2++; - statics->pdx++; - statics->pdy++; - - } - -/* Do not allow isolated segments to be OK. If a segment is flagged as being - OK, but both its neighbours are not OK, set the segment not OK as well. */ - statics->seg0 = seg_ok + 1; - statics->segm = seg_ok; - statics->segp = seg_ok + 2; - - if( !(*statics->seg0) ) *statics->segm = 0; - - for( i = 1; i < CRV_NSEG - 1; i++ ){ - if( !(*statics->segm) && !(*statics->segp) ) *statics->seg0 = 0; - statics->seg0++; - statics->segm++; - statics->segp++; - } - - if( !(*statics->segm) ) *statics->seg0 = 0; - -/* ====================================================================== - The next section of this function draws the curve. Each segment is drawn - as a straight line if the corresponding flag in "seg_ok" is set. - Segments for which the flag is not set are drawn by calling this function - recursivly. - ======================================================================*/ - -/* Get the parametric length (i.e. the increment in "d") of the sub-segments - within each subdivided segment. */ - statics->delta = ( d[ CRV_NSEG ] - d[ 0 ] )/(double)( CRV_NSEG*CRV_NSEG ); - -/* If we have made the maximum number of recursive entries into this - function, or if every supplied point was bad or outside the plotting - area, or if most of the segments were very short in graphics space, we will - not be attempting to subdivide any segments which cannot be drawn directly - as a straight line. If "skipbad" was supplied as zero, we ignore the - restriction which says that we must have some good points (since we - may find some good poits by a further sub-division). */ - subdivide = ( Crv_nent < CRV_MXENT && - ( !statics->all_bad || !skipbad ) && - statics->nlong > statics->nshort ); - -/* We do not sub-divide if the bounding box of the supplied points - is not at least 10% smaller than the supplied bouding box on either axis. */ - if( box && bbox[ 0 ] != DBL_MAX ) { - if( bbox[ 1 ] - bbox[ 0 ] > 0.9*( box[ 1 ] - box[ 0 ] ) && - bbox[ 3 ] - bbox[ 2 ] > 0.9*( box[ 3 ] - box[ 2 ] ) ) { - subdivide = 0; - } - } - -/* Initialise some pointers to the data defineding the subsegments. */ - dd = NULL; - xx = NULL; - yy = NULL; - -/* If we may be subdividing any segments, find which segments they are - and set up the offset to each sub-segment. */ - if( subdivide ){ - -/* Initialise the number of segments being subdivided. */ - statics->nseg = 0; - -/* Loop round each segment. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* If the segment cannot be drawn directly as a straight line, we will - subdivide it. */ - if( !seg_ok[ i ] ){ - -/* Increment the number of segments being subdivided, and let the array - of subsegment offsets grow to accomodate it. */ - statics->nseg++; - dd = (double *) astGrow( dd, statics->nseg, sizeof(double)*( CRV_NSEG + 1 ) ); - if( !astOK ) break; - -/* Append the offset to each new subsegment to the "dd" array. */ - statics->el = ( statics->nseg - 1 )*( CRV_NSEG + 1 ); - statics->d0 = d[ i ]; - for( statics->j = 0; statics->j <= CRV_NSEG; statics->j++ ){ - dd[ statics->el++ ] = statics->d0; - statics->d0 += statics->delta; - } - } - } - -/* If any segments needed subdividing, get room to store the graphics - coordinates at each point, and then fill these arrays by calling - Crv_map to map the offsets in "dd" into graphics coordinates. */ - if( statics->nseg > 0 ){ - statics->nel = statics->nseg*( CRV_NSEG + 1 ); - xx = (double *) astMalloc( sizeof(double)*(size_t)statics->nel ); - yy = (double *) astMalloc( sizeof(double)*(size_t)statics->nel ); - Crv_map( statics->nel, dd, xx, yy, method, class, status GLOBALS_NAME ); - } - } - -/* If all has gone OK, we will draw each segment. Initialise pointers - used to walk through the "xx", "yy" and "dd" arrays. */ - if( astOK ){ - px = xx; - py = yy; - pd = dd; - -/* Draw each segment in turn. */ - for( i = 0; i < CRV_NSEG; i++ ){ - -/* If possible, draw it as a single straight line, and then store the - unit vector along the line in the appropriate external variables for - use by the next invocation of this function. */ - if( seg_ok[ i ] ){ - CrvLine( this, x[ i ], y[ i ], x[ i + 1 ], y[ i + 1 ], method, class, status ); - statics->dl = sqrt( dl2[ i ] ); - Crv_ux0 = dx[ i ]/statics->dl; - Crv_uy0 = dy[ i ]/statics->dl; - -/* Otherwise, if we are subdividing, and if the current segment is - not very short, we call this function recursively to draw the segment. - Increment pointers into the "xx", "yy" and "dd" arrays so that they - point to the start of the subsegment information for the next segment - to be subdivided. If all the graphics positions at this level were - bad or outside the plot, tell the next invocation of Crv to do no - further sub-divisions if it too finds all graphics positions to be bad or - outside the plot. */ - } else if( subdivide ) { - -#ifdef CRV_TRACE - statics->levels[ Crv_nent ] = i; -#endif - - Crv( this, pd, px, py, statics->all_bad, bbox, statics, method, - class, status ); - pd += CRV_NSEG + 1; - px += CRV_NSEG + 1; - py += CRV_NSEG + 1; - -/* Otherwise, we assume we have hit a discontinuity in the curve. Store - bad values for the unit vector along the previous sgment, and do not - draw anything. */ - } else { - Crv_ux0 = AST__BAD; - Crv_uy0 = AST__BAD; - } - } - } - -/* Free any memory used to store subsegment information. */ - if( dd ) dd = (double *) astFree( (void *) dd ); - if( xx ) xx = (double *) astFree( (void *) xx ); - if( yy ) yy = (double *) astFree( (void *) yy ); - -/* Decrement the number of recursive entries into this function. */ - Crv_nent--; - -/* Free the memory holding the static data values if we are leaving the - final entry. */ - if( ! pstatics ) statics = astFree( statics ); - -/* Return. */ - return; -} - -static int CvBrk( AstPlot *this, int ibrk, double *brk, double *vbrk, - double *len, int *status ){ -/* -*+ -* Name: -* astCvBrk - -* Purpose: -* Return information about breaks in the last curve drawn by astGridLine, -* astCurve or astGenCurve. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* int CvBrk( AstPlot *this, int ibrk, double *brk, double *vbrk, -* double *len ) - -* Class Membership: -* Plot method. - -* Description: -* Curves drawn by astGridLine, astCurve or astGenCurve may contain breaks -* for several reasons (for instance, it may go outside the plotting area, -* or the mapping between physical and graphics coordinates may be -* discontinuous). This function returns information about such breaks. - -* Parameters: -* this -* Pointer to a Plot. -* ibrk -* The index of the break for which information is required. The first -* break has index 1. An error is reported if no break with the -* required index exists. The exception to this is that zero can be -* supplied, in which case the "brk" and "vbrk" parameters -* are ignored, but all other information is returned. -* brk -* A pointer to an array of 2 elements -* in which to return the X and Y graphics coordinates of the break. -* vbrk -* A pointer to an array of 2 elements -* in which to return the X and Y components of a unit vector in the -* graphics coordinate system. The vector is tangential to the curve -* at the requested break, and points back along the drawn section of -* the curve. -* len -* A pointer to a "double" in which to return the -* length of the drawn curve, in the graphics coordinate system. - -* Returned Value: -* astCvBrk() -* The number of breaks which occurred in the curve. - -* Notes: -* - Currently, this function may not be used to return information -* about curves drawn using astPolyCurve. -* - All curves contain at least two breaks; one at the start and one -* at the end. This is true even if the start and end of the curve are -* coincident. However, if the entire curve was outside the plotting area -* (i.e. if the length of the drawn curve is zero), then it will have no -* breaks. -* - If no curve has yet been drawn by astGridLine or astCurve, then -1 is -* returned for the function value, and the function parameter values are -* left unchanged. -* - The returned information refers to the most recent curve drawn by -* astGridLine or astCurve, even if that curve was drawn by a Plot other than -* the one supplied to this function. -* - NULL pointers may be supplied for "brk", "vbrk" or "len", in which -* case the corresponding values are not returned. -* - Zero is returned by this function if an error has already occurred, -* or if this function should fail for any reason. - -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int ret; /* The number of breaks in the curve. */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Information about the most recent curve drawn by astGridLine or astCurve is - stored in the external structure "Curve_data". Get the number of breaks - in the last curve. This is initialised to -1 in astInitPlot when the - virtual function table for this class is initialised. */ - ret = Curve_data.nbrk; - -/* If a curve has been drawn, store the length of the drawn curve if - required. */ - if( ret != -1 ){ - if( len ) *len = (double) Curve_data.length; - -/* If a legal break index has been supplied, return the position and - direction at the requested break (if required). */ - if( ibrk > 0 && ibrk <= ret ){ - if( brk ){ - brk[ 0 ] = (double) Curve_data.xbrk[ ibrk - 1 ]; - brk[ 1 ] = (double) Curve_data.ybrk[ ibrk - 1 ]; - } - if( vbrk ){ - vbrk[ 0 ] = (double) Curve_data.vxbrk[ ibrk - 1 ]; - vbrk[ 1 ] = (double) Curve_data.vybrk[ ibrk - 1 ]; - } - -/* If an illegal break index has been supplied (other than zero), report - an error, and set the number of breaks to zero. */ - } else if( ibrk ){ - if( ret > 0 ){ - astError( AST__BDBRK, "astCvBrk(%s): The supplied break index " - "(%d) should be in the range [1,%d].", status, astGetClass(this), - ibrk, ret ); - ret = 0; - } else { - astError( AST__BDBRK, "astCvBrk(%s): The most recent curve " - "plotted by method astGridLine or astCurve had no breaks.", status, - astGetClass(this) ); - } - } - } - -/* If an error has occurred, return 0. */ - if( !astOK ) ret = 0; - -/* Return the result. */ - return ret; - -} - -static void CrvLine( AstPlot *this, double xa, double ya, double xb, double yb, - const char *method, const char *class, int *status ){ -/* -* Name: -* CrvLine - -* Purpose: -* Draw a straight line between two points, with clipping. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void CrvLine( AstPlot *this, double xa, double ya, double xb, double yb, -* const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This functions draws a straight line from (xa,ya) to (xb,yb), breaking -* the line at the edges of the plotting area defined by Crv_xlo, Crv_xhi, -* Crv_ylo and Crv_yhi if Crv_clip is non-zero. If the line does not start -* at the end of the previous line plotted by this function, then -* information describing the break in the curve is stored in external -* arrays. - -* Parameters: -* xa -* The graphics X coordinate at the start of the line. -* ya -* The graphics Y coordinate at the start of the line. -* xb -* The graphics X coordinate at the end of the line. -* yb -* The graphics Y coordinate at the end of the line. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* External Variables: -* Crv_ink = int (Read) -* If zero then no line is drawn even if the line intersects the -* plotting space, but break information (etc) is still returned. -* Crv_clip = double (Read) -* Clip lines at boundary of plotting space? -* Crv_xlo = double (Read) -* Lower x limit of the plotting space. -* Crv_xhi = double (Read) -* Upper x limit of the plotting space. -* Crv_ylo = double (Read) -* Lower y limit of the plotting space. -* Crv_yhi = double (Read) -* Upper y limit of the plotting space. -* Crv_tol = double (Read) -* The tolerance for determining if 2 points are coincident. -* Crv_out = int (Read/Write) -* Returned as zero if the line intersects the plotting space. -* Unchanged otherwise. -* Crv_xbrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the graphics X coordinates at which each break -* in the plotted curve occurred. A break is recorded if the starting -* point of the current line is not the same as the end point of -* the previous line. -* Crv_ybrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the graphics Y coordinates at which each break -* in the plotted curve occurred. -* Crv_vxbrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the X component of the unit vector (within the -* graphics coordinate system) parallel to the tangent to the curve -* at each break. The sense is such that the vector always points back -* along the plotted section of the curve. -* Crv_vybrk = float * (Read/Write) -* Pointer to the next available element in an array of AST__PLOT_CRV_MXBRK -* values containing the Y component of the unit vector parallel to -* the tangent to the curve at each break. -* Crv_nbrk = int (Write) -* The number of breaks for which information is returned in Crv_xbrk, -* etc. -* Crv_len = float (Write) -* The length of the section of the curve which has been drawn so far. -* Crv_xl = double (Write) -* The graphics X coordinate at the end of the last line drawn. -* Crv_yl = double (Write) -* The graphics Y coordinate at the end of the last line drawn. -* Crv_vxl = double (Write) -* The X component of the unit vector along the last line drawn. -* Crv_vyl = double (Write) -* The Y component of the unit vector along the last line drawn. -* Grf_alpha = float (Read) -* The factor for scaling graphics X axis values into equal scaled -* X axis values. -* Grf_beta = float (Read) -* The factor for scaling graphics Y axis values into equal scaled -* Y axis values. - -*/ - -/* local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double a1; /* Distance from B to the lower x boundary */ - double a2; /* Distance from B to the upper x boundary */ - double a3; /* Distance from B to the lower y boundary */ - double a4; /* Distance from B to the upper y boundary */ - double aamax; /* Distance from supplied point B to the plotable point A */ - double aamin; /* Distance from supplied point B to the plotable point B */ - double dl; /* Length of plotted line segment */ - double dx; /* Difference in x between supplied points */ - double dy; /* Difference in y between supplied points */ - double t; /* Temporary storage */ - double xam; /* Modified xa position */ - double xbm; /* Modified xb position */ - double yam; /* Modified ya position */ - double ybm; /* Modified yb position */ - int plot; /* True if a line can be plotted */ - -/* Check inherited global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - dl = 0.0; - xam = 0.0; - xbm = 0.0; - yam = 0.0; - ybm = 0.0; - -/* Store the shifts in x and y. */ - dx = xb - xa; - dy = yb - ya; - -/* Do nothing if the line is of zero length. */ - if( dx == 0.0 && dy == 0.0 ) return; - -/* If either end is outside the zone, replace the given coordinates with - the end coordinates of the section of the line which lies within the - zone. */ - if( Crv_clip && ( xa < Crv_xlo || xa > Crv_xhi || - xb < Crv_xlo || xb > Crv_xhi || - ya < Crv_ylo || ya > Crv_yhi || - yb < Crv_ylo || yb > Crv_yhi ) ){ - -/* Find the distance from point B towards point A at which the - line cuts the two x bounds of the zone (distance at point B is - 0.0, and at point A is 1.0). */ - if( dx != 0.0 ){ - a1 = ( xb - Crv_xlo )/dx; - a2 = ( xb - Crv_xhi )/dx; - -/* Ensure that a1 represents the highest plottable offset, and a2 the - lowest. */ - if( a1 < a2 ){ - t = a1; - a1 = a2; - a2 = t; - } - -/* If the line joining A and B is vertical... */ - } else { - -/* If the line is within the plottable x range, indicate that all - offsets are plottable (as far as the x range is concerned at least). */ - if( ( xa > Crv_xlo || astEQUALS( xa, Crv_xlo, 1.0E8 ) ) && - ( xa < Crv_xhi || astEQUALS( xa, Crv_xhi, 1.0E8 ) ) ){ - a1 = DBL_MAX; - a2 = -DBL_MAX; - -/* If the line is ouside the plottable x range, indicate that no - offsets are plottable. */ - } else { - a1 = 0.0; - a2 = 0.0; - } - } - -/* Find the fractional distance from point A to point B at which the - line cuts the two y bounds of the zone. */ - if( dy != 0.0 ){ - a3 = ( yb - Crv_ylo )/dy; - a4 = ( yb - Crv_yhi )/dy; - -/* Ensure that a3 represents the highest plottable offset, and a4 the - lowest. */ - if( a3 < a4 ){ - t = a3; - a3 = a4; - a4 = t; - } - -/* If the line joining A and B is horizontal... */ - } else { - -/* If the line is within the plottable y range, indicate that all - offsets are plottable (as far as the y range is concerned at least). */ - if( ( ya > Crv_ylo || astEQUALS( ya, Crv_ylo, 1.0E8 ) ) && - ( ya < Crv_yhi || astEQUALS( ya, Crv_yhi, 1.0E8 ) ) ){ - a3 = DBL_MAX; - a4 = -DBL_MAX; - -/* If the line is ouside the plottable y range, indicate that no - offsets are plottable. */ - } else { - a3 = 0.0; - a4 = 0.0; - } - } - -/* Find the fractional distances from point A to point B at the ends - of the plotable line. */ - aamin = astMIN( 1.0, astMAX( 0.0, astMAX( a2, a4 ) ) ); - aamax = astMAX( 0.0, astMIN( 1.0, astMIN( a1, a3 ) ) ); - -/* Store the end coordinates of the line joining the plotable points. */ - if( aamax > aamin ){ - xam = xb - aamax*dx; - yam = yb - aamax*dy; - xbm = xb - aamin*dx; - ybm = yb - aamin*dy; - plot = 1; - -/* Get the unit vector along the line and the length of the plotted section. */ - dx *= Grf_alpha; - dy *= Grf_beta; - dl = sqrt( dx*dx + dy*dy ); - dx /= dl; - dy /= dl; - dl *= astMAX( 0.0, aamax - aamin ); - -/* Clear the "plot" flag if the line does not intersect the plotting area. */ - } else { - plot = 0; - } - -/* If both ends of the line are within the plotting zone, draw the whole - line between the supplied end points. */ - } else { - xam = xa; - yam = ya; - xbm = xb; - ybm = yb; - plot = 1; - -/* Get the length of the line and the unit vector along the line. */ - dx *= Grf_alpha; - dy *= Grf_beta; - dl = sqrt( dx*dx + dy*dy ); - dx /= dl; - dy /= dl; - } - -/* If a line is to be plotted... */ - if( plot ){ - -/* If this is the first line to be plotted in the current curve, save - the start of the line as a break, and indicate that some of the curve - falls within the plotting zone. */ - if( Crv_out ){ - Crv_nbrk = 1; - *(Crv_xbrk++) = (float) xam; - *(Crv_ybrk++) = (float) yam; - *(Crv_vxbrk++) = (float) dx; - *(Crv_vybrk++) = (float) dy; - Crv_out = 0; - -/* Set the length of the curve plotted so far to the length of this first - segment. */ - Crv_len = (float) dl; - -/* Start a poly line. */ - if( Crv_ink ) Bpoly( this, (float) xam, (float) yam, status ); - -/* If this is not the first line to be plotted... */ - } else { - -/* ... increment the length of the curve plotted so far. */ - Crv_len += (float) dl; - -/* If the start of this line is not coincident with the end - of the previous line, save the previous and current positions as - breaks in the curve. Note, the previous vector is reversed so that - it points back towards the drawn section of the curve. Report an - error if the arrays are full. */ - if( fabs( xam - Crv_xl ) > Crv_tol || - fabs( yam - Crv_yl ) > Crv_tol ){ - Crv_nbrk += 2; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in plotted " - "curve exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - *(Crv_xbrk++) = (float) xam; - *(Crv_ybrk++) = (float) yam; - *(Crv_vxbrk++) = (float) dx; - *(Crv_vybrk++) = (float) dy; - } - -/* Start a poly line. */ - if( Crv_ink ) Bpoly( this, (float) xam, (float) yam, status ); - } - } - -/* Append a section to the current poly line. */ - if( Crv_ink ) Apoly( this, (float) xbm, (float) ybm, status ); - -/* Save the position and vector at the end of the current line. */ - Crv_xl = xbm; - Crv_yl = ybm; - Crv_vxl = dx; - Crv_vyl = dy; - } - -/* Return. */ - return; -} - - -static void Curve( AstPlot *this, const double start[], - const double finish[], int *status ){ -/* -*++ -* Name: -c astCurve -f AST_CURVE - -* Purpose: -* Draw a geodesic curve. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astCurve( AstPlot *this, const double start[], -c const double finish[] ) -f CALL AST_CURVE( THIS, START, FINISH, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a geodesic curve between two points in the -f This routine draws a geodesic curve between two points in the -* physical coordinate system of a Plot. The curve drawn is the -* path of shortest distance joining the two points (as defined by -c the astDistance function for the current Frame of the Plot). -f the AST_DISTANCE function for the current Frame of the Plot). -* For example, if the current Frame is a basic Frame, then the -* curve joining the two points will be a straight line in physical -* coordinate space. If the current Frame is more specialised and -* describes, for instance, a sky coordinate system, then the -* geodesic curve would be a great circle in physical coordinate -* space passing through the two sky positions given. -* -* Note that the geodesic curve is transformed into graphical -* coordinate space for plotting, so that a straight line in -* physical coordinates may result in a curved line being drawn if -* the Mapping involved is non-linear. Any discontinuities in the -* Mapping between physical and graphical coordinates are -c catered for, as is any clipping established using astClip. -f catered for, as is any clipping established using AST_CLIP. -* -c If you need to draw many geodesic curves end-to-end, then the -c astPolyCurve function is equivalent to repeatedly using -c astCurve, but will usually be more efficient. -f If you need to draw many geodesic curves end-to-end, then the -f AST_POLYCURVE routine is equivalent to repeatedly calling -f AST_CURVE, but will usually be more efficient. -* -c If you need to draw curves which are not geodesics, see astGenCurve -c or astGridLine. -f If you need to draw curves which are not geodesics, see AST_GENCURVE -f or AST_GRIDLINE. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c start -f START( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the first point on the geodesic -* curve. -c finish -f FINISH( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the second point on the geodesic -* curve. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - No curve is drawn if either of the "start" or "finish" arrays -c contains any coordinates with the value AST__BAD. -f - No curve is drawn if either of the START or FINISH arrays -f contains any coordinates with the value AST__BAD. -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astCurve"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Initialise the bounding box for primitives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Draw the curve. The break information is stored in an external structure - where it can be accessed by public methods which return information - about the most recently drawn curve. */ - CurvePlot( this, start, finish, 1, &Curve_data, method, class, status ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Return. */ - return; -} - -static void CurvePlot( AstPlot *this, const double *start, const double *finish, - int ink, AstPlotCurveData *cdata, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* CurvePlot - -* Purpose: -* Draw a geodesic curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void CurvePlot( AstPlot *this, const double *start, const double *finish, -* int ink, AstPlotCurveData *cdata, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a geodesic curve between the supplied starting and -* finishing positions. The algorithm used can handle discontinuities in the -* Mapping between the current Frame and graphics coordinates, and -* information describing any breaks in the curve (including the start and -* end of the curve) are returned in the supplied AstPlotCurveData structure. - -* Parameters: -* this -* Pointer to the Plot. -* start -* A pointer to a an array holding the coordinates of the start of the -* curve within the current Frame of the Plot. -* finish -* A pointer to a an array holding the coordinates of the finish of the -* curve within the current Frame of the Plot. -* ink -* If zero, the curve is not actually drawn, but information about -* the breaks is still returned. If non-zero, the curve is also drawn. -* cdata -* A pointer to a structure in which to return information about the -* breaks in the curve. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - No curve is draw if the "start" or "finish" arrays contains any bad -* values, or if a NULL pointer is supplied for "cdata". No errors are -* reported in these cases. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - int ok; /* Are all start coords good? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Get the number of axes in the current Frame. */ - naxes = astGetNout( this ); - -/* Check the "start" and "finish" parameter for bad values. */ - ok = 1; - for( i = 0; i < naxes; i++ ) { - if( start[ i ] == AST__BAD || finish[ i ] == AST__BAD ){ - ok = 0; - break; - } - } - -/* Check that the "cdata" pointer can be used. */ - if( !cdata ) ok = 0; - -/* Only proceed if the parameters are OK, and there has been no error. */ - if( ok && astOK ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__CURVE_ID, 1, GRF__LINE, method, class ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the externals used to communicate with the Map3 function... - The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map3_ncoord = naxes; - -/* A pointer to the Plot, the Curretn Frame, and and Mapping. */ - Map3_plot = this; - Map3_frame = astGetFrame( this, AST__CURRENT ); - Map3_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* The physical coordinates at the start of the curve. */ - Map3_origin = start; - -/* The physical coordinates at the end of the curve. */ - Map3_end = finish; - -/* The scale factor to convert "dist" values into physical offset values. */ - Map3_scale = astDistance( Map3_frame, start, finish ); - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map3; - Crv_ink = ink; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata->xbrk; - Crv_ybrk = cdata->ybrk; - Crv_vxbrk = cdata->vxbrk; - Crv_vybrk = cdata->vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map3( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map3 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map3. */ - Map3( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - if( cdata ){ - cdata->length = Crv_len; - cdata->out = Crv_out; - cdata->nbrk = Crv_nbrk; - PurgeCdata( cdata, status ); - } - -/* Annul the Frame and Mapping. */ - Map3_frame = astAnnul( Map3_frame ); - Map3_map = astAnnul( Map3_map ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__CURVE_ID, 0, GRF__LINE, method, class ); - - } - -/* Return. */ - return; - -} - - -static AstPointSet *DefGap( AstPlot *this, double *gaps, int *ngood, - double *frac, int *inval, const char *method, - const char *class, int *status ){ -/* -* Name: -* DefGap - -* Purpose: -* Find default gap sizes for the tick marks on the axes of a 2-D -* physical coordinate system. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *DefGap( AstPlot *this, double *gaps, int *ngood, -* double *frac, int *inval, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns default gap sizes for each axis in a 2-D Frame. -* The values are found by first obtaining a grid of points spread over -* the region containing good physical coordinates. The physical -* coordinate values (non-normalized) for each axis are sorted into -* increasing order. -* -* For linearly spaced tick marks, a set of quantile axis values is then -* found, and the median of the gaps between these quantiles is returned -* as the default gap for the axis. -* -* For logarithmically spaced tick marks, the returned gap size is the -* ratio between adjacent tick mark values, chosen to give an optimal -* number of ticks between the maximum and minimum axis values found in -* the grid. - -* Parameters: -* this -* Pointer to a Plot. -* gaps -* Pointer to an array in which to return the default gap value for -* each axis. -* ngood -* Pointer to an array in which toi return the number of good -* values in the returned PointSet for each axis. -* frac -* Pointer to a double in which to return the fraction of the -* plotting area containing good physical coordinates. -* inval -* Pointer to a location at which to return a flag indicating if -* any bad physical coordinates were encountered. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a PointSet holding the physical coordinate values at a -* set of points spread across the plotting area. The values on each -* axis are sorted into increasing order. The values will not have -* been normalized. - -* Notes: -* - The returned PointSet should be annulled when no longer needed. -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - Gap sizes of 1.0, zero good points, and a NULL pointer are returned -* if an error has already occurred, or if this function should fail for -* any reason. - -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* Pointer to PointSet holding graphics coords */ - AstPointSet *pset2; /* Pointer to PointSet holding physical coords */ - double **ptr1; /* Pointer to graphics axis values */ - double **ptr2; /* Pointer to physical axis values */ - double dran; /* Dynamic range */ - double maxv; /* Maximum axis value */ - double minv; /* Minimum axis value */ - double qgap[ MAJTICKS_OPT ];/* Gaps between physical coordinate quantiles */ - int dim; /* Dimension of grid */ - int dk; /* The number of points between quantiles */ - int i; /* The quantile index */ - int j; /* Axis index */ - int k; /* Index into the sorted array of axis values */ - int logticks; /* Logarithmically spaced tick marks? */ - int n; /* Target number fo ticks */ - int psize; /* Total number of axis value */ - -/* Initialise the returned values. */ - gaps[ 0 ] = 1.0; - gaps[ 1 ] = 1.0; - ngood[ 0 ] = 0; - ngood[ 1 ] = 0; - *frac = 0.0; - *inval = 0; - -/* Check global status. */ - if( !astOK ) return NULL; - -/* Get two PointSets, one holding a grid of 2D graphics coordinates, - and one holding the corresponding (non-normalized) physical - coordinates. */ - dim = 0; - *frac = GoodGrid( this, &dim, &pset1, &pset2, method, class, status ); - -/* Get pointers to the data values in each PointSet. */ - ptr1 = astGetPoints( pset1 ); - ptr2 = astGetPoints( pset2 ); - -/* Store the number of elements in each PointSet. */ - psize = astGetNpoint( pset1 ); - -/* For each axis... */ - for( j = 0; j < 2 && astOK; j++ ){ - -/* Sort the axis values into increasing order. Any bad values are stored at - the end of the array on return. */ - qsort( (void *) ptr2[ j ], (size_t) psize, sizeof(double), Compared ); - -/* Count the number of non-bad values returned. */ - ngood[ j ] = CountGood( psize, ptr2[ j ], status ); - -/* Set the returned flag to indicate if any bad values were found. */ - if( ngood[ j ] < psize ) *inval = 1; - -/* Report an error if there are too few good points. */ - if( ngood[ j ] < MAJTICKS_OPT ){ - astError( AST__VSMAL, "%s(%s): The range of coordinate values " - "covered by axis %d is too small to plot.", status, method, - class, j + 1 ); - break; - } - -/* Get the maximum and minimum axis value */ - minv = ptr2[ j ][ 0 ]; - maxv = ptr2[ j ][ ngood[ j ] - 1 ]; - -/* See if ticks on this axis are spaced linearly or logarithmically. If a - value has been set for LogTicks used it, otherwise find a default value. - The default is 0 unless LogPlot is non-zero, the axis range does not - encompass zero and and the dynamic range is 90 or more. Set this - default value explicitly so that later functions will pick it up (it will - be cleared at the end of the astGrid function). */ - if( astTestLogTicks( this, j ) ) { - logticks = astGetLogTicks( this, j ); - } else { - logticks = 0; - if( astGetLogPlot( this, j ) && minv*maxv > 0.0 ) { - dran = maxv/minv; - if( dran >= 90.0 || dran <= 1.0/90.0 ) logticks = 1; - } - astSetLogTicks( this, j, logticks ); - } - -/* If no value has been supplied for LogLabel use the value of LogTicks - as the default. */ - if( !astTestLogLabel( this, j ) ) astSetLogLabel( this, j, logticks ); - -/* For linear gaps, find the gaps between adjacent evenly spaced quantiles. - The number of quantiles used equals the optimal number of major tick - marks. */ - if( !logticks ) { - dk = (int)( (double)ngood[ j ]/MAJTICKS_OPT ); - i = 0; - for( k = dk; k < ngood[ j ] && i < MAJTICKS_OPT; k += dk ){ - qgap[ i++ ] = ptr2[ j ][ k ] - ptr2[ j ][ k - dk ]; - } - -/* Find the median of the gaps between adjacent quantiles. */ - qsort( (void *) qgap, (size_t) i, sizeof(double), Compared ); - gaps[ j ] = qgap[ i/2 ]; - -/* If the test gap size is zero, use a fraction of the total range. Report - an error if the total range is zero. */ - if( gaps[ j ] <= 0.0 ){ - gaps[ j ] = ( ptr2[ j ][ ngood[ j ] - 1 ] - ptr2[ j ][ 0 ] )/MAJTICKS_OPT;; - if( gaps[ j ] <= 0.0 ){ - astError( AST__VSMAL, "%s(%s): The range of coordinate values " - "covered by axis %d is too small to plot.", status, method, - class, j + 1 ); - } - } - -/* For logarithmic gaps, use the Nth root of the ratio of the maximum and - minimum data value found. */ - } else if( astOK ) { - -/* Report an error if the max and min values are of opposite signs or - zero or equal. */ - if( maxv*minv <= 0.0 ) { - astError( AST__ZERAX, "%s(%s): The range of coordinate values " - "covered by axis %d includes the origin and so " - "logarithmic ticks cannot be produced.", status, method, - class, j + 1 ); - - } else if( maxv == minv ) { - astError( AST__VSMAL, "%s(%s): The range of coordinate values " - "covered by axis %d is too small to plot.", status, method, - class, j + 1 ); - -/* Otherwise find the gap to use. */ - } else { - -/* Store the maximum and minimum number of major tick marks along each - axis. These numbers are reduced if only a small part of the plotting - area contains valid coordinates, so that the tick marks do not end up - to close together. */ - n = (int) ( 0.5 + MAJTICKS_OPT*sqrt( *frac ) ); - if( n < 5 ) n = 5; - -/* Choose a gap size which makes this many gaps. */ - gaps[ j ] = pow( maxv/minv, 1.0/( n - 1.0 ) ); - } - } - } - -/* Annul the PointSet holding Graphics coordinates. */ - pset1 = astAnnul( pset1 ); - -/* If an error has occurred, annul the PointSet holding physical - coordinates, and return gaps of 1.0. */ - if( !astOK ) { - pset2 = astAnnul( pset2 ); - gaps[ 0 ] = 1.0; - gaps[ 1 ] = 1.0; - ngood[ 0 ] = 0; - ngood[ 1 ] = 0; - *frac = 0.0; - *inval = 0; - } - -/* Return the physical PointSet. */ - return pset2; - -} - -static void DrawAxis( AstPlot *this, TickInfo **grid, double *labelat, - double *gap, const char *method, const char *class, int *status ){ -/* -* -* Name: -* DrawAxis - -* Purpose: -* Draw a curve joining the major tick marks. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void DrawAxis( AstPlot *this, TickInfo **grid, double *labelat, -* double *gap, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a curve through interior tick marks on both axes. -* The curve is drawn even if it has already been drawn as part of a -* grid of curves, because it may have been assigned different graphics -* attributes to the grid curves. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* labelat -* A pointer to a 2 element array giving the constant axis values at -* which tick marks are put. Element 0 should give the axis 1 value at -* which tick marks for axis 0 are placed. Element 1 should give the -* axis 0 value at which tick marks for axis 1 are placed. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. - -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to current Frame */ - AstPlotCurveData cdata;/* Somewhere to put the unneeded curve information */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - double *value; /* Current tick value */ - double bot; /* Lowest axis value to be displayed */ - double diff; /* Difference between adjacent tick marks */ - double udiff; /* Used section length */ - double start[ 2 ]; /* The start of the curve in physical coordinates */ - double tmp; /* Temporary storage */ - double top; /* Highest axis value to be displayed */ - int axis; /* Current axis index */ - int axisid; /* ID value for current axis plotting attributes */ - int logticks; /* Are major ticks spaced logarithmically? */ - int tick; /* Current tick index */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Not the id value for the first axis. */ - axisid = AST__AXIS1_ID; - -/* Get a pointer to the current Frame. */ - frm = astGetFrame( this, AST__CURRENT ); - -/* Consider drawing a curve parallel to each axis in turn. */ - for( axis = 0; axis < 2; axis++ ){ - -/* Establish the correct graphical attributes for this axis as defined by - attributes with the supplied Plot. */ - astGrfAttrs( this, axisid, 1, GRF__LINE, method, class ); - -/* Check the axis is required. */ - if( astGetDrawAxes( this, axis ) ){ - -/* If the tick marks have been placed round the edges of the plotting - area, we do not need to draw the curves. */ - if( labelat[ axis ] != AST__BAD ){ - -/* Get the max and min values allowed on this axis. */ - bot = astGetBottom( frm, axis ); - top = astGetTop( frm, axis ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along the current axis. */ - info = grid[ axis ]; - -/* Get a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* See if the major tick marks are logarithmically spaced on this axis. */ - logticks = astGetLogTicks( this, axis ); - -/* Initialise the difference between major tick marks. */ - diff = logticks ? 0.0 : gap[ axis ]; - -/* Loop round all ticks. */ - for( tick = 0; tick < info->nmajor; tick++, value++ ){ - -/* Update the difference between major tick marks if we are producing - logarithmically spaced ticks (in which "gap" is a ratio, not a - difference). */ - if( logticks ) diff = (*value)*( gap[ axis ] - 1.0 ); - -/* Note the starting point for this section. */ - start[ axis ] = *value; - start[ 1 - axis ] = labelat[ axis ]; - -/* If this is the first tick, draw an axis section going "backwards" in - case the first tick isn't at the lower visible bound. Limit the length - of this backwards section so that it does not extend beyond the minimum - axis value. */ - if( tick == 0 ) { - udiff = *value - bot; - if( udiff > diff ) udiff = diff; - if( udiff > 0.0 ) { - AxPlot( this, axis, start, -udiff, 1, &cdata, method, - class, status ); - } - } - -/* Limit the length of the section so that it does not extend beyond the - maximum axis value. */ - udiff = ( *value + diff > top ) ? top - *value : diff; - -/* Do not draw zero length sections. */ - if( udiff > 0.0 ) { - -/* Draw a curve parallel to the current axis, starting at the tick mark, - with length equal to the gap between tick marks. Do not draw sections - of the curve which are outside the primary domains of the physical axes. */ - AxPlot( this, axis, start, udiff, 1, &cdata, method, - class, status ); - } - - } - -/* Once the last section has been drawn, draw another axis section in case the - last tick isn't at the upper visible bound. Limit the length of this - section so that it does not extend beyond the maximum axis value. */ - udiff = top - start[ axis ]; - if( udiff > diff ) udiff = diff; - if( udiff > 0.0 ) { - AxPlot( this, axis, start, udiff, 1, &cdata, method, - class, status ); - } - } - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, axisid, 0, GRF__LINE, method, class ); - -/* Set up the id value for the next axis. */ - axisid = AST__AXIS2_ID; - - } - -/* Free the pointer to the current Frame. */ - frm = astAnnul( frm ); - -} - - -static AstPlotCurveData **DrawGrid( AstPlot *this, TickInfo **grid, int drawgrid, - const char *method, const char *class, int *status ){ -/* -* Name: -* DrawGrid - -* Purpose: -* Draw a grid of lines at the major tick mark positions on both axes. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPlotCurveData **DrawGrid( AstPlot *this, TickInfo **grid, int drawgrid, -* const char *method, const char *class ) - -* Class Membership: -* Plot method. - -* Description: -* This function draw a grid of curves at the major tick mark -* positions on both axes, and returns information describing the -* breaks in the curves. If short tick marks are required rather -* than long curves (as specified by the Grid attribute of the supplied -* Plot), then the curves are not drawn but the break information is -* still returned. - -* Parameters: -* this -* Pointer to a Plot. -* grid -* A pointer to an array of two pointers (one for each axis), each -* pointing to a TickInfo structure. These describe the positions -* of the tick marks and should have been produced by function -* GridLines. -* drawgrid -* If non-zero, draw a grid of curves marking the major axis -* values. Otherwise, tick marks will be drawn at these values later. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Returned Value: -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structures (one for each tick -* value). - -* Notes: -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. - -*/ - -/* Local Variables: */ - AstPlotCurveData **cdata;/* The returned pointer */ - AstPlotCurveData *cdt; /* Pointer to break info. for current tick mark */ - AstPlotCurveData tcdt; /* Pointer to break info. for current curve section */ - TickInfo *info; /* Tick mark information for a single axis */ - double start[ 2 ]; /* Strting position for current curve section */ - double total_length; /* Total curve length for all axis ticks */ - int i; /* Axis index */ - int j; /* Tick mark index */ - int k; /* Curve section index */ - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Allocate memory to hold two pointers, each pointing to an array of - AstPlotCurveData structure. */ - cdata = (AstPlotCurveData **) astMalloc( 2*sizeof( AstPlotCurveData *) ); - -/* If succesful, initialise the pointers. */ - if( astOK ){ - cdata[ 0 ] = NULL; - cdata[ 1 ] = NULL; - -/* Draw the curves marking the major tick values on each axis. If no grid is - required, we still do this in order to get information about the breaks - in the curves which will be used later to decide where to put the labels, - but we use "invisible ink". */ - for( i = 0; i < 2; i++ ){ - -/* Get a pointer to the TickInfo structure for this axis holding information - about where to put tick marks on this axis. */ - info = grid[ i ]; - -/* Allocate memory to hold information describing the breaks in each tick - mark curve. This takes the form of an array of AstPlotCurveData structures, - one for each tick mark. */ - cdata[ i ] = (AstPlotCurveData *) astMalloc( sizeof(AstPlotCurveData)* - (size_t) info->nmajor ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Initialise a pointer to the first AstPlotCurveData structure for this axis. */ - cdt = cdata[ i ]; - total_length = 0.0; - -/* Do each tick mark. */ - for( j = 0; j < info->nmajor; j++ ){ - -/* Store the starting point of the first section of the curve. */ - start[ i ] = (info->ticks)[ j ]; - start[ 1 - i ] = (info->start)[ 0 ]; - -/* Draw the first section of the curve parallel to the other axis, starting - at the values in "start", and extending for a length given in the TickInfo - structure. We use invisible ink if short tick marks are required instead - of a grid of curves. */ - AxPlot( this, 1 - i, start, (info->length)[ 0 ], - drawgrid, cdt, method, class, status ); - -/* Now draw any other sections in the curve. */ - for( k = 1; k < info->nsect; k++ ){ - -/* Modify the starting value on the other axis. The starting value on - the current axis remains set to the tick mark value. */ - start[ 1 - i ] = (info->start)[ k ]; - -/* Draw the curve, the information describing the breaks goes into - temporary storage in the local structure "tcdt". */ - AxPlot( this, 1 - i, start, (info->length)[ k ], - drawgrid, &tcdt, method, class, status ); - -/* Concatenate the break information for this section with the break - information describing the previous sections. */ - AddCdt( cdt, &tcdt, method, class, status ); - - } - -/* Increment the total length of curves drawn for all ticks on this axis. */ - total_length += cdt->length; - -/* Point to the AstPlotCurveData structure for the next tick mark. */ - cdt++; - - } - -/* Report an error if the total length of all curves on this axis is zero. - This can be caused for instance by bugs in the algorithm for finding - major tick values (which may cause AST__BAD tick mark values). */ - if( total_length == 0.0 && astOK ) { - astError( AST__INTER, "%s(%s): No grid curves can be drawn for " - "axis %d.", status, method, class, i + 1 ); - } - - } - - } - - } - -/* If an error has occurred, clean up the returned structures. */ - if( !astOK ) cdata = CleanCdata( cdata, status ); - -/* Return. */ - return cdata; - -} - -static int DrawRegion( AstPlot *this, AstFrame *frm, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* DrawRegion - -* Purpose: -* Draw the outline of a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int DrawRegion( AstPlot *this, AstFrame *frm, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* If the current Frame in the supplied Plot is a Region, this function -* draws a curve marking the outline of the Region. It returns without -* action otherwise. - -* Parameters: -* this -* Pointer to the Plot. -* frm -* Pointer to the current Frame in the Plot (possibly a Region). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if and only if a Region outline was drawn. - -*/ - -/* Local Variables: */ - AstMapping *map; /* Mapping with Region masking included */ - AstPlotCurveData cdata; /* Stores information about curve breaks */ - AstRegion **comps; /* List of component Regions */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - int i; /* Loop count */ - int icomp; /* Index of component Region */ - int ncomp; /* Number of component Regions */ - int result; /* The returned value */ - -/* Initialise */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Check the current Frame is a Region, and is of a class that implements - the astRegTrace method. */ - if( astIsARegion( frm ) && - astRegTrace( (AstRegion *) frm, 0, NULL, NULL ) ){ - -/* Set up the externals used to communicate with the Map5 function... - The number of axes in the physical coordinate system (i.e. the - Region). */ - Map5_ncoord = astGetNaxes( frm ); - -/* A pointer to the Plot, the Region, and the Mapping. */ - Map5_plot = this; - Map5_region = (AstRegion *) frm; - -/* Also store a pointer to the Mapping, ensuring that the Mapping does - not contain any masking effects from the Region. */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - Map5_map = astRemoveRegions( map ); - map = astAnnul( map ); - -/* Convert the tolerance from relative to absolute graphics coordinates. - Make the tolerance smaller by a factor of 10 because Regions - (specifically Polygonsd) can have very crinkly edges. */ - tol = 0.1* astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map5; - Crv_ink = 1; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata.xbrk; - Crv_ybrk = cdata.ybrk; - Crv_vxbrk = cdata.vxbrk; - Crv_vybrk = cdata.vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Attempt to split the Region into a set of disjoint component Regions. */ - comps = astRegSplit( (AstRegion *) frm, &ncomp ); - -/* Draw each one. */ - for( icomp = 0; icomp < ncomp; icomp++ ) { - -/* A pointer to the Region. */ - Map5_region = comps[ icomp ]; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map5( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map5 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map5. */ - Map5( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* Annul the component Region pointer. */ - comps[ icomp ] = astAnnul( Map5_region ); - } - -/* Free the memory holding the list of component Region pointers. */ - comps = astFree( comps ); - -/* Annul the Mapping. */ - Map5_map = astAnnul( Map5_map ); - -/* Indicate the outline was drawn. */ - result = 1; - } - -/* Return. */ - return result; -} - -static void DrawText( AstPlot *this, int ink, int esc, const char *text, - float x, float y, const char *just, float upx, - float upy, float *xbn, float *ybn, float *drop, - const char *method, const char *class, int *status ){ -/* -* Name: -* DrawText - -* Purpose: -* Draw a character string, potentially including superscripts and -* subscripts. - -* Synopsis: -* #include "plot.h" -* void DrawText( AstPlot *this, int ink, int esc, const char *text, -* float x, float y, const char *just, float upx, -* float upy, float *xbn, float *ybn, float *drop, -* const char *method, const char *class, int *status ) - -* Description: -* This function displays a character string at a given position -* using a specified up-vector, optionally interpreting any Plot escape -* sequences contained within the text. It also returns its bounding -* box. - -* Parameters: -* this -* The plot. -* ink -* If zero, nothing is drawn but the bounding box is still returned. -* esc -* Should escape sequences be interpreted? They will be printed -* literally otherwise. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The graphics X coordinate of the label's reference point. -* y -* The graphics Y coordinate of the label's reference point. -* just -* Pointer to a null-terminated character string identifying the -* reference point for the text being drawn. The first character in -* this string identifies the reference position in the "up" direction -* and may be "M", "B", "C" or "T" (for bottom, baseline, centre or -* top). The second character identifies the side-to-side reference -* position and may be "L", "C" or "R" (for left, centre or right). The -* string is case-insensitive, and only the first two characters are -* significant. -* upx -* The x component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics x axis increases in the opposite sense. -* upy -* The y component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics y axis increases in the opposite sense. -* xbn -* An array in which is returned the x coordinates at the corners -* of the bounding box. The order is: bottom left, top left, top -* right, bottom right. -* ybn -* An array in which is returned the Y coordinates at the corners -* of the bounding box (see xbn). -* drop -* Address of a float in which to return the distance between the -* bottom of the bounding box and the baseline of normal text. May -* be NULL. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The "B" option for the justification in the "up" direction refers -* to the base-line on which the text is written. Some characters -* ("y", "p", "g", etc) descend below this line. In addition, if the -* supplied text string includes any escape sequences which produce -* sub-scripts, then these will also descend below the base-line. To -* justify the bottom of the entire string (instead of just the -* base-line), specify "M" instead of "B" in the justification string. -* - See function astFindEscape for details of the supported escape -* sequences. -*/ - - -/* Local Variables: */ - astDECLARE_GLOBALS - char *a; - char *lt; - char cc; - const char *lj; - double ncol; - double nfont; - double nsize; - double nstyle; - double nwidth; - float alpha_hi; - float alpha_lo; - float beta_lo; - float beta_hi; - float cy; - float cx; - float dy; - float dx; - float height; - float hmx; - float hmy; - float ly; - float lx; - float rx; - float rlen; - float rise; - float rxu; - float ryu; - float ry; - float tdrop; - float tybn[ 4 ]; - float txbn[ 4 ]; - float ulen; - float uyu; - float uxu; - float uy; - float ux; - float width; - float x0; - float y0; - int estype; - int esval; - int got_esc; - int grfcap; - int i; - int nc; - -/* Check the global error status, and that we have something to plot, and - the reference position is good, and that the up vector is not zero. */ - if ( !astOK || !text || !text[ 0 ] || x == AST__BAD || y == AST__BAD || - ( upx == 0.0 && upy == 0.0 ) ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Initialise variables to avoid compiler warnings. */ - rx = 0.0f; - ry = 0.0f; - x0 = 0.0f; - y0 = 0.0f; - -/* Get an up vector which refers to the graphics coordinates in their correct - senses (the supplied values are reversed if the corresponding axis is - reversed). */ - ux = ( this->xrev ) ? -upx : upx; - uy = ( this->yrev ) ? -upy : upy; - -/* Find a vector which points from left to right along the text - baseline, taking account of any difference in the scales of the x - and y axes (is possible). This also scales the up vector so that it - has a length equal to the height of normal text, and scales the right - vector to have the same length (on the screen) as the up vector. */ - RightVector( this, &ux, &uy, &rx, &ry, method, class, status ); - -/* Create a unit right vector. */ - rlen = sqrt( rx*rx + ry*ry ); - rxu = rx/rlen; - ryu = ry/rlen; - -/* Create a unit up vector. */ - ulen = sqrt( ux*ux + uy*uy ); - uxu = ux/ulen; - uyu = uy/ulen; - -/* Some older GRF modules cannot plot strings with vertical justification - of "M". Check the capabilities of the grf module, and, if necessary, - modify the justification and the coords of the reference point to use - "B" instead of "M". This call also returns us the coords at the left - end of the baseline of normal text. */ - lx = x; - ly = y; - lj = JustMB( this, esc, text, &lx, &ly, upx, upy, just, uxu, uyu, rxu, - ryu, &x0, &y0, method, class, status ); - -/* Initialise the horizontal and verical limits of the total bounding box. */ - alpha_lo = FLT_MAX; - alpha_hi = -FLT_MAX; - beta_lo = FLT_MAX; - beta_hi = -FLT_MAX; - -/* Tell the grf module whether or not to interpret escape sequences,and - also note if the grf module is capable of interpreting escape - sequences. */ - grfcap = GCap( this, GRF__ESC, esc, status ); - -/* Forget the horizontal position remembered by any "%h+" escape sequences - from any previous string. */ - this->hmarkx = FLT_MAX; - this->hmarky = FLT_MAX; - -/* If escape sequences are being interpreted and the string contains some - escape sequences, but the grf module cannot interpret escape sequences, - split the supplied text up into sub-strings delimited by escape sequences - and plot each sub-string individually, modifying the reference point and - graphics attributes as indicated by the escape sequences. */ - if( esc && HasEscapes( text, status ) && !grfcap ) { - -/* Take a copy of the supplied text so that we can temporarily terminate - each sub-string by poking a null (0) character into it. */ - lt = (char *) astStore( NULL, (void *) text, strlen( text ) + 1 ); - -/* Indicate that the current baseline is at its normal height. */ - rise = 0.0; - -/* Get the graphical attribute values for normal text. */ - GAttr( this, GRF__SIZE, AST__BAD, &nsize, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, AST__BAD, &nwidth, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, AST__BAD, &nfont, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, AST__BAD, &nstyle, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, AST__BAD, &ncol, GRF__TEXT, method, class, status ); - -/* The "concatenation point" (cx,cy) is the point where the normal baseline - crosses the left hand edge of the substring bounding box. Initialise - this to the left edge of the first substring. */ - cx = x0; - cy = y0; - -/* Loop round the whole string, drawing each sub-string. */ - a = lt; - while( *a && astOK ) { - -/* Examine the start of the remaining string and note if it begins with - an escape sequence. If so, the type and value of the escape sequnece - is returned. In either case the number of characters to the next - delimiter is returned. */ - got_esc = astFindEscape( a, &estype, &esval, &nc ); - -/* If the string starts with an escaped percent sign, modify things so that - we can draw the percent sign with the normal text drawing code below. */ - if( got_esc && estype == GRF__ESPER ) { - got_esc = 0; - a++; - nc = 1; - } - -/* If the string starts with any other escape sequence, modify the graphics - attributes and concatenation point as required by the escape sequence. */ - if( got_esc ) { - InterpEscape( this, estype, (double) esval, &cx, &cy, ux, uy, - rx, ry, lj, &rise, nsize, nstyle, nwidth, ncol, - nfont, method, class, status ); - -/* If the remaining string starts with normal text, draw it. */ - } else { - -/* Temporarily terminate the sub-string which ends with the next escape - sequence. */ - cc = a[ nc ]; - a[ nc ] = 0; - -/* We now have to decide on the reference point for this sub-string. If - the justification is "BL" then the reference point is just the current - concatenation point. */ - if( lj[ 0 ] == 'B' && lj[ 1 ] == 'L' ) { - lx = cx; - ly = cy; - -/* Otherwise, the reference point is offset from the concatenation point. - It would be simpler to draw all substrings with "BL" justification but - this causes problems with some grf modules (such as GAIA) which zoom - the display by modifying the position of text strings without also - modifying the size of text strings. Using the correct reference point - for all sub-strings minimises the drift which occurs when such a grf - modules zooms the display. */ - } else { - -/* Find the width and height of this substring, and the distance between the - bottom of the bounding box and the baseline (the drop). We do this - by calling this function recursively, using "BL" justification to - avoid infinite recursion. */ - -/* Forget the horizontal position remembered by any "%h+" escape sequences - from any previous string. Save and re-instate the position of the - horizontal mark since the call to DrawText may change it. */ - hmx = this->hmarkx; - hmy = this->hmarky; - - DrawText( this, 0, esc, a, cx, cy, "BL", upx, upy, txbn, tybn, - &tdrop, method, class, status ); - - this->hmarkx = hmx; - this->hmarky = hmy; - - dx = txbn[ 0 ] - txbn[ 3 ]; - dy = tybn[ 0 ] - tybn[ 3 ]; - width = sqrt( dx*dx + dy*dy ); - - dx = txbn[ 0 ] - txbn[ 1 ]; - dy = tybn[ 0 ] - tybn[ 1 ]; - height = sqrt( dx*dx + dy*dy ); - -/* First move right from the concatenation point by a fraction of the width - of the substring (0.5 for "C" and 1.0 for "R"). */ - if( lj[ 1 ] == 'C' ) { - width *= 0.5; - } else if( lj[ 1 ] != 'R' ) { - width = 0; - } - lx = cx + rxu*width; - ly = cy + ryu*width; - -/* Now move vertically by an amount which produes the requested vertical - justification. */ - if( lj[ 0 ] == 'T' ) { - height -= tdrop; - lx += height*uxu; - ly += height*uyu; - - } else if( lj[ 0 ] == 'C' ) { - height = 0.5*height - tdrop; - lx += height*uxu; - ly += height*uyu; - - } else if( lj[ 0 ] == 'M' ) { - lx -= tdrop*uxu; - ly -= tdrop*uyu; - } - } - -/* Draw it, and then find its real bounding box (i.e. using the correct - reference position found above). */ - if( ink ) GText( this, a, lx, ly, lj, upx, upy, method, class, status ); - GTxExt( this, a, lx, ly, lj, upx, upy, txbn, tybn, method, class, status ); - -/* Re-instate the orignal value of the terminator character.*/ - a[ nc ] = cc; - -/* Move the concatenation point to the right (i.e. in the direction of the text - baseline) by an amount equal to the width of the bounding box. Also - update the total bounding box limits.*/ - UpdateConcat( txbn, tybn, ux, uy, rx, ry, &cx, &cy, - x0, y0, &alpha_lo, &alpha_hi, &beta_lo, &beta_hi, status ); - } - -/* Move on to the next character. */ - a += nc; - } - -/* Free resources. */ - lt = astFree( lt ); - -/* Reset all attributes to their normal values. */ - GAttr( this, GRF__SIZE, nsize, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, nwidth, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, ncol, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, nfont, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, nstyle, NULL, GRF__TEXT, method, class, status ); - -/* If any escape sequences can be interpreted by the grf module, just pass - the text string on to the grf module. */ - } else { - if( ink ) GText( this, text, lx, ly, lj, upx, upy, method, class, status ); - GTxExt( this, text, lx, ly, lj, upx, upy, txbn, tybn, method, class, status ); - -/* The corners in the bounding box returned by GTxExt are in no - particular order. But this function is contracted to return them - in a specified order. So we use UpdateConcat to find the verical and - horizontal limits of the box in a form which can be used to produce - the correct order. UpdateConcat will also update the concatenation point, - but that is irrelevant in this context. */ - UpdateConcat( txbn, tybn, ux, uy, rx, ry, &lx, &ly, x0, y0, &alpha_lo, - &alpha_hi, &beta_lo, &beta_hi, status ); - } - -/* Return the total bounding box,in the order bottom left, topleft, top - right, bottom right. */ - xbn[ 0 ] = x0 + alpha_lo*ux + beta_lo*rx; - ybn[ 0 ] = y0 + alpha_lo*uy + beta_lo*ry; - - xbn[ 1 ] = x0 + alpha_hi*ux + beta_lo*rx; - ybn[ 1 ] = y0 + alpha_hi*uy + beta_lo*ry; - - xbn[ 2 ] = x0 + alpha_hi*ux + beta_hi*rx; - ybn[ 2 ] = y0 + alpha_hi*uy + beta_hi*ry; - - xbn[ 3 ] = x0 + alpha_lo*ux + beta_hi*rx; - ybn[ 3 ] = y0 + alpha_lo*uy + beta_hi*ry; - -/* Return the drop. */ - if( drop ) *drop = -alpha_lo*ulen; - -/* Free memory.*/ - lj = astFree( (void *) lj ); - -/* If OK, update the box containing all drawn graphics primitives. */ - if( ink && astOK && !Boxp_freeze ) { - for( i = 0; i < 4; i++ ){ - Boxp_lbnd[ 0 ] = astMIN( xbn[ i ], Boxp_lbnd[ 0 ] ); - Boxp_ubnd[ 0 ] = astMAX( xbn[ i ], Boxp_ubnd[ 0 ] ); - Boxp_lbnd[ 1 ] = astMIN( ybn[ i ], Boxp_lbnd[ 1 ] ); - Boxp_ubnd[ 1 ] = astMAX( ybn[ i ], Boxp_ubnd[ 1 ] ); - } - } -} - -static void DrawTicks( AstPlot *this, TickInfo **grid, int drawgrid, - double *labelat, double *gap, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* DrawTicks - -* Purpose: -* Draw tick marks for a 2-D annotated coordinate grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void DrawTicks( AstPlot *this, TickInfo **grid, int drawgrid, -* double *labelat, double *gap, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws major and minor tick marks. It uses a different -* technique depending on whether the tick marks are to be put along the -* edges of the plotting area, or along a curve through the middle of the -* plotting area. The physical axis values at which to put tick marks -* are supplied in parameter "grid". -* -* If the ticks are placed on the edges of the plotting area, The -* EdgeCrossings function is used to find all points along the edge which -* have a physical axis value correspoinding to a tick value (there can in -* general be more than one point on an edge with a given physical axis -* value). Ticks are put at all such crossings. -* -* If ticks are placed within the plotting area, then they are put -* along a curve defined by the "other axis" values supplied in -* parameter "labelat". - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* drawgrid -* If non-zero, then a grid of curves has been drawn to mark the -* major axis values. -* labelat -* A pointer to a 2 element array in holding the constant axis -* values at which tick marks are to be put. Element 0 should hold -* the axis 1 value at which tick marks for axis 0 are placed. Element -* 1 should hold the axis 0 value at which tick marks for axis -* 1 are placed. If ticks are to be placed round the edges of the -* plotting zone instead of within the plotting zone, then values of -* AST__BAD should be supplied. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. This will be the difference between, -* or the ratio of, adjacent tick mark values, depending on the -* setting of the LogTicks attribute. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to current Frame in Plot */ - AstMapping *mapping; /* Pointer to graphics->physical Mapping */ - AstPointSet *pset1; /* Pointer to PointSet holding physical coords. */ - AstPointSet *pset2; /* Pointer to PointSet holding graphics coords. */ - AstPointSet *pset3; /* Pointer to PointSet holding clipped graphics coords. */ - EdgeCrossingsStatics *ecstatics = NULL; /* For static data structure */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - double *ptr1[2]; /* Pointer to physical data */ - double **ptr2; /* Pointer to graphics data */ - double **ptr3; /* Pointer to clipped graphics data */ - double *a; /* Pointer to next current axis value */ - double *b; /* Pointer to next other axis value */ - double *value; /* Current tick value */ - double *x; /* Pointer to next X value */ - double *xc; /* Pointer to next clipped X value */ - double *y; /* Pointer to next Y value */ - double *yc; /* Pointer to next clipped Y value */ - double a0; /* Physical axis value at base of tick */ - double axmax; /* Upper axis limit */ - double axmin; /* Lower axis limit */ - double delta1; /* Increment between minor ticks above major tick */ - double delta2; /* Increment between minor ticks below major tick */ - double diff; /* Difference between adjacent major ticks */ - double dl2; /* Squared increment between points */ - double dl2_limit; /* Minimum usable squared increment between points */ - double dl; /* Increment between points */ - double dx; /* X component of increment along tick mark */ - double dy; /* Y component of increment along tick mark */ - double ex; /* X component of increment between points */ - double ey; /* Y component of increment between points */ - double lblat2; /* Other axis value part way up each tick */ - double lblat; /* Other axis value at base of each tick */ - double mindim; /* Shortest dimension of plotting area */ - double minval; /* Current axis value at next minor tick */ - double mjsign; /* Sign of the major tick mark length */ - double mjtklen; /* Length of major tick marks */ - double mnsign; /* Sign of the minor tick mark length */ - double mntklen; /* Length of minor tick marks */ - double ux; /* X component of unit vector along tick mark */ - double uy; /* Y component of unit vector along tick mark */ - double val; /* Major axis value */ - double x0; /* X at base of tick */ - double x1; /* X at end of tick */ - double x2; /* Clipped X at base of tick */ - double y0; /* Y at base of tick */ - double y1; /* Y at end of tick */ - double y2; /* Clipped Y at base of tick */ - int *majflag; /* Pointer to next major/minor flag */ - int *majflags; /* Pointer to aray of major/minor flags */ - int axis; /* Current axis index */ - int ed; /* Doing a secondary edge? */ - int edge; /* Index of edge being ticked */ - int first; /* Is this the first tick to be drawn? */ - int gelid; /* ID for next graphical element to be drawn */ - int i; /* Minor tick mark index */ - int logticks; /* Are major tick marks logarithmically spaced? */ - int minhi; /* Highest minor tick mark index */ - int minlo; /* Lowest minor tick mark index */ - int nedge; /* No. of edges to be ticked for each axis */ - int nel; /* Actual number of tick marks to draw */ - int ntot; /* Maximum number of tick marks */ - int tick; /* Tick index */ - int lasttick; /* Index of last major tick mark */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - a = NULL; - delta1 = 0.0; - delta2 = 0.0; - lblat2 = 0.0; - uy = 0.0; - logticks = 0; - -/* Get the minimum dimension of the plotting ares. */ - mindim = astMIN( this->xhi - this->xlo, this->yhi - this->ylo ); - -/* Information about the drawn tick marks is saved in the Plot structure. - Reset this information now so that we are ready to store information - about the new ticks that will be drawn by this function invocation. */ - SaveTick( this, -1, 0.0, 0.0, 0, status ); - -/* If ticks are to be put round the edges of the plotting area... */ -/* ============================================================== */ - if( labelat[ 0 ] == AST__BAD || labelat[ 1 ] == AST__BAD ){ - -/* Store the number of edges to be ticked for each axis. */ - nedge = astGetTickAll( this )? 2 : 1; - -/* Do each required edge. */ - for( ed = 0; ed < nedge; ed++ ){ - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__TICKS1_ID; - -/* Do each axis. */ - for( axis = 0; axis < 2; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__LINE, method, class ); - -/* Store the length in graphics coordinates of major tick marks for this - axis. Use a default of zero if a grid has been drawn. */ - if( astTestMajTickLen( this, axis ) || !drawgrid ){ - mjtklen = astGetMajTickLen( this, axis )*mindim; - } else { - mjtklen = 0.0; - } - -/* Store the length in graphics coordinates of minor tick marks. */ - mntklen = astGetMinTickLen( this, axis )*mindim; - -/* Get the edge to be labelled with the axis values. Edge 0 is the left hand - edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 is - the bottom edge. */ - edge = ( astGetEdge( this, axis ) + ed*2 ) % 4; - if( edge < 0 ) edge = -edge; - -/* Store a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Store a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* Minor tick marks are drawn on both sides of each major tick mark. They - are identified by an index number relative to major tick mark at zero. - Store the indices of the first and last minor tick marks. */ - minlo = ( 1 - info->nminor )/2; - minhi = info->nminor/2; - -/* If major ticks are linear, store the difference between minor tick marks. - This value will be the same for all major ticks. */ - logticks = astGetLogTicks( this, axis ); - if( !logticks ) { - delta1 = gap[ axis ]/(double)info->nminor; - delta2 = delta1; - } - -/* Loop round until all ticks have been done. */ - for( tick = 0; tick < info->nmajor; tick++ ){ - -/* Draw tick marks at all occurrences of the current major tick value on - the selected edge of the plotting area. */ - Ticker( this, edge, axis, *value, gap, mjtklen, - 1, ( ed == 0 ), &ecstatics, method, class, status ); - -/* If minor tick mark values were not supplied, calculate them as even - intervals between the major tick values. */ - if( !info->minticks ) { - -/* If major ticks are logarithmic, store the difference between minor tick - marks. This value will be different for each major tick. Also, since - the minor ticks are drawn on either side of the major tick, the minor - tick spacing above the major tick will be different to that below the - minor tick when using logarathmic ticks. "delta1" is the minor gap - above the major value, and "delta2" is the minor gap below the major - value. */ - if( logticks ) { - delta1 = (*value) * ( gap[ axis ] - 1.0 )/ - (double)info->nminor; - delta2 = delta1 / gap[ axis ]; - } - -/* Extra minor tick marks are drawn below the first major tick mark and - above the last major tick mark to fill in any gaps caused by axis - limits being exceeded. */ - if( tick == 0 ) { - minlo = 1 - info->nminor; - } if( tick == 1 ) { - minlo = ( 1 - info->nminor )/2; - } else if( tick == info->nmajor - 1 ) { - minhi = info->nminor - 1; - } - -/* Store the axis value at the first minor tick mark. */ - minval = *value + minlo*delta2; - -/* Loop round all the minor tick marks, storing the physical coordinates - defining the tick mark. */ - for( i = minlo; i <= minhi; i++ ){ - -/* Draw tick marks at all occurrences of the current minor tick value on - the selected edge of the plotting area. Do not do the minor tick mark - with index zero, since this corresponds to the position of the major - tick mark. */ - if( i ) Ticker( this, edge, axis, minval, gap, mntklen, - 0, ( ed == 0 ), &ecstatics, method, class, status ); - -/* Get the axis value at the next minor tick mark. */ - minval += ( i < 0 ) ? delta2 : delta1; - } - } - -/* Point to the next major tick value. */ - value++; - - } - -/* If minor tick mark values have been supplied, used them. */ - if( info->minticks ) { - value = info->minticks; - for( tick = 0; tick < info->nminor; tick++, value++ ){ - Ticker( this, edge, axis, *value, gap, mntklen, 0, - ( ed == 0 ), &ecstatics, method, class, status ); - } - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__LINE, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__TICKS2_ID; - } - } - -/* Free the static resources allocated within EdgeCrossings (called - by Ticker). */ - (void) EdgeCrossings( NULL, 0, 0, 0.0, NULL, NULL, &ecstatics, method, - class, status ); - -/* If ticks are to put within the interior of the plotting area... */ -/* ============================================================== */ - } else { - -/* Get the mapping from base Frame (graphics coords) to current Frame - (physical coords). */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get the current Frame from the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__TICKS1_ID; - -/* Do each axis. */ - for( axis = 0; axis < 2; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__LINE, method, class ); - -/* Store the length in graphics coordinates of major tick marks for this - axis. Use a default of zero if a grid has been drawn. */ - if( astTestMajTickLen( this, axis ) || !drawgrid ){ - mjtklen = astGetMajTickLen( this, axis )*mindim; - } else { - mjtklen = 0.0; - } - -/* Store the length in graphics coordinates of minor tick marks. */ - mntklen = astGetMinTickLen( this, axis )*mindim; - -/* Indicate that the tick mark lengths should not be negatated. */ - mjsign = 1.0; - mnsign = 1.0; - -/* Store the smallest squared distance in graphics coordinates which - can reliably be used to determine the direction of a tick mark. */ - dl2_limit = 0.0001*mindim; - dl2_limit *= dl2_limit; - -/* Store a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Store a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* Get the maximum number of tick marks to be drawn on this axis. */ - ntot = 0; - ntot = info->nmajor; - if( info->minticks ) { - ntot += info->nmajor + info->nminor; - } else { - ntot += ( info->nmajor + 1 )*( info->nminor - 1 ); - } - -/* Pass on to the next axis if no ticks are to be drawn. */ - if( ntot ) { - -/* Allocate memory to hold the physical coordinates defining all the - required tick marks. Each tick mark is defined by 2 points. */ - ptr1[ 0 ] = (double *) astMalloc( sizeof(double)*(size_t)(2*ntot) ); - ptr1[ 1 ] = (double *) astMalloc( sizeof(double)*(size_t)(2*ntot) ); - -/* Allocate memory to hold a set of flags indicating whether each tick - mark is minor or major. */ - majflags = (int *) astMalloc( sizeof(int)*(size_t)ntot ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* If the tick values have been supplied using astSetTickValues, just - copy them into the above arrays. */ - if( info->minticks ) { - - a = ptr1[ axis ]; - b = ptr1[ 1 - axis ]; - majflag = majflags; - - for( tick = 0; tick <= info->nmajor; tick++ ){ - - val = info->ticks[ tick ]; - if( logticks ) { - diff = val * ( gap[ axis ] - 1.0 ); - lblat2 = labelat[ axis ] + 0.2*diff; - } else { - lblat2 = labelat[ axis ] + 0.2*gap[ 1 - axis ]; - } - - *(a++) = val; - *(b++) = labelat[ axis ]; - *(a++) = val; - *(b++) = lblat2; - *(majflag++) = 1; - } - - for( tick = 0; tick <= info->nminor; tick++ ){ - - val = info->minticks[ tick ]; - if( logticks ) { - diff = val * ( gap[ axis ] - 1.0 ); - lblat2 = labelat[ axis ] + 0.2*diff; - } else { - lblat2 = labelat[ axis ] + 0.2*gap[ 1 - axis ]; - } - - *(a++) = val; - *(b++) = labelat[ axis ]; - *(a++) = val; - *(b++) = lblat2; - *(majflag++) = 0; - } - -/* If the tick values were not supplied using astSetTickValues, then we - need to calculate the minor tick positions explicitly. */ - } else { - -/* Store pointers to the next point on each axis. "a" always refers to the - current axis. Also store the value on the other axis at which the tick - marks starts, and another value on the other axis which is used to - defined the tick mark directions. */ - a = ptr1[ axis ]; - b = ptr1[ 1 - axis ]; - majflag = majflags; - lblat = labelat[ axis ]; - -/* Store another value on the other axis which is used to defined the tick - mark directions, and the difference between minor tick marks. For - linearly spaced tick marks these values will be the same for all major - ticks. Minor ticks are always drawn above the correponding major - value (i.e. minlo == 1 ) and so we do not need to set delta2. */ - logticks = astGetLogTicks( this, axis ); - if( !logticks ) { - lblat2 = labelat[ axis ] + 0.2*gap[ 1 - axis ]; - delta1 = gap[ axis ]/(double)info->nminor; - } - -/* Store the indices of the first and last minor tick marks, relative to - a major tick mark. */ - minlo = 1; - minhi = info->nminor - 1; - -/* Get the axis limits. */ - axmin = astGetBottom( frame, axis ); - axmax = astGetTop( frame, axis ); - -/* Loop round until all ticks have been done. We include a hypothetical tick - at index -1 (i.e. one gap below the first listed tick value) in order - to get minor tick marks below the first major tick. But the - hypothetical major tick value is not included in the list of major tick - values to draw. */ - lasttick = info->nmajor - 1; - for( tick = -1; tick <= lasttick; tick++ ){ - -/* Get the major tick value. */ - if( tick == -1 ) { - if( !logticks ) { - val = (*value) - gap[ axis ]; - }else { - val = (*value)/gap[ axis ]; - } - } else { - val = *(value++); - } - -/* Now find the value on the other axis which is used to defined the tick - mark directions, and the difference between minor tick marks, in the - case of logarithmically spaced tick marks. These values will be - different for every major tick. Minor ticks are always drawn above the - correponding major value (i.e. minlo == 1 ) and so we do not need to set - delta2. */ - if( logticks ) { - diff = val * ( gap[ axis ] - 1.0 ); - lblat2 = labelat[ axis ] + 0.2*diff; - delta1 = diff / (double)info->nminor; - } - -/* If major tick marks are required, store the physical coordinates at the - start of the major tick mark, and at a point a little way up the major - tick mark. */ - if( tick > -1 ){ - *(a++) = val; - *(b++) = lblat; - *(a++) = val; - *(b++) = lblat2; - *(majflag++) = 1; - } - -/* Store the points defining the minor tick marks on either side of - this major tick mark. First store the axis value at the first minor - tick mark. */ - minval = val + minlo*delta1; - -/* Loop round all the minor tick marks, storing the physical coordinates - defining the tick mark. */ - for( i = minlo; i <= minhi; i++ ){ - -/* Do not do the minor tick mark with index zero, since this corresponds - to the position of the major tick mark. Do not do any minor ticks that - are outside the axis range. */ - if( i && minval >= axmin && minval <= axmax ){ - *(a++) = minval; - *(b++) = lblat; - *(a++) = minval; - *(b++) = lblat2; - *(majflag++) = 0; - } - -/* Get the axis value at the next minor tick mark. */ - minval += delta1; - } - } - } - } - -/* Adjust the size of the arrays to exclude any unused space. */ - nel = a - ptr1[axis]; - ptr1[axis] = (double *) astRealloc( (void *) ptr1[axis], - sizeof(double)*nel ); - ptr1[1-axis] = (double *) astRealloc( (void *) ptr1[1-axis], - sizeof(double)*nel ); - -/* Create a pointset holding these coordinates. */ - pset1 = astPointSet( nel, 2, "", status ); - astSetPoints( pset1, ptr1 ); - -/* Transform these physical coordinates into graphics coordinates, without - doing any clipping (this is so that tick marks are still drawn even if - they extend into the area containing clipped physical coordinates). */ - pset2 = astTransform( mapping, pset1, 0, NULL ); - ptr2 = astGetPoints( pset2 ); - -/* Transform them again this time with clipping. */ - pset3 = Trans( this, NULL, mapping, pset1, 0, NULL, 0, method, class, status ); - ptr3 = astGetPoints( pset3 ); - -/* Check the pointers can be used.*/ - if( astOK ){ - -/* Store pointers to the next point on each axis. */ - a = ptr1[ axis ]; - - x = ptr2[ 0 ]; - y = ptr2[ 1 ]; - - xc = ptr3[ 0 ]; - yc = ptr3[ 1 ]; - - majflag = majflags; - -/* Loop round all ticks (major and minor). */ - ux = AST__BAD; - first = 1; - for( tick = 0; tick < nel/2; tick++ ){ - -/* Store the physical axis value at the base of the tick mark (skip over - the physical axis value at the point up the tick mark). */ - a0 = *(a++); - a++; - -/* Store the x and y coordinates at the base of the tick mark. */ - x0 = *(x++); - y0 = *(y++); - -/* Store the x and y coordinates at a point up the tick mark. */ - x1 = *(x++); - y1 = *(y++); - -/* Store the clipped x and y coordinates at the base of the tick mark. */ - x2 = *(xc++); - y2 = *(yc++); - -/* Skip over the clipped x and y coordinates at the point up the tick mark. */ - xc++; - yc++; - -/* Check they are all valid, and that the start of the tick mark is within - the plotting area. */ - if( x0 != AST__BAD && y0 != AST__BAD && - x1 != AST__BAD && y1 != AST__BAD && - x2 != AST__BAD && y2 != AST__BAD && - x0 <= this->xhi && x0 >= this->xlo && - y0 <= this->yhi && y0 >= this->ylo ){ - -/* Get the increments in X and Y beyween the two points, and the squared - distance between the two points. */ - dx = x1 - x0; - dy = y1 - y0; - dl2 = dx*dx + dy*dy; - -/* Check the two points are not co-incident. */ - if( dl2 > dl2_limit ){ - -/* Store the distance between the two points. */ - dl = sqrt( dl2 ); - -/* If this is the first tick to be drawn on this axis, decide which - direction to draw the tick mark so that they will appear on the right - hand side of the axis as seen by someone moving along the axis in the - positive direction (the numerical labels are also drawn on the same - side). */ - if( first ){ - first = 0; - -/* If the next tick mark is not defined, make an arbitrary decision by - leaving the sign of the tick mark length unchanged. */ - if( tick + 1 < nel/2 && - *x != AST__BAD && *y != AST__BAD && - a0 != AST__BAD && *a != AST__BAD ){ - -/* Form the vector joining this tick mark to the next. */ - ex = *x - x0; - ey = *y - y0; - -/* Ensure this vector is in the positive direction of the axis. */ - if( *a < a0 ) { - ex = -ex; - ey = -ey; - } - -/* If a positive tick mark length would put the marks on the wrong side, - negate the tick mark length. */ - if( ex*dy > ey*dx ){ - mjsign = -1.0; - mnsign = -1.0; - } - } - } - -/* Store the unit vector in the direction of the tick mark. This is used - as the default vector for the next tick mark if the direction of the - next tick mark is indeterminate. */ - ux = dx/dl; - uy = dy/dl; - } - -/* Only draw this tickmark if its direction is known. */ - if( ux != AST__BAD ) { - -/* Get the position of the end of the tick mark. The length of the tick - mark depends on whether it is a major or minor tick mark. */ - if( *majflag ){ - x1 = x0 + mjsign*mjtklen*ux; - y1 = y0 + mjsign*mjtklen*uy; - } else { - x1 = x0 + mnsign*mntklen*ux; - y1 = y0 + mnsign*mntklen*uy; - } - -/* Save and draw the tick mark. */ - SaveTick( this, axis, x0, y0, *majflag, status ); - if( x0 != x1 || y0 != y1 ) { - Bpoly( this, (float) x0, (float) y0, status ); - Apoly( this, (float) x1, (float) y1, status ); - Opoly( this, status ); - } - } - } - -/* Point to the next major/minor flag. */ - majflag++; - } - } - -/* Free the memory holding the physical coordinates. */ - ptr1[ 0 ] = (double *) astFree( ( void *) ptr1[ 0 ] ); - ptr1[ 1 ] = (double *) astFree( ( void *) ptr1[ 1 ] ); - majflags = (int *) astFree( (void *) majflags ); - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - pset3 = astAnnul( pset3 ); - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__LINE, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__TICKS2_ID; - } - -/* Annul the pointers to the Mapping and Frame. */ - mapping = astAnnul( mapping ); - frame = astAnnul( frame ); - - } - -/* Return. */ - return; - -} - -static void EBuf( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astEBuf -f AST_EBUF - -* Purpose: -* End the current graphical buffering context. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astEBuf( AstPlot *this ) -f CALL AST_EBUF( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function -f This routine -* ends the current graphics buffering context. It should match a -* corresponding call to the -c astBBuf function. -f AST_EBUF routine. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The nature of the buffering is determined by the underlying -* graphics system (as defined by the current grf module). Each call -c to this function -f to this routine -* simply invokes the astGEBuf function in the grf module. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Invoke the active GRF EBuf function. */ - GEBuf( this, "astEBuf", astGetClass( this ), status ); -} - -static int EdgeLabels( AstPlot *this, int ink, TickInfo **grid, - AstPlotCurveData **cdata, int force, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* EdgeLabels - -* Purpose: -* Attempts to display labels for the major tick values around the edges -* of the plotting area. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int EdgeLabels( AstPlot *this, int ink, TickInfo **grid, -* AstPlotCurveData **cdata, int force, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function determines how many major tick value labels could be -* placed on the specified edges of the plotting area, and then if -* requested, and if sufficient such labels are found (more than 3 on -* each axis), they are drawn. To place a label on an edge, the curve -* defining the major tick value must cross the edge at a reasonably -* angle (at least 3 degrees). Labels are not drawn which would overlap -* other, previously drawn, labels. A flag is returned indicating if -* edge labels were (or could be) drawn. - -* Parameters: -* this -* A pointer to the Plot. -* ink -* If zero, then no labels are drawn, but the decision whether or -* not to draw them is still made and indicated in the returned function -* value. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* force -* If non-zero, then an attempt is made to draw edge labels even if -* it looks like insufficient edge labels can be produced. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* If edge labels were drawn, 1 is returned. Otherwise 0 is returned. - -* Notes: -* - Zero is returned if an error has already occurred. -*/ - - -/* Local Variables: */ - AstFrame *frame; /* Pointer to current Frame */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - LabelList *labellist; /* Pointer to a ingle list of labels to be plotted */ - LabelList *ll; /* Pointer to next label to be plotted */ - LabelList *llist[2]; /* Pointers to both lists of labels to be plotted */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - const char *just[ 2 ]; /* Justification string */ - const char *text; /* Pointer to label text */ - double edgeval; /* Axis value at the labelled edge */ - double mindim; /* Minimum dimension of the plotting area */ - double oppval; /* Axis value on the edge opposite to the labels */ - double tol; /* Max. distance between a break and the edge */ - double txtgap; /* Absolute gap between labels and edges */ - float *box; /* Pointer to array of label bounding boxes */ - float *vxbrk; /* X component of unit vector at current break */ - float *vybrk; /* Y component of unit vector at current break */ - float *xbrk; /* X coord. of current break */ - float *ybrk; /* Y coord. of current break */ - float xref; /* X coordinate at label's reference position */ - float yref; /* Y coordinate at label's reference position */ - int axis; /* Current axis index */ - int brk; /* Current break index */ - int edge; /* The edge to be labelled */ - int edgeax; /* Index of axis parallel to the labelled edge */ - int edgelabs; /* Can edge labels be produced? */ - int esc; /* INterpret escape sequences? */ - int gelid; /* ID for next graphical element to be drawn */ - int ii; /* Index into existing labels */ - int maxlab; /* Number of distinct edge labels */ - int medge[2]; /* No. of distinct edge labels for each axis */ - int naxlab; /* Number of edge labels */ - int near; /* Draw a label on the near edge? */ - int nedge[2]; /* No. of edge labels for each axis */ - int ok; /* Can the current tick mark be labelled on the edge? */ - int labfound; /* Label value has already been used? */ - int tick; /* Tick index */ - int upright; /* Draw all labels upright? */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - xref = 0.0; - yref = 0.0; - -/* See if escape sequences in text strings are to be interpreted. */ - esc = astGetEscape( this ); - -/* Initialise the returned flag to indicate that edge labels cannot be - produced. */ - edgelabs = 0; - -/* Get the minimum dimension of the plotting ares. */ - mindim = astMIN( this->xhi - this->xlo, this->yhi - this->ylo ); - -/* Set up the tolerance for curve breaks occuring on an edge of - the plotting zone. */ - tol = 0.005*mindim; - -/* First, we get a list of all the labels which can be produced on each - axis. The list includes the labels reference position in graphics - coordinates, and the index of the major tick value which it - represents. We do not yet know whether enough of the grid lines cross - the required edge to make it feasable to use edge labelling, so we do - not yet draw the labels. - =====================================================================*/ - -/* Initialise pointers to arrays of structures holding information - about the labels which can be draw round the edge for both axes. */ - llist[ 0 ] = NULL; - llist[ 1 ] = NULL; - -/* Indicate that no labels can yet be drawn on either axis. */ - nedge[ 0 ] = 0; - nedge[ 1 ] = 0; - -/* The "nedge" array counts the number of labels on each edge. But some - of these labels may be for the same tick mark (if the tick mark curve has - more than 1 intersection with the edge). The "medge" array counts the - number of *distinct* tick mark labels (i.e. the number of tick mark - values which have 1 or more interesections with the edge). */ - medge[ 0 ] = 0; - medge[ 1 ] = 0; - -/* For each axis, identify the the usable edge labels. */ - for( axis = 0; axis < 2; axis++ ){ - -/* See if labels for this axis are to be drawn upright. */ - if( astTestLabelUp( this, axis ) ) { - upright = astGetLabelUp( this, axis ); - } else { - upright = 1; - } - -/* Store the required gap between the label text and the axis. */ - txtgap = astGetNumLabGap( this, axis )*mindim; - -/* Get the edge to be labelled with the axis values. Edge 0 is the left hand - edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 is - the bottom edge. */ - edge = astGetEdge( this, axis ) % 4; - if( edge < 0 ) edge = -edge; - -/* If edge labels for the current axis are to go on the left hand edge of - the plotting area... */ - if( edge == 0 ){ - -/* Choose the justification based on the sign of the text gap. */ - if( !upright ) { - just[ axis ] = "BC"; - } else if( txtgap > 0.0 ){ - just[ axis ] = "CR"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "CL"; - } else { - just[ axis ] = "CC"; - } - -/* Store the constant X axis value at the edge being labelled. Also store - the X value to use for the reference position for all labels. Take into - account whether or not the X axis is displayed reversed (i.e. with high - X values at the left hand side of the screen ). */ - if( !this->xrev ){ - edgeval = this->xlo; - oppval = this->xhi; - xref = (float)( edgeval - txtgap ); - } else { - edgeval = this->xhi; - oppval = this->xlo; - xref = (float)( edgeval + txtgap ); - } - -/* Indicate that the "edgeval" value refers to axis 1 (the X axis). */ - edgeax = 1; - -/* Do the same if the labels are to go on the top edge. */ - } else if( edge == 1 ){ - if( txtgap > 0.0 ){ - just[ axis ] = "BC"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "TC"; - } else { - just[ axis ] = "CC"; - } - - if( !this->yrev ){ - edgeval = this->yhi; - oppval = this->ylo; - yref = (float)( edgeval + txtgap ); - } else { - edgeval = this->ylo; - oppval = this->yhi; - yref = (float)( edgeval - txtgap ); - } - - edgeax = 0; - -/* Do the same if the labels are to go on the right-hand edge. */ - } else if( edge == 2 ){ - - if( !upright ) { - just[ axis ] = "BC"; - } else if( txtgap > 0.0 ){ - just[ axis ] = "CL"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "CR"; - } else { - just[ axis ] = "CC"; - } - - if( !this->xrev ){ - edgeval = this->xhi; - oppval = this->xlo; - xref = (float)( edgeval + txtgap ); - } else { - edgeval = this->xlo; - oppval = this->xhi; - xref = (float)( edgeval - txtgap ); - } - - edgeax = 1; - -/* Do the same if the labels are to go on the bottom edge. */ - } else { - if( txtgap > 0.0 ){ - just[ axis ] = "TC"; - } else if( txtgap < 0.0 ){ - just[ axis ] = "BC"; - } else { - just[ axis ] = "CC"; - } - - if( !this->yrev ){ - edgeval = this->ylo; - oppval = this->yhi; - yref = (float)( edgeval - txtgap ); - } else { - edgeval = this->yhi; - oppval = this->ylo; - yref = (float)( edgeval + txtgap ); - } - - edgeax = 0; - - } - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Get a pointer to the structure containing information describing the - breaks in the curve which is parallel to the other axis and passes - through the first major tick mark. */ - cdt = cdata[ axis ]; - -/* Initialise the pointer to the list of text strings to be drawn. */ - labellist = NULL; - -/* Initialise the number of labels which can be placed on the near edge of - the plotting zone (some of which may be the same). */ - naxlab = 0; - -/* Initialise the number of distinct labelled tick mark values. */ - maxlab = 0; - -/* Loop round each of the major tick marks on the current axis. */ - for( tick = 0; cdt && info && tick < info->nmajor; tick++ ){ - -/* Store pointers to the values giving the position and unit direction - vector of the curve at the first break. */ - xbrk = cdt->xbrk; - ybrk = cdt->ybrk; - vxbrk = cdt->vxbrk; - vybrk = cdt->vybrk; - -/* Loop round each of the breaks in the curve which passes through the - current major tick mark, and is parallel to the other axis. */ - ok = 0; - for( brk = 0; brk < cdt->nbrk; brk++ ){ - -/* A label can be produced on the near edge of the plotting zone if the - current break occurs on, or close to, the edge, and the curve is not - nearly parallel to the axis (limit is 5 degs). */ - near = ( ( edgeax == 0 && - fabs( (double) *ybrk - edgeval ) < tol && - fabs( (double) *vybrk ) > 0.09 ) || - ( edgeax == 1 && - fabs( (double) *xbrk - edgeval ) < tol && - fabs( (double) *vxbrk ) > 0.09 ) ); - -/* Get the label text. */ - if( info->labels ) { - text = (info->labels)[ tick ]; - } else { - text = NULL; - } - -/* If a label can be produced, record the information needed to draw the - label. */ - if( near && text ){ - - labellist = (LabelList *) astGrow( (void *) labellist, naxlab + 1, sizeof(LabelList) ); - if ( !astOK ) break; - - if( edgeax == 0 ){ - (labellist + naxlab)->index = (double) *xbrk; - (labellist + naxlab)->x = (double) *xbrk; - (labellist + naxlab)->y = (double) yref; - } else { - (labellist + naxlab)->index = (double) *ybrk; - (labellist + naxlab)->x = (double) xref; - (labellist + naxlab)->y = (double) *ybrk; - } - - (labellist + naxlab)->text = (char *) astStore( NULL, (void *) text, strlen(text) + 1 ); - (labellist + naxlab)->just = (char *) astStore( NULL, (void *) just[ axis ], strlen(just[ axis ]) + 1 ); - -/* The up vector depends on which edge is being labelled and whether all - labels are being drawn upright or not. */ - if( edge == 1 || edge == 3 || upright ) { - (labellist + naxlab)->upx = 0.0; - (labellist + naxlab)->upy = 1.0; - } else if( edge == 0 ) { - (labellist + naxlab)->upx = -1.0; - (labellist + naxlab)->upy = 0.0; - } else { - (labellist + naxlab)->upx = 1.0; - (labellist + naxlab)->upy = 0.0; - } - - (labellist + naxlab)->val = (info->ticks)[ tick ]; - naxlab++; - -/* If this label has not already been included in the label list, indicate - that we have found another usable label. */ - labfound = 0; - for( ii = 0; ii < naxlab-1; ii++ ) { - if( fabs( (info->ticks)[ tick ] - - (labellist + ii)->val ) < 0.2*info->gap ) { - labfound = 1; - break; - } - } - if( !labfound ) ok = 1; - - } - -/* Increment the pointers to the values giving the position and unit direction - vector of the next break. */ - xbrk++; - ybrk++; - vxbrk++; - vybrk++; - - } - -/* If an error has occurred, break out of the loop. */ - if( !astOK ) break; - -/* If one or more labels could be produced for this tick mark value, - increment the number of labeled tick marks found. */ - if( ok ) maxlab++; - -/* Get a pointer to the curve through the next major tick mark. */ - cdt++; - - } - -/* If an error has occurred, break out of the loop. */ - if( !astOK ) break; - -/* Store the number of labels for this axis, and the pointer to the - drawable labels. */ - nedge[ axis ] = naxlab; - medge[ axis ] = maxlab; - llist[ axis ] = labellist; - } - -/* We now know how many labels would be produced on each axis if edge - labelling were to be used. We also know what those labelled values are, - and where the labels would be drawn. We now take the decision as to - whether there are enough of these labels to make edge labelling - feasable. If so, we carry on and draw the labels. There need to be - at least 3 labels on each axis for linear tick spacing and 2 for log - tick spacing (or a non-zero value supplied for "force")... - ================================================================= */ - if( astOK && ( ( medge[ 0 ] > ( astGetLogTicks( this, 0 ) ? 1 : 2 ) && - medge[ 1 ] > ( astGetLogTicks( this, 1 ) ? 1 : 2 ) ) - || force ) ) { - -/* Set the returned flag to indicate that edge labelling is being used. */ - edgelabs = 1; - -/* Initialise the pointer to the memory holding the bounding boxes for - all labels (used by function Overlap). */ - box = NULL; - -/* Get a pointer to the current Frame in the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__NUMLAB1_ID; - -/* If required, draw the labels for each axis in turn. */ - for( axis = 0; axis < 2 && ink; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__TEXT, method, class ); - -/* Plot them. */ - info = grid[ axis ]; - PlotLabels( this, esc, frame, axis, llist[ axis ], info->fmt, - nedge[ axis ], &box, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__TEXT, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__NUMLAB2_ID; - - } - -/* Free the memory used to hold the bounding boxes. */ - box = (float *) astFree( (void *) box ); - -/* Annul the pointer to the Frame. */ - frame = astAnnul( frame ); - } - -/* Free the memory used to store the label information. */ - for( axis = 0; axis < 2; axis++ ){ - ll = llist[ axis ]; - if( ll ) { - for( tick = 0; tick < nedge[ axis ]; tick ++ ) { - ll->text = (char *) astFree( (void *) ll->text ); - ll->just = (char *) astFree( (void *) ll->just ); - ll++; - } - llist[ axis ] = (LabelList *) astFree( (void *) llist[ axis ] ); - } - } - -/* Return the flag indicating if edge labels were produced. */ - return edgelabs; - -} - -static int EdgeCrossings( AstPlot *this, int edge, int axis, double axval, - double *gap, double **cross, - EdgeCrossingsStatics **pstatics, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* EdgeCrossings - -* Purpose: -* Find all occurrences of a given physical axis value on an edge of the -* plotting area. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int EdgeCrossings( AstPlot *this, int edge, int axis, double axval, -* double *gap, double **cross, -* EdgeCrossingsStatics **pstatics, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function finds all occurences of a given physical axis value -* along a specified edge of the plotting area. Firstly, a set of evenly -* spaced points ("edge samples") are placed along the edge and the -* corresponding physical coordinates are found. These physical coordinates -* are then offset slightly from their original positions in the direction -* of the "other" axis (i.e. index [ 1 - axis ] ), and transformed back -* into graphics coordinates. These coordinates give the tangent vector -* at each of the edge samples. -* -* To find the crossings, the supplied axis value is compared with the axis -* value at each sample in turn, starting from one end of the edge and -* working through to the other end. When a crossing is found, linear -* interpolation is used between the two adjacent edge samples to find a -* more accurate estimate of the crossing. The vector at the crossing -* is also estimated by linear interpolation between the vectors at the two -* adjacent samples. -* -* This basic algorithm fails if there is a discontinuity in the axis -* values along the edge. For instance, if the edge covers a range of -* Right Ascension from 23h to 1h, there will be a discontinuity at 0h -* at which the RA values suddenly jump from 2*PI to zero. This jump -* encompasses all normalised RA values and so every axis value would be -* given a crossing at this point. To avoid this, a bad sample is -* interposed between the two samples on either side of the -* discontinuity. This prevents any crossings from being placed at the -* discontinuity. -* -* There is a second problem related to discontinuities. If the supplied -* axis value is zero (using the above RA example again), then no -* crossings will be found, not only because of the extra bad sample, -* but also because the samples will not quite cover the range of axis -* values covered by the discontinuity because of the discrete nature -* of the samples). To get round this, the sections on either side -* of the discontinity are extended by a single sample. These extra -* samples are assumed to be conincident with the neighbouring sample, -* except that the value for the searched axis is modified to be a -* linear extension from the neighbouring samples. - - -* Parameters: -* this -* A pointer to the Plot. Supply a NULL pointer to release resources. -* edge -* The edge of the plotting area to be used. Edge 0 is the left hand -* edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 -* is the bottom edge. -* axis -* The index of the axis to which "axval" refers. -* axval -* The physical axis value to be searched for. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. -* cross -* A pointer to the location at which to return a pointer to an -* array of doubles holding the crossing information. Each crossing -* is described by 4 doubles. The first pair are the graphiucs (x,y) -* coordinates of the point on the edge at which the crossing occurs. -* The second pair represents a unit vector in graphics coordinates -* which is tangential to the curve of constant axis value at the -* crossing. The memory allocated within this function to hold this -* data should be freed using astFree when no longer needed. If no -* crossings are found a NULL pointer is returned. -* pstatics -* Address of a pointer to a structure holding values for variables -* which were statically defined within this function prior to the -* thread-safe version of AST. If the pointer is supplied as NULL, -* then a new structure is allocated and initialised. Any supplied -* structure is freed if a NULL pointer is supplied for "this". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Return Value: -* The number of crossings found. - -* Notes: -* - This function allocates static resource on the first invocation -* which should be freed when no more calls are to be made, by making a -* final call with a NULL pointer supplied for "this". All other parameters -* are then ignored. -* - The static resources are re-initialised each time "edge" or -* "axis" changes, and so the calling function should be structure in -* order to minimise the number of times these parameter values change. -* - If an error has already occurred, or if this function should -* fail for any reason, zero is returned, and a NULL pointer is stored at -* "cross". - -*/ - -/* Local Variables: */ - EdgeCrossingsStatics *statics; /* Structure holding static data */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPointSet *pset1a; /* Physical cooords at offset edge samples */ - AstPointSet *pset2a; /* Physical cooords at offset edge samples */ - AstPointSet *pset3; /* Physical cooords at offset edge samples */ - AstPointSet *pset4a; /* Physical cooords at offset edge samples */ - double **ptr1a; /* Pointer to physical coord. data */ - double **ptr2a; /* Pointer to physical coord. data */ - double **ptr3; /* Pointer to physical coord. data */ - double **ptr4a; /* Pointer to physical coord. data */ - double *data; /* Pointer to next item of crossing information */ - double *p1; /* Pointer to graphics axis with constant value */ - double *p1a; /* Pointer to graphics axis with constant value */ - double *p2; /* Pointer to graphics axis with varying value */ - double *p2a; /* Pointer to graphics axis with varying value */ - double *q1; /* Pointer to physical axis being searched */ - double *q1a; /* Pointer to physical axis being searched */ - double *q2; /* Pointer to other physical axis */ - double *q2a; /* Pointer to other physical axis */ - double *v1; /* Pointer to vector component on axis 0 */ - double *v2; /* Pointer to vector component on axis 1 */ - double *v1a; /* Pointer to vector component on axis 0 */ - double *v2a; /* Pointer to vector component on axis 1 */ - double dd; /* The gap between edge samples */ - double diff; /* Squared differences between adjacent edge samples */ - double dl2; /* Squared vector length */ - double dl; /* Vector length */ - double dx; /* Vector X component */ - double dy; /* Vector Y component */ - double f; /* Weight for the current edge sample */ - double offset; /* Physical offset */ - double pp2; /* Varying graphics axis value at previous sample */ - double pq1; /* Required physical axis value at previous sample */ - double pv1; /* Previous vector component on axis 0 */ - double pv2; /* Previous vector component on axis 1 */ - double sum; /* Sum of squared differences between adjacent edge samples */ - double value; /* The current graphics axis value */ - double vx; /* Vector component on axis 0 at crossing */ - double vy; /* Vector component on axis 1 at crossing */ - double z; /* Varying graphics axis value at crossing */ - int i; /* Edge sample index */ - int iter; /* Iteration index */ - int larger; /* Is current axis value larger than target? */ - int logticks; /* Are major ticks logarithmically spaced? */ - int ncross; /* No. of crossings */ - int ndisc; /* No. of discontinuities along the edge */ - int nsum; /* Number of values summed in "sum" */ - int plarger; /* Was previous axis value larger than target? */ - -/* Get a pointer to the supplied statics object. */ - statics = *pstatics; - -/* If a NULL Plot pointer has been supplied, release the static - resources, and return. */ - if( !this ){ - if( statics ){ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pset4 ) statics->pset4 = astAnnul( statics->pset4 ); - if( statics->frame ) statics->frame = astAnnul( statics->frame ); - *pstatics = astFree( statics ); - } - return 0; - } - -/* Initialise the number of crossings found, and the pointer to the place - to store them. */ - ncross = 0; - *cross = NULL; - -/* Check the global status. */ - if( !astOK ) return 0; - -/* If no statics structure was supplied, create one now and initialise it. */ - if( !statics ) { - statics = astMalloc( sizeof( EdgeCrossingsStatics ) ); - if( statics ) { - statics->frame = NULL; - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->pset4 = NULL; - statics->ptr1 = NULL; - statics->ptr2 = NULL; - statics->ptr4 = NULL; - statics->paxis = -1; - statics->pedge = -1; - *pstatics = statics; - } - } - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - pp2 = 0.0; - pv1 = 0.0; - pv2 = 0.0; - plarger = 0; - -/* See if the major ticks on the other axis are logarithmically or - linearly spaced. */ - logticks = astGetLogTicks( this, 1 - axis ); - -/* Ensure that "edge" is in the range 0 - 3. */ - edge = edge % 4; - if( edge < 0 ) edge = -edge; - -/* If the edge or axis has changed since the last invocation, or if this is - the first invocation, initialise some static data. */ -/* ======================================================================*/ - if( statics->pedge == -1 || statics->pedge != edge || statics->paxis != axis ){ - -/* Save the edge and axis. */ - statics->pedge = edge; - statics->paxis = axis; - -/* Annull any previous static data objects */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pset4 ) statics->pset4 = astAnnul( statics->pset4 ); - if( statics->frame ) statics->frame = astAnnul( statics->frame ); - -/* Store some values so that the code does not need to consider each edge - separately. First deal with the left hand edge. */ - if( edge == 0 ){ - statics->edgeax = 0; - if( this->xrev ){ - statics->edgeval = this->xhi; - } else { - statics->edgeval = this->xlo; - } - statics->edgehi = this->yhi; - statics->edgelo = this->ylo; - -/* Now deal with the right hand edge. */ - } else if( edge == 2 ){ - statics->edgeax = 0; - if( this->xrev ){ - statics->edgeval = this->xlo; - } else { - statics->edgeval = this->xhi; - } - statics->edgehi = this->yhi; - statics->edgelo = this->ylo; - -/* Now deal with the bottom edge. */ - } else if( edge == 3 ){ - statics->edgeax = 1; - if( this->yrev ){ - statics->edgeval = this->yhi; - } else { - statics->edgeval = this->ylo; - } - statics->edgehi = this->xhi; - statics->edgelo = this->xlo; - - -/* Finally deal with the top edge. */ - } else { - statics->edgeax = 1; - if( this->yrev ){ - statics->edgeval = this->ylo; - } else { - statics->edgeval = this->yhi; - } - statics->edgehi = this->xhi; - statics->edgelo = this->xlo; - - } - -/* Get a pointer to the current Frame in the supplied Plot. */ - statics->frame = astGetFrame( this, AST__CURRENT ); - -/* Get a pointer to the mapping from base to current Frame in the supplied - Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Create a PointSet to hold the graphics coordinates at a set of - regularly spaced points along the specified edge of the plotting area. */ - pset1a = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr1a = astGetPoints( pset1a ); - -/* Create a PointSet to hold the corresponding physical coordinates. */ - pset2a = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr2a = astGetPoints( pset2a ); - -/* Check they can be used. */ - if( astOK ){ - -/* Set up the graphics coordinates. */ - dd = ( statics->edgehi - statics->edgelo )/(double)( EDGETICKS_DIM - 1 ); - value = statics->edgelo; - - p1 = ptr1a[ statics->edgeax ]; - p2 = ptr1a[ 1 - statics->edgeax ]; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - *(p1++) = statics->edgeval; - *(p2++) = value; - value += dd; - } - } - -/* Transform the graphics coordinates to physical coordinates, - *without* normalising them into their normal ranges. */ - (void) Trans( this, statics->frame, mapping, pset1a, 1, pset2a, 0, method, class, status ); - -/* Find the RMS step size along the axis. This is used to locate - discontinuities along the edge. Do three rejection iterations. */ - statics->limit = DBL_MAX; - for( iter = 0; iter < 3; iter ++ ){ - q1 = ptr2a[ axis ]; - pq1 = AST__BAD; - sum = 0.0; - nsum = 0; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *q1 != AST__BAD && pq1 != AST__BAD ){ - diff = *q1 - pq1; - if( fabs( diff ) < statics->limit ){ - sum += diff*diff; - nsum++; - } - } - pq1 = *(q1++); - } - - if( nsum == 0 ) break; - statics->limit = 3.0*sqrt( sum/(double)nsum ); - } - -/* Now create another PointSet holding positions slightly offset from the - physical coordinates at the edge samples. The offset is in the direction - of the other physical axis. These positions are used to determine the - vector at the crossings. */ - if( nsum > 0 ){ - pset3 = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr3 = astGetPoints( pset3 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. */ - pset4a = astPointSet( EDGETICKS_DIM, 2, "", status ); - ptr4a = astGetPoints( pset4a ); - -/* Check they can be used. */ - if( astOK ){ - -/* Copy the physical coordinates from PointSet 2 to PointSet 3, offseting - them slightly along the other axis. */ - p1 = ptr2a[ axis ]; - p2 = ptr2a[ 1 - axis ]; - - q1 = ptr3[ axis ]; - q2 = ptr3[ 1 - axis ]; - - offset = 0.2*gap[ 1 - axis ]; - - pq1 = AST__BAD; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *p1 != AST__BAD && *p2 != AST__BAD ){ - if( logticks ) offset = 0.2*(*p2)*( gap[ 1 -axis ] - 1.0 ); - *(q2++) = *p2 + offset; - } else { - *(q2++) = AST__BAD; - } - pq1 = *(p1++); - *(q1++) = pq1; - p2++; - } - - } - -/* Transform the physical coordinates to graphics coordinates. */ - (void) Trans( this, NULL, mapping, pset3, 0, pset4a, 0, method, class, status ); - -/* Check they can be used. */ - if( astOK ){ - -/* Modify the contents of PointSet 4 to represent the unit vector in - graphics coordinates at each edge sample. */ - p1 = ptr1a[ 0 ]; - p2 = ptr1a[ 1 ]; - q1 = ptr4a[ 0 ]; - q2 = ptr4a[ 1 ]; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *p1 != AST__BAD && *p2 != AST__BAD && - *q1 != AST__BAD && *q2 != AST__BAD ){ - - dx = *q1 - *p1; - dy = *q2 - *p2; - dl2 = dx*dx + dy*dy; - - if( dl2 > 0.0 ){ - dl = sqrt( dl2 ); - *q1 = dx/dl; - *q2 = dy/dl; - } else { - *q1 = AST__BAD; - *q2 = AST__BAD; - } - - } else { - *q1 = AST__BAD; - *q2 = AST__BAD; - } - - p1++; - p2++; - q1++; - q2++; - - } - - } - -/* Annul the PointSet holding offset physical cooridnates. */ - pset3 = astAnnul( pset3 ); - -/* Discontinuities in the axis values can cause problems. For instance, - using the above PointSets, no tick mark could be put at 0 hours RA - because of the discontinuity there. To get round this, 3 extra samples - are added at each discontinuity, the first extends the continuous section - which ends at the discontinuity, and the third extends the secion which - starts at the discontinuity. This results in the two sections overlapping - by one sample. The second is placed between these two and has a bad - axis value. It prevents crossings from being found in between the values - at the ends of the two sections. - - First count the number of discontinuities in the axis values. - Discontinuites are defined as steps of more than 9 times the RMS step - size. */ - q1 = ptr2a[ axis ]; - pq1 = AST__BAD; - statics->limit *= 3.0; - ndisc = 0; - - for( i = 0; i < EDGETICKS_DIM; i++ ){ - if( *q1 != AST__BAD && pq1 != AST__BAD ){ - if( fabs( *q1 - pq1 ) > statics->limit ) ndisc++; - } - pq1 = *(q1++); - } - -/* Store the size of the new PointSets holding the extra samples. */ - statics->dim = EDGETICKS_DIM + 3*ndisc; - -/* If there are no discontinuities, just clone the existing PointSets. */ - if( !ndisc ){ - statics->pset1 = astClone( pset1a ); - statics->pset2 = astClone( pset2a ); - statics->pset4 = astClone( pset4a ); - statics->ptr1 = astGetPoints( statics->pset1 ); - statics->ptr2 = astGetPoints( statics->pset2 ); - statics->ptr4 = astGetPoints( statics->pset4 ); - -/* Otherwise, create new PointSets. */ - } else { - statics->pset1 = astPointSet( statics->dim, 2, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - statics->pset2 = astPointSet( statics->dim, 2, "", status ); - statics->ptr2 = astGetPoints( statics->pset2 ); - statics->pset4 = astPointSet( statics->dim, 2, "", status ); - statics->ptr4 = astGetPoints( statics->pset4 ); - -/* Set up pointers used to walk through the arrays in the original - PointSets and the new PointSets. */ - p1 = statics->ptr1[ 0 ]; - p2 = statics->ptr1[ 1 ]; - q1 = statics->ptr2[ axis ]; - q2 = statics->ptr2[ 1 - axis ]; - v1 = statics->ptr4[ 0 ]; - v2 = statics->ptr4[ 1 ]; - - p1a = ptr1a[ 0 ]; - p2a = ptr1a[ 1 ]; - q1a = ptr2a[ axis ]; - q2a = ptr2a[ 1 - axis ]; - v1a = ptr4a[ 0 ]; - v2a = ptr4a[ 1 ]; - -/* Initialise the axis value at the previous sample. */ - pq1 = AST__BAD; - -/* Check all samples in the original PointSets. */ - for( i = 0; i < EDGETICKS_DIM; i++ ){ - -/* If this is the first point after a discontinuity... */ - if( *q1a != AST__BAD && pq1 != AST__BAD ){ - if( fabs( *q1a - pq1 ) > statics->limit ) { - -/* Insert an extra sample with the coordinates of the previous sample, - but with an axis value which is linearly extrapolated from the previous - samples. */ - *(p1++) = p1a[ 0 ]; - *(p2++) = p2a[ 0 ]; - *(v1++) = v1a[ -1 ]; - *(v2++) = v2a[ -1 ]; - *(q2++) = q2a[ -1 ]; - if( i > 1 && q1a[ -2 ] != AST__BAD ){ - *(q1++) = 2.0*pq1 - q1a[ -2 ]; - } else { - *(q1++) = pq1; - } - -/* Insert an extra sample with bad coordinates. */ - *(p1++) = AST__BAD; - *(p2++) = AST__BAD; - *(v1++) = AST__BAD; - *(v2++) = AST__BAD; - *(q2++) = AST__BAD; - *(q1++) = AST__BAD; - -/* Insert an extra sample with the cooridnates of the current sample, - but with an axis value which is linearly extrapolated from the - subsequent samples. */ - *(p1++) = p1a[ -1 ]; - *(p2++) = p2a[ -1 ]; - *(v1++) = *v1a; - *(v2++) = *v2a; - *(q2++) = *q2a; - if( i < EDGETICKS_DIM - 1 && q1a[ 1 ] != AST__BAD ){ - *(q1++) = 2.0*(*q1a) - q1a[ 1 ]; - } else { - *(q1++) = pq1; - } - - } - - } - -/* Save the current axis value. */ - pq1 = *q1a; - -/* Copy the current input values to the new PointSets, and move on the next - point in the original PointSets. */ - *(p1++) = *(p1a++); - *(p2++) = *(p2a++); - *(q1++) = *(q1a++); - *(q2++) = *(q2a++); - *(v1++) = *(v1a++); - *(v2++) = *(v2a++); - - } - - } - -/* Anull the original PointSets. */ - pset4a = astAnnul( pset4a ); - -/* If all the physical coordinates are bad, indicate this by setting the - limiting step size bad. */ - } else { - statics->limit = AST__BAD; - } - -/* Anull the original PointSets. */ - pset1a = astAnnul( pset1a ); - pset2a = astAnnul( pset2a ); - -/* Annul the pointer to the mapping from base to current Frame. */ - mapping = astAnnul( mapping ); - - } - -/* ======================================================================*/ -/* The initialisation has now been done. Check the physical coordinate data - can be used. */ - if( astOK && statics->limit != AST__BAD ){ - -/* Store pointers to the graphics and physical coordinates at the first - edge sample. */ - p1 = statics->ptr1[ statics->edgeax ]; /* Graphics axis with constant value */ - p2 = statics->ptr1[ 1 - statics->edgeax ]; /* Graphics axis with varying value */ - q1 = statics->ptr2[ axis ]; /* Physical axis values to be searched */ - q2 = statics->ptr2[ 1 - axis ]; /* The other physical axis */ - -/* Store pointers to the components of the unit vector at the first - edge sample. */ - v1 = statics->ptr4[ 0 ]; - v2 = statics->ptr4[ 1 ]; - -/* Inidicate that there is currently no "previous sample". */ - pq1 = AST__BAD; - -/* Check each point in turn... */ - for( i = 0; i < statics->dim; i++ ){ - -/* Skip this point if the physical coordinates are undefined. */ - if( *q1 != AST__BAD && *q2 != AST__BAD ){ - -/* Get a flag indicating if the required axis value has been exceeded at - the current edge sample. */ - larger = ( *q1 > axval ); - -/* If the state of this flag has changed since the previous edge sample, - and if we know where the previous sample was, we have found a - crossing. */ - if( pq1 != AST__BAD && larger != plarger ){ - -/* Find the distance from the previous physical axis value to the required - axis value, as a fraction of the distance from the previous axis value - to the current axis value. Since the flag has changed, we know that the - q1 value at this edge sample and the previous one must be different, so - we know that the denominator is not zero. */ - f = ( axval - pq1 )/( *q1 - pq1 ); - -/* Use linear interpolation to estimate the graphics axis value at the - crossing. */ - if( f != -1.0 ){ - z = pp2 + f*( *p2 - pp2 ); - -/* Use linear interpolation to estimate the two components of the unit - vector at the crossing. */ - if( *v1 != AST__BAD && pv1 != AST__BAD && - *v2 != AST__BAD && pv2 != AST__BAD ){ - vx = pv1 + f*( *v1 - pv1 ); - vy = pv2 + f*( *v2 - pv2 ); - -/* Normalise the vector. */ - dl2 = vx*vx + vy*vy; - if( dl2 > 0.0 ){ - dl = sqrt( dl2 ); - vx /= dl; - vy /= dl; - } else { - vx = AST__BAD; - vy = AST__BAD; - } - - } else { - vx = AST__BAD; - vy = AST__BAD; - } - -/* Grow the returned array to hold another crossing. */ - ncross++; - *cross = (double *) astGrow( (void *) *cross, ncross, - 4*sizeof( double ) ); - -/* If succesful, store the crossing. */ - if( astOK ) { - - data = *cross + 4*( ncross - 1 ); - if( statics->edgeax ){ - *(data++) = z; - *(data++) = statics->edgeval; - } else { - *(data++) = statics->edgeval; - *(data++) = z; - } - *(data++) = vx; - *(data++) = vy; - - } - - } - - } - -/* Save the flag for use on the next pass through this loop. */ - plarger = larger; - - } - -/* Save the varying graphics axis value and the required physical axis - value at the current edge sample (also save the vector). */ - pp2 = *p2; - pq1 = *q1; - pv1 = *v1; - pv2 = *v2; - -/* Point to the next edge sample. */ - p1++; - p2++; - q1++; - q2++; - v1++; - v2++; - - } - - } - -/* If an error has occurred, free the array holding the crossings, and - indicate that there are zero corssing. */ - if( !astOK ) { - *cross = (double *) astFree( (void *) *cross ); - ncross = 0; - } - -/* Return the answer. */ - return ncross; - -} - -int astFindEscape_( const char *text, int *type, int *value, int *nc, int *status ){ -/* -*+ -* Name: -* astFindEscape - -* Purpose: -* Check if a string starts with a graphics escape sequence. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* int astFindEscape( const char *text, int *type, int *value, int *nc ) - -* Description: -* This function returns a flag indiciating if the first character in -* the supplied string is the start of a graphics escape sequence. If -* so, the type and associated value (if any) of the escape sequence -* are returned in "type" and "value", and the number of characters -* occupied by the escape sequence is returned in "nc". If the -* supplied text string does not begin with an escape sequence, the -* number of characters before the first escape sequence is returned in -* "nc" (the length of the string is returned in "nc" if the string -* contains no escape sequences). -* -* This function can be used by grf modules which wish to implement -* interpretation of escape sequences internally, rather than allowing the -* Plot class to do the interpretation. - -* Parameters: -* text -* Pointer to the string to be checked. -* type -* Pointer to a location at which to return the type of escape -* sequence. Each type is identified by a symbolic constant defined -* in grf.h. The returned value is undefined if the supplied text -* does not begin with an escape sequence. -* value -* Pointer to a lcation at which to return the integer value -* associated with the escape sequence. All usable values will be -* positive. Zero is returned if the escape sequence has no associated -* integer. A value of -1 indicates that the attribute identified by -* "type" should be reset to its "normal" value (as established using -* the astGAttr function, etc). The returned value is undefined if the -* supplied text does not begin with an escape sequence. -* nc -* Pointer to a location at which to return the number of -* characters read by this call. If the text starts with an escape -* sequence, the returned value will be the number of characters in -* the escape sequence. Otherwise, the returned value will be the -* number of characters prior to the first escape sequence, or the -* length of the supplied text if no escape sequence is found. - -* Returned Value: -* A non-zero value is returned if the supplied text starts with a -* graphics escape sequence, and zero is returned otherwise. - -* Escape Sequences: -* Escape sequences are introduced into the text string by a percent -* "%" character. The following escape sequences are currently recognised -* ("..." represents a string of one or more decimal digits): -* -* %% - Print a literal "%" character. -* -* %^...+ - Draw subsequent characters as super-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the super-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* %^+ - Draw subsequent characters with the normal base-line. -* -* %v...+ - Draw subsequent characters as sub-scripts. The digits -* "..." give the distance from the base-line of "normal" -* text to the base-line of the sub-script text, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %v+ - Draw subsequent characters with the normal base-line -* (equivalent to %^+). -* -* %>...+ - Leave a gap before drawing subsequent characters. -* The digits "..." give the size of the gap, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %<...+ - Move backwards before drawing subsequent characters. -* The digits "..." give the size of the movement, scaled -* so that a value of "100" corresponds to the height of -* "normal" text. -* -* %s...+ - Change the Size attribute for subsequent characters. The -* digits "..." give the new Size as a fraction of the -* "normal" Size, scaled so that a value of "100" corresponds -* to 1.0; -* -* %s+ - Reset the Size attribute to its "normal" value. -* -* %w...+ - Change the Width attribute for subsequent characters. The -* digits "..." give the new width as a fraction of the -* "normal" Width, scaled so that a value of "100" corresponds -* to 1.0; -* -* %w+ - Reset the Size attribute to its "normal" value. -* -* %f...+ - Change the Font attribute for subsequent characters. The -* digits "..." give the new Font value. -* -* %f+ - Reset the Font attribute to its "normal" value. -* -* %c...+ - Change the Colour attribute for subsequent characters. The -* digits "..." give the new Colour value. -* -* %c+ - Reset the Colour attribute to its "normal" value. -* -* %t...+ - Change the Style attribute for subsequent characters. The -* digits "..." give the new Style value. -* -* %t+ - Reset the Style attribute to its "normal" value. -* -* %h+ - Remember the current horizontal position (see "%g+") -* -* %g+ - Go to the horizontal position of the previous "%h+" (if any). -* -* %- - Push the current graphics attribute values onto the top of -* the stack (see "%+"). -* -* %+ - Pop attributes values of the top the stack (see "%-"). If -* the stack is empty, "normal" attribute values are restored. - -* Notes: -* - Zero is returned if an error has already occurred. -*- -*/ - -/* Local Variables: */ - int result; - const char *a; - const char *b; - int nd; - const char *perc; - -/* Initialise */ - result = 0; - *type = GRF__ESPER; - *value = 0; - *nc = 0; - perc = NULL; - -/* Check inherited status and supplied pointer. */ - if( !astOK || !text ) return result; - -/* Loop round, looking for percent signs. Break out of the loop when a - complete escape sequence has been found and read, leaving the "b" pointer - pointing to the first character following the escape sequence. */ - b = NULL; - a = text; - while( ( a = strchr( a, '%' ) ) ) { - perc = a; - -/* Compare the following character to each known escape sequence type. */ - a++; - if( *a == '%') { - *type = GRF__ESPER; - b = a + 1; - break; - - } else if( *a == '^') { - *type = GRF__ESSUP; - - } else if( *a == 'v') { - *type = GRF__ESSUB; - - } else if( *a == '>') { - *type = GRF__ESGAP; - - } else if( *a == '<') { - *type = GRF__ESBAC; - - } else if( *a == 's') { - *type = GRF__ESSIZ; - - } else if( *a == 'w') { - *type = GRF__ESWID; - - } else if( *a == 'f') { - *type = GRF__ESFON; - - } else if( *a == 'c') { - *type = GRF__ESCOL; - - } else if( *a == 'g') { - *type = GRF__ESG; - - } else if( *a == 'h') { - *type = GRF__ESH; - - } else if( *a == 't') { - *type = GRF__ESSTY; - - } else if( *a == '-') { - *type = GRF__ESPSH; - b = a + 1; - break; - - } else if( *a == '+') { - *type = GRF__ESPOP; - b = a + 1; - break; - -/* If the next character is illegal, skip to the next percent sign. */ - } else { - continue; - } - -/* The escape sequence looks legal so far, so move on to the next - character (if any). */ - if( *(++a) ){ - -/* If the next character is a "+" sign, the attribute needs to be reset - to its "normal" value. Indicate this by returning a value of "-1" (all - usable values will be positive). */ - if( *a == '+' ) { - *value = -1; - b = a + 1; - break; - -/* Otherwise, to be a legal escape sequence, this character must be the - first in a sequence of digits, terminated by a "+" sign.*/ - } else if( (nd = 0, astSscanf( a, "%d%n+", value, &nd ))) { - b = a + nd + 1; - break; - } - } - } - -/* Was a usable escape sequence found at the start of the supplied text? - If so, return a function value of 1 and store the number of characters in - the escape sequence. */ - if( b && perc == text ) { - result = 1; - *nc = b - perc; - -/* Otherwise, return the preset function value of zero. If an escape - sequence was found later in the text, return the number of characters - prior to the escape sequence. */ - } else if( b ) { - *nc = perc - text; - -/* Otherwise, if no escape sequence was found, return the length of the - supplied text. */ - } else { - *nc = strlen( text ); - } - -/* Return the result. */ - return result; -} - -static int FindMajTicks( AstMapping *map, AstFrame *frame, int axis, - double refval, double width, double gap, double *cen, int ngood, - double *data, double **tick_data, int *status ){ -/* -* Name: -* FindMajTicks - -* Purpose: -* Place the major tick marks for a physical coordinate axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindMajTicks( AstMapping *map, AstFrame *frame, int axis, -* double refval, double width, double gap, double *cen, int ngood, -* double *data, double **tick_data ) - -* Class Membership: -* Plot member function. - -* Description: -* The caller supplies an array of axis values (non-normalized), sorted -* into ascending order (with any bad values at the end), together with -* the gap size for the axis. The array of axis values is assumed to cover -* the entire range which the axis can take within the plotting zone. The -* first tick mark is placed just below the smallest axis value, at a -* position which is an integral number of gaps away from the value -* supplied in "cen" (if a value of AST__BAD is supplied for "cen" then -* "cen = 0.0" is assumed). Notionally, tick marks are then placed at -* intervals given by "gap" all the way upto, and just beyond, the -* largest axis value. However, it could be that large sections of the -* axis are not actually present within the plotting zone. For instance, -* an RA axis covering the two hour range from 23h to 1h (centred on -* 0h), will have some values at zero and some at 23.999.., but there -* will be a large range inbetween these limits which is not represented -* in the plotting area (i.e. the 22h range from 1h to 23h centred on -* 12h). For this reason, tick marks are removed if there are no axis -* values inbetween the tick mark and either of its neighbours. However, -* small "holes" in the axis coverage are allowed, and ticks marks are -* returned covering such small holes. Extra tick marks are also placed -* at each end of the range to guard against the supplied array of axis -* values not entirely covering the range of axis values in the plotting -* area. -* -* For SkyFrames, positions which have latitude values outside the -* normal ranges are ignored. Longitude ranges are not checked to -* avoid problems with CAR projections. -* -* The returned tick mark values are placed into their primary domain -* using the Norm1 method, but are NOT normalised using the astNorm -* method for the supplied Frame. Duplicate tick marks values are -* removed from the returned list. - -* Parameters: -* map -* Mapping from the Plot Base Frame to Plot Current Frame. -* frame -* Pointer to the Frame. -* axis -* Zero-based index of the axis being used. -* refval -* Value to use for the other axis (index [1-axis]) when placing -* the tick mark values into their primary domain. -* width -* Range of used values on the other axis (index [1-axis]). -* gap -* The supplied value for the gaps between ticks on the axis. -* cen -* Pointer to the supplied axis value at which to put a central tick. -* Other ticks will be placed evenly on either side of this tick. If -* AST__BAD is provided, a value will be used which would put a tick -* at an axis value of zero. The used value is returned. -* ngood -* The number of good values in the array pointer to by "data" (i.e. -* values not equal to AST__BAD). -* data -* A pointer to an array holding sorted axis values (non-normalized) -* covering the entire plotting area. -* tick_data -* A pointer to a place at which to store a pointer to an array -* holding the returned tick mark values for the axis. - -* Returned Value: -* The number of major tick mark values stored in the array pointer to -* by "*tick_data". - -* Notes: -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned in "tick_data", and zero -* is returned for the function value. -*/ - -/* Local Variables: */ - double *r; /* Pointer to next tick value to be read */ - double *ticks; /* Pointer to the axis values at the major tick marks */ - double *w; /* Pointer to last tick value to be written */ - double bot; /* Lowest axis value to be displayed */ - double centre; /* The axis value at the first tick mark */ - double delta; /* A safe distance from an axis limit */ - double f; /* The nearest acceptable tick mark index */ - double tmp; /* Temporary storage */ - double top; /* Highest axis value to be displayed */ - int inc; /* This times increase in nticks */ - int k; /* Tick mark index */ - int linc; /* Last times increase in nticks */ - int lnfill; /* Last used value for nfill */ - int nfill; /* No of tick marks to extend by at edges of coverage */ - int nsame; /* Number of equal inc values there have been */ - int nticks; /* Number of major tick marks used */ - int ntnew; /* This times new value of nticks */ - int use_nfill; /* nfill value which started this run of equal inc values */ - -/* Initialise the returned pointer. */ - *tick_data = NULL; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - nsame = 0; - use_nfill = 0; - -/* Decide where to put the first major tick. Use any value supplied by - the caller. Otherwise put it an integral number of gaps away from the - origin. This would result in the origin being at a major tick mark. */ - if( cen && *cen != AST__BAD ) { - centre = *cen; - } else { - centre = astCentre( frame, axis, data[ 0 ], gap ); - if( cen ) *cen = centre; - } - -/* Find the number of candidate tick marks assuming an nfill value of 0. */ - nfill = 0; - nticks = FindMajTicks2( nfill, gap, centre, ngood, data, &ticks, status ); - -/* Loop round increasing the nfill value until an unreasonably large value - of nfill is reached. The loop will exit early via a break statement when - all small holes in the axis coverage are filled in. */ - lnfill = nfill; - linc = -100000; - while( nfill < 100 && astOK ){ - -/* Increment the number of ticks added as "padding" at the edges of any - gaps in the coverage of axis values. */ - nfill++; - -/* Form a new set of tick mark values using this new nfill value */ - ticks = (double *) astFree( (void *) ticks ); - ntnew = FindMajTicks2( nfill, gap, centre, ngood, data, &ticks, status ); - -/* We need to know if the rate of increase of nticks has settled down to - a constant value. Inititially increasing nfill will cause the total - number of ticks (nticks) to increase rapidly. But this rate of - increase will get less as any small gaps in axis coverage are filled in. - We break out of the while loop when the rate of increase has settled - down to a constant value (indicating that only very large holes are left - in the axis coverage). Find the increase in the number of ticks caused by - the increase in the nfill value made in this loop. If this increase is the - same as the increase caused by the previous loop, increment the number of - equal increases there have been. If the increase is different to last time, - reset the number of equal increases to zero. */ - inc = ntnew - nticks; - if( inc == linc ) { - nsame++; - } else { - nsame = 0; - use_nfill = nfill; - } - -/* If the past 3 increases in nfill has not caused any change in the rate - of increase of nticks, then re-create the ticks for the value of nfill - which started the current run of equal increment values, and leave the - loop. */ - if( nsame == 3 ) { - ticks = (double *) astFree( (void *) ticks ); - nticks = FindMajTicks2( use_nfill, gap, centre, ngood, data, &ticks, status ); - break; - } - -/* Save this times values for use in the next loop. */ - linc = inc; - nticks = ntnew; - } - -/* Remove ticks which are not within the axis ranges to be displayed. - Ticks which are very close to the limit are moved to a safe (but - visually negligable) distance away from the limit). */ - bot = astGetBottom( frame, axis ); - top = astGetTop( frame, axis ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - delta = 0.05*gap; - r = ticks; - for( k = 0; k < nticks; k++ ){ - if( *r != AST__BAD ) { - if( fabs( *r - bot ) < delta ) { - *r = bot + delta; - } else if( fabs( *r - top ) < delta ) { - *r = top - delta; - } else if( *r < bot || *r > top ) { - *r = AST__BAD; - } - } - r++; - } - -/* Use the Mapping to place each tick mark value in its primary domain. - This is a sort of normalization, similar but different to that performed - by the astNorm method. */ - Norm1( map, axis, nticks, ticks, refval, width, status ); - -/* Check for success. */ - if( astOK ){ - -/* Ensure that all ticks marks are offset from the "centre" value by an - integer multiple of the gap size. This is done by changing each tick - value to the closest acceptable value. Also ensure that values close to - zero (i.e. less than 1E-10 of the gap size) are set exactly to zero. */ - r = ticks; - for( k = 0; k < nticks; k++ ){ - if( *r != AST__BAD ) { - f = floor( 0.5 + ( *r - centre )/gap ); - *r = f*gap + centre; - if( fabs( *r ) < 1.0E-10*gap ) *r = 0.0; - r++; - } else { - r++; - } - } - -/* Sort the tick values into increasing order. */ - qsort( (void *) ticks, (size_t) nticks, sizeof(double), Compared ); - -/* Remove any duplicate or BAD tick values by shuffling the higher unique - values down to over-write them. We subtract the centre value of both - tick values before comparing them for equality in order to avoid - unnecessarily removing tick marks in high precsion data. */ - r = ticks + 1; - w = ticks; - for( k = 1; k < nticks && astOK; k++ ){ - if( *r != AST__BAD && !astEQUALS( *r-centre, *w-centre, 1.0E8 ) ){ - w++; - *w = *r; - } - r++; - } - -/* Modify the number of ticks to exclude the duplicate ones. */ - nticks = (int) ( w - ticks ) + 1; - - } - -/* If an error has occurred, free the memory holding the major tick mark - values, and indicate that zero tick marks have been found. */ - if( !astOK ){ - ticks = (double *) astFree( (void *) ticks ); - nticks = 0; - } - -/* Store the pointer to the major tick mark values. */ - *tick_data = ticks; - -/* Return the number of major ticks. */ - return nticks; - -} -static int FindMajTicks2( int nfill, double gap, double centre, int ngood, - double *data, double **tick_data, int *status ){ -/* -* Name: -* FindMajTicks2 - -* Purpose: -* Find candidate major tick marks for FindMajTicks. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindMajTicks2( int nfill, double gap, double centre, int ngood, -* double *data, double **tick_data, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* A service routine for function FindMajTicks. - -* Parameters: -* nfill -* Number of tick marks to extend by at edges of coverage -* gap -* The supplied value for the gaps between ticks on the axis. -* centre -* The supplied axis value at which to put a central tick. -* ngood -* The number of good values in the array pointer to by "data" (i.e. -* values not equal to AST__BAD). -* data -* A pointer to an array holding sorted axis values covering the -* entire plotting area. -* tick_data -* A pointer to a place at which to store a pointer to an array -* holding the returned tick mark values for the axis. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of major tick mark values stored in the array pointer to -* by "*tick_data". - -* Notes: -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned in "tick_data", and zero -* is returned for the function value. -*/ - -/* Local Variables: */ - double *ticks; /* Pointer to the axis values at the major tick marks */ - int i; /* Index of current axis value */ - int j; /* Index of filled in tick */ - int k; /* Tick mark index */ - int klast; /* Index of the previous tick mark */ - int nticks; /* Number of major tick marks used */ - -/* Initialise the returned pointer. */ - *tick_data = NULL; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - nticks = 0; - -/* Reserve memory to hold a reasonable number of tick mark axis values. - This memory is later extended as necessary. */ - ticks = (double *) astMalloc( sizeof(double)*( 6*nfill + 14 ) ); - -/* Check that the pointer can be used. */ - if( astOK ){ - -/* Put the first tick marks just below the lowest axis value (in case - the grid did not sample the entire range of the axis). */ - k = floor( ( data[ 0 ] - centre )/gap ); - - for ( i = 0; i < nfill; i++ ){ - ticks[ i ] = gap*(double)( k - nfill + i ) + centre; - } - ticks[ nfill ] = gap*(double)( k ) + centre; - -/* Initialise the number of major tick marks found so far. */ - nticks = nfill + 1; - -/* Loop round each of the remaining good ordered axis values. */ - klast = k; - for( i = 1; i < ngood && astOK; i++ ) { - -/* Find the tick marks enclosing the axis value. The tick mark placed at - "centre" is called tick mark zero, and tick marks are indexed (positive - or negative) from an origin at "centre". Find the index of the more - negative of the two tick marks enclosing the axis value. */ - k = floor( ( data[ i ] - centre )/gap ); - -/* Ensure that the tick marks enclosing the current axis value are used. - Some extra tick marks are used at the start and end of any gaps in - the axis coverage. This is done to "fill in" small holes caused by the - grid of physical coordinate values not completely covering the - plotting area. Large holes, such as occur on an RA axis covering the 2 - hour range from 23 hours to 1 hour are left without any tick marks in - them (the "hole" in this case is the 22 hours range from 1 hour to 23 - hours). */ - for( j = 0; j < nfill + 1; j++ ){ - if( k - klast > nfill + 2 - j ) { - ticks = (double *) astGrow( ticks, nticks + 1, sizeof( double ) ); - if( astOK ) ticks[ nticks++ ] = - gap*(double)( klast + nfill + 1 - j ) + centre; - } - if( k - klast > nfill - j ) { - ticks = (double *) astGrow( ticks, nticks + 1, sizeof( double ) ); - if( astOK ) ticks[ nticks++ ] = - gap*(double)( k - nfill + j ) + centre; - } - } - -/* Save the index of the current tick mark. */ - klast = k; - - } - -/* Add extra tick marks beyond the end in case the grid did not sample - the entire range of the axis. */ - ticks = (double *) astGrow( ticks, nticks + nfill + 1, sizeof( double ) ); - for( i = 0; i < nfill && astOK; i++ ){ - ticks[ nticks++ ] = gap*(double)( klast + i + 1 ) + centre; - } - - } - -/* If an error has occurred, free the memory holding the major tick mark - values, and indicate that zero tick marks have been found. */ - if( !astOK ){ - ticks = (double *) astFree( (void *) ticks ); - nticks = 0; - } - -/* Store the pointer to the major tick mark values. */ - *tick_data = ticks; - -/* Return the number of major ticks. */ - return nticks; - -} - -static int FindDPTZ( AstFrame *fr, int axis, const char *fmt, - const char *text, int *ndp, int *ntz, int *status ) { -/* -* Name: -* FindDPTZ - -* Purpose: -* Find the number of decimal places and trailing zeros in a label. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindDPTZ( AstFrame *fr, int axis, const char *fmt, -* const char *text, int *ndp, int *ntz, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied label is split into fields using the astFields method of -* the supplied frame. The number of decimal places in the last -* field is returned in *ndp, and the total number of trailing zeros -* (excluding exponents) is returned in *ntz. - -* Parameters: -* fr -* The frame. -* axis -* The axis index to which the label applies. -* fmt -* The format string used to format the label. -* text -* The text of the label. -* ndp -* Pointer to an int in which to return the number of decimal -* places in the final field. -* ntz -* Pointer to an int in which to return the number of trailing zeros. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if and only if a non-zero digit is found in any field. - -*/ - -/* Local Constants: */ -#define MAXFLD 10 - -/* Local Variables: */ - char *fields[ MAXFLD ]; - const char *a; - const char *dot; - const char *ff; - double junk; - int fnc; - int i; - int j; - int l; - int mxnd; - int nc[ MAXFLD ]; - int nf; - int result; - -/* Initialise */ - *ndp = 0; - *ntz = 0; - result = 0; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Split the label up into fields. */ - nf = astFields( fr, axis, fmt, text, MAXFLD, fields, nc, &junk ); - if( nf > 0 ) { - -/* Search the last fields (assumed to be the least significant) for a - decimal point. */ - ff = fields[ nf - 1 ]; - fnc = nc[ nf - 1 ]; - dot = strchr( ff, '.' ); - if( dot && ( ff - dot >= fnc ) ) dot = NULL; - -/* Find the number of digits following the decimal point. */ - if( dot ) { - *ndp = strspn( dot + 1, "0123456789" ); - mxnd = fnc - ( dot - ff ) - 1; - if( *ndp > mxnd ) *ndp = mxnd; - } else { - *ndp = 0; - } - -/* Loop through all the fields, from least significant to most significant, - counting the number of trailing zeros. */ - *ntz = 0; - for( i = nf - 1; i >= 0; i-- ) { - l = strspn( fields[ i ], "-+0123456789." ); - if( l > nc[ i ] ) l = nc[ i ]; - a = fields[ i ] + l - 1; - for( j = l - 1; j >= 0; j--,a-- ){ - if( *a == '0' ) { - (*ntz)++; - } else if( isdigit( *a ) ) { - result = 1; - break; - } - } - if( j >= 0 ) break; - } - } - -/* Return the result. */ - return result; - -/* Undefine local constants: */ -#undef MAXFLD - -} - -static int FindString( int n, const char *list[], const char *test, - const char *text, const char *method, - const char *class, int *status ){ -/* -* Name: -* FindString - -* Purpose: -* Find a given string within an array of character strings. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FindString( int n, const char *list[], const char *test, -* const char *text, const char *method, const char *class, -* int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function identifies a supplied string within a supplied -* array of valid strings, and returns the index of the string within -* the array. The test option may not be abbreviated, but case is -* insignificant. - -* Parameters: -* n -* The number of strings in the array pointed to be "list". -* list -* A pointer to an array of legal character strings. -* test -* A candidate string. -* text -* A string giving a description of the object, parameter, -* attribute, etc, to which the test value refers. -* This is only for use in constructing error messages. It should -* start with a lower case letter. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the identified string within the supplied array, starting -* at zero. - -* Notes: -* - A value of -1 is returned if an error has already occurred, or -* if this function should fail for any reason (for instance if the -* supplied option is not specified in the supplied list). - -*/ - -/* Local Variables: */ - int ret; /* The returned index */ - -/* Check global status. */ - if( !astOK ) return -1; - -/* Compare the test string with each element of the supplied list. Leave - the loop when a match is found. */ - for( ret = 0; ret < n; ret++ ) { - if( !Ustrcmp( test, list[ ret ], status ) ) break; - } - -/* Report an error if the supplied test string does not match any element - in the supplied list. */ - if( ret >= n ) { - astError( AST__OPT, "%s(%s): Illegal value '%s' supplied for %s.", status, - method, class, test, text ); - ret = -1; - } - -/* Return the answer. */ - return ret; -} - -static char *FindWord( char *ptr, const char *d, const char **p, int *status ) { -/* -* Name: -* FindWord - -* Purpose: -* Return a copy of the next word in a supplied string. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* char *FindWord( char *ptr, const char *d, const char **p, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function locates the start and end of the first word in the -* string pointed to by *p, and returns a copy of the word. The pointer -* *p is modified to point to the start of the following word (if any). -* The characters which delimit words are supplied in string "d". - -* Parameters: -* ptr -* A pointer to a character string in which to store the returned -* word. The memory holding this string should have been allocated -* using one of the functions in the AST "memory" module. The memory -* area will be modified in size to fit the returned word. A NULL -* pointer may be supplied if no memory has yet been allocated. -* Any memory pointed to by ptr is freed if a NULL pointer is -* returned by this function (i.e. if no word is found). -* d -* A string holding the characters which are to be used as word -* delimiters. -* p -* The address of a character string pointer. On entry, this pointer -* identifies the start of the string to be searched. On exit, it is -* modified to point to the start of the following word. It is -* returned NULL if there are no more words. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated character string holding the -* next word, or NULL if no word could be found. - -*/ - -/* Local Variables: */ - const char *a, *b, *c; - char *ret; - int nc; - -/* Free any allocated memory and return if any of the supplied pointers - (except ptr) is NULL, or if an error has occurred. */ - if( !astOK || !d || !p || !*p ) { - (void) astFree( (void *) ptr ); - return NULL; - } - -/* Get a pointer to the first character which is not in "d". Terminate - the loop if a null character is encountered. */ - a = *p; - while( *a && strchr( d, (int) *a ) ) a++; - -/* Get a pointer to the next character which is in "d". Terminate - the loop if a null character is encountered. */ - b = a; - while( *b && !strchr( d, (int) *b ) ) b++; - -/* Get a pointer to the next character which is not in "d". Terminate - the loop if a null character is encountered. */ - c = b; - while( *c && strchr( d, (int) *c ) ) c++; - -/* Adjust the supplied pointer so that it points to the start of the next - word. */ - if( *c ){ - *p = c; - } else { - *p = NULL; - } - -/* Get a null-terminated copy of the word between a and b. */ - nc = b - a; - if( nc > 0 ) { - ret = (char *) astStore( (void *) ptr, (void *) a, (size_t) (nc + 1) ); - ret[ nc ] = 0; - } else { - ret = astFree( (void *) ptr ); - } - - return ret; -} - -static const char *SplitValue( AstPlot *this, const char *value, int axis, - int *split, int *status ) { -/* -* Name: -* FormatValue - -* Purpose: -* Format a coordinate value for a Frame axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* const char *SplitValue( AstPlot *this, const char *value, -* int axis, int *split ) - -* Class Membership: -* Plot member function - -* Description: -* This function splits long formatted values (such as the date/time -* format produced by the TimeFrame class) if possible onto two lines -* by inclusion of Plot escape sequences. - -* Parameters: -* this -* Pointer to the Plot. -* value -* The formatted coordinate value. -* axis -* Indicates whether or not short lines should be split by -* including a blank first line. If zero, and if "*split" is non-zero, -* then short lines are put onto the second line,and the first line -* is blank. -* split -* Pointer to an integer that controls behaviour: -* -* 0 - Split the line if it is too long, and return a value of +1 -* in *split. -* 1 - Split the line even if it does not need splitting, making -* the first line blank and the second line containing all the -* supplied text (*split is unchanged on exit). - -* Returned Value: -* A pointer to a static buffer containing a null-terminated string -* holding the (possibly split) formatted value. This will be a copy of -* the supplied pointer if the string does not need to be split. - -* Notes: -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - char *d; - const char *result; - float rsp; - int aft_end; - int aft_start; - int bef_end; - int bef_start; - int i; - int id; - int idmin; - int imin; - int l; - int naft; - int nbef; - int nlong; - int nshort; - int nsp; - -/* Initialise */ - result = value; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Do nothing more if the formatted value already contains graphical - escape sequences, or if graphical escapes sequences are not being - interpreted. */ - if( value && astGetEscape( this ) && !HasEscapes( value, status ) ) { - -/* Attempt to find a space close to the centre of the formatted string. */ - l = strlen( value ); - idmin = 2*l; - imin = -1; - for( i = 0; i < l; i++ ) { - if( isspace( value[ i ] ) ) { - id = abs( i - l/2 ); - if( id < idmin ) { - idmin = id; - imin = i; - } - } - } - -/* We split the line if previous lines have been split (i.e. if *split was - non-zero on entry) or if this line is long AND it contains a space. This - means that a sequence of long labels will not be split unless they contain - spaces. */ - if( *split || ( l > 9 && imin != -1 ) ) { - *split = 1; - -/* Initialse the pointer into the returned buffer at which the next - character will be placed. */ - d = splitvalue_buff; - -/* If no spaces were found... */ - if( imin == -1 ) { - -/* If axis is zero, we add a blank first line. */ - if( axis == 0 ) { - -/* Fill the first line with spaces. */ - for( i = 0; i < l; i++ ) *(d++) = ' '; - -/* Add an escape sequence that moves down by one character height. */ - d += sprintf( d, "%%v170+" ); - } - -/* Add the whole of the supplied text. */ - for( i = 0; i < l; i++ ) *(d++) = value[ i ]; - -/* If a space was found... */ - } else { - -/* Find the first and last non-blank characters before the mid-space. */ - bef_start = -1; - bef_end = -1; - for( i = 0; i < imin; i++ ) { - if( !isspace( value[ i ] ) ) { - if( bef_start == -1 ) bef_start = i; - bef_end = i; - } - } - -/* Find the first and last non-blank characters after the mid-space. */ - aft_start = -1; - aft_end = -1; - for( i = imin + 1; i < l; i++ ) { - if( !isspace( value[ i ] ) ) { - if( aft_start == -1 ) aft_start = i; - aft_end = i; - } - } - -/* How many significant characters before and after the space? */ - nbef = bef_end - bef_start + 1; - naft = aft_end - aft_start + 1; - -/* Get the lengths of the longer and shorter line. */ - if( nbef > naft ) { - nlong = nbef; - nshort = naft; - } else { - nlong = naft; - nshort = nbef; - } - -/* Find the fractional number of spaces before the significant text of the - shorter line.*/ - rsp = 0.5*( nlong - nshort + 1 ); - -/* If the top line is the shorter line, put some spaces in at the start. */ - if( nbef < naft ) { - nsp = (int) rsp; - for( i = 0; i < nsp; i++ ) *(d++) = ' '; - } - -/* Add the significant text from the top line. */ - for( i = bef_start; i <= bef_end; i++ ) *(d++) = value[ i ]; - -/* Add an escape sequence that moves down by one character height. */ - d += sprintf( d, "%%v100+" ); - - -/* Add an escape sequence that moves to the left by the required amount. */ - d += sprintf( d, "%%<%d+", (int) ( 60.0*( (float) nlong - rsp )) ); - -/* Add the significant text from the bottom line. */ - for( i = aft_start; i <= aft_end; i++ ) *(d++) = value[ i ]; - - } - -/* Terminate it. */ - *d = 0; - -/* Return a pointer to the buffer. */ - result = splitvalue_buff; - } - } - -/* If an error occurred, clear the returned value. */ - if ( !astOK ) result = NULL; - -/* Return the result. */ - return result; -} - -static void Fpoly( AstPlot *this, const char *method, const char *class, - int *status ){ -/* -* Name: -* Fpoly - -* Purpose: -* Flush all stored poly lines to the graphics system. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Fpoly( AstPlot *this, const char *method, const char *class, -* int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function sends all previously drawn poly lines to the graphics -* system for rendering, and frees the memory used to hold the poly -* lines. It attempts to reduce the number of graphics calls by -* concatenating continuous polylines together. - -* Parameters: -* this -* Pointer to the Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - float xmid; - float xt; - float ymid; - float *xnew; - float *ynew; - int polylen; - float *xp1; - float *xp2; - float *yp1; - float *yp2; - float yt; - int *ekey; - int *p; - int *skey; - int *drawn; - int ihi; - int ikey; - int ilo; - int imid; - int ipass; - int ipoint; - int ipoly; - int jpoly; - int kpoly; - int *polylist; - int npoly; - int np; - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Output any pending polyline. */ - Opoly( this, status ); - -/* If there is just one polyline to output, just draw it and then free - the memory used to hold the polyline. */ - if( Poly_npoly == 1 ) { - GLine( this, Poly_np[ 0 ], Poly_xp[ 0 ], Poly_yp[ 0 ], method, class, - status ); - Poly_xp[ 0 ] = astFree( Poly_xp[ 0 ] ); - Poly_yp[ 0 ] = astFree( Poly_yp[ 0 ] ); - Poly_np[ 0 ] = 0; - -/* If there are multiple polylines to output, see if any of them can be - combined before drawing them. */ - } else if( Poly_npoly > 1 ) { - -/* No polyline buffer allocated yet. */ - xnew = NULL; - ynew = NULL; - -/* Allocate an array to hold the order in which polylines should be - concatenated. Each value in this array will be the index of one of the - original polylines. A positive index indicates that the polyline - should be appended in its original order. A negative index indicates - that the polyline should be appended in reversed order. Polyline zero - is always appended in its original order. */ - polylist = astMalloc( Poly_npoly*sizeof( int ) ); - npoly = 0; - -/* Create an array of drawn, one for each individual polyline. The flag - is zero if the corresponding polyline has not yet been drawn. */ - drawn = astCalloc( Poly_npoly, sizeof( int ) ); - -/* Create two sorted keys for the polylines - one that sorts them into - increasing x at the start of the polyline, and another that sorts them - into increasing x at the end of the polyline. */ - skey = astMalloc( Poly_npoly*sizeof( int ) ); - ekey = astMalloc( Poly_npoly*sizeof( int ) ); - if( astOK ) { - - p = skey; - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) *(p++) = ipoly; - qsort( skey, Poly_npoly, sizeof(int), Fpoly_scmp ); - - p = ekey; - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) *(p++) = ipoly; - qsort( ekey, Poly_npoly, sizeof(int), Fpoly_ecmp ); - - } - -/* Continue to search for separate polylines that can be combined together - until we know there are no more. */ - while( astOK ) { - -/* Search for the first polyline that has not already been drawn. */ - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) { - if( !drawn[ ipoly ] ) break; - } - -/* Leave the loop if no more polylines remain to be plotted. */ - if( ipoly == Poly_npoly ) break; - -/* Initialise the list of polylines to hold the polyline found above, in - its forward sense. */ - polylist[ 0 ] = ipoly; - npoly = 1; - drawn[ 0 ] = 1; - -/* Initialise the concatenation point to be the end of the polyline found - above. Also, initialise the total number of points in the combined - polyline (polylen). */ - ipoint = Poly_np[ ipoly ] - 1; - xt = Poly_xp[ ipoly ][ ipoint ]; - yt = Poly_yp[ ipoly ][ ipoint ]; - polylen = ipoint + 1; - -/* Loop until we can find no more polylines to append to the list. - A polyline can be appended if it starts or ends at the current - concatenation point. */ - while( astOK ) { - -/* On the first pass through the next loop, search for a polyline that - starts at the concatenation point. If no such polyline is found, do - a second pass in which we search for a polyline that ends at the - concatenation point. Do not include any previously drawn polylines - in the search. */ - for( ipass = 0; ipass < 2; ipass++ ) { - -/* We use a binary chop to find a polyline which starts (or ends) at the - x value of the concatenation point. */ - jpoly = -1; - ilo = 0; - ihi = Poly_npoly - 1; - while( 1 ) { - imid = ( ilo + ihi )/2; - if( ipass == 0 ) { - jpoly = skey[ imid ]; - xmid = Poly_xp[ jpoly ][ 0 ]; - } else { - jpoly = ekey[ imid ]; - xmid = Poly_xp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( astEQUALS( xmid, xt, 1.0E8 ) ) { - ikey = imid; - break; - } else if( xmid > xt ) { - if( ihi == imid ) { - if( ipass == 0 ) { - jpoly = skey[ ilo ]; - xmid = Poly_xp[ jpoly ][ 0 ]; - } else { - jpoly = ekey[ ilo ]; - xmid = Poly_xp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( !astEQUALS( xmid, xt, 1.0E8 ) ) jpoly = -1; - ikey = ilo; - break; - } - ihi = imid; - } else { - if( ilo == imid ) { - if( ipass == 0 ) { - jpoly = skey[ ihi ]; - xmid = Poly_xp[ jpoly ][ 0 ]; - } else { - jpoly = ekey[ ihi ]; - xmid = Poly_xp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( !astEQUALS( xmid, xt, 1.0E8 ) ) jpoly = -1; - ikey = ihi; - break; - } - ilo = imid; - } - } - -/* If found, there may be more than one such polyline. So we now search - for a polyline that also has the y value of the concatenation point. */ - if( jpoly != -1 ) { - -/* If the polyline found above starts (or ends) at the same Y value as the - concatenation point, then we have found the required polyline. */ - if( ipass == 0 ) { - ymid = Poly_yp[ jpoly ][ 0 ]; - } else { - ymid = Poly_yp[ jpoly ][ Poly_np[ jpoly ] - 1 ]; - } - if( astEQUALS( ymid, yt, 1.0E8 ) && !drawn[ jpoly ] ) break; - jpoly = -1; - -/* Otherwise, search down the list, starting at the polyline found above. */ - if( imid > 0 ) { - for( ikey = imid - 1; ikey >= 0; ikey-- ) { - if( ipass == 0 ) { - kpoly = skey[ ikey ]; - xmid = Poly_xp[ kpoly ][ 0 ]; - ymid = Poly_yp[ kpoly ][ 0 ]; - } else { - kpoly = ekey[ ikey ]; - xmid = Poly_xp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - ymid = Poly_yp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - } - if( astEQUALS( xmid, xt, 1.0E8 ) ) { - if( astEQUALS( ymid, yt, 1.0E8 ) && !drawn[ kpoly ] ) { - jpoly = kpoly; - break; - } - } else { - break; - } - } - if( jpoly != -1 ) break; - } - -/* Now search up the list, starting at the polyline found above. */ - if( imid < Poly_npoly - 1 ) { - for( ikey = imid + 1; ikey < Poly_npoly; ikey++ ) { - if( ipass == 0 ) { - kpoly = skey[ ikey ]; - xmid = Poly_xp[ kpoly ][ 0 ]; - ymid = Poly_yp[ kpoly ][ 0 ]; - } else { - kpoly = ekey[ ikey ]; - xmid = Poly_xp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - ymid = Poly_yp[ kpoly ][ Poly_np[ kpoly ] - 1 ]; - } - if( astEQUALS( xmid, xt, 1.0E8 ) ) { - if( astEQUALS( ymid, yt, 1.0E8 ) && !drawn[ kpoly ] ) { - jpoly = kpoly; - break; - } - } else { - break; - } - } - if( jpoly != -1 ) break; - } - } - } - -/* If a polyline was found that can be combined with the total polyline, - increment the total number of points in the total polyline, add it to - the list, and update the concatenation point. Note, we can omit the - start or end point of the new polyline since it will already be - present in the total polyline, hence the " - 1 " below. */ - if( ipass < 2 ) { - ipoint = Poly_np[ jpoly ] - 1; - - if( ipass == 0 ) { - polylist[ npoly++ ] = jpoly; - xt = Poly_xp[ jpoly ][ ipoint ]; - yt = Poly_yp[ jpoly ][ ipoint ]; - } else { - polylist[ npoly++ ] = -jpoly; - xt = Poly_xp[ jpoly ][ 0 ]; - yt = Poly_yp[ jpoly ][ 0 ]; - } - - polylen += ipoint; - -/* Indicate the polyline has been drawn. */ - drawn[ jpoly ] = 1; - -/* If we cannot find any polyline that starts or ends at the - concatenation point, then we have completed the total polyline. So break - out of the loop, and move on to draw the total polyline. */ - } else { - break; - } - } - -/* If a single polyline is to be drawn, just draw it. */ - if( npoly == 1 ) { - jpoly = polylist[ 0 ]; - GLine( this, Poly_np[ jpoly ], Poly_xp[ jpoly ], - Poly_yp[ jpoly ], method, class, status ); - -/* If more than one polyline is to be drawn, ensure we have arrays that - are large enough to hold all the vertices in the combined polyline. */ - } else { - xnew = astRealloc( xnew, polylen*sizeof( float ) ); - ynew = astRealloc( ynew, polylen*sizeof( float ) ); - if( astOK ) { - -/* Loop round all the polylines that are to be combined to form the total - polyline, and copy all the vertex coordinates into the above arrays. */ - xp1 = xnew; - yp1 = ynew; - for( ipoly = 0; ipoly < npoly; ipoly++ ) { - -/* Index of the next polyline to include in the total polyline. */ - jpoly = polylist[ ipoly ]; - -/* The jpoly value is positive if the polylline is to be inclued in its - original direction. */ - if( jpoly >= 0 ) { - -/* Use the whole of the first polyline. */ - if( ipoly == 0 ) { - np = Poly_np[ jpoly ]; - xp2 = Poly_xp[ jpoly ]; - yp2 = Poly_yp[ jpoly ]; - -/* Omit eh first point of subsequent polylines since it will be the same - as the last pointy already in the total polyline. */ - } else { - np = Poly_np[ jpoly ] - 1; - xp2 = Poly_xp[ jpoly ] + 1; - yp2 = Poly_yp[ jpoly ] + 1; - } - -/* Copy the vertex values in their original order, and update the - pointers to the next element of the total polyline. */ - memcpy( xp1, xp2, np*sizeof(float) ); - memcpy( yp1, yp2, np*sizeof(float) ); - xp1 += np; - yp1 += np; - -/* The jpoly value is negative if the polyline is to be included in its - reversed direction. */ - } else { - jpoly = -jpoly; - -/* Get the number of points to copy. Omit the last point if this is not - the first polyline, since it is already in the total polyline. */ - if( ipoly == 0 ) { - np = Poly_np[ jpoly ]; - } else { - np = Poly_np[ jpoly ] - 1; - } - -/* Copy the individual values in reversed order. */ - xp2 = Poly_xp[ jpoly ] + np - 1; - yp2 = Poly_yp[ jpoly ] + np - 1; - for( ipoint = 0; ipoint < np; ipoint++ ) { - *(xp1++) = *(xp2--); - *(yp1++) = *(yp2--); - } - } - } - -/* And finally, draw the total polyline. */ - GLine( this, polylen, xnew, ynew, method, class, status ); - } - } - } - -/* Free all the individual polylines. */ - for( ipoly = 0; ipoly < Poly_npoly; ipoly++ ) { - Poly_xp[ ipoly ] = astFree( Poly_xp[ ipoly ] ); - Poly_yp[ ipoly ] = astFree( Poly_yp[ ipoly ] ); - Poly_np[ ipoly ] = 0; - } - -/* Free other resources. */ - polylist = astFree( polylist ); - drawn = astFree( drawn ); - xnew = astFree( xnew ); - ynew = astFree( ynew ); - skey = astFree( skey ); - ekey = astFree( ekey ); - } - -/* Indicate that all polylines have been sent to the graphics system. */ - Poly_npoly = 0; -} - -static int Fpoly_ecmp( const void *a, const void *b ){ -/* -* Name: -* Fpoly_ecmp - -* Purpose: -* Compare two polylines ending X position - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Fpoly_ecmp( const void *a, const void *b ) - -* Class Membership: -* Plot member function. - -* Description: -* This function is designed to be used as a comparison function with -* the "qsort" function. It is used in function Fpoly. -* -* If orders the two polylines on the basis of the X coordinate at -* their ends. - -* Parameters: -* a -* Pointer to an int holding the index of the first polyline. -* b -* Pointer to an int holding the index of the second polyline. - -* Returned Value: -* -1 if the first polyline ends at a lower X than the second. -* +1 if the first polyline ends at a higher X than the second. -* 0 if the two polylines end at the same X. - -*/ - -/* Local Variables: */ - float xa; /* X at end of first polyline */ - float xb; /* X at end of second polyline */ - int result = 0; /* Returned value */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get the x coord at the end of the two polylines. */ - xa = Poly_xp[ *( (int *) a) ][ Poly_np[ *( (int *) a) ] - 1 ]; - xb = Poly_xp[ *( (int *) b) ][ Poly_np[ *( (int *) b) ] - 1 ]; - -/* Compare them. */ - if( xa < xb ) { - result = -1; - } else if( xa > xb ){ - result = 1; - } - - return result; -} - -static int Fpoly_scmp( const void *a, const void *b ){ -/* -* Name: -* Fpoly_scmp - -* Purpose: -* Compare two polylines starting X position - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Fpoly_scmp( const void *a, const void *b ) - -* Class Membership: -* Plot member function. - -* Description: -* This function is designed to be used as a comparison function with -* the "qsort" function. It is used in function Fpoly. -* -* If orders the two polylines on the basis of the X coordinate at -* their starts. - -* Parameters: -* a -* Pointer to an int holding the index of the first polyline. -* b -* Pointer to an int holding the index of the second polyline. - -* Returned Value: -* -1 if the first polyline starts at a lower X than the second. -* +1 if the first polyline starts at a higher X than the second. -* 0 if the two polylines starts at the same X. - -*/ - -/* Local Variables: */ - float xa; /* X at start of first polyline */ - float xb; /* X at start of second polyline */ - int result = 0; /* Returned value */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Get the x coord at the start of the two polylines. */ - xa = Poly_xp[ *( (int *) a) ][ 0 ]; - xb = Poly_xp[ *( (int *) b) ][ 0 ]; - -/* Compare them. */ - if( xa < xb ) { - result = -1; - } else if( xa > xb ){ - result = 1; - } - - return result; -} - -static AstFrameSet *Fset2D( AstFrameSet *fset, int ifrm, int *status ) { -/* -* Name: -* Fset2D - -* Purpose: -* Create a FrameSet with no more than 2 dimensions for a given Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstFrameSet *Fset2D( AstFrameSet *fset, int ifrm, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function checks a specified Frame in the supplied FrameSet. -* If the Frame has more than 2 dimensions, a new Frame is added to -* the FrameSet containing just the first two axes of the specified -* Frame. A PermMap is used to connect this Frame to the specified -* Frame, which supplied bad values for any missing axes. If the -* specified Frame is the base Frame in the supplied FrameSet, then the -* new Frame becomes the base Frame in the returned FrameSet. Like-wise, -* if the specified Frame is the current Frame, then the new Frame -* will be the current Frame in the returned FrameSet. -* -* If the specified Frame does not have more than 2 axes, then a clone -* of the FrameSet pointer is returned, otherwise the returned pointer -* points to a copy of the supplied FrameSet with the new 2-D Frame -* added. - -* Parameters: -* fset -* Pointer to the FrameSet. -* ifrm -* The index of the Frame to check. This should be AST__BASE or -* AST_CURRENT. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a FrameSet in which the Frame with index given by ifrm -* has no more than 2 axes. -*/ - -/* Local Variables: */ - AstFrame *frm; - AstFrame *newfrm; - AstFrameSet *ret; - AstPermMap *map; - double zero; - int *inperm; - int axes[2]; - int i; - int ic; - int nax; - -/* Check the inherited status. */ - if( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - map = NULL; - -/* Get a pointer to the requested Frame in the supplied FrameSet. */ - frm = astGetFrame( fset, ifrm ); - -/* See how many dimensions the specified Frame of the supplied FrameSet - has. */ - nax = astGetNaxes( frm ); - -/* If it is more than 2-dimensionbal, create a 2D Frame by picking - axes 1 and 2 from the original Frame. */ - if( nax > 2 ) { - axes[ 0 ] = 0; - axes[ 1 ] = 1; - newfrm = astPickAxes( frm, 2, axes, NULL ); - -/* Create a PermMap to describe the mapping between the two Frames. - Use zero as the value for unknown axes (the optional mapping which - can be returned by astPickAxes uses AST__BAD for unknown axes). */ - inperm = (int *) astMalloc( sizeof(int)*(size_t) nax ); - if( astOK ){ - inperm[ 0 ] = 0; - inperm[ 1 ] = 1; - for( i = 2; i < nax; i++ ) inperm[ i ] = -1; - zero = 0.0; - map = astPermMap( nax, inperm, 2, axes, &zero, "", status ); - inperm = (int *) astFree( (void *) inperm ); - } - -/* Get a copy of the supplied FrameSet. */ - ret = astCopy( fset ); - -/* Add the new Frame to the FrameSet (it becomes the current Frame). */ - ic = astGetCurrent( ret ); - astAddFrame( ret, ifrm, map, newfrm ); - newfrm = astAnnul( newfrm ); - -/* If the new Frame was derived from the base frame, set the new base - Frame, and re-instate the original current Frame */ - if( ifrm == AST__BASE ){ - astSetBase( ret, astGetCurrent( ret ) ); - astSetCurrent( ret, ic ); - } - -/* If the specified Frame in the supplied FrameSet is 2-dimensional, just - return a clone of it. */ - } else { - ret = astClone( fset ); - } - -/* Annul the pointer to the original Frame. */ - frm = astAnnul( frm ); - - return ret; - -} - -static int FullForm( const char *list, const char *test, const char *text, - const char *method, const char *class, int *status ){ -/* -* Name: -* FullForm - -* Purpose: -* Identify the full form of an option string. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int FullForm( const char *list, const char *test, const char *text, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function identifies a supplied test option within a supplied -* list of valid options, and returns the index of the option within -* the list. The test option may be abbreviated, and case is -* insignificant. - -* Parameters: -* list -* A list of space separated option strings. -* test -* A candidate option string. -* text -* A string giving the context in which the supplied test option -* was supplied. For instance, this may be an attribute setting string. -* This is only for use in constructing error messages. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The index of the identified option within the supplied list, starting -* at zero. - -* Notes: -* - A value of -1 is returned if an error has already occurred, or -* if this function should fail for any reason (for instance if the -* supplied option is not uniquely specified in the supplied list). - -*/ - -/* Local Variables: */ - char *option; /* Pointer to a copy of the next option */ - const char *p; /* Pointer to the start of the next word */ - int i; /* Current option index */ - int len; /* Length of supplied option */ - int nmatch; /* Number of matching options */ - int ret; /* The returned index */ - -/* Initialise the answer to indicate that the option has not been - uniquely identified. */ - ret = -1; - -/* Check global status. */ - if( !astOK ) return ret; - -/* Save the number of characters in the supplied test option (excluding - trailing spaces). */ - len = ChrLen( test, status ); - -/* Compare the supplied test option against each of the known options in - turn. Count the number of matches. */ - nmatch = 0; - p = list; - option = FindWord( NULL, " ", &p, status ); - i = 0; - while( option ){ - -/* If the test string and the current option are identical (including - length). use the current option. */ - -/* If every character in the supplied label matches the corresponding - character in the current test label we have a match. Increment the - number of matches and save the current item index. If the test string - and the current option are identical (including length), use the - current option. */ - - if( !Ustrncmp( test, option, len, status ) ) { - ret = i; - if( ChrLen( option, status ) == len ) { - nmatch = 1; - option = astFree( option ); - break; - } else { - nmatch++; - } - } - -/* Get a pointer to the next option. */ - option = FindWord( option, " ", &p, status ); - i++; - } - -/* Report an error if no match was found, and return -1. */ - if( !nmatch ){ - astError( AST__OPT, "%s(%s): Option '%.*s' is unknown in '%.*s'.", status, - method, class, len, test, ChrLen( text, status ), text ); - ret = -1; - -/* Report an error if the label was ambiguous, and return -1. */ - } else if( nmatch > 1 ){ - astError( AST__OPT, "%s(%s): Option '%.*s' is ambiguous in '%.*s'.", status, - method, class, len, test, ChrLen( text, status ), text ); - ret = -1; - } - -/* Return the answer. */ - return ret; -} - -static void GAttr( AstPlot *this, int attr, double value, double *old_value, - int prim, const char *method, const char *class, int *status ) { -/* -* -* Name: -* GAttr - -* Purpose: -* Call the GAttr Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GAttr( AstPlot *this, int attr, double value, double *old_value, -* int prim, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GAttr grf function to enquire or set a -* graphics attribute value. It either calls the version registered using -* astGrfSet, or the version in the linked grf module. The linked version -* is used if the Grf attribute is zero, or if no function has been -* registered for GAttr using astGrfSet. - -* Parameters: -* this -* The Plot. -* attr -* An integer value identifying the required attribute. The -* following symbolic values are defined in grf.h: -* -* GRF__STYLE - Line style. -* GRF__WIDTH - Line width. -* GRF__SIZE - Character and marker size scale factor. -* GRF__FONT - Character font. -* GRF__COLOUR - Colour index. -* value -* A new value to store for the attribute. If this is AST__BAD -* no value is stored. -* old_value -* A pointer to a double in which to return the attribute value. -* If this is NULL, no value is returned. -* prim -* The sort of graphics primitive to be drawn with the new attribute. -* Identified by the following values defined in grf.h: -* GRF__LINE -* GRF__MARK -* GRF__TEXT -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. Also return if there is nothing to do. */ - if ( !astOK || ( !old_value && value == AST__BAD ) ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GATTR ] ) { - grf_status = ( *( this->GAttr ) )( this, attr, value, old_value, prim, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGAttr( attr, value, old_value, prim ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGAttr. ", status, method, - class ); - } - -} - -static AstKeyMap *GetGrfContext( AstPlot *this, int *status ){ -/* -*++ -* Name: -c astGetGrfContext -f AST_GETGRFCONTEXT - -* Purpose: -* Return the KeyMap that describes a Plot's graphics context. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c AstKeyMap *astGetGrfContext( AstPlot *this ) -f RESULT = AST_GETGRFCONTEXT( THIS, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function -f This routine -* returns a reference to a KeyMap that will be passed to any drawing -c functions registered using astGrfSet. -f routines registered using AST_GRFSET. -* This KeyMap can be used by an application to pass information to -c the drawing functions -f the drawing routines -* about the context in which they are being called. The contents of -* the KeyMap are never accessed byt the Plot class itself. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astGetGrfContext() -f AST_GETGRFCONTEXT = INTEGER -* A pointer to the graphics context KeyMap. The returned pointer -* should be annulled when it is no longer needed. - -*-- -*/ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Ensure that a grfcon KeyMap exists. */ - (void) astGrfConID(this); - -/* Return a cloned pointer to the KeyMap. */ - return astClone( this->grfcontext ); -} - -AstKeyMap *astGrfConID_( AstPlot *this, int *status ) { -/* -*+ -* -* Name: -* astGrfConID - -* Purpose: -* Ensure a GrfContext KeyMap exists and return an ID for it. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* AstKeyMap *astGrfConID( AstPlot *this ) - -* Class Membership: -* Plot private function. - -* Description: -* This function creates a GrfContext KeyMap if the Plot does not -* currently have one, and returns an ID for it. - -* Parameters: -* this -* The Plot. - -* Returned Value: -* ID for the GrfContext KeyMap. - -*- -*/ - if( !this->grfcontext ) { - this->grfcontext = astKeyMap("", status ); - this->grfcontextID = astMakeId( astClone( this->grfcontext ) ); - astExempt( this->grfcontextID ); - } - return this->grfcontextID; -} - -static void GScales( AstPlot *this, float *alpha, float *beta, - const char *method, const char *class, int *status ) { -/* -* -* Name: -* GScales - -* Purpose: -* Call the GScales Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GScales( AstPlot *this, float *alpha, float *beta, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GScales grf function, either calling the -* version registered using astGrfSet, or the version in the linked grf -* module. The linked version is used if the Grf attribute is zero, or if -* no function has been registered for GScales using astGrfSet. - -* Parameters: -* this -* The Plot. -* alpha -* A pointer to the location at which to return the scale for the -* X axis (i.e. Xnorm = alpha*Xworld). -* beta -* A pointer to the location at which to return the scale for the -* Y axis (i.e. Ynorm = beta*Yworld). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* if we already have the required values, return them. */ - if( Grf_alpha != 0.0 && Grf_beta != 0.0 ) { - if( alpha ) *alpha = Grf_alpha; - if( beta ) *beta = Grf_beta; - return; - } - -/* Check that the grf mdoule can give us scales information. */ - if( GCap( this, GRF__SCALES, 1, status ) ) { - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GSCALES ] ) { - grf_status = ( *( this->GScales ) )( this, &Grf_alpha, &Grf_beta, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGScales( &Grf_alpha, &Grf_beta ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Check neither value is zero. */ - if( grf_status && ( Grf_alpha == 0.0 || Grf_beta == 0.0 ) ) { - astError( AST__GRFER, "astGScales: Returned axis scales are %g and %g " - "but zero is illegal!", status, Grf_alpha, Grf_beta ); - grf_status = 0; - } - -/* Report an error if anything went wrong, and return safe values. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGScales. ", status, method, - class ); - Grf_alpha = 1.0; - Grf_beta = 1.0; - } - -/* If the grf module is not capable of giving us scale information, then - just assume the the axes are equally scaled, except for any axis reversal - indicated in the supplied Plot. */ - } else { - Grf_alpha = ( this->xrev ) ? -1.0 : 1.0; - Grf_beta = ( this->yrev ) ? -1.0 : 1.0; - } - -/* Store them for future use. */ - if( alpha ) *alpha = Grf_alpha; - if( beta ) *beta = Grf_beta; -} - -static int GCap( AstPlot *this, int cap, int value, int *status ){ -/* -* -* Name: -* GCap - -* Purpose: -* Call the GCap Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GCap( AstPlot *this, int cap, int value, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GCap grf function to inquire a capability -* of the grf module, either calling the version registered using -* astGrfSet, or the version in the linked grf module. The linked -* version is used if the Grf attribute is zero, or if no function -* has been registered for GCap using astGrfSet. - -* Parameters: -* this -* The Plot. -* cap -* The capability to be inquired aboue. -* value -* The value ot assign to the capability. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the grf module is capabale of performing the action -* requested by "cap". - -*/ - -/* Local Variables: */ - int result; /* Value retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GCAP ] ) { - result = ( *( this->GCap ) )( this, cap, value, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - result = astGCap( cap, value ); - - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Return the result. */ - return result; -} - -static void GenCurve( AstPlot *this, AstMapping *map, int *status ){ -/* -*++ -* Name: -c astGenCurve -f AST_GENCURVE - -* Purpose: -* Draw a generalized curve. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astGenCurve( AstPlot *this, astMapping *map ) -f CALL AST_GENCURVE( THIS, MAP ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a general user-defined curve defined by the -f This routine draws a general user-defined curve defined by the -* supplied Mapping. Note that the curve is transformed into graphical -* coordinate space for plotting, so that a straight line in -* physical coordinates may result in a curved line being drawn if -* the Mapping involved is non-linear. Any discontinuities in the -* Mapping between physical and graphical coordinates are -c catered for, as is any clipping established using astClip. -f catered for, as is any clipping established using AST_CLIP. -* -c If you need to draw simple straight lines (geodesics), astCurve -c or astPolyCurve will usually be easier to use and faster. -f If you need to draw simple straight lines (geodesics), AST_CURVE -f or AST_POLYCURVE will usually be easier to use and faster. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c map -f MAP = INTEGER (Given) -* Pointer to a Mapping. This Mapping should have 1 input -* coordinate representing offset along the required curve, -* normalized so that the start of the curve is at offset 0.0, -* and the end of the curve is at offset 1.0. Note, this offset -* does not need to be linearly related to distance along the curve. -* The number of output coordinates should equal the number of axes -* in the current Frame of the Plot. The Mapping should map a -* specified offset along the curve, into the corresponding -* coordinates in the current Frame of the Plot. The inverse -* transformation need not be defined. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astGenCurve"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Only proceed if there has been no error. */ - if( astOK ){ - -/* Initialise the bounding box for primitives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__CURVE_ID, 1, GRF__LINE, method, class ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the externals used to communicate with the Map4 function... */ - Map4_ncoord = astGetNout( this ); - Map4_plot = this; - Map4_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - Map4_umap = map; - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map4; - Crv_ink = 1; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = Curve_data.xbrk; - Crv_ybrk = Curve_data.ybrk; - Crv_vxbrk = Curve_data.vxbrk; - Crv_vybrk = Curve_data.vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over the curve. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Map these points into graphics coordinates. */ - Map4( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map4 to draw the curve. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map4. */ - Map4( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - Curve_data.length = Crv_len; - Curve_data.out = Crv_out; - Curve_data.nbrk = Crv_nbrk; - PurgeCdata( &Curve_data, status ); - -/* Annul the Mapping. */ - Map4_map = astAnnul( Map4_map ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__CURVE_ID, 0, GRF__LINE, method, class ); - } - -/* Return. */ - return; - -} - -static int GetLabelUnits( AstPlot *this, int axis, int *status ) { -/* -* Name: -* GetLabelUnits - -* Purpose: -* Return the value of the LabelUnits attribute for a Plot axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetLabelUnits( AstPlot *this, int axis, int *status ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns the value of the LabelUnits attribute for a -* Plot axis, supplying a suitable default if not set. - -* Parameters: -* this -* The Plot. -* axis -* The axis index (zero based). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The attribute value. - -*/ - -/* Local Variables: */ - AstFrame *fr; /* The current Frame in the Plot */ - AstFrame *primframe; /* The primary Frame holding the requested axis */ - AstSystemType system; /* The SkyFrame System attribute */ - int primaxis; /* Index of requested axis in the primary frame */ - int ret; /* The returned value */ - -/* Initialise. */ - ret = 0; - -/* Check global status. */ - if( !astOK ) return ret; - -/* If a value has been set, return it. */ - ret = this->labelunits[ axis ]; - -/* If no value has been set, find a default. */ - if( ret == -1 ) { - -/* Assume "no" for any SkyAxis axes within the current frame of the Plot, - and "yes" for other axes. Get a pointer to the current Frame of the - Plot. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* The current Frame may be a CmpFrame. So find the primary Frame containing - the requested axis. The primary Frame is guaranteed not to be a CmpFrame. */ - astPrimaryFrame( fr, axis, &primframe, &primaxis ); - -/* If the primary Frame is a SkyFrame representing ICRS, equatorial, ecliptic, - galactic or supergalactic coords, use a default of "no" for LabelUnits. - Otherwise use a default of "yes". */ - ret = 1; - if( IsASkyFrame( (AstObject *) primframe, status ) ) { - system = astGetSystem( primframe ); - if( system == AST__ICRS || - system == AST__FK4 || - system == AST__FK4_NO_E || - system == AST__FK5 || - system == AST__GAPPT || - system == AST__ECLIPTIC || - system == AST__GALACTIC || - system == AST__SUPERGALACTIC ) ret = 0; - } - -/* Annul the frame pointers. */ - primframe = astAnnul( primframe ); - fr = astAnnul( fr ); - } - -/* Return the answer. */ - return ret; -} - -static void GBBuf( AstPlot *this, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GBBuf - -* Purpose: -* Call the GBBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GBBuf( AstPlot *this, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GBBuf grf function to begin a new graphics -* context, either calling the version registered using astGrfSet, or -* the version in the linked grf module. The linked version is used -* if the Grf attribute is zero, or if no function has been registered -* for GBBuf using astGrfSet. - -* Parameters: -* this -* The Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GBBUF ] ) { - grf_status = ( *( this->GBBuf ) )( this, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGBBuf(); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGBBuf. ", status, method, - class ); - } - -} - -static void GEBuf( AstPlot *this, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GEBuf - -* Purpose: -* Call the GEBuf Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GEBuf( AstPlot *this, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GEBuf grf function to end the current graphics -* context, either calling the version registered using astGrfSet, or -* the version in the linked grf module. The linked version is used -* if the Grf attribute is zero, or if no function has been registered -* for GEBuf using astGrfSet. - -* Parameters: -* this -* The Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GEBUF ] ) { - grf_status = ( *( this->GEBuf ) )( this, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGEBuf(); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGEBuf. ", status, method, - class ); - } - -} - -static void GFlush( AstPlot *this, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GFlush - -* Purpose: -* Call the Gflush Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GFlush( AstPlot *this, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the Gflush grf function to flush graphics, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for Gflush using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GFLUSH ] ) { - grf_status = ( *( this->GFlush ) )( this, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGFlush(); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGFlush. ", status, method, - class ); - } - -} - -static void GLine( AstPlot *this, int n, const float *x, - const float *y, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GLine - -* Purpose: -* Call the Gline Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GLine( AstPlot *this, int n, const float *x, -* const float *y, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the Gline grf function to draw a polyline, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for Gline using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int i; /* Loop count */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Do not draw anything if we are using "invisible ink". */ - if( astGetInvisible( this ) ) { - grf_status = 1; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - } else if( astGetGrf( this ) && this->grffun[ AST__GLINE ] ) { - grf_status = ( *( this->GLine ) )( this, n, x, y, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGLine( n, x, y ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGLine. ", status, method, - class ); - -/* Otherwise, update the box containing all drawn graphics primitives. */ - } else if( !Boxp_freeze ){ - for( i = 0; i < n; i++ ) { - Boxp_lbnd[ 0 ] = astMIN( x[ i ], Boxp_lbnd[ 0 ] ); - Boxp_ubnd[ 0 ] = astMAX( x[ i ], Boxp_ubnd[ 0 ] ); - Boxp_lbnd[ 1 ] = astMIN( y[ i ], Boxp_lbnd[ 1 ] ); - Boxp_ubnd[ 1 ] = astMAX( y[ i ], Boxp_ubnd[ 1 ] ); - } - } - -} - -static void GMark( AstPlot *this, int n, const float *x, - const float *y, int type, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GMark - -* Purpose: -* Call the GMark Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GMark( AstPlot *this, int n, const float *x, -* const float *y, int type, const char *method, -* const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GMark grf function to draw markers, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for GMark using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* n -* The number of positions to be joined together. -* x -* A pointer to an array holding the "n" x values. -* y -* A pointer to an array holding the "n" y values. -* type -* An integer which can be used to indicate the type of marker symbol -* required. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int i; /* Loop count */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Do not draw anything if we are using "invisible ink". */ - if( astGetInvisible( this ) ) { - grf_status = 1; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - } else if( astGetGrf( this ) && this->grffun[ AST__GMARK ] ) { - grf_status = ( *( this->GMark ) )( this, n, x, y, type, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGMark( n, x, y, type ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGMark. ", status, method, - class ); - -/* Otherwise, update the box containing all drawn graphics primitives. */ - } else if( !Boxp_freeze ){ - for( i = 0; i < n; i++ ) { - Boxp_lbnd[ 0 ] = astMIN( x[ i ], Boxp_lbnd[ 0 ] ); - Boxp_ubnd[ 0 ] = astMAX( x[ i ], Boxp_ubnd[ 0 ] ); - Boxp_lbnd[ 1 ] = astMIN( y[ i ], Boxp_lbnd[ 1 ] ); - Boxp_ubnd[ 1 ] = astMAX( y[ i ], Boxp_ubnd[ 1 ] ); - } - } - -} - -static void GQch( AstPlot *this, float *chv, float *chh, const char *method, - const char *class, int *status ) { -/* -* -* Name: -* GQch - -* Purpose: -* Call the GQch Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GQch( AstPlot *this, float *chv, float *chh, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GQch grf function, either calling the -* version registered using astGrfSet, or the version in the linked grf -* module. The linked version is used if the Grf attribute is zero, or if -* no function has been registered for GQch using astGrfSet. - -* Parameters: -* this -* The Plot. -* chv -* A pointer to the double which is to receive the height of -* characters drawn with a vertical baseline . This will be an -* increment in the X axis. -* chh -* A pointer to the double which is to receive the height of -* characters drawn with a horizontal baseline. This will be an -* increment in the Y axis. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* if we already have the required values, return them. */ - if( Grf_chh != AST__BAD && Grf_chv != AST__BAD ) { - *chh = Grf_chh; - *chv = Grf_chv; - return; - } - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GQCH ] ) { - grf_status = ( *( this->GQch ) )( this, chv, chh, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGQch( chv, chh ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Check neither value is zero. */ - if( grf_status && ( *chh == 0.0 || *chv == 0.0 ) ) { - astError( AST__GRFER, "astGQch: Returned text heights are %g and %g " - "but zero is illegal!", status, *chv, *chh ); - grf_status = 0; - } - -/* Report an error if anything went wrong, and return safe values. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGQch. ", status, method, - class ); - *chh = 1.0; - *chv = 1.0; - } - -/* Store them for future use. */ - Grf_chh = *chh; - Grf_chv = *chv; -} - -static void GText( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, - const char *method, const char *class, int *status ) { -/* -* -* Name: -* GText - -* Purpose: -* Call the GText Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GText( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, -* const char *method, const char *class, int *status ) { - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GText grf function to draw a text string, either -* calling the version registered using astGrfSet, or the version in the -* linked grf module. The linked version is used if the Grf attribute -* is zero, or if no function has been registered for GText using -* astGrfSet. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* Do not draw anything if we are using "invisible ink". */ - if( astGetInvisible( this ) ) { - grf_status = 1; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - } else if( astGetGrf( this ) && this->grffun[ AST__GTEXT ] ) { - grf_status = ( *( this->GText ) )( this, text, x, y, just, upx, upy, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGText( text, x, y, just, upx, upy ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGText. ", status, method, - class ); - } - -} - -static void GTxExt( AstPlot *this, const char *text, float x, float y, - const char *just, float upx, float upy, float *xbn, - float *ybn, const char *method, const char *class, int *status ) { -/* -* -* Name: -* GTxExt - -* Purpose: -* Call the GTxExt Grf function. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void GTxExt( AstPlot *this, const char *text, float x, float y, -* const char *just, float upx, float upy, float *xbn, -* float *ybn, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot private function. - -* Description: -* This function calls the GTxExt grf function to find the extent -* of a text string, either calling the version registered using -* astGrfSet, or the version in the linked grf module. The linked -* version is used if the Grf attribute is zero, or if no function -* has been registered for GTxExt using astGrfSet. - -* Parameters: -* this -* The Plot. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* The reference x coordinate. -* y -* The reference y coordinate. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -* upy -* The y component of the up-vector for the text, in graphics world -* coordinates. If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. -* xbn -* An array of 4 elements in which to return the x coordinate of -* each corner of the bounding box. -* ybn -* An array of 4 elements in which to return the y coordinate of -* each corner of the bounding box. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - The corners are returned in no particular order. - -*/ - -/* Local Variables: */ - int grf_status; /* Status retruned from Grf function */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Since we are about to call an external function which may not be - thread safe, prevent any other thread from executing the following code - until the current thread has finished executing it. */ - LOCK_MUTEX2; - -/* If the Grf attribute is set to a non-zero value, use the Grf function - registered using astGrfSet (so long as a function has been supplied). - This is called via a wrapper which adapts the interface to suit the - language in which the function is written. */ - if( astGetGrf( this ) && this->grffun[ AST__GTXEXT ] ) { - grf_status = ( *( this->GTxExt ) )( this, text, x, y, just, upx, upy, - xbn, ybn, status ); - -/* Otherwise, use the function in the external Grf module, selected at - link-time using ast_link options.*/ - } else { - grf_status = astGTxExt( text, x, y, just, upx, upy, xbn, ybn ); - } - -/* Allow the next thread to proceed. */ - UNLOCK_MUTEX2; - -/* Report an error if anything went wrong. */ - if( !grf_status ) { - astError( AST__GRFER, "%s(%s): Graphics error in astGTxExt. ", status, method, - class ); - } -} - -static const char *GetAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* GetAttrib - -* Purpose: -* Get the value of a specified attribute for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* const char *GetAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot member function (over-rides the protected astGetAttrib -* method inherited from the FrameSet class). - -* Description: -* This function returns a pointer to the value of a specified -* attribute for a Plot, formatted as a character string. -* -* The value returned is the value which would actually be used if -* astGrid was called with the current set of attribute values. This -* may not always be the same as the value set by the user. For -* instance, if Labelling is set to "exterior" by the user, it may not -* be possible to produce exterior labels, in which case interior labels -* will be produced. If this function is used to get the value of -* Labelling in this situation, then the value actually used (i.e. -* interior) will be returned instead of the requested value (i.e. -* exterior). -* -* Some attributes have dynamic defaults, (i.e. the behaviour if not -* set depends on the values of other attributes). If the value for -* such an attribute is enquired using this function, then the dynamic -* default value actually used will be returned if no value has been -* set explicitly for the attribute. - -* Parameters: -* this -* Pointer to the Plot. -* attrib -* Pointer to a null terminated string containing the name of -* the attribute whose value is required. This name should be in -* lower case, with all white space removed. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* - Pointer to a null terminated string containing the attribute -* value. - -* Notes: -* - The returned string pointer may point at memory allocated -* within the Plot, or at static memory. The contents of the -* string may be over-written or the pointer may become invalid -* following a further invocation of the same function or any -* modification of the Plot. A copy of the string should -* therefore be made if necessary. -* - A NULL pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *this; /* Pointer to the Plot structure */ - const char *result; /* Pointer value to return */ - char label[21]; /* Graphics item label */ - double dval; /* Double attribute value */ - int axis; /* Axis number */ - int ival; /* Int attribute value */ - int len; /* Length of attrib string */ - int nax; /* Number of base Frame axes */ - int nc; /* No. characters read by astSscanf */ - -/* Initialise. */ - result = NULL; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_object); - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Indicate that the current bound box should not be changed during the - execution of this function (this may happen if a grid is drawn to get - the default value for an attribute such as Labelling). */ - Boxp_freeze = 1; - -/* Compare "attrib" with each recognised attribute name in turn, - obtaining the value of the required attribute. If necessary, write - the value into "getattrib_buff" as a null terminated string in an appropriate - format. Set "result" to point at the result string. */ - -/* Tol. */ -/* ---- */ - if ( !strcmp( attrib, "tol" ) ) { - dval = astGetTol( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Grid. */ -/* ----- */ - } else if ( !strcmp( attrib, "grid" ) ) { - ival = GetUsedGrid( this, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TickAll. */ -/* -------- */ - } else if ( !strcmp( attrib, "tickall" ) ) { - ival = astGetTickAll( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ForceExterior. */ -/* -------------- */ - } else if ( !strcmp( attrib, "forceexterior" ) ) { - ival = astGetForceExterior( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Invisible. */ -/* ---------- */ - } else if ( !strcmp( attrib, "invisible" ) ) { - ival = astGetInvisible( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Border. */ -/* ------- */ - } else if ( !strcmp( attrib, "border" ) ) { - ival = GetUsedBorder( this, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* ClipOp. */ -/* ------- */ - } else if ( !strcmp( attrib, "clipop" ) ) { - ival = astGetClipOp( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Clip. */ -/* ----- */ - } else if ( !strcmp( attrib, "clip" ) ) { - ival = astGetClip( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Grf. */ -/* ---- */ - } else if ( !strcmp( attrib, "grf" ) ) { - ival = astGetGrf( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* DrawTitle. */ -/* --------- */ - } else if ( !strcmp( attrib, "drawtitle" ) ) { - ival = astGetDrawTitle( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Escape. */ -/* ------- */ - } else if ( !strcmp( attrib, "escape" ) ) { - ival = astGetEscape( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelAt(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelat(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedLabelAt( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Centre(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "centre(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedCentre( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Gap. */ -/* ---- */ - } else if ( !strcmp( attrib, "gap" ) ) { - dval = GetUsedGap( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "gap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedGap( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* LogGap. */ -/* ---- */ - } else if ( !strcmp( attrib, "loggap" ) ) { - dval = GetUsedLogGap( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* LogGap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loggap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedLogGap( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* NumLabGap. */ -/* -------- */ - } else if ( !strcmp( attrib, "numlabgap" ) ) { - dval = astGetNumLabGap( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* NumLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetNumLabGap( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* TextLabGap. */ -/* ----------- */ - } else if ( !strcmp( attrib, "textlabgap" ) ) { - dval = astGetTextLabGap( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* TextLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetTextLabGap( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* LabelUp. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelup" ) ) { - ival = astGetLabelUp( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelup(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetLabelUp( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogPlot. */ -/* -------- */ - } else if ( !strcmp( attrib, "logplot" ) ) { - ival = astGetLogPlot( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logplot(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetLogPlot( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogLabel. */ -/* -------- */ - } else if ( !strcmp( attrib, "loglabel" ) ) { - ival = GetUsedLogLabel( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loglabel(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedLogLabel( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogTicks. */ -/* -------- */ - } else if ( !strcmp( attrib, "logticks" ) ) { - ival = GetUsedLogTicks( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logticks(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedLogTicks( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* NumLab. */ -/* -------- */ - } else if ( !strcmp( attrib, "numlab" ) ) { - ival = astGetNumLab( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* NumLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = astGetNumLab( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* MinTick. */ -/* -------- */ - } else if ( !strcmp( attrib, "mintick" ) ) { - ival = GetUsedMinTick( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* MinTick(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "mintick(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedMinTick( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TextLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "textlab" ) ) { - ival = GetUsedTextLab( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* TextLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedTextLab( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* DrawAxes. */ -/* ----------- */ - } else if ( !strcmp( attrib, "drawaxes" ) ) { - ival = astGetDrawAxes( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "drawaxes(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetDrawAxes( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Abbrev. */ -/* ----------- */ - } else if ( !strcmp( attrib, "abbrev" ) ) { - ival = astGetAbbrev( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Abbrev(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "abbrev(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetAbbrev( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelUnits. */ -/* ----------- */ - } else if ( !strcmp( attrib, "labelunits" ) ) { - ival = GetUsedLabelUnits( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* LabelUnits(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelunits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedLabelUnits( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Style. */ -/* ------ */ - } else if ( !strcmp( attrib, "style" ) ) { - ival = GetUseStyle( this, AST__BORDER_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Style(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "style(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseStyle( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Font. */ -/* ----- */ - } else if ( !strcmp( attrib, "font" ) ) { - ival = GetUseFont( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Font(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "font(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseFont( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Colour. */ -/* ------- */ - } else if ( !strcmp( attrib, "colour" ) ) { - ival = GetUseColour( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Colour(label). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "colour(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseColour( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Color. */ -/* ------ */ - } else if ( !strcmp( attrib, "color" ) ) { - ival = GetUseColour( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Color(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "color(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - ival = GetUseColour( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%d", ival ); - result = getattrib_buff; - } - -/* Width. */ -/* ------ */ - } else if ( !strcmp( attrib, "width" ) ) { - dval = GetUseWidth( this, AST__BORDER_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - - -/* Width(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "width(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - dval = GetUseWidth( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Size. */ -/* ----- */ - } else if ( !strcmp( attrib, "size" ) ) { - dval = GetUseSize( this, AST__TEXTLABS_ID, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Size(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "size(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - dval = GetUseSize( this, FullForm( GrfLabels, label, attrib, "astGet", astGetClass( this ), status ), status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* TitleGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "titlegap" ) ) { - dval = astGetTitleGap( this ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MajTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "majticklen" ) ) { - dval = GetUsedMajTickLen( this, 0, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MajTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "majticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = GetUsedMajTickLen( this, axis - 1, status ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MinTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "minticklen" ) ) { - dval = astGetMinTickLen( this, 0 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* MinTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "minticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - dval = astGetMinTickLen( this, axis - 1 ); - if ( astOK ) { - (void) sprintf( getattrib_buff, "%.*g", DBL_DIG, dval ); - result = getattrib_buff; - } - -/* Labelling. */ -/* ---------- */ - } else if ( !strcmp( attrib, "labelling" ) ) { - ival = GetUsedLabelling( this, status ); - if ( astOK ) { - result = ival ? xlbling[1] : xlbling[0]; - } - -/* Edge(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "edge(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - ival = GetUsedEdge( this, axis - 1, status ); - if ( astOK ) { - if( ival == LEFT ){ - result = "left"; - } else if( ival == RIGHT ){ - result = "right"; - } else if( ival == TOP ){ - result = "top"; - } else if( ival == BOTTOM ){ - result = "bottom"; - } else { - result = "<bad>"; - } - } - -/* If the attribute name was not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_getattrib)( this_object, attrib, status ); - } - -/* Unfreeze the bound box so that it may be updated by subsequent - plotting functions. */ - Boxp_freeze = 0; - -/* Return the result. */ - return result; -} - -static AstPointSet *GetDrawnTicks( AstPlot *this, int axis, int major, int *status ){ -/* -*+ -* Name: -* astGetDrawnTicks - -* Purpose: -* Return information about the ticks last drawn by astGrid. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *GetDrawnTicks( AstPlot *this, int axis, int major ) - -* Class Membership: -* Plot method. - -* Description: -* This function returns a PointSet holding information about the -* tick marks (either major and minor) that were drawn by the previous -* invocation of astGrid. A NULL pointer is returned if astGrid has -* not yet been invoked. - -* Parameters: -* this -* Pointer to a Plot. -* axis -* The zero-based axis of the axis for which tick mark information -* is required. -* major -* Supply a non-zero value if information about the major tick -* marks is to be returned, and zero if information about the minor -* tick marks is to be returned. - -* Returned Value: -* A pointSet with one point for every tick of the requested type drawn -* by astGrid for the specified axis. Each point has 2 coordinate values, -* being the graphics coordinates at the start of the tick mark. The -* returned PointSet pointer should be annulled when no longer needed. - -*- -*/ - -/* Local Variables: */ - AstPointSet *result = NULL; - double *ptr[ 3 ]; - int n; - -/* Check the global status. */ - if( !astOK ) return result; - -/* Report an error if the supplied axis value is incorrect. */ - if( axis < 0 || axis > 1 ) { - astError( AST__INTER, "astGetDrawnTicks(Plot): Supplied \"axis\" " - "value is %d - should 0 or 1 (internal AST programming " - "error).", status, axis ); - n = 0; - -/* If OK, get the number of stored tick marks. */ - } else { - n = major ? this->majtickcount[ axis ] : this->mintickcount[ axis ]; - } - -/* Check that information is available. */ - if( n > 0 && astOK ) { - -/* Create a PointSet with the required size. */ - result = astPointSet( n, 2, "", status ); - -/* Store pointers to the arrays within the Plot that hold the required - tick marks positions and types. */ - ptr[ 0 ] = major ? this->majtickgx[ axis ] : this->mintickgx[ axis ]; - ptr[ 1 ] = major ? this->majtickgy[ axis ] : this->mintickgy[ axis ]; - astSetPoints( result, ptr ); - } - -/* Return the PointSet. */ - return result; -} - -static double GetTicks( AstPlot *this, int axis, double *cen, double **ticks, - int *nmajor, double **minticks, int *nminor, - int format_set, int *inval, double *refval, - GetTicksStatics **pstatics, const char *method, - const char *class, int *status ){ -/* -* Name: -* GetTicks - -* Purpose: -* Obtain a list of logarithmically or linearly spaced tick mark values for -* a single axis in a 2-D physical coordinate Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GetTicks( AstPlot *this, int axis, double *cen, double **ticks, -* int *nmajor, double **minticks, int *nminor, -* int format_set, int *inval, double *refval, -* GetTicksStatics **pstatics, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* For linearly spaced major ticks the "gap" returned by this function -* is the constant difference between adjacent major tick marks. For -* logarithmically spaced major ticks the "gap" returned by this -* function is the constant ratio between adjacent major tick marks. -* -* If a gap size has been specified using attribute Gap (or LogGap for -* logarithmic ticks) supplied, the specified value is returned, and used -* to determine the tick values. If no gap size is supplied, a default -* gap size is used and returned. -* -* All this is over-ridden if the astSetTickValues method has been -* called to store explicit tick mark values in the Plot structure. -* In this case, the values supplied using astSetTickValues are -* returned. - -* Parameters: -* this -* The Plot. Supplying a NULL pointer will cause statics resources -* to be released. -* axis -* The zero-based index of the axis to use. -* cen -* Pointer to the supplied axis value at which to put a single -* central tick. Other ticks will be placed evenly on either side -* of this tick. If AST__BAD is provided, a value will be used -* which would put a tick at an axis value of one. The used value -* is returned. -* ticks -* Pointer to a place at which to return a pointer to the memory in -* which are stored the major tick values to be used. This pointer -* should be freed using astFree when no longer needed. The number of -* values in the array is given by the value returned by parameter -* "nmajor". -* nmajor -* A pointer to a location at which to return the number of major -* ticks. -* minticks -* Pointer to a place at which to return a pointer to the memory in -* which are stored the minor tick values to be used. This pointer -* should be freed using astFree when no longer needed. The number of -* values in the array is given by the value returned by parameter -* "nminor". The minor tick marks values returned in this array are -* the ones stored in the Plot via a call to the astSetTickValues -* function. If this function has not been called, then a NULL -* pointer is returned, and the "nminor" value is returned holding the -* number of divisions between major ticks. -* nminor -* A pointer to a location at which to return either the number of -* division into which each gap should be divided when drawing minor -* tick marks (if "*minticks" is returned holding NULL), or the -* total number of minor tick values stored in "*minticks" (if -* "*minticks" is returned non-NULL). The number of divisions -* between major tick values is one more than the number of minor -* tick marks. -* format_set -* Indicates if an explicit format has been set for the axis. If -* not, "cen" is always assumed to be AST__BAD, and any specified -* Gap value is rounded to the nearest "nice" value. This has -* to be done because the algorithm for choosing a format avoiding -* unnecessary precision only works if the gap size causes 1 digit to -* change between adjacent labels. -* inval -* A pointer to a location at which to return a flag indicating if -* any invalid physical coordinates were encountered. -* refval -* A pointer to a location at which to return a value for the other -* axis which can be used when normalizing the returned tick mark -* values. -* pstatics -* Address of a pointer to a structure holding static data values -* used within this function. A NULL pointer should be supplied on -* the first invocation (dynamic memory will then be allocated to -* hold ths structure). The memory is freed when a NULL value for -* "this" is supplied. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The used gap size. - -* Notes: -* - This function allocates some static resources on its first -* invocation, which should be released when no longer needed, or when -* a different Plot is supplied, by calling this function with a NULL -* pointer for parameter "this". All other parameters are ignored. -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - An error is reported if the region containing valid physical -* coordinates is too small to use. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned in "ticks", zero -* is returned for the number of major and minor ticks marks. -*/ - -/* Local Variables: */ - GetTicksStatics *statics; /* Pointer to statics structure */ - double *tick; /* Pointer to next tick value */ - double cen0; /* Supplied value of cen */ - double dran; /* Dynamic range of axis values */ - double frac; /* Fraction of plot area holding good coords */ - double gap; /* Supplied value for Gap or LogGap */ - double log_used_gap; /* Log10( the used gap size ) */ - double maxv; /* Max axis value */ - double minv; /* Min axis value */ - double new_used_gap; /* New value for the used gap size */ - double old_used_gap; /* Old value for the used gap size */ - double test_gap; /* Trial gap size */ - double used_cen; /* Used value of cen */ - double used_gap; /* The used gap size */ - int findcen; /* Find a new centre value? */ - int gap_too_small; /* Test gap too small? */ - int gap_too_large; /* Test gap too large? */ - int i; /* Axis index */ - int ihi; /* Highest tick mark index */ - int ilo; /* Lowest tick mark index */ - int nochange; /* No. of ineffective attempts to change gap size */ - -/* Initialise the returned information. */ - *ticks = NULL; - *minticks = NULL; - *nmajor = 0; - *nminor = 0; - -/* Get a pointer to the supplied statics object. */ - statics = *pstatics; - -/* If a NULL pointer has been supplied for "this", release the resources - allocated on the first call to this function, and return. */ - if( !this ){ - if( statics ) { - if( statics->map ) statics->map = astAnnul( statics->map ); - if( statics->pset ) statics->pset = astAnnul( statics->pset ); - if( statics->frame ) statics->frame = astAnnul( statics->frame ); - *pstatics = astFree( statics ); - } - return 0.0; - } - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* If no statics structure was supplied, create one now and initialise it. */ - if( !statics ) { - statics = astMalloc( sizeof( GetTicksStatics ) ); - if( statics ) { - statics->pset=NULL; - *pstatics = statics; - } - } - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - maxv = 0.0; - minv = 0.0; - used_cen = 0.0; - used_gap = 0.0; - ihi = 0; - ilo = 0; - -/* If this is the first call to this function, do some initialisation. */ - if( !statics->pset ){ - -/* Get the Mapping from Base to Current Frame in the Plot. */ - statics->map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get a pointer to the current Frame from the Plot. */ - statics->frame = astGetFrame( this, AST__CURRENT ); - -/* Get initial guesses at suitable gaps for each axis. A PointSet is - returned holding sorted values (non-normalized) for the physical axes. */ - statics->pset = DefGap( this, statics->defgaps, statics->ngood, &frac, &statics->bad, method, class, status ); - -/* Store the maximum and minimum number of major tick marks along each - axis. These numbers are reduced if only a small part of the plotting - area contains valid coordinates, so that the tick marks do not end up - to close together. */ - statics->maxticks = (int) ( 0.5 + MAJTICKS_MAX*sqrt( frac ) ); - statics->mintick = (int) ( 0.5 + MAJTICKS_MIN*sqrt( frac ) ); - if( statics->mintick < 3 ) statics->mintick = 3; - if( statics->maxticks < 8 ) statics->maxticks = 8; - if( statics->maxticks < statics->mintick ) statics->maxticks = statics->mintick; - -/* Get a pointer to the data in the PointSet. */ - statics->ptr = astGetPoints( statics->pset ); - -/* Find a typical value on each axis. */ - for( i = 0; i < 2 && astOK; i++ ){ - statics->typval[ i ] = Typical( statics->ngood[ i ], statics->ptr[ i ], -DBL_MAX, DBL_MAX, - statics->width + i, status ); - } - } - -/* Return the flag indicating if any regions of invalid physical coordinates - were found. */ - *inval = statics->bad; - -/* Return the typical value on the other axis. */ - *refval = statics->typval[ 1 - axis ]; - -/* See if any tick marks values have been stored in the Plot structure - using astSetTickValues. If so, copy the tick mark values to the - returned arrays and exit with a gap size determined by the first two - ticks. */ - if( this->nmajtickval[ axis ] > 0 ) { - *ticks = astStore( NULL, this->majtickval[ axis ], - this->nmajtickval[ axis ]*sizeof(double) ); - *minticks = astStore( NULL, this->mintickval[ axis ], - this->nmintickval[ axis ]*sizeof(double) ); - *nmajor = this->nmajtickval[ axis ]; - *nminor = this->nmintickval[ axis ]; - - if( *nmajor > 1 && (*ticks)[ 0 ] != AST__BAD && - (*ticks)[ 1 ] != AST__BAD ) { - used_gap = fabs( (*ticks)[ 1 ] - (*ticks)[ 0 ] ); - } else { - used_gap = AST__BAD; - } - - return used_gap; - - } - -/* See if the user has specified a gap size. The default for astGetLogTicks is - determined in DefGaps, so we can now decide whether to use attribute Gap - or LogGap to get the user-supplied gap size. Obtain the requested gap - attribute values for both physical axes. */ - if( astGetLogTicks( this, axis ) ) { - gap = astGetLogGap( this, axis ); - } else { - gap = astGetGap( this, axis ); - } - -/* Find the maximum and minimum value in the plotting area. DefGap will - have reported an error if minv*maxv is negative or zero. */ - if( astOK ) { - maxv = statics->ptr[ axis ][ statics->ngood[ axis ] - 1 ]; - minv = statics->ptr[ axis ][ 0 ]; - } - -/* First deal with logarithmically spaced ticks. */ - dran = ( minv != 0.0 ) ? maxv/minv : 0.0; - if( astGetLogTicks( this, axis ) ) { - -/* If the ratio of max and min data value is not larger than 10, report an - error. */ - dran = ( minv != 0.0 ) ? maxv/minv :0.0; - if( dran < 10.0 && dran > 0.1 ) { - astError( AST__VSMAL, "%s(%s): Cannot produce logarithmically " - "spaced major tick marks on axis %d since the dynamic " - "range of the axis is too small.", status, method, class, axis + 1 ); - } - -/* Should we find a new value for "cen"? */ - findcen = !cen || *cen == AST__BAD || !format_set; - -/* Try to find a "nice" gap size, so long as the caller has not supplied - a gap size. The default gap size obtained above is our initial guess. */ - if( gap == AST__BAD && astOK ){ - -/* Start off using the default gap found during the initialisation. */ - test_gap = statics->defgaps[ axis ]; - -/* Loop round until a gap size is found which gives an acceptable number - of tick marks. Upto 10 gap sizes are tried. */ - for( i = 0; i < 10 && astOK; i++ ){ - -/* Find a "nice" gap size close to the current test gap size. Also find - the number of minor tick marks to use with the nice gap size. Gaps for - logarithmic axes are always powers of ten. */ - log_used_gap = (int) ( log10( test_gap ) + 0.5 ); - if( log_used_gap == 0.0 ) { - log_used_gap = ( test_gap > 1.0 ) ? 1.0 : -1.0; - } - *nminor = 9; - used_gap = pow( 10.0, log_used_gap ); - -/* If no value has been supplied for *cen, choose a value which would put - a major tick mark at the value 1 (or -1), and which is mid way between - the maximum and minimum axis value. */ - if( findcen ) { - used_cen = pow( used_gap, (int) ( 0.5*log10( maxv*minv ) / - log_used_gap ) ); - if( maxv < 0 ) used_cen = -used_cen; - } else { - used_cen = *cen; - } - -/* Find the index of the highest tick which is not larger than the lowest - axis value. */ - if( log_used_gap > 0.0 ) { - ilo = floor( log10( minv/used_cen )/log_used_gap ); - } else { - ilo = ceil( log10( minv/used_cen )/log_used_gap ); - } - -/* Find the index of the lowest tick which is not less than the highest - axis value. */ - if( log_used_gap > 0.0 ) { - ihi = ceil( log10( maxv/used_cen )/log_used_gap ); - } else { - ihi = floor( log10( maxv/used_cen )/log_used_gap ); - } - -/* Find the total number of tick marks. */ - *nmajor = ihi - ilo + 1; - -/* If the number of ticks is unacceptable, try a different gap size. If the - gap was too large to produce any ticks, try using half the gap size. */ - if( *nmajor <= 0 ) { - test_gap = sqrt( test_gap ); - -/* If there were some ticks, but not enough, decrease the gap size in - proportion to the shortfall. */ - } else if( *nmajor < statics->mintick ){ - test_gap = pow( test_gap, (double)( *nmajor )/(double)( statics->mintick ) ); - -/* If there were too many ticks, increase the gap size in proportion to the - excess. */ - } else if( *nmajor > statics->maxticks ){ - test_gap = pow( test_gap, (double)( *nmajor )/(double)( statics->maxticks ) ); - -/* If the number of ticks is acceptable, break out of the loop early.*/ - } else { - break; - } - } - -/* Increase the tick coverage by one at each end to cover up the gaps. */ - ilo--; - ihi++; - *nmajor += 2; - -/* If an explicit gap size was supplied, use it. */ - } else if( astOK ) { - -/* Check it is usable. */ - if( gap == 0.0 && astOK ) { - astError( AST__ATTIN, "%s(%s): Invalid value zero given for " - "attribute LogGap(%d).", status, method, class, axis + 1 ); - - } else if( gap < 0.0 && astOK ) { - astError( AST__ATTIN, "%s(%s): Invalid negative value %f given for " - "attribute LogGap(%d).", status, method, class, gap, axis + 1 ); - -/* If necessary, take its reciprocal in order to ensure that the absolute - tick mark values get smaller or larger as required. */ - } else { - - used_gap = gap; - if( fabs( maxv ) < fabs( minv ) ) { - if( gap > 1.0 ) used_gap = 1.0/gap; - } else { - if( gap < 1.0 ) used_gap = 1.0/gap; - } - -/* Find the nearest power of 10 ( do not allow 10**0 (=1.0) to be used). */ - log_used_gap = (int) ( log10( used_gap ) + 0.5 ); - if( log_used_gap == 0.0 ) { - log_used_gap = ( gap > 1.0 ) ? 1.0 : -1.0; - } - used_gap = pow( 10.0, log_used_gap ); - -/* We always use 9 minor intervals. */ - *nminor = 9; - -/* If no value has been supplied for *cen, choose a value which would put - a major tick mark at the value 1 (or -1), and which is mid way between - the maximum and minimum axis value. */ - if( findcen ) { - used_cen = pow( used_gap, (int) ( 0.5*log10( maxv*minv ) / - log_used_gap ) ); - if( maxv < 0 ) used_cen = -used_cen; - } else { - used_cen = *cen; - } - -/* Find the index of the highest tick which is not larger than the lowest - axis value. */ - if( log_used_gap > 0.0 ) { - ilo = floor( log10( minv/used_cen )/log_used_gap ); - } else { - ilo = ceil( log10( minv/used_cen )/log_used_gap ); - } - -/* Find the index of the lowest tick which is not less than the highest - axis value. */ - if( log_used_gap > 0.0 ) { - ihi = ceil( log10( maxv/used_cen )/log_used_gap ); - } else { - ihi = floor( log10( maxv/used_cen )/log_used_gap ); - } - -/* Find the total number of tick marks. */ - *nmajor = ihi - ilo + 1; - if( *nmajor < 2 && astOK ) { - astError( AST__ATTIN, "%s(%s): Unusable value %f given for " - "attribute LogGap(%d).", status, method, class, gap, axis + 1 ); - - } - } - } - -/* Allocate memory to hold the tick values themselves. */ - *ticks = (double *) astMalloc( sizeof( double )*( *nmajor ) ); - if( astOK ) { - -/* Store them. */ - tick = *ticks; - for( i = ilo; i <= ihi; i++, tick++ ) { - *tick = used_cen*pow( used_gap, i ); - } - } - -/* Store returned centre value. */ - if( cen ) *cen = used_cen; - -/* Now deal with linearly spaced ticks */ - } else { - -/* Store the supplied value of cen. */ - cen0 = ( cen ) ? *cen : AST__BAD; - -/* If no format has been set for the axis, ensure AST__BAD is used for cen. */ - if( !format_set ) cen0 = AST__BAD; - -/* Try to find a "nice" gap size, so long as the caller has not supplied - a gap size. The default gap size obtained above is our initial guess. */ - if( gap == AST__BAD ){ - old_used_gap = AST__BAD; - -/* Start of using the default gap found during the initialisation. */ - test_gap = statics->defgaps[ axis ]; - used_gap = 0.0; - -/* Initialise flags saying the test gap is too large or too small */ - gap_too_large = 0; - gap_too_small = 0; - -/* So far, there have been no ineffective attempts to change the gap - size. */ - nochange = 0; - -/* Loop round until a gap size is found which gives an acceptable number - of tick marks. Upto 10 gap sizes are tried. */ - for( i = 0; i < 10 && astOK; i++ ){ - -/* Find a "nice" gap size close to the current test gap size. Also find - the number of minor tick marks to use with the nice gap size. */ - new_used_gap = astGap( statics->frame, axis, test_gap, nminor ); - -/* Find the number and positions of major tick marks which would result - from using this gap size. Annul the memory used to hold any previous tick - data first. Only do this if the gap being used has actually changed, - otherwise we just retain the values created from the previous run with - this gap size. */ - if( new_used_gap != used_gap ) { - nochange = 0; - old_used_gap = used_gap; - used_gap = new_used_gap; - if( *ticks ) *ticks = astFree( *ticks ); - if( cen ) *cen = cen0; - *nmajor = FindMajTicks( statics->map, statics->frame, axis, *refval, statics->width[ 1-axis ], - used_gap, cen, statics->ngood[ axis ], - statics->ptr[ axis ], ticks, status ); - -/* If the gap size has not changed do an extra pass through this loop, - but only do this a maximum of 25 times in succession. */ - } else if( nochange < 25 ) { - nochange++; - i--; - - } else if( astOK ){ - astError( AST__VSMAL, "%s(%s): Cannot produce enough major " - "tick marks on axis %d using the current axis " - "format (\"%s\").", status, method, class, axis + 1, - astGetFormat( statics->frame, axis ) ); - break; - } - -/* If the number of ticks is unacceptable, try a different gap size. If the - gap was too large to produce any ticks, try using half the gap size. */ - if( *nmajor == 0 ) { - test_gap *= 0.5; - gap_too_large = 1; - gap_too_small = 0; - -/* If there were some ticks, but not enough... */ - } else if( *nmajor < statics->mintick ){ - -/* If the previous test gap produced too many ticks, use the current gap - size. */ - if( gap_too_small ) { - break; - -/* Otherwise, decrease the gap size in proportion to the shortfall. */ - } else { - test_gap *= (double)( *nmajor )/(double)( statics->mintick ); - gap_too_large = 1; - gap_too_small = 0; - } - -/* If there were too many ticks... */ - } else if( *nmajor > statics->maxticks ){ - -/* If the previous test gap produced too few ticks, use the previous gap - size. */ - if( gap_too_large ) { - used_gap = old_used_gap; - if( *ticks ) *ticks = astFree( *ticks ); - if( cen ) *cen = cen0; - *nmajor = FindMajTicks( statics->map, statics->frame, axis, *refval, statics->width[ 1-axis ], - used_gap, cen, statics->ngood[ axis ], - statics->ptr[ axis ], ticks, status ); - break; - -/* Otherwise, increase the gap size in proportion to the excess. */ - } else { - test_gap *= (double)( *nmajor )/(double)( statics->maxticks ); - gap_too_small = 1; - gap_too_large = 0; - } - -/* If the number of ticks is acceptable, break out of the loop early.*/ - } else { - break; - } - } - -/* If an explicit gap size was supplied, use it. */ - } else { - -/* Find a likely value for the number of minor tick marks to use, and find - a nice gap close to the supplied gap (unless an explicit format has - been set). */ - if( format_set ){ - used_gap = gap; - (void) astGap( statics->frame, axis, used_gap, nminor ); - } else { - used_gap = astGap( statics->frame, axis, gap, nminor ); - } - -/* Find where the major ticks should be put. */ - if( cen ) *cen = cen0; - *nmajor = FindMajTicks( statics->map, statics->frame, axis, *refval, statics->width[ 1-axis ], - used_gap, cen, statics->ngood[ axis ], statics->ptr[ axis ], - ticks, status ); - } - } - -/* Report an error if no ticks can be found. */ - if( *nmajor == 0 && astOK ) { - astError( AST__GRFER, "%s(%s): Cannot find any usable tick mark values. ", status, method, - class ); - } - -/* If an error has occurred, annul the memory used to hold tick data, and - return zero ticks. */ - if( !astOK ) { - *ticks = (double *) astFree( (void *) *ticks ); - *nmajor = 0; - *nminor = 0; - used_gap = 0.0; - } - -/* Return. */ - return used_gap; -} - -static double GoodGrid( AstPlot *this, int *dim, AstPointSet **pset1, - AstPointSet **pset2, const char *method, - const char *class, int *status ){ -/* -* Name: -* GoodGrid - -* Purpose: -* Create a grid covering the region containing good coordinates in a -* 2-D physical coordinate Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GoodGrid( AstPlot *this, int *dim, AstPointSet **pset1, -* AstPointSet **pset2, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function creates two PointSets, one holding a square grid of -* graphics coordinates, and the other holding the corresponding physical -* coordinates (not normalized). The grid covers just the area containing -* good physical coordinates. The points are stored row by row in the -* returned PointSets. - -* Parameters: -* this -* The Plot. -* dim -* A pointer to an integer in which to store the number of samples -* along each edge of the returned grid. -* pset1 -* A pointer to a location at which to store a pointer to the -* PointSet holding the graphics coordinates. -* pset2 -* A pointer to a location at which to store a pointer to the -* PointSet holding the physical coordinates. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The fraction of the plotting area containing good physical -* coordinates. - -* Notes: -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - The returned PointSets should be annulled when no longer needed, -* using astAnnul. -* - An error is reported if the region containing valid physical -* coordinates is too small to use. -* - A function value of zero, and NULL pointers are returned if an error -* has already occurred, or if this function should fail for any reason. -*/ - -/* Local Variables: */ - AstFrame *frm; /* Pointer to the Current Frame in the Plot */ - AstMapping *map; /* Pointer to "graphics to physical" mapping */ - double **ptr1; /* Pointer to physical axis value data */ - double **ptr2; /* Pointer to graphics axis value data */ - double *pa; /* Pointer to next value on 1st physical axis */ - double *pb; /* Pointer to next value on 2nd physical axis */ - double *px; /* Pointer to next value on 1st graphics axis */ - double *py; /* Pointer to next value on 2nd graphics axis */ - double dx; /* Cell size along graphics X (1st) axis */ - double dy; /* Cell size along graphics Y (2nd) axis */ - double frac; /* Fraction of good physical coordinates */ - double xmax; /* High X bound of region containing good phy. coords */ - double xmin; /* Low X bound of region containing good phy. coords */ - double ymax; /* High Y bound of region containing good phy. coords */ - double ymin; /* Low Y bound of region containing good phy. coords */ - int j; /* Element offset */ - int ngood; /* Number of grid points with good physical coords */ - int size; /* Number of grid points */ - -/* Initialise the returned PointSet pointers. */ - *pset1 = NULL; - *pset2 = NULL; - -/* Check the global error status. */ - if ( !astOK ) return 0.0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - ptr1 = NULL; - frac = 0.0; - xmax = 0.0; - xmin = 0.0; - ymax = 0.0; - ymin = 0.0; - -/* Get the Mapping from base (graphics) to current (physical) Frame in the - supplied Plot. */ - map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get a pointer to the Current Frame in the Plot. */ - frm = astGetFrame( this, AST__CURRENT ); - -/* Initialise the grid dimension. */ - *dim = 16; - -/* We need a grid which has at least 4 good points. */ - ngood = 0; - while( ngood < 4 && astOK ){ - -/* Double the grid dimension. */ - *dim *= 2; - -/* Report an error if the grid is now too big. */ - if( *dim >= 512 ){ - astError( AST__VSMAL, "%s(%s): The area of the plot containing " - "usable coordinates on both axes is too small.", status, method, - class ); - break; - } - -/* Get two PointSets, one holding a regular grid of graphics coordinates, - and the other holding the corresponding physical coordinates. The grid - covers the entire plotting area with the current grid dimension. A - pointer to the physical axis values is returned. */ - ptr2 = MakeGrid( this, frm, map, 1, *dim, this->xlo, this->xhi, this->ylo, - this->yhi, 2, pset1, pset2, 0, method, class, status ); - -/* Get the number of graphics axis values. */ - size = astGetNpoint( *pset1 ); - -/* Get a pointer to the graphics axis values. */ - ptr1 = astGetPoints( *pset1 ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Find the bounds in graphics coordinates of the area enclosing the - good physical positions in the grid, and count the good positions. */ - ngood = 0; - - pa = ptr2[ 0 ]; - pb = ptr2[ 1 ]; - px = ptr1[ 0 ]; - py = ptr1[ 1 ]; - - xmin = DBL_MAX; - xmax = -DBL_MAX; - ymin = DBL_MAX; - ymax = -DBL_MAX; - - for( j = 0; j < size; j++ ){ - if( *pa != AST__BAD && *pb != AST__BAD ){ - if( *px < xmin ) xmin = *px; - if( *px > xmax ) xmax = *px; - if( *py < ymin ) ymin = *py; - if( *py > ymax ) ymax = *py; - ngood++; - } - px++; - py++; - pa++; - pb++; - } - } - } - -/* Store approximate fraction of the plotting area containing good - physical coordinates. */ - if( astOK ) { - frac = ( (double) ngood )/(double)( astGetNpoint( *pset1 ) ); - -/* Get the size of each grid cell. */ - dx = ptr1[0][1] - ptr1[0][0]; - dy = ptr1[1][1] - ptr1[1][0]; - -/* Extend the area containing good points by one grid cell. */ - xmax += dx; - xmin -= dx; - ymax += dy; - ymin -= dy; - -/* If the area containing good points is significantly smaller than - the supplied area, create a new grid covering just the area containing - good positions. */ - if( ( xmax - xmin ) < 0.9*( this->xhi - this->xlo ) || - ( ymax - ymin ) < 0.9*( this->yhi - this->ylo ) ){ - -/* Find a new grid dimension which results in a cell size similar to - the one used to create the grid, but covering only the region containing - good physical coordinates. */ - *dim *= astMAX( (xmax - xmin)/(this->xhi - this->xlo), - (ymax - ymin)/(this->yhi - this->ylo) ); - if( *dim < 32 ) *dim = 32; - -/* Annul the PointSet holding the current grid. */ - *pset1 = astAnnul( *pset1 ); - *pset2 = astAnnul( *pset2 ); - -/* Create the new grid covering the region containing good physical - coordinates. */ - (void) MakeGrid( this, frm, map, 1, *dim, xmin, xmax, ymin, ymax, 2, - pset1, pset2, 0, method, class, status ); - } - } - -/* Annul the Mapping from base to current Frame, and the pointer to the - Current Frame. */ - map = astAnnul( map ); - frm = astAnnul( frm ); - -/* If an error has occurred, annul the two pointsets and indicate that - there are no good points in the plotting area. */ - if( !astOK ){ - *pset1 = astAnnul( *pset1 ); - *pset2 = astAnnul( *pset2 ); - frac = 0.0; - } - -/* Return. */ - return frac; - -} - -static int GraphGrid( int dim, int disk, double xlo, double xhi, double ylo, - double yhi, double **ptr1, int *status ){ -/* -* Name: -* GraphGrid - -* Purpose: -* Fill an array with a square grid of graphics coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GraphGrid( int dim, int disk, double xlo, double xhi, double ylo, -* double yhi, double **ptr1, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function fills the supplied array with a square grid of graphics -* coordinates covering the supplied area. The points are stored row by -* row, i.e. if the cell size for the grid is (dx,dy), the first point -* is (xmin,ymin), followed by (xmin+dx,ymin), (xmin+2*dx,ymin), up to -* (xmin+(dim-1)*dx,ymin), followed by the next row (xmin,ymin+dy), -* (xmin+dx,ymin+dy), etc. - -* Parameters: -* dim -* The number of samples along each edge of the grid. -* disk -* If non-zero, the corners of the grid are omitted, resulting in a -* grid that is more disk like than rectangular. -* xlo -* The lower bound on the first axis of the region to be covered -* by the grid. -* xhi -* The upper bound on the first axis of the region to be covered -* by the grid. -* ylo -* The lower bound on the second axis of the region to be covered -* by the grid. -* yhi -* The upper bound on the second axis of the region to be covered -* by the grid. -* ptr1 -* A pointer to an array of two pointers giving the start of the two -* arrays to receive the values for each of the two axes of the graphics -* coordinate data. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of points in the grid. If "disk" is zero, this will be -* the square of "dim". If "disk" is non-zero, this will be less than -* the square of "dim" to account for the lack of corner points. - -*/ - -/* Local Variables: */ - double *px; - double *py; - double cen; - double dx; - double dy2; - double dy; - double dx2; - double r2; - double y; - int i; - int j; - int ok; - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* Find the cell size. */ - dx = ( xhi - xlo )/(double)( dim - 1 ); - dy = ( yhi - ylo )/(double)( dim - 1 ); - -/* Store the mid cell index. */ - cen = 0.5*( dim - 1 ); - -/* Store the squared radius of the disk. */ - r2 = 1.9*cen*cen; - -/* Initialise pointers to the start of the two arrays to recieve the - returned graphics values for each axis. */ - px = ptr1[ 0 ]; - py = ptr1[ 1 ]; - -/* Loop round row. */ - for( j = 0; j < dim; j++ ){ - dy2 = j - cen; - dy2 *= dy2; - -/* Get the Y coordinate of the current row. */ - y = ylo + j*dy; - -/* Loop round each column in the current row. */ - for( i = 0; i < dim; i++ ){ - -/* If we are forming a disk rather than a square, check if this point is - sufficiently close to the centre to be included in the disk. */ - if( disk ) { - dx2 = i - cen; - dx2 *= dx2; - ok = ( dx2 + dy2 <= r2 ); - } else { - ok = 1; - } - -/* Store the coordinates of the current grid point. */ - if( ok ) { - *(px++) = xlo + i*dx; - *(py++) = y; - } - } - } - -/* Return the used length of the PointSet. */ - return (int)( px - ptr1[ 0 ] ); -} - -static void GrfPop( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astGrfPop -f AST_GRFPOP - -* Purpose: -* Restore previously saved graphics functions used by a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astGrfPop( AstPlot *this ) -f CALL AST_GRFPOP( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function restores a snapshot of the graphics functions -c stored previously by calling astGrfPush. The restored graphics -c functions become the current graphics functions used by the Plot. -* -c The astGrfPush and astGrfPop functions are intended for situations -c where it is necessary to make temporary changes to the graphics -c functions used by the Plot. The current functions should first be -c saved by calling astGrfPush. New functions should then be registered -c using astGrfSet. The required graphics should then be produced. -c Finally, astGrfPop should be called to restore the original graphics -c functions. -f The AST_GRFPUSH and AST_GRFPOP functions are intended for situations -f where it is necessary to make temporary changes to the graphics -f functions used by the Plot. The current functions should first be -f saved by calling AST_GRFPUSH. New functions should then be registered -f using AST_GRFSET. The required graphics should then be produced. -f Finally, AST_GRFPOP should be called to restore the original graphics -f functions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -f - This routine returns without action if there are no snapshots to -c - This function returns without action if there are no snapshots to -* restore. No error is reported in this case. - -*-- -*/ - -/* Local Variables: */ - AstGrfPtrs *newframe; /* Pointer to the stack frame to restore */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check the stack is not already empty. */ - if( this->grfnstack > 0 ) { - this->grfnstack--; - - if( astOK ) { - newframe = this->grfstack + this->grfnstack; - - for( i = 0; i < AST__NGRFFUN; i++ ) { - this->grffun[i] = (newframe->grffun)[i]; - } - this->GAttr = newframe->GAttr; - this->GBBuf = newframe->GBBuf; - this->GEBuf = newframe->GEBuf; - this->GFlush = newframe->GFlush; - this->GLine = newframe->GLine; - this->GMark = newframe->GMark; - this->GText = newframe->GText; - this->GCap = newframe->GCap; - this->GTxExt = newframe->GTxExt; - this->GScales = newframe->GScales; - this->GQch = newframe->GQch; - } - } -} - -static void GrfPush( AstPlot *this, int *status ) { -/* -*++ -* Name: -c astGrfPush -f AST_GRFPUSH - -* Purpose: -* Save the current graphics functions used by a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astGrfPush( AstPlot *this ) -f CALL AST_GRFPUSH( THIS STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function takes a snapshot of the graphics functions which are -f This routine takes a snapshot of the graphics functions which are -* currently registered with the supplied Plot, and saves the snapshot -* on a first-in-last-out stack within the Plot. The snapshot can be -* restored later using function -c astGrfPop. -f AST_GRFPOP. -* -c The astGrfPush and astGrfPop functions are intended for situations -c where it is necessary to make temporary changes to the graphics -c functions used by the Plot. The current functions should first be -c saved by calling astGrfPush. New functions should then be registered -c using astGrfSet. The required graphics should then be produced. -c Finally, astGrfPop should be called to restore the original graphics -c functions. -f The AST_GRFPUSH and AST_GRFPOP functions are intended for situations -f where it is necessary to make temporary changes to the graphics -f functions used by the Plot. The current functions should first be -f saved by calling AST_GRFPUSH. New functions should then be registered -f using AST_GRFSET. The required graphics should then be produced. -f Finally, AST_GRFPOP should be called to restore the original graphics -f functions. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ - -/* Local Variables: */ - AstGrfPtrs *newframe; /* Pointer to the new stack frame */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Increment the number of frames on the stack. */ - this->grfnstack++; - -/* Ensure the stack is large enough to hold this many frames. */ - this->grfstack = (AstGrfPtrs *) astGrow( (void *) this->grfstack, - this->grfnstack, sizeof( AstGrfPtrs ) ); - if( astOK ) { - -/* Get a pointer to the new stack frame. */ - newframe = this->grfstack + this->grfnstack - 1; - -/* Copy the graphics function pointers from the main Plot attributes - to the new stack frame. */ - for( i = 0; i < AST__NGRFFUN; i++ ) { - (newframe->grffun)[i] = this->grffun[i]; - } - newframe->GAttr = this->GAttr; - newframe->GBBuf = this->GBBuf; - newframe->GEBuf = this->GEBuf; - newframe->GFlush = this->GFlush; - newframe->GLine = this->GLine; - newframe->GMark = this->GMark; - newframe->GText = this->GText; - newframe->GCap = this->GCap; - newframe->GTxExt = this->GTxExt; - newframe->GQch = this->GQch; - newframe->GScales = this->GScales; - } -} - -static void GrfSet( AstPlot *this, const char *name, AstGrfFun fun, int *status ){ -/* -*++ -* Name: -c astGrfSet -f AST_GRFSET - -* Purpose: -c Register a graphics function for use by a Plot. -f Register a graphics routine for use by a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c void astGrfSet( AstPlot *this, const char *name, AstGrfFun fun ) -f CALL AST_GRFSET( THIS, NAME, FUN, STATUS ) - -* Class Membership: -* Plot member function. - -* Description: -c This function can be used to select the underlying graphics -c functions to be used when the supplied Plot produces graphical output. -c If this function is not called prior to producing graphical -c output, then the underlying graphics functions selected at -c link-time (using the ast_link command) will be used. To use -c alternative graphics functions, call this function before -c the graphical output is created, specifying the graphics -c functions to be used. This will register the function for future -c use, but the function will not actually be used until the Grf -c attribute is given a non-zero value. -f This routine can be used to select the underlying graphics -f routines to be used when the supplied Plot produces graphical output. -f If this routine is not called prior to producing graphical -f output, then the underlying graphics routines selected at -f link-time (using the ast_link command) will be used. To use -f alternative graphics routines, call this routine before -f the graphical output is created, specifying the graphics -f routines to be used. This will register the routine for future -f use, but the routine will not actually be used until the Grf -f attribute is given a non-zero value. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c name -f NAME = CHARACTER * ( * ) (Given) -c A name indicating the graphics function to be replaced. -c Various graphics functions are used by the -c Plot class, and any combination of them may be supplied by calling -c this function once for each function to be replaced. If any of the -c graphics functions are not replaced in this way, the -c corresponding functions in the graphics interface selected at -c link-time (using the ast_link command) are used. The allowed -c names are: -f A name indicating the graphics routine to be replaced. -f Various graphics routines are used by the -f Plot class, and any combination of them may be supplied by calling -f this routine once for each routine to be replaced. If any of the -f graphics routines are not replaced in this way, the -f corresponding routines in the graphics interface selected at -f link-time (using the ast_link command) are used. The allowed -f function names are: -* -* - Attr - Enquire or set a graphics attribute value -* - BBuf - Start a new graphics buffering context -* - Cap - Inquire a capability -* - EBuf - End the current graphics buffering context -* - Flush - Flush all pending graphics to the output device -* - Line - Draw a polyline (i.e. a set of connected lines) -* - Mark - Draw a set of markers -* - Qch - Return the character height in world coordinates -* - Scales - Get the axis scales -* - Text - Draw a character string -* - TxExt - Get the extent of a character string -* -* The string is case insensitive. For details of the interface -* required for each, see the sections below. -c fun -f FUN = INTEGER FUNCTION (Given) -c A Pointer to the function to be used to provide the -c functionality indicated by parameter name. The interface for -c each function is described below, but the function pointer should -c be cast to a type of AstGrfFun when calling astGrfSet. -f The name of the routine to be used to provide the -f functionality indicated by parameter NAME (the name -f should also appear in a Fortran EXTERNAL statement in the -f routine which invokes AST_GRFSET). -* -c Once a function has been provided, a null pointer can be supplied -c in a subsequent call to astGrfSet to reset the function to the -c corresponding function in the graphics interface selected at -c link-time. -f Once a routine has been provided, the "null" routine AST_NULL can -f be supplied in a subsequent call to astGrfSet to reset the routine -f to the corresponding routine in the graphics interface selected at -f link-time. AST_NULL is defined in the AST_PAR include file. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Function Interfaces: -* All the functions listed below (except for "Cap") should return an -* integer value of 0 if an error occurs, and 1 otherwise. All x and y -* values refer -f to "graphics cordinates" as defined by the GRAPHBOX parameter of -f the AST_PLOT call which created the Plot. -c to "graphics cordinates" as defined by the graphbox parameter of -c the astPlot call which created the Plot. -* -c The first parameter ("grfcon") -f The first argument (GRFCON) -* for each function is an AST KeyMap pointer that can be used by the -* called function to establish the context in which it is being called. -* The contents of the KeyMap are determined by the calling -* application, which should obtain a pointer to the KeyMap using the -f AST_GETGRFCONTEXT routine, -c astGetGrfContext function, -* and then store any necessary information in the KeyMap using the -* methods of the KeyMap class. Note, the functions listed below -* should never annul or delete the supplied KeyMap pointer. - -* Attr: -* The "Attr" function returns the current value of a specified graphics -* attribute, and optionally establishes a new value. The supplied -* value is converted to an integer value if necessary before use. -* It requires the following interface: -* -c int Attr( AstObject *grfcon, int attr, double value, double *old_value, int prim ) -f INTEGER FUNCTION ATTR( GRFCON, ATT, VAL, OLDVAL, PRIM ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - attr - An integer value identifying the required attribute. -c The following symbolic values are defined in grf.h: -f - ATT = INTEGER (Given) - An integer identifying the required attribute. -f The following symbolic values are defined in GRF_PAR: -* GRF__STYLE (Line style), -* GRF__WIDTH (Line width), -* GRF__SIZE (Character and marker size scale factor), -* GRF__FONT (Character font), -* GRF__COLOUR (Colour index). -c - value - -f - VAL = DOUBLE PRECISION (Given) - -c A new value to store for the attribute. If this is AST__BAD -* no value is stored. -c - old_value - A pointer to a double in which to return -f - OLDVAL = DOUBLE PRECISION (Returned) - Returned holding -* the attribute value. -c If this is NULL, no value is returned. -c - prim - -f - PRIM = INTEGER (Given) - -* The sort of graphics primitive to be drawn with the new attribute. -c Identified by the following values defined in grf.h: -f Identified by the following values defined in GRF_PAR: -* GRF__LINE, -* GRF__MARK, -* GRF__TEXT. - -* BBuf: -* The "BBuf" function should start a new graphics buffering context. -* A matching call to the function "EBuf" should be used to end the -* context. The nature of the buffering is determined by the underlying -* graphics system. -* -c int BBuf( AstObject *grfcon ) -f INTEGER FUNCTION BBUF( GRFCON ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. - -* Cap: -* The "Cap" function is called to determine if the grf module has a -* given capability, as indicated by the "cap" argument: -* -c int Cap( AstObject *grfcon, int cap, int value ) -f INTEGER FUNCTION CAP( GRFCON, CAP, VALUE ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - cap - -f - CAP = INTEGER (Given) -* The capability being inquired about. This will be one of the -c following constants defined in grf.h: -f following constants defined in GRF_PAR: -* -* GRF__SCALES: This function should return a non-zero value if the -* "Scales" function is implemented, and zero otherwise. The supplied -c "value" argument should be ignored. -f VALUE argument should be ignored. -* -* GRF__MJUST: This function should return a non-zero value if -* the "Text" and "TxExt" functions recognise "M" as a -* character in the justification string. If the first character of -* a justification string is "M", then the text should be justified -* with the given reference point at the bottom of the bounding box. -* This is different to "B" justification, which requests that the -* reference point be put on the baseline of the text, since some -* characters hang down below the baseline. If the "Text" or -* "TxExt" function cannot differentiate between "M" and "B", -* then this function should return zero, in which case "M" -* justification will never be requested by Plot. The supplied -c "value" argument should be ignored. -f VALUE argument should be ignored. -* -* GRF__ESC: This function should return a non-zero value if the -* "Text" and "TxExt" functions can recognise and interpret -* graphics escape sequences within the supplied string (see -* attribute Escape). Zero should be returned if escape sequences -* cannot be interpreted (in which case the Plot class will interpret -c them itself if needed). The supplied "value" argument should be -f them itself if needed). The supplied VALUE argument should be -* ignored only if escape sequences cannot be interpreted by "Text" and -c "TxExt". Otherwise, "value" indicates whether "Text" and "TxExt" -c should interpret escape sequences in subsequent calls. If "value" is -f "TxExt". Otherwise, VALUE indicates whether "Text" and "TxExt" -f should interpret escape sequences in subsequent calls. If VALUE is -* non-zero then escape sequences should be interpreted by "Text" and -* "TxExt". Otherwise, they should be drawn as literal text. -* -c - value - -f - VALUE = INTEGER (Given) -c The use of this parameter depends on the value of "cap" as -f The use of this parameter depends on the value of CAP as -* described above. - -* - Returned Function Value: -c The value returned by the function depends on the value of "cap" -f The value returned by the function depends on the value of CAP -* as described above. Zero should be returned if the supplied -* capability is not recognised. - -* EBuf: -* The "EBuf" function should end the current graphics buffering -* context. See the description of "BBuf" above for further details. -* It requires the following interface: -* -c int EBuf( AstObject *grfcon ) -f INTEGER FUNCTION EBUF( GRFCON ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. - -* Flush: -* The "Flush" function ensures that the display device is up-to-date, -* by flushing any pending graphics to the output device. It -* requires the following interface: -* -c int Flush( AstObject *grfcon ) -f INTEGER FUNCTION FLUSH( GRFCON ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. - -* Line: -* The "Line" function displays lines joining the given positions and -* requires the following interface: -* -c int Line( AstObject *grfcon, int n, const float *x, const float *y ) -f INTEGER FUNCTION LINE( GRFCON, N, X, Y ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - n - The number of positions to be joined together. -f - N = INTEGER (Given) - The number of positions to be joined together. -c - x - A pointer to an array holding the "n" x values. -f - X( N ) = REAL (Given) - An array holding the "n" x values. -c - y - A pointer to an array holding the "n" y values. -f - Y( N ) = REAL (Given) - An array holding the "n" y values. - -* Mark: -* The "Mark" function displays markers at the given positions. It -* requires the following interface: -* -c int Mark( AstObject *grfcon, int n, const float *x, const float *y, int type ) -f INTEGER FUNCTION MARK( GRFCON, N, X, Y, TYPE ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - n - The number of positions to be marked. -f - N = INTEGER (Given) - The number of positions to be marked. -c - x - A pointer to an array holding the "n" x values. -f - X( N ) = REAL (Given) - An array holding the "n" x values. -c - y - A pointer to an array holding the "n" y values. -f - Y( N ) = REAL (Given) - An array holding the "n" y values. -c - type - An integer which can be used to indicate the type of marker -c symbol required. -f - TYPE = INTEGER (Given) - An integer which can be used to indicate -f the type of marker symbol required. - -* Qch: -* The "Qch" function returns the heights of characters drawn vertically -* and horizontally in graphics coordinates. It requires the following -* interface: -* -c int Qch( AstObject *grfcon, float *chv, float *chh ) -f INTEGER FUNCTION QCH( GRFCON, CHV, CHH ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - chv - A pointer to the float which is to receive the height of -f - CHV = REAL (Returned) The height of -* characters drawn with a vertical baseline. This will be an -* increment in the X axis. -c - chh - A pointer to the float which is to receive the height of -f - CHH = REAL (Returned) The height of -* characters drawn with a horizontal baseline. This will be an -* increment in the Y axis. - -* Scales: -* The "Scales" function returns two values (one for each axis) which -* scale increments on the corresponding axis into a "normal" coordinate -* system in which: 1) the axes have equal scale in terms of (for instance) -* millimetres per unit distance, 2) X values increase from left to -* right, and 3) Y values increase from bottom to top. It requires the -* following interface: -* -c int Scales( AstObject *grfcon, float *alpha, float *beta ) -f INTEGER FUNCTION SCALES( GRFCON, ALPHA, BETA ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - alpha - A pointer to the float which is to receive the -f - ALPHA = REAL (Returned) The -* scale for the X axis (i.e. Xnorm = alpha*Xworld). -c - beta - A pointer to the float which is to receive the -f - BETA = REAL (Returned) The -* scale for the Y axis (i.e. Ynorm = beta*Yworld). - -* Text: -* The "Text" function displays a character string at a given -* position using a specified justification and up-vector. It -* requires the following interface: -* -c int Text( AstObject *grfcon, const char *text, float x, float y, const char *just, -c float upx, float upy ) -f INTEGER FUNCTION TEXT( GRFCON, TEXT, X, Y, JUST, UPX, UPY ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - text - Pointer to a null-terminated character string to be displayed. -f - TEXT = CHARACTER * ( * ) (Given) - The string to be displayed. -c - x - The reference x coordinate. -f - X = REAL (Given) - The reference x coordinate. -c - y - The reference y coordinate. -f - Y = REAL (Given) - The reference y coordinate. -c - just - A character string which specifies the location within the -f - JUST = CHARACTER * ( * ) (Given ) - A string which specifies the -f location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. Note, "bottom" -* corresponds to the base-line of normal text. Some characters -* (eg "y", "g", "p", etc) descend below the base-line. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -c - upx - The x component of the up-vector for the text. -f - UPX = REAL (Given) - The x component of the up-vector for the text. -* If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* left to right on the screen. -c - upy - The y component of the up-vector for the text. -f - UPX = REAL (Given) - The y component of the up-vector for the text. -* If necessary the supplied value should be negated -* to ensure that positive values always refer to displacements from -* bottom to top on the screen. - -* TxExt: -* The "TxExt" function returns the corners of a box which would enclose -* the supplied character string if it were displayed using the -* Text function described above. The returned box includes any leading -* or trailing spaces. It requires the following interface: -* -c int TxExt( AstObject *grfcon, const char *text, float x, float y, const char *just, -c float upx, float upy, float *xb, float *yb ) -f INTEGER FUNCTION TXEXT( GRFCON, TEXT, X, Y, JUST, UPX, UPY, XB, YB ) -* -c - grfcon - -f - GRFCON = INTEGER (Given) - -* A KeyMap containing information passed from the calling application. -c - text - Pointer to a null-terminated character string to be displayed. -f - TEXT = CHARACTER * ( * ) (Given) - The string to be displayed. -c - x - The reference x coordinate. -f - X = REAL (Given) - The reference x coordinate. -c - y - The reference y coordinate. -f - Y = REAL (Given) - The reference y coordinate. -c - just - A character string which specifies the location within the -f - JUST = CHARACTER * ( * ) (Given ) - A string which specifies the -f location within the -* text string which is to be placed at the reference position -* given by x and y. See "Text" above. -c - upx - The x component of the up-vector for the text. -f - UPX = REAL (Given) - The x component of the up-vector for the text. -* See "Text" above. -c - upy - The y component of the up-vector for the text. -f - UPX = REAL (Given) - The y component of the up-vector for the text. -* See "Text" above. -c - xb - An array of 4 elements in which to return the x coordinate of -f - XB( 4 ) = REAL (Returned) - Returned holding the x coordinate of -* each corner of the bounding box. -c - yb - An array of 4 elements in which to return the y coordinate of -f - YB( 4 ) = REAL (Returned) - Returned holding the y coordinate of -* each corner of the bounding box. - -*-- -*/ - -/* Local Variables: */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int ifun; /* Index into grf function list */ - void (* wrapper)(); /* Wrapper function for C Grf routine*/ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - wrapper = NULL; - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astGrfSet"; - class = astClass( this ); - -/* Identify the supplied function name and get its integer index into the - list of grf functions. */ - ifun = astGrfFunID( name, method, class ); - -/* Store the pointer. */ - if( astOK ) { - this->grffun[ifun] = fun; - -/* In general, the interface to each Grf function will differ for - different languages. So we need a wrapper function with a known fixed - interface which can be used to invoke the actual Grf function with - an interface suited to the language in use. Call astGrfWrapper to store - a wrapper to a suitable function which can invoke the supplied - grf function. Here, we assume that the supplied function has a C - interface, so we set up a C wrapper. If this function is being called - from another language, then the interface for this function within - that language should set up an appropriate wrapper after calling this - function, thus over-riding the C wrapper set up here. */ - if( ifun == AST__GATTR ) { - wrapper = (AstGrfWrap) CGAttrWrapper; - - } else if( ifun == AST__GBBUF ) { - wrapper = (AstGrfWrap) CGBBufWrapper; - - } else if( ifun == AST__GEBUF ) { - wrapper = (AstGrfWrap) CGEBufWrapper; - - } else if( ifun == AST__GFLUSH ) { - wrapper = (AstGrfWrap) CGFlushWrapper; - - } else if( ifun == AST__GLINE ) { - wrapper = (AstGrfWrap) CGLineWrapper; - - } else if( ifun == AST__GMARK ) { - wrapper = (AstGrfWrap) CGMarkWrapper; - - } else if( ifun == AST__GTEXT ) { - wrapper = (AstGrfWrap) CGTextWrapper; - - } else if( ifun == AST__GCAP ) { - wrapper = (AstGrfWrap) CGCapWrapper; - - } else if( ifun == AST__GTXEXT ) { - wrapper = (AstGrfWrap) CGTxExtWrapper; - - } else if( ifun == AST__GSCALES ) { - wrapper = (AstGrfWrap) CGScalesWrapper; - - } else if( ifun == AST__GQCH ) { - wrapper = (AstGrfWrap) CGQchWrapper; - - } else if( astOK ) { - astError( AST__INTER, "%s(%s): AST internal programming error - " - "Grf function id %d not yet supported.", status, method, class, - ifun ); - } - astGrfWrapper( this, name, wrapper ); - } -} - -int astGrfFunID_( const char *name, const char *method, const char *class, int *status ) { -/* -*+ -* Name: -* astGrfFunID - -* Purpose: -* Return the integer identifier for a given GRF routine. - -* Type: -* Hidden public function. - -* Synopsis: -* #include "plot.h" -* int astGrfFunID( const char *name, const char *method, -* const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns an integer identifying the named grf function. -* An error is reported if the named function is unknown. This function -* is used by non-class modules within AST (e.g. fplot.c) which is why -* it is public. It is not intended to be used by the public. - -* Parameters: -* name -* The grf function name. Any unambiguous abbreviation will do. -* Case is ignored. The full list of grf function names is: -* "Attr BBuf EBuf Scales Flush Line Mark Qch Text TxExt". See -* grf_pgplot.c for details of these functions. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -*- -*/ - -/* Note that the list of identifiers here must be in the same order as the - sorted values of the constants AST__GATTR, AST__GFLUSH, etc */ - return FullForm( "Attr Flush Line Mark Text TxExt Scales Qch Cap BBuf " - "EBuf", name, "Grf function name (programming error)", - method, class, status ); -} - -static char *GrfItem( int item, const char *text, int *axis, int *status ){ -/* -* Name: -* GrfItem - -* Purpose: -* Return the textual name corresponding to a specified graphical item -* index. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* char *GrfItem( int item, const char *text, int *axis, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns a textual description of the graphical item -* with the supplied index. - -* Parameters: -* item -* The index of the graphical item. -* text -* A pointer to a string which will be appended to the textual -* description of the graphical item. May be NULL. -* axis -* Pointer to a place in which to return the index (0,1, or 2) of -* the axis to which the attribute refers, If the attribute does -* not refer to a specific axis, -1 is returned. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string holding the textual -* description of the graphical item, followed by any supplied "text". - -* Notes: -* - An error is reported and a NULL pointer returned if the -* index does not correspond to any graphical item. -* - The returned pointer should be freed using astFree when it is no -* longer needed. -* - This function attempts to execute even if an error has already -* occurred. - -*/ - -/* Local Variables: */ - char *desc; /* Pointer to the item description */ - char *ret; /* Pointer to the returned string */ - int dlen; /* Length of the item description */ - - if( axis ) *axis = -1; - - if( item == AST__BORDER_ID ) { - desc = "Border"; - - } else if ( item == AST__GRIDLINE_ID ) { - desc = "Gridline"; - - } else if ( item == AST__GRIDLINE1_ID ) { - desc = "Axis 1 gridline"; - if( axis ) *axis = 0; - - } else if ( item == AST__GRIDLINE2_ID ) { - desc = "Axis 2 gridline"; - if( axis ) *axis = 1; - - } else if ( item == AST__GRIDLINE3_ID ) { - desc = "Axis 3 gridline"; - if( axis ) *axis = 2; - - } else if ( item == AST__CURVE_ID ) { - desc = "Curve"; - - } else if ( item == AST__NUMLABS_ID ) { - desc = "Numerical labels"; - - } else if ( item == AST__TEXTLABS_ID ) { - desc = "Textual labels"; - - } else if ( item == AST__TITLE_ID ) { - desc = "Title"; - - } else if ( item == AST__MARKS_ID ) { - desc = "Markers"; - - } else if ( item == AST__TEXT_ID ) { - desc = "Text string"; - - } else if ( item == AST__TICKS_ID ) { - desc = "Major and minor ticks"; - - } else if ( item == AST__AXIS1_ID ) { - desc = "Axis 1"; - if( axis ) *axis = 0; - - } else if ( item == AST__AXIS2_ID ) { - desc = "Axis 2"; - if( axis ) *axis = 1; - - } else if ( item == AST__AXIS3_ID ) { - desc = "Axis 3"; - if( axis ) *axis = 2; - - } else if ( item == AST__NUMLAB1_ID ) { - desc = "Axis 1 numerical labels"; - if( axis ) *axis = 0; - - } else if ( item == AST__NUMLAB2_ID ) { - desc = "Axis 2 numerical labels"; - if( axis ) *axis = 1; - - } else if ( item == AST__NUMLAB3_ID ) { - desc = "Axis 3 numerical labels"; - if( axis ) *axis = 2; - - } else if ( item == AST__TEXTLAB1_ID ) { - desc = "Axis 1 textual label"; - if( axis ) *axis = 0; - - } else if ( item == AST__TEXTLAB2_ID ) { - desc = "Axis 2 textual label"; - if( axis ) *axis = 1; - - } else if ( item == AST__TEXTLAB3_ID ) { - desc = "Axis 3 textual label"; - if( axis ) *axis = 2; - - } else if ( item == AST__TICKS1_ID ) { - desc = "Axis 1 tick marks"; - if( axis ) *axis = 0; - - } else if ( item == AST__TICKS2_ID ) { - desc = "Axis 2 tick marks"; - if( axis ) *axis = 1; - - } else if ( item == AST__TICKS3_ID ) { - desc = "Axis 3 tick marks"; - if( axis ) *axis = 2; - - } else { - desc = NULL; - if( astOK ){ - astError( AST__INTER, "GrfItem: AST internal programming error - " - "Invalid graphical item index %d supplied to GrfItem.", status, - item ); - } - } - - if( desc ) { - dlen = strlen( desc ); - - if( text ) { - ret = astStore( NULL, desc, dlen + strlen( text ) + 1 ); - if( ret ) strcpy( ret + dlen, text ); - } else { - ret = astStore( NULL, desc, dlen + 1 ); - } - - } else { - ret = NULL; - } - -/* Return the answer. */ - return ret; -} - -static void GrfWrapper( AstPlot *this, const char *name, AstGrfWrap wrapper, int *status ) { -/* -*+ -* Name: -* astGrfWrapper - -* Purpose: -* Register a wrapper function for a F77 or C Grf function. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* void astGrfWrapper( AstPlot *this, const char *name, AstGrfWrap wrapper) - -* Description: -* This function stores a pointer to the supplied wrapper function -* within the plot, associating it with the grf function indicated by -* the "name" parameter. The supplied wrapper function should call the -* named grf function, using an interface appropriate to the language -* in which the grf function is written. - -* Parameters: -* this -* The plot. -* name -* A name indicating the graphics function which is called by the -* supplied wrapper function. See astGrfSet for details. -* wrapper -* A pointer to the wrapper function. This will be cast to a -* specific type for the named grf function before being store -* in the Plot. -*- -*/ - -/* Local Variables: */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int ifun; /* Index into grf function list */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astGrfWrapper"; - class = astClass( this ); - -/* Identify the supplied function name and get its integer index into the - list of grf functions. */ - ifun = astGrfFunID( name, method, class ); - -/* Cast the wrapper to an interface appropriate for the wrapped grf - function, and store it in the appropriate component of the Plot. */ - if( ifun == AST__GATTR ) { - this->GAttr = (AstGAttrWrap) wrapper; - - } else if( ifun == AST__GBBUF ) { - this->GBBuf = (AstGBBufWrap) wrapper; - - } else if( ifun == AST__GEBUF ) { - this->GEBuf = (AstGEBufWrap) wrapper; - - } else if( ifun == AST__GFLUSH ) { - this->GFlush = (AstGFlushWrap) wrapper; - - } else if( ifun == AST__GLINE ) { - this->GLine = (AstGLineWrap) wrapper; - - } else if( ifun == AST__GMARK ) { - this->GMark = (AstGMarkWrap) wrapper; - - } else if( ifun == AST__GTEXT ) { - this->GText = (AstGTextWrap) wrapper; - - } else if( ifun == AST__GCAP ) { - this->GCap = (AstGCapWrap) wrapper; - - } else if( ifun == AST__GTXEXT ) { - this->GTxExt = (AstGTxExtWrap) wrapper; - - } else if( ifun == AST__GSCALES ) { - this->GScales = (AstGScalesWrap) wrapper; - - } else if( ifun == AST__GQCH ) { - this->GQch = (AstGQchWrap) wrapper; - - } else if( astOK ) { - astError( AST__INTER, "%s(%s): AST internal programming error - " - "Grf function id %d not yet supported.", status, method, class, - ifun ); - } -} - -static void Grid( AstPlot *this_nd, int *status ){ -/* -*++ -* Name: -c astGrid -f AST_GRID - -* Purpose: -* Draw a set of labelled coordinate axes. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astGrid( AstPlot *this ) -f CALL AST_GRID( THIS, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a complete annotated set of -f This routine draws a complete annotated set of -* coordinate axes for a Plot with (optionally) a coordinate grid -* superimposed. Details of the axes and grid can be controlled by -* setting values for the various attributes defined by the Plot -* class (q.v.). - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - If the supplied Plot is a Plot3D, the axes will be annotated -* using three 2-dimensional Plots, one for each 2D plane in the 3D -* current coordinate system. The plots will be "pasted" onto 3 faces -* of the cuboid graphics volume specified when the Plot3D was -* constructed. The faces to be used can be controlled by the "RootCorner" -* attribute. -* - An error results if either the current Frame or the base Frame -* of the Plot is not 2-dimensional or (for a Plot3D) 3-dimensional. -* - An error also results if the transformation between the base -* and current Frames of the Plot is not defined in either -* direction (i.e. the Plot's TranForward or TranInverse attribute -* is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *this; /* Plot with 2d current Frame */ - AstPlotCurveData **cdata;/* Pointer to info. about breaks in curves */ - TickInfo **grid; /* Pointer to info. about tick marks */ - const char *class; /* Object class */ - const char *method; /* Current method */ - double cen[ 2 ]; /* Position of first tick mark */ - double gap[ 2 ]; /* Gap between tick marks */ - double labelat[ 2 ]; /* Axis values at which tick marks are put */ - int axis; /* Physical axis index */ - int border; /* Draw a border? */ - int clip; /* Original Clip attribute value */ - int dounits[2]; /* Include Units in each axis label? */ - int drawgrid; /* Is a grid of lines to be drawn? */ - int clredge; /* Clear the Edge attributes before returning? */ - int edgeticks; /* Draw labels round edges of plotting area? */ - int escs; /* Original astEscapes value */ - int ink; /* Draw the grid with visible ink? */ - int inval; /* Were areas of invalid coordinates found? */ - int labelling; /* Value of Labelling attribute */ - int loglabelset[2]; /* Were the LogLabel attributes set initially? */ - int logticksset[2]; /* Were the LogTicks attributes set initially? */ - int naxes; /* No. of axes in the base or current Frame */ - int oldedge0; /* Default value for Edge(1) */ - int oldedge1; /* Default value for Edge(2) */ - int useint; /* Do interior labels give us an advantage? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this_nd); - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astGrid"; - class = astClass( this_nd ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this_nd ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Ensure AST functions included graphical escape sequences in any - returned text strings. */ - escs = astEscapes( 1 ); - -/* Note if attributes which have complex dynamic defaults are set - initially. */ - logticksset[0] = astTestLogTicks( this_nd, 0 ); - logticksset[1] = astTestLogTicks( this_nd, 1 ); - loglabelset[0] = astTestLogLabel( this_nd, 0 ); - loglabelset[1] = astTestLogLabel( this_nd, 1 ); - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Get a Plot with a 2D (or 1D) current Frame. */ - this = (AstPlot *) Fset2D( (AstFrameSet *) this_nd, AST__CURRENT, status ); - -/* Check the current Frame of the Plot is 2-D. */ - naxes = astGetNout( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the current " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Ensure that all lines are clipped at the plot boundary.*/ - if( astTestClip( this ) ) { - clip = astGetClip( this ); - astSetClip( this, 1 ); - } else { - clip = -1; - } - -/* If the protected attribute "Ink" is set to zero, then the plot - is drawn in "invisble ink" (i.e. all the calculations needed to - produce the grid are performed, but nothing is actually drawn). */ - ink = astGetInk( this ); - -/* Initialise the bounds of the box containing all plotted lines and - numerical labels. */ - Box_lbnd[ 0 ] = FLT_MAX; - Box_lbnd[ 1 ] = FLT_MAX; - Box_ubnd[ 0 ] = FLT_MIN; - Box_ubnd[ 1 ] = FLT_MIN; - -/* Obtain the requested centre attribute values for both physical axes. */ - for( axis = 0; axis < 2; axis++ ){ - cen[ axis ] = astGetCentre( this, axis ); - } - -/* Determine where to put the major axis values. */ - grid = GridLines( this, cen, gap, &inval, method, class, status ); - -/* If the user has set an explicit value for Grid, use it. */ - if( astTestGrid( this ) ){ - drawgrid = astGetGrid( this ); - -/* If not, the default for Grid is based on whether or not there are any - invalid regions. */ - } else if( inval ){ - drawgrid = 1; - - } else { - drawgrid = 0; - } - -/* Draw the curves marking the major tick values on each axis. Information - is returned describing the positions of the breaks in these curves. */ - cdata = DrawGrid( this, grid, ( ink && drawgrid ), method, class, status ); - -/* See if labels and tick marks will be drawn round the edges of the - plotting area, rather than within it (no labels are actually drawn - yet). Interior labels can always be produced, in which case edgeticks - is set explicitly to zero to indicate that ticks will be internal. - Exterior labelling may or may not be possible. If it is requested, - check to see if it is possible. */ - clredge = 0; - labelling = astGetLabelling( this ); - if( labelling ){ - edgeticks = 0; - } else { - edgeticks = EdgeLabels( this, 0, grid, cdata, 0, method, class, status ); - -/* If the external labelling was requested, but could not be produced... */ - if( !edgeticks ) { - -/* and if the Edge attributes have not been set... */ - if( !astTestEdge( this, 0 ) && !astTestEdge( this, 1 ) ) { - -/* Try flipping the default Edge values, to see if this allows us to - honour the requested Labelling scheme. */ - oldedge0 = astGetEdge( this, 0 ); - oldedge1 = astGetEdge( this, 1 ); - astSetEdge( this, 0, oldedge1 ); - astSetEdge( this, 1, oldedge0 ); - -/* See if exterior labels could be drawn with these new edges. */ - edgeticks = EdgeLabels( this, 0, grid, cdata, 0, method, class, status ); - -/* If this would allow us to use the requested labelling scheme, retain - the new Edge values, setting a flag to indicate that they will need to be - cleared before returning. Otherwise, clear them. */ - if( edgeticks ) { - clredge = 1; - - } else { - astClearEdge( this, 0 ); - astClearEdge( this, 1 ); - } - } - } - } - -/* If edge ticks can still not be produced, but the ForceExterior attribute - has a non-zero value, attempt to create exterior labels even though it - looks like there may be insufficient of them to justify their use. */ - if( !edgeticks && astGetForceExterior( this ) ) { - edgeticks = EdgeLabels( this, 0, grid, cdata, 1, method, class, status ); - } - -/* We may also need to swap edge values when using interior labelling in - order to ensure that the text labels are placed on appropriate edges of - the plotting box. */ - if( !edgeticks && !astTestEdge( this, 0 ) && !astTestEdge( this, 1 ) ) { - if( swapEdges( this, grid, cdata, status ) ) { - oldedge0 = astGetEdge( this, 0 ); - oldedge1 = astGetEdge( this, 1 ); - astSetEdge( this, 0, oldedge1 ); - astSetEdge( this, 1, oldedge0 ); - clredge = 1; - } - } - -/* If edge ticks are being used, store bad values for the labelat values to - indicate that labels are not being drawn within the interior of the - plotting area. */ - if( edgeticks ){ - labelat[ 0 ] = AST__BAD; - labelat[ 1 ] = AST__BAD; - -/* Otherwise, see where interior labels and tick marks should go (the axis - values are put in "labelat"). */ - } else { - useint = Labelat( this, grid, cdata, labelat, method, class, status ); - -/* If interior labelling does not allow us to draw any more ticks, revert - to edge labelling if that is what the user requested. */ - if( !useint && !labelling ) { - labelat[ 0 ] = AST__BAD; - labelat[ 1 ] = AST__BAD; - edgeticks = EdgeLabels( this, 0, grid, cdata, 1, method, class, status ); - } - } - -/* See if a border is required. By default, a border is drawn only when - using exterior labelling. */ - if( astTestBorder( this ) ) { - border = astGetBorder( this ); - } else { - border = edgeticks; - } - -/* See if the Units string is to be inluded in the label. */ - dounits[ 0 ] = astGetLabelUnits( this, 0 ); - dounits[ 1 ] = astGetLabelUnits( this, 1 ); - -/* The rest is not done if no output is required. */ - if( ink ) { - -/* Draw tick marks (major and minor). */ - DrawTicks( this, grid, drawgrid, labelat, gap, method, class, status ); - -/* If required, ensure that curves through the tick marks have been drawn */ - DrawAxis( this, grid, labelat, gap, method, class, status ); - -/* If required, draw a curve around the edge of the area containing valid - physical coordinates. */ - if( border ) (void) astBorder( this ); - -/* Draw the numerical labels at the major tick values. */ - Labels( this, grid, cdata, gap, labelat, method, class, status ); - -/* Draw the textual labels for each axis and a title. */ - TextLabels( this, edgeticks, dounits, method, class, status ); - } - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Store the actual values used for all attributes which have dynamic - defaults. Check the global status to ensure the pointer "grid" can be - used without the possibility of a segmentation violation. */ - for( axis = 0; axis < 2 && astOK ; axis++ ) { - SetUsedLogTicks( this_nd, axis, astGetLogTicks( this, axis ), status ); - SetUsedLogLabel( this_nd, axis, astGetLogLabel( this, axis ), status ); - - if( astGetLogTicks( this, axis ) ) { - SetUsedLogGap( this_nd, axis, gap[ axis ], status ); - } else { - SetUsedGap( this_nd, axis, gap[ axis ], status ); - } - SetUsedCentre( this_nd, axis, cen[ axis ], status ); - SetUsedEdge( this_nd, axis, astGetEdge( this, axis ), status ); - SetUsedLabelAt( this_nd, axis, labelat[ axis ], status ); - SetUsedLabelUnits( this_nd, axis, dounits[ axis ], status ); - -/* If explicit minor tick values were supplied using astSetTickValues, - then set MinTick to the average number of minor tick divisions per major - tick division. */ - if( grid[ axis ]->minticks ) { - SetUsedMinTick( this_nd, axis, - ( grid[ axis ]->nminor + grid[ axis ]->nmajor )/ - ( grid[ axis ]->nmajor - 1 ), status ); - } else { - SetUsedMinTick( this_nd, axis, grid[ axis ]->nminor, status ); - } - - if( astTestTextLab( this, axis ) ) { - SetUsedTextLab( this_nd, axis, astGetTextLab( this, axis ), status ); - } else { - SetUsedTextLab( this_nd, axis, edgeticks, status ); - } - - if( astTestMajTickLen( this, axis ) ) { - SetUsedMajTickLen( this_nd, axis, astGetMajTickLen( this, axis ), status ); - } else { - SetUsedMajTickLen( this_nd, axis, drawgrid ? 0.0 : - astGetMajTickLen( this, axis ), status ); - } - - } - - SetUsedGrid( this_nd, drawgrid, status ); - SetUsedLabelling( this_nd, edgeticks ? 0 : 1, status ); - SetUsedBorder( this_nd, border, status ); - -/* Free the memory used to hold information about the curves. */ - cdata = CleanCdata( cdata, status ); - -/* Free the memory used to hold information about the tick marks. */ - grid = CleanGrid( grid, status ); - -/* If required clear attributes. */ - if( clredge ) { - astClearEdge( this, 0 ); - astClearEdge( this, 1 ); - } - - if( !logticksset[ 0 ] ) astClearLogTicks( this, 0 ); - if( !logticksset[ 1 ] ) astClearLogTicks( this, 1 ); - if( !loglabelset[ 0 ] ) astClearLogLabel( this, 0 ); - if( !loglabelset[ 1 ] ) astClearLogLabel( this, 1 ); - -/* Restore the original value of the Clip attribute. */ - if( clip != -1 ) astSetClip( this, clip ); - -/* Free the 2D Plot. */ - this = astAnnul( this ); - -/* Restore the original value of the flag which says whether graphical - escape sequences should be incldued in any returned text strings. */ - astEscapes( escs ); - -/* Copy the total bounding box to the box which is returned by - astBoundingBox. */ - if( !Boxp_freeze ){ - Boxp_lbnd[ 0 ] = Box_lbnd[ 0 ]; - Boxp_lbnd[ 1 ] = Box_lbnd[ 1 ]; - Boxp_ubnd[ 0 ] = Box_ubnd[ 0 ]; - Boxp_ubnd[ 1 ] = Box_ubnd[ 1 ]; - } - -/* Return. */ - return; - -} - -static void GridLine( AstPlot *this, int axis, const double start[], - double length, int *status ){ -/* -*++ -* Name: -c astGridLine -f AST_GRIDLINE - -* Purpose: -* Draw a grid line (or axis) for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astGridLine( AstPlot *this, int axis, const double start[], -c double length ) -f CALL AST_GRIDLINE( THIS, AXIS, START, LENGTH, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a curve in the physical coordinate system of -f This routine draws a curve in the physical coordinate system of -* a Plot by varying only one of the coordinates along the length -* of the curve. It is intended for drawing coordinate axes, -* coordinate grids, and tick marks on axes (but note that these -c are also available via the more comprehensive astGrid function). -f are also available via the more comprehensive AST_GRID routine). -* -* The curve is transformed into graphical coordinate space for -* plotting, so that a straight line in physical coordinates may -* result in a curved line being drawn if the Mapping involved is -* non-linear. Any discontinuities in the Mapping between physical -* and graphical coordinates are catered for, as is any -c clipping established using astClip. -f clipping established using AST_CLIP. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c axis -f AXIS = INTEGER (Given) -* The index of the Plot axis whose physical coordinate value is -* to be varied along the length of the curve (all other -* coordinates will remain fixed). This value should lie in the -* range from 1 to the number of Plot axes (Naxes attribute). -c start -f START( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the start of the curve. -c length -f LENGTH = DOUBLE PRECISION (Given) -* The length of curve to be drawn, given as an increment along -* the selected physical axis. This may be positive or negative. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -c - No curve is drawn if the "start" array contains any -c coordinates with the value AST__BAD, nor if "length" has this value. -f - No curve is drawn if the START array contains any -f coordinates with the value AST__BAD, nor if LENGTH has this value. -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - int naxes; /* No. of axes in the base Frame */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astGridLine"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Validate the axis index, converting the axis index to be zero-based. */ - (void) astValidateAxis( this, axis - 1, 1, method ); - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Draw the curve. The break information is stored in an external structure - where it can be accessed by public methods which return information - about the most recently drawn curve. */ - AxPlot( this, axis - 1, start, length, 1, &Curve_data, method, class, status ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); -} - -static TickInfo **GridLines( AstPlot *this, double *cen, double *gap, - int *inval, const char *method, const char *class, int *status ){ -/* -* Name: -* GridLines - -* Purpose: -* Obtain information desribing the major tick values within the plotting -* area. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* TickInfo **GridLines( AstPlot *this, double *cen, double *gap, -* int *inval, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* A pointer is returned which points to an array of two pointers. Each -* of these pointers points to a TickInfo structure which holds -* information about the ticks on a single axis. These structures, -* together with the array holding the two pointers, should be released -* when no longer needed using CleanGrid. - -* Parameters: -* this -* The Plot. -* cen -* A pointer to an array holding axis values at which to put a single -* central tick. Other ticks are placed evenly on either side of this -* tick. If AST__BAD is provided, a value will be used which would put a -* tick at an axis value of zero. -* gap -* A pointer to an array holding the gaps between ticks required on -* each axis. If this is AST__BAD a suitable default value will be used -* and returned in place of the AST__BAD value. -* inval -* A pointer to a location at which to return a flag indicating if -* any invalid physical coordinates were encountered while deciding on -* the tick values. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to an array of two TickInfo pointers. - -* Notes: -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. -*/ - -/* Local Variables: */ - AstFrame *fr; /* Pointer to current Frame */ - GetTicksStatics *statics = NULL; /* Pointer to static data for GetTicks */ - TickInfo **info; /* Returned array of two TickInfo pointers */ - double *lengths; /* Pointer to lengths of each curve section */ - double *starts; /* Pointer to start of each curve section */ - double *ticks; /* Pointer to tick mark values */ - double bot; /* Lowest axis value to display */ - double end; /* Axis value at end of curve section */ - double tmp; /* Temp storage */ - double top; /* Highest axis value to display */ - int i; /* Tick mark index */ - int j; /* Axis index */ - int k; /* Section index */ - int logticks[ 2 ]; /* Uses logarithmicaly spaced tick marks? */ - int nticks; /* Number of tick marks */ - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Get memory to hold two TickInfo pointers. */ - info = (TickInfo **) astMalloc( 2*sizeof( TickInfo *) ); - -/* If succesfull... */ - if( astOK ){ - -/* Initialise the two pointers. */ - info[ 0 ] = NULL; - info[ 1 ] = NULL; - -/* Obtain the tick mark values, and the corresponding formatted labels for - each axis. */ - for( j = 0; j < 2; j++ ){ - info[ j ] = TickMarks( this, j, cen + j, gap + j, inval, - &statics, method, class, status ); - logticks[ j ] = astGetLogTicks( this, j ); - } - -/* Release the resources allocated in the first call to TickMarks. */ - for( j = 0; j < 2; j++ ){ - (void) TickMarks( NULL, j, NULL, gap, NULL, &statics, method, class, - status ); - } - -/* Each major tick value for axis "j" may be marked with a curve parallel - to axis "1-j" drawn across the entire plotting area. We need to decide - where to start drawing this curve and how long it should be. We can - simply use the minimum value on axis "1-j" together with the tick value - on axis "j" to define the starting position. The length could be taken - as the difference between the maximum and minimum values on axis "1-j". - However, this may not be right in some situations. For instance if the - plotting area covers a small range of Right Ascension from 23:59:59 to - 00:00:01. Using the difference between the maximum and minimum values - to give the length of the curve would result in the curve starting at - 00:00:00 (the minimum axis value) and extending for a length of 23:59:59 - (the axis range). To get round this sort of problem, the curve is split - up into sections with lengths and starting positions determined by the - tick mark values on axis "1-j". The first section starts at the minimum - axis value and extends upto the first missing tick mark (in the RA - example, this would be at 00:00:01). Subsequent sections starts at the - next tick mark (23:59:59 in the RA example) and extends upto the next - missing tick mark, or the last tick mark if none are missing. */ - -/* Get the current frame. */ - fr = astGetFrame( this, AST__CURRENT ); - -/* If either axis has log tick spacing, use the simple approach which - assumes that each curve has only one section. */ - if( logticks[ 0 ] || logticks[ 1 ] ) { - -/* Find the start and length of the curve for each tick mark on axis "j". */ - for( j = 0; j < 2 && astOK; j++ ){ - -/* Find the axis range to display on the other axis. */ - bot = astGetBottom( fr, 1 - j ); - top = astGetTop( fr, 1 - j ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - -/* Get a pointer to the major tick mark values on the other axis ("1-j"), - together with the number of them. */ - ticks = info[ 1 - j ]->ticks; - nticks = info[ 1 - j ]->nmajor; - -/* Reserve memory to hold the starts and lengths of each section of the - grid line marking the major ticks on the axis "j". There will only be - one section. */ - starts = (double *) astMalloc( sizeof(double) ); - lengths = (double *) astMalloc( sizeof(double) ); - info[ j ]->start = starts; - info[ j ]->length = lengths; - -/* Check that the pointers can be used. */ - if( astOK ) { - -/* The section starts one gap below the first tick, and ends one gap above - the first tick. Limit both to the displayed range of the axis. */ - if( logticks[ 1 - j ] ) { - starts[ 0 ] = astMIN( top, astMAX( bot, ticks[ 0 ]/gap[ 1 - j ] ) ); - end = astMIN( top, astMAX( bot, ticks[ nticks - 1 ]*gap[ 1 - j ] ) ); - } else { - starts[ 0 ] = astMIN( top, astMAX( bot, ticks[ 0 ] - gap[ 1 - j ] ) ); - end = astMIN( top, astMAX( bot, ticks[ nticks - 1 ] + gap[ 1 - j ] ) ); - } - -/* Store the length of the section. */ - lengths[ 0 ] = end - starts[ 0 ]; - -/* Store the number of sections in the returned structure. */ - info[ 0 ]->nsect = 1; - - } - } - -/* If both axes have linear tick spacing, use the complete approach. */ - } else { - -/* Find the start and length of each section of the curve for each tick - mark on axis "j". */ - for( j = 0; j < 2 && astOK; j++ ){ - -/* Find the axis range to display on the other axis. */ - bot = astGetBottom( fr, 1 - j ); - top = astGetTop( fr, 1 - j ); - if( bot > top ) { - tmp = top; - top = bot; - bot = tmp; - } - -/* Get a pointer to the major tick mark values on the other axis ("1-j"), - together with the number of them. */ - ticks = info[ 1 - j ]->ticks; - nticks = info[ 1 - j ]->nmajor; - -/* Reserve memory to hold the starts and lengths of each section of the - grid line marking the major ticks on the axis "j". The allocated - arrays are the largest that could possibly be needed (i.e. if every - tick mark starts a new section). */ - starts = (double *) astMalloc( sizeof(double)*(size_t) nticks ); - lengths = (double *) astMalloc( sizeof(double)*(size_t) nticks ); - info[ j ]->start = starts; - info[ j ]->length = lengths; - -/* Check that the pointers can be used. */ - if( astOK ) { - -/* Loop round each of the major tick marks on axis "1-j". */ - k = 0; - i = 0; - while( i < nticks ){ - -/* Record the start of the next section of the grid lines. */ - starts[ k ] = ticks[ i++ ]; - -/* Tick marks should be regularly spaced by the values in "gap". Check each - tick mark until a missing tick mark is found. The section ends at the - start of the gap. */ - while( i < nticks && - ( ticks[ i ] - ticks[ i - 1 ] ) < 1.5*gap[ 1 - j ] ) i++; - -/* Record the length of the section. */ - lengths[ k ] = ticks[ i - 1 ] - starts[ k ]; - -/* The section is extended at start and end by one gap in order to "cover - up the joins". Limit this to the displayed range of the axis. */ - starts[ k ] -= gap[ 1 - j]; - lengths[ k ] += 2.0*gap[ 1 - j ]; - -/* Limit the start and end to the displayed range of the axis. */ - end = starts[ k ] + lengths[ k ]; - starts[ k ] = astMIN( top, astMAX( bot, starts[ k ] ) ); - lengths[ k ] = astMIN( top, astMAX( bot, end ) ) - starts[ k ]; - -/* Increment the number of sections. */ - k++; - } - -/* Store the number of sections in the returned structure. */ - info[j]->nsect = k; - - } - } - } - -/* Annull the current frame. */ - fr = astAnnul( fr ); - - } - -/* If an error has occurred, clean up the returned TickInfo structures. */ - if( !astOK ) info = CleanGrid( info, status ); - -/* Return. */ - return info; - -} - -void astGrfAttrs_( AstPlot *this, int id, int set, int prim, const char *method, const char *class, int *status ){ -/* -*+ -* Name: -* astGrfAttrs - -* Purpose: -* Establish values for the graphics attributes for a given object. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* void astGrfAttrs( AstPlot *this, int id, int set, int prim, const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This function should be called with "set=1" to establish the correct -* graphics attributes prior to drawing specific graphical objects. Once -* the object has been drawn, it should be called again with "set=0" to -* re-establish the original graphics attributes. -* -* NOTE, each type of graphical object identified by "id" should be -* drawn entirely by calls to just one of GMark, GText or GLine -* as indicated by argument "prim". - -* Parameters: -* this -* A pointer to the Plot. -* id -* An integer specifying the graphical object to be drawn. -* set -* If non-zero then the attributes for the specified object are set -* to the values indicated by the corresponding Plot attributes, -* and the current values are saved in a static array. If zero, then -* the values are set to the values stored in the static array. -* prim -* Indicates the sort of graphics primative used to draw the -* object. This must be one of (defined in grf.h) : -* -* GRF__LINE -* GRF__MARK -* GRF__TEXT -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Notes: -* - This function should always be called in pairs with set=1 on the -* first call and set=0 on the second call. -* - If a pair of calls is nested within another pair of calls, the -* inner pair has no effect. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double *attr; /* Pointer to the next attribute value */ - double dval; /* Floating point attribute value */ - int ival; /* Integer attribute value */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Set up a pointer to the next element in "grfattrs_attrs". */ - attr = grfattrs_attrs; - -/* If we are setting new values, increment the nesting level, otherwise - decrement it. */ - if( set ){ - grfattrs_nesting++; - } else { - grfattrs_nesting--; - } - -/* If we are changing any line attributes, ensure all lines are flushed to - the graphics system. */ - if( prim == GRF__LINE ) Fpoly( this, method, class, status ); - -/* First deal with cases where we are establishing new values for the - graphics attributes by setting them to the values of the corresponding - Plot attributes. Only do this if we are at nesting level one. */ - if( set && grfattrs_nesting == 1 ){ - -/* See if a value has been set in the Plot for the line style attribute for - the specified object, If so, use the value. */ - if( TestUseStyle( this, id, status ) ) { - ival = GetUseStyle( this, id, status ); - -/* Save the current value, and establish the new value. */ - GAttr( this, GRF__STYLE, (double) ival, attr++, prim, method, - class, status ); - -/* If no style was specified, retain the current value. Indicate that no - new value has been established by setting the old value bad. */ - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the line width attribute. */ - if( TestUseWidth( this, id, status ) ){ - dval = GetUseWidth( this, id, status ); - GAttr( this, GRF__WIDTH, dval, attr++, prim, method, class, status ); - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the character size attribute. */ - if( TestUseSize( this, id, status ) ) { - dval = GetUseSize( this, id, status ); - GAttr( this, GRF__SIZE, dval, attr++, prim, method, class, status ); - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the character font attribute. */ - if( TestUseFont( this, id, status ) ){ - ival = GetUseFont( this, id, status ); - GAttr( this, GRF__FONT, (double) ival, attr++, prim, method, class, status ); - } else { - *(attr++) = AST__BAD; - } - -/* Do the same for the colour attribute. */ - if( TestUseColour( this, id, status ) ) { - ival = GetUseColour( this, id, status ); - GAttr( this, GRF__COLOUR, (double) ival, attr++, prim, method, - class, status ); - } else { - *(attr++) = AST__BAD; - } - - } - -/* Now deal with cases where we are re-establishing old values saved on a - previous call to this function. Only do this if we are at nesting - level zero. */ - if( !set && !grfattrs_nesting ){ - GAttr( this, GRF__STYLE, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__WIDTH, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__SIZE, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__FONT, *(attr++), NULL, prim, method, class, status ); - GAttr( this, GRF__COLOUR, *(attr++), NULL, prim, method, class, status ); - } - -/* Return. */ - return; - -} - -static int GVec( AstPlot *this, AstMapping *mapping, double *phy, - int axis, double delta, AstPointSet **pset1, - AstPointSet **pset2, double *gx, double *gy, - double *dx, double *dy, int *flag, const char *method, - const char *class, int *status ){ -/* -* Name: -* GVec - -* Purpose: -* Returns a unit vector parallel to a physical axis at a given point. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GVec( AstPlot *this, AstMapping *mapping, double *phy, -* int axis, double delta, AstPointSet **pset1, -* AstPointSet **pset2, double *gx, double *gy, -* double *dx, double *dy, int *flag, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns a unit vector (in the graphics coordinate -* system) in the positive direction of the specified physical axis, -* at the given physical position. It works by transforming the given -* physical position, together with another very close position, and -* returning the vector between them. It is possible for a -* discontinuity to occur between these two close positions, -* resulting in a very large meaningless vector prior to -* normalisation. For this reason two vectors are found, one joining -* the given position to a close position higher up the axis, and one -* joining a close position lower down the axis to the given position. -* If these two vectors differ in magnitude by a large factor, then -* the shorter of the two vectors is normalised and returned. -* Otherwise, the vector which is closest in direction to the vector -* supplied in [dx,dy] is returned. The returned vector is reversed if -* necessary so that it always points in the positive direction of the -* axis. -* -* If neither of the two vectors can be found (i.e. if the graphics -* coordinates are bad, or coincident), then the vector supplied in -* [dx,dy] is returned unchanged, and a function value of zero is -* returned. Otherwise, a function value of one is returned. - -* Parameters: -* this -* Pointer to the Plot. -* mapping -* Pointer to the Mapping from the base Frame of the Plot ot the -* current Frame. -* phy -* Pointer to an array holding the coordinates in the current Frame -* of the Plot at which the tangent vector is required. -* axis -* The index of the axis within the current Frame for which the -* tangent vector is required. -* delta -* The increment in the axis value to use between positions defining -* the vectors. -* pset1 -* A pointer to a place at which to store a pointer to a PointSet -* holding current Frame coordinates. This PointSet pointer should -* be supplied as NULL on the first call to this function, resulting -* in a new PointSet being created and a pointer to it returned. -* Subsequent calls to this function shopuld retain the pointer -* returned by the first call. The PointSet pointer should be -* annulled using astAnnul when no longer needed. -* pset2 -* A pointer to a place at which to store a pointer to a PointSet -* holding base Frame coordinates. This PointSet is managed in the -* same way as "pset1". -* gx -* A pointer to a double in which to return the graphics X -* coordinate of the position supplied by "phy". -* gy -* A pointer to a double in which to return the graphics Y -* coordinate of the position supplied by "phy". -* dx -* A pointer to a double in which to return the X component -* of the unit tangent vector. This should be supplied holding a -* "default" unit vector which is left unchanged if no new vector -* can be found. -* dy -* A pointer to a double in which to return the Y component -* of the unit tangent vector. This should be supplied holding a -* "default" unit vector which is left unchanged if no new vector -* can be found. -* flag -* A pointer to an int in which to return a flag indicating which -* of the two vectors was returned. Zero is returned if the vector -* was estimated by moving in a positive direction along the axis -* from the position supplied by "phy". One is returned if the vector -* was estimated by moving in a negative direction along the axis -* from the position supplied by "phy" (in this case the returned -* vector will have been negated so that it refers to the positive -* direction). -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One is returned if the vector was found succesfully, Zero is returned -* if the vector could not be estimated for any reason. No error is -* reported if the failure was due to the nature of the mapping. - -* Notes: -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. -*/ - -/* Local Variables: */ - double dd1; /* Length of positive vector */ - double dd2; /* Length of negative vector */ - double dx1; /* X component of positive vector */ - double dx2; /* X component of negative vector */ - double dy1; /* Y component of positive vector */ - double dy2; /* Y component of negative vector */ - double **ptr1; /* Pointers to physical coordinate data */ - double **ptr2; /* Pointers to graphics coordinate data */ - int i; /* Axis index */ - int nphy; /* No. of axes in current (physical) Frame */ - int ret; /* Was a vector estimated succesfully? */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - dx1 = 0.0; - dx2 = 0.0; - dy1 = 0.0; - dy2 = 0.0; - -/* Initialise the returned value to indicate that the vector can not - be found. */ - ret = 0; - -/* Get the number of physical coordinates from the mapping. */ - nphy = astGetNout( mapping ); - -/* If no PointSets have been supplied, create some now. PointSet 1 - contains physical coordinates, PointSet 2 contains graphics - coordinates. */ - if( !(*pset1) ) *pset1 = astPointSet( 3, nphy, "", status ); - if( !(*pset2) ) *pset2 = astPointSet( 3, 2, "", status ); - -/* Get pointers to the PointSet data. */ - ptr1 = astGetPoints( *pset1 ); - ptr2 = astGetPoints( *pset2 ); - -/* Check the PointSets can be used. */ - if( astOK ){ - -/* Store the physical coordinates of three close points on a curve - parallel to the given axis, with the centre point at the given - position. */ - for( i = 0; i < nphy; i++ ){ - ptr1[ i ][ 0 ] = phy[ i ]; - ptr1[ i ][ 1 ] = phy[ i ]; - ptr1[ i ][ 2 ] = phy[ i ]; - } - - if( phy[ axis ] != AST__BAD ){ - ptr1[ axis ][ 0 ] = phy[ axis ] - delta; - ptr1[ axis ][ 2 ] = phy[ axis ] + delta; - } - -/* Find the corresponding graphics coordinates. */ - (void) Trans( this, NULL, mapping, *pset1, 0, *pset2, 0, method, class, status ); - -/* Check the central position is OK. */ - *gx = ptr2[ 0 ][ 1 ]; - *gy = ptr2[ 1 ][ 1 ]; - if( astOK && *gx != AST__BAD && *gy != AST__BAD ){ - -/* Get the unit vector between the central position and the position at - the higher physical axis value. Also get the length of the vector - joining the two positions. */ - if( ptr2[ 0 ][ 2 ] != AST__BAD && ptr2[ 1 ][ 2 ] != AST__BAD ){ - dx1 = ptr2[ 0 ][ 2 ] - *gx; - dy1 = ptr2[ 1 ][ 2 ] - *gy; - dd1 = dx1*dx1 + dy1*dy1; - - if( dd1 > 0.0 ) { - dd1 = sqrt( dd1 ); - dx1 /= dd1; - dy1 /= dd1; - } else { - dd1 = AST__BAD; - } - - } else { - dd1 = AST__BAD; - } - -/* Do the same for the position with lower physical axis value, - reversing the direction of the vector so that it refers to the - positive direction. */ - if( ptr2[ 0 ][ 0 ] != AST__BAD && ptr2[ 1 ][ 0 ] != AST__BAD ){ - dx2 = *gx - ptr2[ 0 ][ 0 ]; - dy2 = *gy - ptr2[ 1 ][ 0 ]; - dd2 = dx2*dx2 + dy2*dy2; - - if( dd2 > 0.0 ) { - dd2 = sqrt( dd2 ); - dx2 /= dd2; - dy2 /= dd2; - } else { - dd2 = AST__BAD; - } - - } else { - dd2 = AST__BAD; - } - -/* Only overwrite the supplied vector if at least one of the two tangent - vectors was defined. */ - if( dd1 != AST__BAD || dd2 != AST__BAD ){ - -/* If the first vector was not defined, return the second. */ - if( dd1 == AST__BAD ){ - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - -/* If the second vector was not defined, return the first. */ - } else if( dd2 == AST__BAD ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - -/* If the first vector is much longer than the second, return the - second. */ - } else if( dd1 > 100.0*dd2 ){ - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - -/* If the second vector is much longer than the first, return the - first. */ - } else if( dd2 > 100.0*dd1 ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - -/* If both vectors are defined and of comparable length, return the - vector which is most nearly parallel to the supplied vector. Note, we - assume that the supplied vector [dx,dy] is a unit vector. */ - } else if( *dx != AST__BAD && *dx != AST__BAD ){ - if( ( dx1*(*dx) + dy1*(*dy) )/dd1 > - ( dx2*(*dx) + dy2*(*dy) )/dd2 ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - - } else { - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - } - -/* If no vector was supplied, return the shorter of the two vectors. */ - } else if( dd1 < dd2 ){ - *dx = dx1; - *dy = dy1; - *flag = 0; - ret = 1; - - } else { - *dx = dx2; - *dy = dy2; - *flag = 1; - ret = 1; - - } - - } - - } - - } - -/* Return the answer. */ - return ret; - -} - -static int HasEscapes( const char *text, int *status ) { -/* -* Name: -* HasEscapes - -* Purpose: -* Check if a text string contains any escape sequences. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int HasEscapes( const char *text, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function checks if a text string contains any escape sequences -* (see attribute Escape). - -* Parameters: -* text -* The text to check. -* status -* Pointer to the inherited status variable. - -* Returned: -* Non-zero if any escape sequences are found in the text. Zero -* otherwise. - -*/ - -/* Local Variables: */ - int result; - int type; - int value; - int nc; - -/* Initialise. */ - result = 0; - -/* Check the global error status and the supplied pointer. */ - if ( !astOK || ! text ) return result; - -/* Does the string begin with an escape sequence? */ - if( astFindEscape( text, &type, &value, &nc ) ){ - result = 1; - -/* If not, there must be an escape sequence later in the string if the - number of characters skipped by the above call to astFindEscape is less - than the length of the string. */ - } else if( nc < strlen( text ) ) { - result = 1; - } - -/* Return the result. */ - return result; -} - -static int IdFind( int id, int nax, int *id1, int *id2, int *id3, int *status ) { -/* -* Name: -* IdFind - -* Purpose: -* Find the numerical identifiers to use for a given identifier. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int IdFind( int id, int nax, int *id1, int *id2, int *id3, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied integer should be a numerical identifier for a -* graphical element of a plot (AST__MARKS_ID, AST__CURVES_ID, etc), or a -* "psuedo-identifier" which represents two other genuine identifiers. -* If the supplied value is a genuine identifier then it is returned -* in *id1, and *id2 is returned equal to -1. If the supplied value -* is a pseudo-identifier then the two corresponding genuine -* identifiers are returned in *id1 and *id2 - -* For instance, if "id" is AST__AXIS1_ID (a genuine id), then *id1 is -* returned equal to AST__AXIS1_ID and *id2 is returned equal to -1. If -* "id" is AST__AXES_ID (a pseudo-identifier), then *id1 is returned equal -* to AST__AXIS1_ID and *id2 is returned equal to AST__AXIS2_ID. - -* Genuine identifiers all have values which are less than the value -* of AST__NPID. Pseudo-identifiers have values which are greater than -* or equal to the value of AST__NPID. - -* Parameters: -* id -* The supplied identifier (genuine or pseudo). -* nax -* The number of axes spanning graphics space (2 or 3). -* id1 -* Pointer to the int at which to return the first genuine -* identifier corresponding to "id". -* id2 -* Pointer to the int at which to return the second genuine -* identifier corresponding to "id" (or -1 if "id" is a genuine -* identifier). -* id3 -* Pointer to the int at which to return the third genuine -* identifier corresponding to "id" (or -1 if "id" has no third -* genuine identifier). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The number of genuine identifiers corresponding to the supplied -* (possibly Pseudo-) identifier. This will be in the range 1 to 3. - -*/ - -/* Local Variables: */ - int ret; - -/* Initialise returned values. */ - *id1 = id; - *id2 = -1; - *id3 = -1; - ret = 0; - -/* Check the local error status. */ - if ( !astOK ) return ret; - -/* Assume a genuine identifier was supplied. */ - ret = 1; - -/* Check against all known pseudo-identifier. */ - if( id == AST__AXES_ID ) { - ret = nax; - *id1 = AST__AXIS1_ID; - *id2 = AST__AXIS2_ID; - if( nax == 3 ) *id3 = AST__AXIS3_ID; - - } else if( id == AST__GRIDLINE_ID ) { - ret = nax; - *id1 = AST__GRIDLINE1_ID; - *id2 = AST__GRIDLINE2_ID; - if( nax == 3 ) *id3 = AST__GRIDLINE3_ID; - - } else if( id == AST__NUMLABS_ID ) { - ret = nax; - *id1 = AST__NUMLAB1_ID; - *id2 = AST__NUMLAB2_ID; - if( nax == 3 ) *id3 = AST__NUMLAB3_ID; - - } else if( id == AST__TEXTLABS_ID ) { - ret = nax; - *id1 = AST__TEXTLAB1_ID; - *id2 = AST__TEXTLAB2_ID; - if( nax == 3 ) *id3 = AST__TEXTLAB3_ID; - - } else if( id == AST__TICKS_ID ) { - ret = nax; - *id1 = AST__TICKS1_ID; - *id2 = AST__TICKS2_ID; - if( nax == 3 ) *id3 = AST__TICKS3_ID; - - } else if( id >= AST__NPID ) { - astError( AST__INTER, "AST internal programming error - " - "function IdFind in class Plot does not yet support " - "pseudo-identifier value %d", status, id ); - } - -/* Return the answer. */ - return ret; - -} - -void astInitPlotVtab_( AstPlotVtab *vtab, const char *name, int *status ) { -/* -*+ -* Name: -* astInitPlotVtab - -* Purpose: -* Initialise a virtual function table for a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* void astInitPlotVtab( AstPlotVtab *vtab, const char *name ) - -* Class Membership: -* Plot vtab initialiser. - -* Description: -* This function initialises the component of a virtual function -* table which is used by the Plot class. - -* Parameters: -* vtab -* Pointer to the virtual function table. The components used by -* all ancestral classes will be initialised if they have not already -* been initialised. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the virtual function table belongs (it -* is this pointer value that will subsequently be returned by the Object -* astClass function). -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrameSetVtab *fset; /* Pointer to FrameSet component of Vtab */ - AstObjectVtab *object; /* Pointer to Object component of Vtab */ - AstMappingVtab *mapping; /* Pointer to Mapping component of Vtab */ - -/* Check the local error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialize the component of the virtual function table used by the - parent class. */ - astInitFrameSetVtab( (AstFrameSetVtab *) vtab, name ); - -/* Store a unique "magic" value in the virtual function table. This will be - used (by astIsAPlot) to determine if an object belongs to this class. - We can conveniently use the address of the (static) class_init variable to - generate this unique value. */ - vtab->id.check = &class_check; - vtab->id.parent = &(((AstFrameSetVtab *) vtab)->id); - -/* Initialise member function pointers. */ -/* ------------------------------------ */ -/* Store pointers to the member functions (implemented here) that provide - virtual methods for this class. */ - vtab->BBuf = BBuf; - vtab->Border = Border; - vtab->BoundingBox = BoundingBox; - vtab->ClearGrid = ClearGrid; - vtab->ClearTol = ClearTol; - vtab->Clip = Clip; - vtab->CopyPlotDefaults = CopyPlotDefaults; - vtab->Curve = Curve; - vtab->CvBrk = CvBrk; - vtab->EBuf = EBuf; - vtab->GenCurve = GenCurve; - vtab->GetDrawnTicks = GetDrawnTicks; - vtab->GetGrid = GetGrid; - vtab->GetTol = GetTol; - vtab->GrfPop = GrfPop; - vtab->GrfPush = GrfPush; - vtab->GrfSet = GrfSet; - vtab->GrfWrapper = GrfWrapper; - vtab->Grid = Grid; - vtab->GridLine = GridLine; - vtab->Mark = Mark; - vtab->Mirror = Mirror; - vtab->PolyCurve = PolyCurve; - vtab->RegionOutline = RegionOutline; - vtab->SetGrid = SetGrid; - vtab->SetTickValues = SetTickValues; - vtab->SetTol = SetTol; - vtab->TestGrid = TestGrid; - vtab->TestTol = TestTol; - vtab->Text = Text; - - vtab->ClearTickAll = ClearTickAll; - vtab->SetTickAll = SetTickAll; - vtab->GetTickAll = GetTickAll; - vtab->TestTickAll = TestTickAll; - - vtab->ClearForceExterior = ClearForceExterior; - vtab->SetForceExterior = SetForceExterior; - vtab->GetForceExterior = GetForceExterior; - vtab->TestForceExterior = TestForceExterior; - - vtab->ClearInvisible = ClearInvisible; - vtab->SetInvisible = SetInvisible; - vtab->GetInvisible = GetInvisible; - vtab->TestInvisible = TestInvisible; - vtab->ClearBorder = ClearBorder; - vtab->SetBorder = SetBorder; - vtab->GetBorder = GetBorder; - vtab->TestBorder = TestBorder; - vtab->ClearInk = ClearInk; - vtab->SetInk = SetInk; - vtab->GetInk = GetInk; - vtab->TestInk = TestInk; - vtab->ClearClipOp = ClearClipOp; - vtab->SetClipOp = SetClipOp; - vtab->GetClipOp = GetClipOp; - vtab->TestClipOp = TestClipOp; - vtab->ClearClip = ClearClip; - vtab->SetClip = SetClip; - vtab->GetClip = GetClip; - vtab->TestClip = TestClip; - vtab->ClearGrf = ClearGrf; - vtab->SetGrf = SetGrf; - vtab->GetGrf = GetGrf; - vtab->TestGrf = TestGrf; - vtab->ClearDrawTitle = ClearDrawTitle; - vtab->SetDrawTitle = SetDrawTitle; - vtab->GetDrawTitle = GetDrawTitle; - vtab->TestDrawTitle = TestDrawTitle; - vtab->ClearLabelUp = ClearLabelUp; - vtab->SetLabelUp = SetLabelUp; - vtab->GetLabelUp = GetLabelUp; - vtab->TestLabelUp = TestLabelUp; - vtab->ClearLogPlot = ClearLogPlot; - vtab->SetLogPlot = SetLogPlot; - vtab->GetLogPlot = GetLogPlot; - vtab->TestLogPlot = TestLogPlot; - vtab->ClearLogTicks = ClearLogTicks; - vtab->SetLogTicks = SetLogTicks; - vtab->GetLogTicks = GetLogTicks; - vtab->TestLogTicks = TestLogTicks; - vtab->ClearLogLabel = ClearLogLabel; - vtab->SetLogLabel = SetLogLabel; - vtab->GetLogLabel = GetLogLabel; - vtab->TestLogLabel = TestLogLabel; - vtab->ClearDrawAxes = ClearDrawAxes; - vtab->SetDrawAxes = SetDrawAxes; - vtab->GetDrawAxes = GetDrawAxes; - vtab->TestDrawAxes = TestDrawAxes; - vtab->ClearAbbrev = ClearAbbrev; - vtab->SetAbbrev = SetAbbrev; - vtab->GetAbbrev = GetAbbrev; - vtab->TestAbbrev = TestAbbrev; - vtab->ClearEscape = ClearEscape; - vtab->SetEscape = SetEscape; - vtab->GetEscape = GetEscape; - vtab->TestEscape = TestEscape; - vtab->ClearLabelling = ClearLabelling; - vtab->SetLabelling = SetLabelling; - vtab->GetLabelling = GetLabelling; - vtab->TestLabelling = TestLabelling; - vtab->ClearMajTickLen = ClearMajTickLen; - vtab->SetMajTickLen = SetMajTickLen; - vtab->GetMajTickLen = GetMajTickLen; - vtab->TestMajTickLen = TestMajTickLen; - vtab->ClearLogGap = ClearLogGap; - vtab->SetLogGap = SetLogGap; - vtab->GetLogGap = GetLogGap; - vtab->TestLogGap = TestLogGap; - vtab->ClearTitleGap = ClearTitleGap; - vtab->SetTitleGap = SetTitleGap; - vtab->GetTitleGap = GetTitleGap; - vtab->TestTitleGap = TestTitleGap; - vtab->ClearMinTickLen = ClearMinTickLen; - vtab->SetMinTickLen = SetMinTickLen; - vtab->GetMinTickLen = GetMinTickLen; - vtab->TestMinTickLen = TestMinTickLen; - vtab->ClearNumLabGap = ClearNumLabGap; - vtab->SetNumLabGap = SetNumLabGap; - vtab->GetNumLabGap = GetNumLabGap; - vtab->TestNumLabGap = TestNumLabGap; - vtab->ClearTextLabGap = ClearTextLabGap; - vtab->SetTextLabGap = SetTextLabGap; - vtab->GetTextLabGap = GetTextLabGap; - vtab->TestTextLabGap = TestTextLabGap; - vtab->ClearLabelAt = ClearLabelAt; - vtab->SetLabelAt = SetLabelAt; - vtab->GetLabelAt = GetLabelAt; - vtab->TestLabelAt = TestLabelAt; - vtab->ClearCentre = ClearCentre; - vtab->SetCentre = SetCentre; - vtab->GetCentre = GetCentre; - vtab->TestCentre = TestCentre; - vtab->ClearGap = ClearGap; - vtab->SetGap = SetGap; - vtab->GetGap = GetGap; - vtab->TestGap = TestGap; - vtab->ClearEdge = ClearEdge; - vtab->SetEdge = SetEdge; - vtab->GetEdge = GetEdge; - vtab->TestEdge = TestEdge; - vtab->ClearNumLab = ClearNumLab; - vtab->SetNumLab = SetNumLab; - vtab->GetNumLab = GetNumLab; - vtab->TestNumLab = TestNumLab; - vtab->ClearMinTick = ClearMinTick; - vtab->SetMinTick = SetMinTick; - vtab->GetMinTick = GetMinTick; - vtab->TestMinTick = TestMinTick; - vtab->ClearTextLab = ClearTextLab; - vtab->SetTextLab = SetTextLab; - vtab->GetTextLab = GetTextLab; - vtab->TestTextLab = TestTextLab; - vtab->ClearLabelUnits = ClearLabelUnits; - vtab->SetLabelUnits = SetLabelUnits; - vtab->GetLabelUnits = GetLabelUnits; - vtab->TestLabelUnits = TestLabelUnits; - vtab->ClearStyle = ClearStyle; - vtab->SetStyle = SetStyle; - vtab->GetStyle = GetStyle; - vtab->TestStyle = TestStyle; - vtab->ClearFont = ClearFont; - vtab->SetFont = SetFont; - vtab->GetFont = GetFont; - vtab->TestFont = TestFont; - vtab->ClearColour = ClearColour; - vtab->SetColour = SetColour; - vtab->GetColour = GetColour; - vtab->TestColour = TestColour; - vtab->ClearWidth = ClearWidth; - vtab->SetWidth = SetWidth; - vtab->GetWidth = GetWidth; - vtab->TestWidth = TestWidth; - vtab->ClearSize = ClearSize; - vtab->SetSize = SetSize; - vtab->GetSize = GetSize; - vtab->TestSize = TestSize; - vtab->GetGrfContext = GetGrfContext; - -/* Save the inherited pointers to methods that will be extended, and replace - them with pointers to the new member functions. */ - object = (AstObjectVtab *) vtab; - mapping = (AstMappingVtab *) vtab; - fset = (AstFrameSetVtab *) vtab; - - parent_clearattrib = object->ClearAttrib; - object->ClearAttrib = ClearAttrib; - parent_getattrib = object->GetAttrib; - object->GetAttrib = GetAttrib; - parent_setattrib = object->SetAttrib; - object->SetAttrib = SetAttrib; - parent_testattrib = object->TestAttrib; - object->TestAttrib = TestAttrib; - -#if defined(THREAD_SAFE) - parent_managelock = object->ManageLock; - object->ManageLock = ManageLock; -#endif - - parent_transform = mapping->Transform; - mapping->Transform = Transform; - - parent_removeframe = fset->RemoveFrame; - fset->RemoveFrame = RemoveFrame; - -/* Declare the destructor and copy constructor. */ - astSetDelete( (AstObjectVtab *) vtab, Delete ); - astSetCopy( (AstObjectVtab *) vtab, Copy ); - -/* Declare the class dump function. */ - astSetDump( vtab, Dump, "Plot", "Provide facilities for 2D graphical output" ); - -/* If we have just initialised the vtab for the current class, indicate - that the vtab is now initialised, and store a pointer to the class - identifier in the base "object" level of the vtab. */ - if( vtab == &class_vtab ) { - class_init = 1; - astSetVtabClassIdentifier( vtab, &(vtab->id) ); - } -} - -static int Inside( int n, float *cx, float *cy, float x, float y, int *status ){ -/* -* Name: -* Inside - -* Purpose: -* See if a given point is inside a 2-d polygon. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Inside( int n, float *cx, float *cy, float x, float y, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function determines if the position given by x and y, is inside -* or outside the polygon specified by the vertices given in arrays cx -* and cy. - -* Parameters: -* n -* The number of vertices in the polygon. -* cx -* A pointer to an array holding the x coordinates at the "n" vertices. -* cy -* A pointer to an array holding the y coordinates at the "n" vertices. -* x -* The x coordinate of the test point. -* y -* The y coordinate of the test point. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A boolean flag indicating if the test point is inside the polygon. - -* Notes: -* - The algorithm used only works for convex polygons. -* - The polygon is closed by joining the last vertex to the first -* vertex. -* - Zero is returned if an error has occurred. - -*/ - -/* Local Variables: */ - int i; /* Index of the current vertex */ - int j; /* Index of the next vertex */ - int ret; /* Is the test point inside the polygon? */ - int sgn; /* Which side of the first edge is the test point? */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise the returned value to indicate that the point is inside the - box. */ - ret = 1; - -/* Get the sign of the angle between the vector joining vertex 1 to vertex - 0, and the vector joining the test point to vertex zero. */ - if( ( cx[ 1 ] - cx[ 0 ] )*( y - cy[ 0 ] ) > - ( x - cx[ 0 ] )*( cy[ 1 ] - cy[ 0 ] ) ){ - sgn = 1; - } else { - sgn = -1; - } - -/* Check that the remaining test point is on the same side of the remaining - sides. */ - for( i = 1; i < n; i++ ){ - -/* Get the index of the next vertex, joining the last vertex up with - vertex zero. */ - j = i + 1; - if( j >= n ) j -= n; - -/* Get the sign of the angle between the vector joining vertex j to vertex - i, and the vector joining the test point to vertex i. If the sign is - opposite to that found for vertex zero, then the test point is outside - the polygon. Break out of the loop if this is the case. */ - if( ( cx[ j ] - cx[ i ] )*( y - cy[ i ] ) > - ( x - cx[ i ] )*( cy[ j ] - cy[ i ] ) ){ - - if( sgn == -1 ) { - ret = 0; - break; - } - - } else { - - if( sgn == 1 ) { - ret = 0; - break; - } - - } - - } - - -/* Return the answer. */ - return ret; - -} - -static void InterpEscape( AstPlot *this, int type, double value, float *x, - float *y, float ux, float uy, float rx, float ry, - const char *just, float *rise, double nsize, - double nstyle, double nwidth, double ncol, - double nfont, const char *method, const char *class, int *status ){ -/* -* Name: -* InterpEscape - -* Purpose: -* Prepare things for drawing the next part of a string which includes -* graphics escape sequences. - -* Synopsis: -* #include "plot.h" -* void InterpEscape( AstPlot *this, int type, double value, float *x, -* float *y, float ux, float uy, float rx, float ry, -* const char *just, float *rise, double nsize, -* double nstyle, double nwidth, double ncol, -* double nfont, const char *method, const char *class, int *status ) - -* Description: -* This function modifies the current graphics attributes, the supplied -* reference position, in preparation for drawing another sub-string -* from a string containing graphics escape sequences. The type and -* value of an escape sequence preceding the substring is supplied. -* Note, this function ignored escape sequences which represent an -* escaped percent sign. Such escape sequences are drawn as normal -* text by the claling function. - -* Parameters: -* this -* The plot. -* type -* The type of escape sequence. Each type is identified by a symbolic -* constant defined in grf.h. -* value -* The value associated with the escape sequence. All usable values -* will be positive. A value of -1 shold be supplied if the attribute -* identified by "type" should be reset to its "normal" value (as -* established using the astGAttr function, etc). -* x -* Pointer to a double holding the x coordinate at the concatenation -* point. This will be modified on exit if the escape sequence -* requires it. -* y -* Pointer to a double holding the y coordinate at the concatenation -* point. This will be modified on exit if the escape sequence -* requires it. -* ux -* The x component of the up-vector for the text, in graphics coords. -* The length of this vector should be equal to the height of normal -* text drawn with this up-vector. -* uy -* The y component of the up-vector for the text. See "ux". -* rx -* The x component of the right-vector for the text. The length of this -* vector should be equal to the height of normal text drawn with the -* supplied up-vector. -* ry -* The y component of the right-vector for the text. see "rx". -* just -* The justification being used for each substring. -* rise -* Pointer to a float holding the height of the current baseline -* above the normal baseline, given as a percentage of the height of -* normal text. May be negative for sub-scripts. May be modified on -* exit if the escape sequence effects the height of the baseline. -* nsize -* The size of normal text. -* nstyle -* The style of normal text. -* nwidth -* The width of normal text. -* ncol -* The colour of normal text. -* nfont -* The font of normal text. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - float new_rise; - float t1, t2; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Type GRF__ESSUP: Move the concatenation point in the up direction, and - update the current baseline height. If the value is -1, then reset the - baseline to its normal height. */ - if( type == GRF__ESSUP ) { - if( value > 0 ) { - *x += 0.01*ux*( value - *rise ); - *y += 0.01*uy*( value - *rise ); - *rise = value; - } else { - *x -= 0.01*ux*(*rise); - *y -= 0.01*uy*(*rise); - *rise = 0; - } - -/* Type GRF__ESSUB: Move the concatenation point in the down direction, and - update the current baseline height. If the value is -1, then reset the - baseline to its normal height. */ - } else if( type == GRF__ESSUB ) { - if( value > 0 ) { - *x -= 0.01*ux*( value + *rise ); - *y -= 0.01*uy*( value + *rise ); - *rise = -value; - } else { - *x -= 0.01*ux*(*rise); - *y -= 0.01*uy*(*rise); - *rise = 0; - } - -/* Type GRF__ESGAP: Move the concatenation point to the right. */ - } else if( type == GRF__ESGAP ) { - *x += 0.01*rx*value; - *y += 0.01*ry*value; - -/* Type GRF__ESBAC: Move the concatenation point to the left. */ - } else if( type == GRF__ESBAC ) { - *x -= 0.01*rx*value; - *y -= 0.01*ry*value; - -/* Remember the current horizontal position. */ - } else if( type == GRF__ESH ) { - this->hmarkx = *x; - this->hmarky = *y; - -/* Go to the previously stored horizontal position. */ - } else if( type == GRF__ESG ) { - if( this->hmarkx != FLT_MAX && this->hmarky != FLT_MAX ) { - t1 = ( *x - this->hmarkx )*rx + ( *y - this->hmarky )*ry; - t2 = rx*rx + ry*ry; - *x -= rx*t1/t2; - *y -= ry*t1/t2; - } - -/* Type GRF__ESSIZ: Change the text size. */ - } else if( type == GRF__ESSIZ ) { - if( value < 0 ) value = 100.0; - GAttr( this, GRF__SIZE, 0.01*value*nsize, NULL, GRF__TEXT, - method, class, status ); - -/* Type GRF__ESWID: Change the text width. */ - } else if( type == GRF__ESWID ) { - if( value < 0 ) value = 100.0; - GAttr( this, GRF__WIDTH, 0.01*value*nwidth, NULL, GRF__TEXT, - method, class, status ); - -/* Type GRF__ESFON: Change the text font. */ - } else if( type == GRF__ESFON ) { - if( value < 0 ) value = nfont; - GAttr( this, GRF__FONT, value, NULL, GRF__TEXT, method, class, status ); - -/* Type GRF__ESCOL: Change the text colour. */ - } else if( type == GRF__ESCOL ) { - if( value < 0 ) value = ncol; - GAttr( this, GRF__COLOUR, value, NULL, GRF__TEXT, method, class, status ); - -/* Type GRF__ESSTY: Change the text style. */ - } else if( type == GRF__ESSTY ) { - if( value < 0 ) value = nstyle; - GAttr( this, GRF__STYLE, value, NULL, GRF__TEXT, method, class, status ); - -/* Type GRF__ESPSH: Push current attributes onto a stack. */ - } else if( type == GRF__ESPSH ) { - PushGat( this, *rise, method, class, status ); - -/* Type GRF__ESSTY: Reset everything to normal. */ - } else if( type == GRF__ESPOP ) { - - if( !PopGat( this, &new_rise, method, class, status ) ) { - new_rise = 0.0; - GAttr( this, GRF__SIZE, nsize, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, nwidth, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, ncol, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, nfont, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, nstyle, NULL, GRF__TEXT, method, class, status ); - } - - *x -= 0.01*ux*( *rise - new_rise ); - *y -= 0.01*uy*( *rise - new_rise ); - *rise = new_rise; - - } -} - -static int IsASkyAxis( AstFrame *frm, int axis, int *status ) { -/* -* Name: -* IsASkyAxis - -* Purpose: -* Checks if a specified axis of the supplied Frame is a SkyAxis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int IsASkyAxis( AstFrame *frm, int axis, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function checks if if a specified axis of the supplied Frame is -* a SkyAxis. - -* Parameters: -* frm -* The Frame. -* axis -* The zero-based axis index. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A boolean flag indicating if the axis is a SkyAxis. - -*/ - -/* Local Variables: */ - int ret; - AstAxis *ax; - -/* initialise */ - ret = 0; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* Extract the required axis from the Frame and test if it is a SkyAxis. - Then free the axis memory. */ - ax = astGetAxis( frm, axis ); - ret = astIsASkyAxis( ax ); - ax = astAnnul( ax ); - -/* Return the answer. */ - return ret; - -} - -static int IsASkyFrame( AstObject *obj, int *status ) { -/* -* Name: -* IsASkyFrame - -* Purpose: -* Checks if the supplied Object ca be treated as a SkyFrame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int IsASkyFrame( AstObject *obj, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function checks if the supplied Object is a SkyFrame or a -* FrameSet which has a SkyFrame as its current Frame. - -* Parameters: -* obj -* The object. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A boolean flag indicating if the Object can be treated as SkyFrame. - -*/ - -/* Local Variables: */ - int ret; - AstFrame *frm; - -/* initialise */ - ret = 0; - -/* Check the global status. */ - if( !astOK ) return ret; - -/* If the Object is a SkyFrame, return 1. */ - if( astIsASkyFrame( obj ) ) { - ret = 1; - -/* If the Object is a FrameSet, check its current Frame recursively, - using this method. */ - } else if( astIsAFrameSet( obj ) ) { - frm = astGetFrame( (AstFrameSet *) obj, AST__CURRENT ); - ret = IsASkyFrame( (AstObject *) frm, status ); - frm = astAnnul( frm ); - } - -/* Return the answer. */ - return ret; - -} - -static const char *JustMB( AstPlot *this, int esc, const char *text, float *x, - float *y, float upx, float upy, const char *just, - float uxu, float uyu, float rxu, float ryu, - float *x0, float *y0, const char *method, - const char *class, int *status ){ -/* -* Name: -* JustMB - -* Purpose: -* Modifies a "M" vertical reference point to be a "B" reference point, -* if necessary. - -* Synopsis: -* #include "plot.h" -* const char *JustMB( AstPlot *this, int esc, const char *text, float *x, -* float *y, float upx, float upy, const char *just, -* float uxu, float uyu, float rxu, float ryu, -* float *x0, float *y0, const char *method, -* const char *class, int *status ) - -* Description: -* This function is used to modify the reference point and justification -* of a string by converting the vertical "M" justification option (which -* indicates that the reference point refers to the bottom of the -* bounding box) into a corresponding "B" option (which indicates that -* the reference point refers to the text baseline). The reference -* point is modified accordingly. -* -* This is only done if the grf module does not support "M" -* justification. Otherwise, the supplied justification string and -* reference point coordinates are returned unchanged. - -* Parameters: -* this -* The plot. -* esc -* Should escape sequences be interpreted? They will be printed -* literally otherwise. -* text -* Pointer to a null-terminated character string to be displayed. -* x -* Pointer to a double holding the x coordinate at the reference -* point. This is modified on exit if the supplied "just" string -* indicates that the supplied value refers to the bottom of the -* bounding box, and the grf module does not support such -* justification. In this case, the returned value is a point on -* the baseline of the text which would result in the bottom of -* the bounding box being at the supplied position. -* y -* Pointer to a double holding the y coordinate at the reference -* point. This is modified on exit if the supplied "just" string -* indicates that the supplied value refers to the bottom of the -* bounding box, and the grf module does not support such -* justification. In this case, the returned value is a point on -* the baseline of the text which would result in the bottom of -* the bounding box being at the supplied position. -* upx -* The x component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics x axis increases in the opposite sense. -* upy -* The y component of the up-vector for the text. Positive values -* always refer to displacements from left to right on the screen, -* even if the graphics y axis increases in the opposite sense. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", 'B' for "baseline" or "M" for "bottom", and -* specifies the vertical location of the reference position. Note, -* "baseline" corresponds to the base-line of normal text,and "M" -* corresponds to the bottom of the bounding box. Some characters -* (eg "y", "g", "p", etc) and sub-scripts descend below the base-line. -* The second character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* uxu -* X component of normalised up-vector, in graphics coords. -* uyu -* Y component of normalised up-vector, in graphics coords. -* rxu -* X component of normalised right-vector, in graphics coords. -* ryu -* Y component of normalised right-vector, in graphics coords. -* x0 -* Address of a float at which to return the x coordinate at the -* left end of the baseline of the whole string. -* y0 -* Address of a float at which to return the y coordinate at the -* left end of the baseline of the whole string. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a dynamically allocated string which contains the -* justification to use in future. This pointer should be freed using -* astFree when no longer needed. This string will contain a full -* upper-case justification string which can be used by the current -* grf module. - -* Notes; -* - NULL is returned if an error has occurred. - -*/ - -/* Local Variables: */ - char cc; - float drop; - float dx; - float dy; - float f; - float height; - float width; - float xbn[ 4 ]; - float ybn[ 4 ]; - int called; - char *result; - -/* Check inherited status */ - if( !astOK ) return NULL; - -/* Allocate memory for the returned string. */ - result = astMalloc( sizeof( char )*3 ); - if( astOK ) { - -/* Fill in any missing parts of the justification string. */ - if( just ){ - cc = toupper( just[ 0 ] ); - result[ 0 ] = ( cc == 'T' || cc == 'C' || cc == 'B' || cc == 'M' ) ? cc : 'C'; - - cc = toupper( just[ 1 ] ); - result[ 1 ] = ( cc == 'L' || cc == 'C' || cc == 'R' ) ? cc : 'C'; - - } else { - result[ 0 ] = 'C'; - result[ 1 ] = 'C'; - } - - result[ 2 ] = 0; - -/* Indicate that DrawText has not been called. */ - called = 0; - -/* The justfication need not be changed unless the requested vertical - justification is "bottom" (m), AND the grf module does not support "M" - justification. */ - if( ( result[ 0 ] == 'M' ) && !GCap( this, GRF__MJUST, 1, status ) ){ - -/* Find the bounding box which would result from putting the left end of - the baseline at the specified position. */ - DrawText( this, 0, esc, text, *x, *y, "BL", upx, upy, xbn, ybn, - &drop, method, class, status ); - -/* Indicate that DrawText has not been called. */ - called = 1; - -/* Get the vector from the bottom left corner of the bounding box to the - reference point (on the base-line), and add this vector on to the reference - point. */ - *x += *x - xbn[ 0 ]; - *y += *y - ybn[ 0 ]; - -/* Modified the returned justification string. */ - result[ 0 ] = 'B'; - } - -/* If the returned justification is "BL", then the left end of the - baseline is just the returned reference point. */ - if( result[ 0 ] == 'B' && result[ 1 ] == 'L' ) { - *x0 = *x; - *y0 = *y; - -/* Otherwise, we work out the coords of the left end of the baseline from - the values returned by DrawText above. Call DrawText now if it was not - called above. */ - } else { - if( ! called ) { - DrawText( this, 0, esc, text, *x, *y, "BL", upx, upy, xbn, ybn, - &drop, method, class, status ); - } - -/* Find the height and width of the bounding box. */ - dx = xbn[ 0 ] - xbn[ 3 ]; - dy = ybn[ 0 ] - ybn[ 3 ]; - width = sqrt( dx*dx + dy*dy ); - - dx = xbn[ 0 ] - xbn[ 1 ]; - dy = ybn[ 0 ] - ybn[ 1 ]; - height = sqrt( dx*dx + dy*dy ); - -/* For "C" and "R" horizontal justification we first need to move the - returned reference point left by 0.5 or 1.0 times the width of the whole - string respectively. */ - if( result[ 1 ] == 'C' ) { - f = 0.5; - - } else if( result[ 1 ] == 'R' ) { - f = 1.0; - - } else { - f = 0.0; - } - - f *= width; - - *x0 = *x - f*rxu; - *y0 = *y - f*ryu; - -/* Unless the vertical justification is "B", we also need to move the - concatenation point vertically to put it on the baseline. */ - if( result[ 0 ] == 'T' ) { - f = height - drop; - - } else if( result[ 0 ] == 'C' ) { - f = 0.5*height - drop; - - } else if( result[ 0 ] == 'M' ) { - f = -drop; - - } else { - f = 0.0; - } - - *x0 -= f*uxu; - *y0 -= f*uyu; - } - } - -/* Return the result. */ - return result; -} - -static int Labelat( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, - double *labelat, const char *method, const char *class, - int *status ){ -/* -* -* Name: -* Labelat - -* Purpose: -* Determine the other axis value at which to place interior labels -* and tick marks. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Labelat( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, -* double *labelat, const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* If tick marks and labels are to be placed within the plotting area, -* the tick values stored in "grid" determine their position on one -* axis, and their position on the other axis is determined by this -* function. If a value has been set for the "LabelAt" attribute, then -* it is used, otherwise the "other axis" value on the longest curve -* parallel to the "other axis" is used (although the curve "other axis -* = zero" is used if it passes through the plotting area and is not too -* short). The effective length assigned to each curve is reduced in -* proportion to the number of tick marks which are close to the edge -* of the plotting area. -* -* A flag is returned indicating if the two axes appear to be -* independent, in which case there is nothing to be gained by using -* interior labelling. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick values on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* labelat -* A pointer to a 2 element array in which to store the constant axis -* values at which tick marks are put. Element 0 is returned holding -* the axis 1 value at which tick marks for axis 0 are placed. Element -* 1 is returned holding the axis 0 value at which tick marks for axis -* 1 are placed. -* flags -* A pointer to a 2 element array. Each element is a flag which is -* returned non-zero if the corresponding axis -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Returned Value: -* Zero if and only if the lines of constant axis value are all the -* same length for all tick marks on either axis. If this is so, using -* interior labelling will not enable any more major ticks to be -* drawn, and so there is no reason to switch to interior labelling (unless -* the user has specifically requested interior labelling). - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. -*/ - -/* Local Variables: */ - AstMapping *mapping; /* Mapping from graphics to physical coords */ - AstPointSet *pset2; /* Pointset for graphical tick positions */ - AstPointSet *pset[ 2 ];/* Pointsets for physical tick positions */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - double **ptr2; /* Pointers to graphics pointset data */ - double *ptr1[ 2 ]; /* Pointers to physical pointset data */ - double *tvals[ 2 ]; /* Pointers to arrays of other axis values */ - double *value; /* Current tick value */ - double efflen; /* Effective length of current curve */ - double lim; /* Largest insignificant axis value */ - double margin; /* Width of margin around plotting area */ - double maxlen; /* Effective length of longest curve */ - double minlen; /* Effective length of shortest (non-zero) curve */ - double x; /* Tick X value */ - double xhi; /* Upper limit on acceptable X range */ - double xlo; /* Lower limit on acceptable X range */ - double y; /* Tick Y value */ - double yhi; /* Upper limit on acceptable Y range */ - double ylo; /* Lower limit on acceptable Y range */ - double zerolen; /* Effective length of curve for other axis = 0.0 */ - int axis; /* Current axis index */ - int i; /* Tick index for this axis */ - int nin; /* No. of counted ticks */ - int result; /* Does interior labelling allow more ticks to be drawn? */ - int tick; /* Tick index */ - -/* Check the global status. */ - if( !astOK ) return 0; - -/* Initialise */ - result = 1; - -/* Create two PointSets to hold a set of tick mark positions along each - axis. The values on "axis" will be taken from the info structure. For - each axis create an array to hold values for the "other" axis. */ - for( axis = 0; axis < 2; axis++ ){ - info = grid[ axis ]; - pset[ axis ] = astPointSet( info->nmajor, 2, "", status ); - tvals[ axis ] = (double *) astMalloc( sizeof(double)*(size_t)(info->nmajor) ); - } - -/* Get the mapping from Base (graphics) frame the Current (physical) */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Get the bounds of the area in which tick marks must occur to be - counted. This is the total plotting area minus a 5% margin at each - edge. */ - margin = 0.05*( this->xhi - this->xlo ); - xlo = this->xlo + margin; - xhi = this->xhi - margin; - - margin = 0.05*( this->yhi - this->ylo ); - ylo = this->ylo + margin; - yhi = this->yhi - margin; - -/* Do each axis. */ - for( axis = 0; axis < 2 && astOK; axis++ ){ - -/* Find the longest and shortest curves parallel to the axis being labelled. - Also find the length of the curve which passes through the origin of the - other axis which is within the plotting area. We need to do this even - if LabelAt has been set since we need to calculate the returned flag. */ - -/* Store pointers to the arrays holding tick mark physical coordinates, - and set these in the PointSet. */ - ptr1[ axis ] = grid[ axis ]->ticks; - ptr1[ 1 - axis ] = tvals[ axis ]; - astSetPoints( pset[ axis ], ptr1 ); - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along the other axis. */ - info = grid[ 1 - axis ]; - -/* Get a pointer to the other axis value at the first other axis major tick - mark. */ - value = info->ticks; - -/* Get a limit on absolute magnitude for an axis value to be consider - equal to zero. */ - lim = 1.0E-6*fabs( value[ 1 ] - value [ 0 ] ); - -/* Get a pointer to the structure containing information describing the - breaks in the curve which passes through the first major tick mark. */ - cdt = cdata[ 1 - axis ]; - -/* Initialise the effective length of the longest and shortest curves, and - the curve passing through the origin. */ - maxlen = -1.0; - minlen = DBL_MAX; - zerolen = 0.0; - labelat[ axis ] = AST__BAD; - -/* Loop round each of the major tick marks on the other axis. */ - for( tick = 0; tick < info->nmajor && astOK; tick++ ){ - -/* Fill the array of other axis values with the current other axis value. */ - for( i = 0; i < grid[ axis ]->nmajor; i++ ){ - tvals[ axis ][ i ] = *value; - } - -/* Transform the tick positions from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping. */ - pset2 = Trans( this, NULL, mapping, pset[ axis ], 0, NULL, 0, - method, class, status ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - if( astOK ) { - -/* Count the number of graphics positions which are well within the plotting - area. */ - nin = 0; - for( i = 0; i < grid[ axis ]->nmajor; i++ ){ - x = ptr2[ 0 ][ i ]; - y = ptr2[ 1 ][ i ]; - if( x != AST__BAD && x > xlo && x < xhi && - y != AST__BAD && y > ylo && y < yhi ) nin++; - } - -/* Find the effective length of this curve.*/ - efflen = sqrt( (float) nin )*cdt->length; - -/* If the curve through this tick mark has a greater effective length than any - other found so far, record it. */ - if( efflen > maxlen ){ - maxlen = efflen; - labelat[ axis ] = *value; - } - -/* If the curve through this tick mark has a smaller non-zero effective length - than any other found so far, record it. */ - if( efflen < minlen && efflen > 0.0 ) minlen = efflen; - -/* If this tick mark is at the origin, note the effective length. */ - if( fabs( *value ) <= lim ) zerolen = efflen; - -/* Get a pointer to the curve through the next major tick mark. */ - cdt++; - -/* Get a pointer to the axis value at the next major tick mark. */ - value++; - - } - -/* Free resources. */ - pset2 = astAnnul( pset2 ); - } - -/* Use the curve through the origin unless it is significantly shorter - than the longest curve. */ - if( zerolen > 0.4*maxlen ) labelat[ axis ] = 0.0; - -/* Return a flag if the lengths of the shortest and longest curves are nearly - equal. */ - if( ( maxlen - minlen )/( maxlen + minlen ) < 1.0E-5 ) result = 0; - -/* If the LabelAt attribute has been set, use it in preference to the - value found above. */ - if( astTestLabelAt( this, axis ) ){ - labelat[ axis ] = astGetLabelAt( this, axis ); - } - } - -/* Release resources. */ - for( axis = 0; axis < 2; axis++ ){ - if( pset[ axis ] ) pset[ axis ] = astAnnul( pset[ axis ] ); - if( tvals[ axis ] ) tvals[ axis ] = (double *) astFree( (void *) tvals[ axis ] ); - } - mapping = astAnnul( mapping ); - -/* Return. */ - return result; - -} - -static void Labels( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, - double *gap, double *labelat, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* Labels - -* Purpose: -* Draw numerical axis labels for a 2-D annotated coordinate grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Labels( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, -* double *gap, double *labelat, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The policy for placing labels for the major tick values is broadly as -* follows: if possible, labels for a given physical axis are placed on -* one edge of the plotting area, at the place where the curve for a -* major tick value crosses the edge. If very few of the curves cross -* the edge, then the label for a curve is placed at the intersection -* of that curve with the longest of the curves representing the major -* tick values on the other axis. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick values on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* gap -* Pointer to array of two values holding the gap between major -* tick values on the two axes. -* labelat -* A pointer to a 2 element array holding the constant axis -* values at which tick marks are put. Element 0 should hold -* the axis 1 value at which tick marks for axis 0 are placed. Element -* 1 should hold the axis 0 value at which tick marks for axis -* 1 are placed. If labels are to be placed round the edges of the -* plotting zone instead of within the plotting zone, then values of -* AST__BAD should be supplied. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This function assumes the current Frame of the Plot is 2 -* dimensional, and it should not be called if this is not the case. -*/ - -/* Local Variables: */ - AstFrame *frame; /* Pointer to current Frame */ - AstMapping *mapping; /* Pointer to graphics->physical Mapping */ - AstPointSet *pset1; /* Pointer to PointSet holding physical coords. */ - AstPointSet *pset2; /* Pointer to PointSet holding graphics coords. */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - LabelList *labellist; /* Pointer to list of labels to be plotted */ - LabelList *ll; /* Pointer to next label to be plotted */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - char just_buf[3]; /* Buffer to hold a justification string */ - const char *just; /* Justification string */ - const char *text; /* Pointer to label text */ - double *used; /* Pointer to list of used label values */ - double *value; /* Current tick value */ - double diff; /* Difference between adjacent major tick marks */ - double dx; /* Text base-line X component */ - double dy; /* Text base-line Y component */ - double gx; /* Reference position graphics X coord. */ - double gy; /* Reference position graphics Y coord. */ - double mindim; /* Shortest dimension of plotting area */ - double offx; /* X component of offset vector */ - double offy; /* Y component of offset vector */ - double rlen; /* Length of perpendicular vector */ - double rx; /* X comp of vector perpendicular to (dx,dy) */ - double ry; /* Y comp of vector perpendicular to (dx,dy) */ - double sin45; /* Sine of 45 degrees */ - double txtgap; /* Absolute gap between labels and edges */ - double upx; /* Text up-vector X component */ - double upy; /* Text up-vector Y component */ - double val[ 2 ]; /* Physical coordinates */ - float *box; /* Pointer to array of label bounding boxes */ - float alpha; /* Factor to convert graphics X to equal scaled X */ - float beta; /* Factor to convert graphics Y to equal scaled Y */ - int axis; /* Current axis index */ - int esc; /* Interpret escape sequences? */ - int flag; /* Flag indicating which way the base-vector points */ - int iused; /* Index into list of used axis values */ - int last; /* The index of the last tick to use */ - int logticks; /* ARe major ticks spaced logarithmically? */ - int nlab; /* The number of labels to be plotted */ - int nused; /* Number of used axis values */ - int t0; /* Index of central tick */ - int tick; /* Current tick index */ - int tinc; /* Increment between ticks */ - int upfree; /* Are we free to change the up-vector? */ - int gelid; /* ID for next graphical element to be drawn */ - -/* Check the global status. */ - if( !astOK ) return; - -/* See if escape sequences in text strings are to be interpreted */ - esc = astGetEscape( this ); - -/* Empty the list of bounding boxes kept by the Overlap function. */ - (void) Overlap( this, 0, 0, NULL, 0.0, 0.0, NULL, 0.0, 0.0, NULL, - method, class, status ); - -/* If required, draw the labels around the edges of the plotting area. */ - if( labelat[ 0 ] == AST__BAD || labelat[ 1 ] == AST__BAD ){ - (void) EdgeLabels( this, 1, grid, cdata, 1, method, class, status ); - -/* Otherwise, draw labels within the interior of the plotting area. */ - } else { - -/* Find the scale factors for the two axes which scale graphics coordinates - into a "standard" equal scaled coordinate system in which: 1) the axes - have equal scale in terms of (for instance) millimetres per unit distance, - 2) X values increase from left to right, 3) Y values increase from bottom - to top. */ - GScales( this, &alpha, &beta, method, class, status ); - -/* Get the minimum dimension of the plotting area in equal scaled coords. */ - mindim = astMIN( fabs( alpha*(this->xhi - this->xlo) ), - fabs( beta*(this->yhi - this->ylo) ) ); - -/* Store a value for the sine of 45 degrees. */ - sin45 = 1.0/sqrt( 2.0 ); - -/* Initialise the pointer to the memory holding the bounding boxes for - all labels (used by function Overlap). */ - box = NULL; - -/* Get a pointer to the current Frame in the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Get a pointer to the mapping form the base Frame to the current Frame in - the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__NUMLAB1_ID; - -/* Do each axis. */ - for( axis = 0; axis < 2; axis++ ){ - -/* See of major ticks are spaced logarithmically on this axis. */ - logticks = astGetLogTicks( this, axis ); - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__TEXT, method, class ); - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along this axis. */ - info = grid[ axis ]; - -/* Only progress if there are some labels stored within the structure. */ - if( info->labels ) { - -/* Initialise the pointer to the list of text strings to be drawn. */ - labellist = NULL; - nlab = 0; - -/* See if numerical labels are always to be drawn horizontal. If so, set - a flag and initialise a vertical up-vector. */ - if( astGetLabelUp( this, axis ) ){ - upfree = 0; - upx = 0.0; - upy = 1.0; - -/* Otherwise, clear the flag and indicate that we do not yet have an - up-vector. */ - } else { - upfree = 1; - upx = AST__BAD; - upy = AST__BAD; - } - -/* Indicate that the tangent vector to the other axis is not yet - known. */ - dx = AST__BAD; - dy = AST__BAD; - gx = AST__BAD; - gy = AST__BAD; - -/* Store the gap to put next to the label text. This is in equal scaled - coords, not graphics coords. */ - txtgap = astGetNumLabGap( this, axis )*mindim; - -/* Get a pointer to the structure containing information describing the - breaks in the curve which passes through the first major tick mark. */ - cdt = cdata[ axis ]; - -/* Get a pointer to the axis value at the first major tick mark. */ - value = info->ticks; - -/* Initialise pointers to two PointSets which will be created and used - within function GVec. */ - pset1 = NULL; - pset2 = NULL; - -/* Get memory to hold the axis values at which labels have been put. */ - used = (double *) astMalloc( sizeof(double)*(size_t)info->nmajor ); - nused = 0; - -/* The tick marks are done in two batches, each batch working out from the - middle. This is done because there may be extra tick marks outside the - normal ranges at the extremes, and these should not be given the - priority caused by doing them first. Store the mid-tick index, the - current tick index, and the increment between ticks. The ticks from the - middle up to the highest index are done first. */ - t0 = info->nmajor/2; - tick = t0 - 1; - tinc = 1; - -/* Loop round until all ticks have been done. */ - last = info->nmajor - 1; - while( (tick += tinc) >= 0 && astOK ){ - -/* If we have done the highest tick index, start again at the tick just - below middle, and work done towards index zero. */ - if( tick == info->nmajor ){ - tick = t0 - 1; - tinc = -1; - } - -/* Store the reference position for the label . */ - val[ axis ] = value[ tick ]; - val[ 1 - axis ] = labelat[ axis ]; - -/* Store the difference between this tick and the next. */ - if( logticks ) { - diff = value[ tick ]*( gap[ axis ] - 1.0 ); - } else { - diff = gap[ axis ]; - } - -/* See if this axis value has already been used. */ - for( iused = 0; iused < nused; iused++ ){ - if( fabs( val[ axis ] - used[ iused ] ) < - 1.0E-3*diff ) break; - } - -/* If the axis value has already been used, don't use it again. */ - if( iused >= nused || nused == 0 ){ - used[ nused++ ] = val[ axis ]; - -/* We now need to decide where to put the reference point for the text - string, and what justification to use. Assuming that NumLabGap is +ve, - the labels are drawn on the left hand side of the axis as seen by - someone moving along the axis in the positive direction, with an - up-vector which is normal to the axis tangent. First, find the graphics - coordinates at the point being labelled, and the unit tangent-vector - parallel to the axis being labelled. If the tangent vector is not defined, - then the tangent vector used for the previous label is re-used. This - unit tangent vector is expressed in graphics coords. */ - GVec( this, mapping, val, axis, 0.01*diff, &pset1, - &pset2, &gx, &gy, &dx, &dy, &flag, method, class, - status ); - -/* If we now have a tangent vector and good graphics coordinates for the - label's reference position... */ - if( dx != AST__BAD && dy != AST__BAD && - gx != AST__BAD && gy != AST__BAD ){ - -/* Convert the unit tangent vector from graphics coords to equal-scaled coords. */ - dx *= alpha; - dy *= beta; - -/* Rotate through 90 degrees to get a vector perpendicular to the axis in - equal scaled coords. This vector points to the left as you move along - the physical axis in the positive direction. Find its length. */ - rx = -dy; - ry = dx; - rlen = sqrt( rx*rx + ry*ry ); - -/* The reference position for the text is displaced away from the - reference position normal to the axis on the left hand side by the - "txtgap" value. */ - offx = rx*txtgap/rlen; - offy = ry*txtgap/rlen; - gx += offx/alpha; - gy += offy/beta; - -/* The up-vector and justification for the text depends on whether or - not the up-vector is free to rotate. If it is free, the up-vector is - chosen so that the text is not upside-down. Note, the up-vector is - specified in the equally scaled coordinate system. */ - if( upfree ){ - - if( dx < -0.01*fabs( alpha ) ){ - upx = -rx; - upy = -ry; - just = ( txtgap < 0.0 )? "BC" : "TC"; - } else { - upx = rx; - upy = ry; - just = ( txtgap < 0.0 )? "TC" : "BC"; - } - if( txtgap == 0.0 ) just = "CC"; - -/* If the up vector is required to be vertical, a system is used which - tries to put the centre of the text string on or near the offset - vector. */ - } else { - upx = 0.0; - upy = 1.0; - - if( offy > fabs(txtgap)*sin45 ){ - just_buf[0] = 'B'; - } else if( offy < -fabs(txtgap)*sin45 ){ - just_buf[0] = 'T'; - } else { - just_buf[0] = 'C'; - } - if( txtgap == 0.0 ) just_buf[0] = 'C'; - - if( offx < -fabs(txtgap)*sin45 ){ - just_buf[1] = 'R'; - } else if( offx > fabs(txtgap)*sin45 ){ - just_buf[1] = 'L'; - } else { - just_buf[1] = 'C'; - } - if( txtgap == 0.0 ) just_buf[1] = 'C'; - - just_buf[2] = 0; - just = just_buf; - } - -/* Get the label text. */ - text = (info->labels)[ tick ]; - if( text ){ - -/* Check that the reference position is within the plotting area. - If so, add it to the list of labels to be drawn. */ - if( gx >= this->xlo && gx <= this->xhi && - gy >= this->ylo && gy <= this->yhi ){ - - labellist = (LabelList *) astGrow( (void *) labellist, nlab + 1, sizeof(LabelList) ); - if ( astOK ) { - (labellist + nlab)->index = tick; - (labellist + nlab)->text = (char *) astStore( NULL, (void *) text, strlen(text) + 1 ); - (labellist + nlab)->x = gx; - (labellist + nlab)->y = gy; - (labellist + nlab)->just = (char *) astStore( NULL, (void *) just, strlen(just) + 1 ); - (labellist + nlab)->upx = upx; - (labellist + nlab)->upy = upy; - (labellist + nlab)->val = val[ axis ]; - nlab++; - } else { - break; - } - } - } - } - } - } - -/* If any labels were stored, draw the text strings, and then release the - memory used to hold the text, etc. */ - if( nlab > 0 ) { - PlotLabels( this, esc, frame, axis, labellist, info->fmt, nlab, - &box, method, class, status ); - ll = labellist; - for( tick = 0; tick < nlab; tick ++ ) { - ll->text = (char *) astFree( (void *) ll->text ); - ll->just = (char *) astFree( (void *) ll->just ); - ll++; - } - labellist = (LabelList *) astFree( (void *) labellist ); - } - -/* Free the memory used to hold the axis values at which labels have - been put. */ - used = (double *) astFree( (void *) used ); - -/* Annul the PointSets (if used). */ - if( pset1 ) pset1 = astAnnul( pset1 ); - if( pset2 ) pset2 = astAnnul( pset2 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__TEXT, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__NUMLAB2_ID; - - } - } - -/* Free the memory used to hold the bounding boxes. */ - box = (float *) astFree( (void *) box ); - -/* Annul the pointers to the Frame and the Mapping. */ - mapping = astAnnul( mapping ); - frame = astAnnul( frame ); - - } - -/* Return. */ - return; - -} - -static void LinePlot( AstPlot *this, double xa, double ya, double xb, - double yb, int ink, AstPlotCurveData *cdata, - const char *method, const char *class, int *status ){ -/* -* -* Name: -* LinePlot - -* Purpose: -* Draws a straight line omitting bad regions. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void LinePlot( AstPlot *this, double xa, double ya, double xb, -* double yb, int ink, AstPlotCurveData *cdata, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws a straight line between two positions in graphics -* coordinates but leaves gaps in the line where it passes through -* regions which have no corresponding physical coordinates. - -* Parameters: -* this -* Pointer to the Plot. -* xa -* The graphics X coordinate at the start of the line. -* ya -* The graphics Y coordinate at the start of the line. -* xb -* The graphics X coordinate at the end of the line. -* yb -* The graphics Y coordinate at the end of the line. -* ink -* If zero, the line is not actually drawn, but information about -* the breaks is still returned. If non-zero, the line is also drawn. -* cdata -* A pointer to a structure in which to return information about the -* breaks in the line. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Notes: -* - No curve is draw if any of the start or end positions are bad -* (i.e. equal to AST__BAD), or if a NULL pointer is supplied for "cdata". -* No errors are reported in these cases. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - int i; /* Loop count */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Check the supplied values are usable. */ - if( xa == AST__BAD || ya == AST__BAD || - xb == AST__BAD || yb == AST__BAD || - !cdata ) return; - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, this->yhi - this->ylo ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Set up the external variables used by the Crv and CrvLine function (see - their prologues for details). */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_ux0 = AST__BAD; - Crv_limit = 0.5*tol*tol; - Crv_tol = tol; - Crv_map = Map2; - Crv_ink = ink; - Crv_len = 0.0F; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_out = 1; - Crv_xbrk = cdata->xbrk; - Crv_ybrk = cdata->ybrk; - Crv_vxbrk = cdata->vxbrk; - Crv_vybrk = cdata->vybrk; - Crv_clip = astGetClip( this ) & 1; - -/* Create a set of evenly spaced values between 0.0 and 1.0. These are the - offsets the edge of the plotting zone at which the mapping is tested. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Now set up the externals used to communicate with the Map2 function. - Map2 transforms a set of offsets between zero and one into a set of - corresponding graphics coordinates, with bad values substituted for any - offsets which correspond to points outside the domain of the mapping. */ - -/* The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map2_ncoord = astGetNout( this ); - -/* A pointer to the mapping from graphics world cordinates to physical - coordinates. */ - Map2_plot = this; - Map2_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* The graphics coordinates corresponding to an offset of zero (i.e. - the start of the line). */ - Map2_x0 = xa; - Map2_y0 = ya; - -/* The increments in X and Y between offset zero (the start of the - line) and offset 1 (the end of the line). */ - Map2_deltax = xb - xa; - Map2_deltay = yb - ya; - -/* Get the graphics coordinates corresponding to the initial set of - offsets. */ - Map2( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map2 to draw the intersection of the straight line with - the region containing valid physical coordinates. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* End the current poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map2. */ - Map2( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - if( cdata ){ - cdata->length = Crv_len; - cdata->out = Crv_out; - cdata->nbrk = Crv_nbrk; - PurgeCdata( cdata, status ); - } - -/* Annul the Mapping. */ - Map2_map = astAnnul( Map2_map ); - -/* Return. */ - return; - -} - -static double **MakeGrid( AstPlot *this, AstFrame *frm, AstMapping *map, - int disk, int dim, double xlo, double xhi, - double ylo, double yhi, int nphy, AstPointSet **pset1, - AstPointSet **pset2, int norm, const char *method, - const char *class, int *status ){ -/* -* Name: -* MakeGrid - -* Purpose: -* Create a square grid of graphics coordinates and the corresponding -* physical coordinates. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double **MakeGrid( AstPlot *this, AstFrame *frm, AstMapping *map, -* int disk, int dim, double xlo, double xhi, double ylo, -* double yhi, int nphy, AstPointSet **pset1, -* AstPointSet **pset2, int norm, const char *method, -* const char *class, int *status ){ - -* Class Membership: -* Plot member function. - -* Description: -* This function creates two PointSets, one holding a square grid of -* graphics coordinates covering the supplied area, and the other -* holding the corresponding physical coordinates. The points are -* stored row by row in the returned PointSets, i.e. if the cell size -* for the grid is (dx,dy), the first point is (xmin,ymin), followed -* by (xmin+dx,ymin), (xmin+2*dx,ymin), up to (xmin+(dim-1)*dx,ymin), -* followed by the next row (xmin,ymin+dy), (xmin+dx,ymin+dy), etc. - -* Parameters: -* this -* The Plot. -* frm -* A pointer to the Current Frame in the Plot. If this is supplied -* NULL, then a pointer is found within this function if required (i.e. -* if "norm" is non-zero). -* map -* The Mapping from graphics to physical coordinates, extracted from -* the Plot. -* disk -* If non-zero, the corners of the grid are omitted form the -* returned PointSets, resulting in a grid that is more disk like than -* rectangular. -* dim -* The number of samples along each edge of the grid. -* xlo -* The lower bound on the first axis of the region to be covered -* by the grid. -* xhi -* The upper bound on the first axis of the region to be covered -* by the grid. -* ylo -* The lower bound on the second axis of the region to be covered -* by the grid. -* yhi -* The upper bound on the second axis of the region to be covered -* by the grid. -* nphy -* The number of axes in the physical cooridinate system. -* pset1 -* A pointer to a location at which to store a pointer to the -* PointSet holding the graphics coordinates. -* pset2 -* A pointer to a location at which to store a pointer to the -* PointSet holding the physical coordinates. -* norm -* If non-zero the physical cooridnates are normalised using the -* Plot's astNorm method. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to the physical coordinate data stored in the PointSet -* "pset2". - -* Notes: -* - The returned PointSets should be annulled when no longer needed, -* using astAnnul. -* - NULL pointers are returned if an error has already occurred, or -* if this function should fail for any reason. -*/ - -/* Local Variables: */ - double **ptr1; /* Pointers to graphics axis values */ - double **ptr2; /* Pointers to physical axis values */ - int size; /* No. of points in the grid */ - -/* Initialise the returned pointers. */ - *pset1 = NULL; - *pset2 = NULL; - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Create two PointSets. We assume for the moment that they cover the - full grid, including corners. */ - size = dim*dim; - *pset1 = astPointSet( size, 2, "", status ); - *pset2 = astPointSet( size, nphy, "", status ); - -/* Get pointers to the data arrays for the two PointSets. */ - ptr1 = astGetPoints( *pset1 ); - ptr2 = astGetPoints( *pset2 ); - -/* Create a grid covering the supplied area. */ - size = GraphGrid( dim, disk, xlo, xhi, ylo, yhi, ptr1, status ); - -/* If the corners are being omitted, reduce the number of points in the - two PointSets. */ - if( disk ) { - astSetNpoint( *pset1, size ); - astSetNpoint( *pset2, size ); - } - -/* Transform these graphics positions to physical coordinates. */ - Trans( this, frm, map, *pset1, 1, *pset2, norm, method, class, status ); - -/* If an error has occurred, annul the two pointsets. */ - if( !astOK ){ - *pset1 = astAnnul( *pset1 ); - *pset2 = astAnnul( *pset2 ); - ptr2 = NULL; - } - -/* Return. */ - return ptr2; - -} - - -#if defined(THREAD_SAFE) -static int ManageLock( AstObject *this_object, int mode, int extra, - AstObject **fail, int *status ) { -/* -* Name: -* ManageLock - -* Purpose: -* Manage the thread lock on an Object. - -* Type: -* Private function. - -* Synopsis: -* #include "object.h" -* AstObject *ManageLock( AstObject *this, int mode, int extra, -* AstObject **fail, int *status ) - -* Class Membership: -* Plot member function (over-rides the astManageLock protected -* method inherited from the parent class). - -* Description: -* This function manages the thread lock on the supplied Object. The -* lock can be locked, unlocked or checked by this function as -* deteremined by parameter "mode". See astLock for details of the way -* these locks are used. - -* Parameters: -* this -* Pointer to the Object. -* mode -* An integer flag indicating what the function should do: -* -* AST__LOCK: Lock the Object for exclusive use by the calling -* thread. The "extra" value indicates what should be done if the -* Object is already locked (wait or report an error - see astLock). -* -* AST__UNLOCK: Unlock the Object for use by other threads. -* -* AST__CHECKLOCK: Check that the object is locked for use by the -* calling thread (report an error if not). -* extra -* Extra mode-specific information. -* fail -* If a non-zero function value is returned, a pointer to the -* Object that caused the failure is returned at "*fail". This may -* be "this" or it may be an Object contained within "this". Note, -* the Object's reference count is not incremented, and so the -* returned pointer should not be annulled. A NULL pointer is -* returned if this function returns a value of zero. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A local status value: -* 0 - Success -* 1 - Could not lock or unlock the object because it was already -* locked by another thread. -* 2 - Failed to lock a POSIX mutex -* 3 - Failed to unlock a POSIX mutex -* 4 - Bad "mode" value supplied. - -* Notes: -* - This function attempts to execute even if an error has already -* occurred. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to Plot structure */ - int result; /* Returned status value */ - -/* Initialise */ - result = 0; - -/* Check the supplied pointer is not NULL. */ - if( !this_object ) return result; - -/* Obtain a pointers to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Invoke the ManageLock method inherited from the parent class. */ - if( !result ) result = (*parent_managelock)( this_object, mode, extra, - fail, status ); - -/* If defined, ensure the grfcontext KeyMap contained within the Plot is - locked, unlocked or checked. */ - if( this->grfcontext ) { - if( !result ) result = astManageLock( this->grfcontext, mode, extra, fail ); - -/* Also lock or unlock the associated object handle. */ - if( mode == AST__LOCK ) { - if( !result ) astLock( this->grfcontextID, extra ); - - } else if( mode == AST__UNLOCK ) { - if( !result ) astUnlock( this->grfcontextID, 0 ); - - } - } - - return result; - -} -#endif - -static void Map1( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map1 - -* Purpose: -* Find graphics coordinates at given distances along a curve -* parallel to a physical axis. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map1( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical coordinates -* using the scalings described by various external variables, and then -* these physical coordinates are mapped into graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map1_origin. A "dist" value of one corresponds to the -* finishing position which is a distance Map1_length away from -* Map1_origin, moving in the positive direction of the axis given -* by Map1_axis. "dist" values can be either linearly or -* logarithmically related to axis values (see Map1_log). -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map1_log = int (Read) -* If zero, then "dist" in learly related to axis value. Otherwise -* it is linearly related to log10(axis value). -* Map1_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map1_axis = int (Read) -* The zero-based index of the axis which the curve follows (i.e. -* the axis which changes value along the curve). -* Map1_statics = Map1Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map1. -* Map1_origin = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the start of the curve (i.e. at dist = 0.0). -* Map1_length = double (Read) -* The scale factor to convert "dist" values into increments -* along the physical axis given by Map1_axis. -* Map1_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map1_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map1_frame = AstFrame * (Read) -* A pointer to the Current Frame in the Plot. -* Map1_norm = int (Read) -* A flag indicating if physical coordinate values which are not in -* the normal ranges of the corresponding axes should be considered -* bad. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Constants: */ - Map1Statics *statics; /* Pointer to structure holding static data */ - double *p; /* Pointer to next value */ - double axval; /* Axis origin value */ - int i, j; /* Loop counts */ - -/* Convert the global "void *" pointer to a Map1Statics pointer */ - statics = (Map1Statics *) Map1_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->work1 ) statics->work1 = (double *) astFree( (void *) statics->work1 ); - if( statics->work2 ) statics->work2 = (double *) astFree( (void *) statics->work2 ); - Map1_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map1Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr1 = NULL; - statics->pax = NULL; - statics->ptr2[ 0 ] = NULL; - statics->ptr2[ 1 ] = NULL; - statics->work1 = NULL; - statics->work2 = NULL; - statics->nl = 0; - Map1_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied offsets. First annul any existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, Map1_ncoord, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - The supplied "x" and "y" arrays will be used to store the data - so we do not need to get pointers to the data using astGetPoints. First - annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, 2, "", status ); - -/* Get work space to hold two positions. */ - statics->work1 = (double *) astRealloc( (void *) statics->work1, - sizeof(double)*(size_t)Map1_ncoord ); - statics->work2 = (double *) astRealloc( (void *) statics->work2, - sizeof(double)*(size_t)Map1_ncoord ); - -/* Check the pointer can be used. */ - if( astOK ){ - -/* Store a pointer to the start of the memory which will be used to store - the physical data for the axis being drawn. */ - statics->pax = statics->ptr1[ Map1_axis ]; - -/* Fill the PointSet which is used to hold physical data with the physical - coordinates at the start of the curve. */ - for( i = 0; i < Map1_ncoord; i++ ){ - axval = Map1_origin[ i ]; - p = statics->ptr1[ i ]; - for( j = 0; j < n; j++ ) *(p++) = axval; - } - -/* Store the scale and offset to apply to the "dist" values. If Map1_log is - zero (linear axes) then applying these values gives axis value directly. - If Map1_log is non-zero (log axes) then applying these values gives - log10( axis value). */ - if( Map1_log ) { - statics->neg = ( Map1_origin[ Map1_axis ] < 0 ); - statics->axorig = log10( fabs( Map1_origin[ Map1_axis ] ) ); - statics->axscale = log10( fabs( Map1_origin[ Map1_axis ] + - Map1_length ) ) - statics->axorig; - } else { - statics->axorig = Map1_origin[ Map1_axis ]; - statics->axscale = Map1_length; - } - } - } - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Loop round each offset along the curve, converting the normalised offset - in the range [0,1] to a physical coordinate and storing in PointSet 1. */ - p = statics->pax; - for( i = 0; i < n; i++){ - *(p++) = statics->axorig + statics->axscale*dist[ i ]; - } - if( Map1_log ) { - p = statics->pax; - for( i = 0; i < n; i++,p++ ){ - *p = statics->neg ? -pow( 10.0, *p ) : pow( 10.0, *p ); - } - } - -/* Store pointers to the results arrays in PointSet 2. */ - statics->ptr2[ 0 ] = x; - statics->ptr2[ 1 ] = y; - astSetPoints( statics->pset2, statics->ptr2 ); - -/* Map all the positions into graphics coordinates. */ - (void) Trans( Map1_plot, NULL, Map1_map, statics->pset1, 0, statics->pset2, 1, method, class, status ); - -/* If points not in their normal ranges are to be set bad... */ - if( Map1_norm ) { - -/* The following code simply normalizes the physical position, and if this - produces any change, the graphics positions are set bad. */ - for( i = 0; i < n; i++){ - for( j = 0; j < Map1_ncoord; j++) statics->work1[j] = statics->ptr1[j][i]; - astNorm( Map1_frame, statics->work1 ); - for( j = 0; j < Map1_ncoord; j++) { - if( !astEQUALS( statics->work1[j], statics->ptr1[j][i], 1.0E8 ) ) { - statics->ptr2[0][i] = AST__BAD; - statics->ptr2[1][i] = AST__BAD; - break; - } - } - } - } - } - -/* Return. */ - return; - -} - -static void Map2( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map2 - -* Purpose: -* Find which graphics coordinates have good physical coordinates -* at given distances along a straight line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map2( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances refer to the distance along a straight line -* in the graphics coordinate system. The returned graphics coordinates -* correspond to the supplied distances, except that any position for -* which there are no defined physical coordinates is returned bad. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the graphics position supplied in external -* variables (Map2_x0, Map2_y0). A "dist" value of one corresponds to -* the graphics position which is offset from the start by the vector -* (Map2_deltax, Map2_deltay). -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist", -* except that any which have no corresponding physical coordinates -* are set to AST__BAD. -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist", -* except that any which have no corresponding physical coordinates -* are set to AST__BAD. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map2_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map2_x0 = double (Read) -* The graphics X coordinate at the start of the line (i.e. at dist -* = 0.0). -* Map2_y0 = double (Read) -* The graphics Y coordinate at the start of the line (i.e. at dist -* = 0.0). -* Map2_deltax = double (Read) -* The increment along the graphics X axis between the start and -* end of the line. -* Map2_deltay = double (Read) -* The increment along the graphics Y axis between the start and -* end of the line. -* Map2_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map2_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates, extracted from the Plot. -* Map2_statics = Map2Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map2. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ -/* Local Constants: */ - Map2Statics *statics; /* Pointer to structure holding static data */ - int i, j; /* Loop counts */ - double *p; /* Pointer to next physical value */ - double *px; /* Pointer to next x graphics value */ - double *py; /* Pointer to next y graphics value */ - -/* Convert the global "void *" pointer to a Map2Statics pointer */ - statics = (Map2Statics *) Map2_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - Map2_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map2Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr2 = NULL; - statics->ptr1[ 0 ] = NULL; - statics->ptr1[ 1 ] = NULL; - statics->nl = 0; - Map2_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the graphics coordinates corresponding to - the supplied offsets. The supplied arrays will be used to hold the - data for this PointSet, and so astGetPoints is not called. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, 2, "", status ); - -/* Create a PointSet to hold the corresponding physical coordinates, and - get pointers to the associated axis values. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, Map2_ncoord, "", status ); - statics->ptr2 = astGetPoints( statics->pset2 ); - } - - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Store pointers to the results arrays in PointSet 1. */ - statics->ptr1[ 0 ] = x; - statics->ptr1[ 1 ] = y; - astSetPoints( statics->pset1, statics->ptr1 ); - -/* Loop round each offset along the curve, converting the normalised offset - in the range [0,1] to graphics coordinate and storing in PointSet 1. */ - px = x; - py = y; - for( i = 0; i < n; i++){ - *(px++) = Map2_x0 + Map2_deltax*dist[ i ]; - *(py++) = Map2_y0 + Map2_deltay*dist[ i ]; - } - -/* Map all the positions into physical coordinates. */ - (void) Trans( Map2_plot, NULL, Map2_map, statics->pset1, 1, statics->pset2, 0, method, class, status ); - -/* Check the physical coordinates for bad values, setting the corresponding - graphics coordinates bad. */ - for( j = 0; j < Map2_ncoord; j++ ){ - p = statics->ptr2[ j ]; - px = x; - py = y; - - for( i = 0; i < n; i++){ - if( *(p++) == AST__BAD ){ - *(px++) = AST__BAD; - *(py++) = AST__BAD; - } else { - px++; - py++; - } - } - } - } - -/* Return. */ - return; - -} - -static void Map3( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map3 - -* Purpose: -* Find graphics coordinates at given distances along a geodesic curve -* between two physical coordinate positions. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map3( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical offsets along the -* geodesic curve joining the starting and finishing points given by -* externals Map3_origin and Map3_end. The physical coordinates at these -* offsets are found, and transformed into graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map3_origin. A "dist" value of one corresponds to the -* finishing position given by Map3_end. -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map3_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map3_origin = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the start of the curve (i.e. at dist = 0.0). -* Map3_end = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the end of the curve (i.e. at dist = 1.0). -* Map3_scale = double (Read) -* The scale factor to convert "dist" values into physical offsets -* along the geodesic curve. -* Map3_statics = Map3Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map3. -* Map3_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map3_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map3_frame = AstFrame * (Read) -* A pointer to the Current Frame in the Plot. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Constants: */ - Map3Statics *statics; /* Pointer to structure holding static data */ - int i, j; /* Loop counts */ - -/* Convert the global "void *" pointer to a Map3Statics pointer */ - statics = (Map3Statics *) Map3_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pos ) statics->pos = (double *) astFree( (void *) statics->pos ); - Map3_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map3Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr1 = NULL; - statics->ptr2[ 0 ] = NULL; - statics->ptr2[ 1 ] = NULL; - statics->nc = 0; - statics->nl = 0; - statics->pos = NULL; - Map3_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied offsets. First annul any existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, Map3_ncoord, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - The supplied "x" and "y" arrays will be used to store the data - so we do not need to get pointers to the data using astGetPoints. First - annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, 2, "", status ); - - } - -/* If the number of physical axes is different to last time, allocate - memory to hold a single physical position. */ - if( statics->nc != Map3_ncoord ){ - statics->nc = Map3_ncoord; - statics->pos = (double *) astMalloc( sizeof(double)*(size_t)Map3_ncoord ); - } - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Loop round each offset along the curve, converting the normalised offset - in the range [0,1] to a physical offset, and then into a physical - position, and store in PointSet 1. */ - for( i = 0; i < n; i++){ - astOffset( Map3_frame, Map3_origin, Map3_end, Map3_scale*dist[ i ], - statics->pos ); - - for( j = 0; j < Map3_ncoord; j++ ){ - statics->ptr1[ j ][ i ] = statics->pos[ j ]; - } - - } - -/* Store pointers to the results arrays in PointSet 2. */ - statics->ptr2[ 0 ] = x; - statics->ptr2[ 1 ] = y; - astSetPoints( statics->pset2, statics->ptr2 ); - -/* Map all the positions into graphics coordinates. */ - (void) Trans( Map3_plot, NULL, Map3_map, statics->pset1, 0, statics->pset2, 1, method, class, status ); - } - -/* Return. */ - return; - -} - -static void Map4( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map4 - -* Purpose: -* Find graphics coordinates at given distances along a user -* specified curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map4( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical coordinates using -* the Mapping Map4_umap. These physical coordinates are transformed into -* graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map3_origin. A "dist" value of one corresponds to the -* finishing position given by Map3_end. -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map4_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map4_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map4_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map4_statics = Map4Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map4. -* Map4_umap = AstMapping * (Read) -* A pointer to the mapping from distance along the curve to physical -* coordinates. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Variables: */ - Map4Statics *statics; /* Pointer to structure holding static data */ - double *ptr1[ 1 ]; /* Pointer to distances data */ - double *ptr3[ 2 ]; /* Pointers to graphics coord data */ - -/* Convert the global "void *" pointer to a Map4Statics pointer */ - statics = (Map4Statics *) Map4_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - if( statics->pset3 ) statics->pset3 = astAnnul( statics->pset3 ); - Map4_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map4Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->pset3 = NULL; - statics->nl = 0; - Map4_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the distances along the curve. First annul any - existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, 1, "", status ); - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied distances. First annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, Map4_ncoord, "", status ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - First annul any existing PointSet. */ - if( statics->pset3 ) statics->pset3 = astAnnul( statics->pset3 ); - statics->pset3 = astPointSet( n, 2, "", status ); - - } - -/* Check the initialisation went OK (if done). */ - if( astOK ){ - -/* Use Map4_umap to convert the supplied distances into physical coords - (i.e. coords in the current Frame of the Plot). */ - ptr1[ 0 ] = dist; - astSetPoints( statics->pset1, ptr1 ); - (void) astTransform( Map4_umap, statics->pset1, 1, statics->pset2 ); - -/* Store pointers to the results arrays in PointSet 2. */ - ptr3[ 0 ] = x; - ptr3[ 1 ] = y; - astSetPoints( statics->pset3, ptr3 ); - -/* Now transform these physical coords into graphical coords, - incorporating clipping. */ - (void) Trans( Map4_plot, NULL, Map4_map, statics->pset2, 0, statics->pset3, 1, method, class, status ); - } - -/* Return. */ - return; - -} - -static void Map5( int n, double *dist, double *x, double *y, - const char *method, const char *class, - int *status GLOBALS_ARG ){ -/* -* Name: -* Map5 - -* Purpose: -* Find graphics coordinates at given distances along the boundary of -* a Region. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Map5( int n, double *dist, double *x, double *y, -* const char *method, const char *class, -* int *status [,AstGlobals *AST__GLOBALS] ) - -* Class Membership: -* Plot member function. - -* Description: -* The supplied distances are converted into physical coordinates -* using the Region specified by an external variable, and then -* these physical coordinates are mapped into graphics coordinates. - -* Parameters: -* n -* The number of points to map. Static resources are released but -* no points are mapped if zero is supplied. -* dist -* A pointer to an array holding "n" distances. A "dist" value of -* zero corresponds to the starting position supplied in external -* variable Map1_origin. A "dist" value of one corresponds to the -* finishing position which is a distance Map1_length away from -* Map1_origin, moving in the positive direction of the axis given -* by Map1_axis. "dist" values can be either linearly or -* logarithmically related to axis values (see Map1_log). -* x -* A pointer to an array in which to store the "n" graphics X -* coordinate values corresponding to the positions in "dist". -* y -* A pointer to an array in which to store the "n" graphics Y -* coordinate values corresponding to the positions in "dist". -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -* AST__GLOBALS -* Only present if compiled with -DTHREAD_SAFE. It is a pointer to -* the structure holding the global data for the executing thread. -* It is passed as a function parameter, rather than being accessed -* within this function using the astGET_GLOBALS(NULL) macro (as -* other Object-less functions do) in order to avoid the time -* overheads of calling astGET_GLOBALS(NULL) . This function is -* time-critical. - -* External Variables: -* Map1_log = int (Read) -* If zero, then "dist" in learly related to axis value. Otherwise -* it is linearly related to log10(axis value). -* Map1_ncoord = int (Read) -* The number of axes in the physical coordinate system. -* Map1_axis = int (Read) -* The zero-based index of the axis which the curve follows (i.e. -* the axis which changes value along the curve). -* Map1_statics = Map1Statics * (Read and Write) -* Pointer to a structure holding other static data used by Map1. -* Map1_origin = const double * (Read) -* A pointer to an array holding the physical coordinate value on -* each axis at the start of the curve (i.e. at dist = 0.0). -* Map1_length = double (Read) -* The scale factor to convert "dist" values into increments -* along the physical axis given by Map1_axis. -* Map1_plot = AstPlot * (Read) -* A pointer to the Plot defining the mapping from graphics cordinates -* to physical coordinates. -* Map1_map = AstMapping * (Read) -* A pointer to the mapping from graphics cordinates to physical -* coordinates extracted from the Plot. -* Map1_frame = AstFrame * (Read) -* A pointer to the Current Frame in the Plot. -* Map1_norm = int (Read) -* A flag indicating if physical coordinate values which are not in -* the normal ranges of the corresponding axes should be considered -* bad. - -* Notes: -* - On the first call, this function allocates static resources which -* are used by subsequent invocation. These resources should be freed before -* calling this function with new values for any of the external variables, -* or when no longer needed, by calling this function with "n" supplied as -* zero. -* - If an error has already occurred, this runction returns without -* action ,except that if "n" is supplied as zero then static resources -* are released even if an error has already occurred. - -*/ - -/* Local Constants: */ - Map5Statics *statics; /* Pointer to structure holding static data */ - -/* Convert the global "void *" pointer to a Map5Statics pointer */ - statics = (Map5Statics *) Map5_statics; - -/* If zero points were supplied, release static resources and return. */ - if( n == 0 ){ - if( statics ) { - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - Map5_statics = astFree( statics ); - } - return; - } - -/* Otherwise, check the inherited global status. */ - if( !astOK ) return; - -/* Create and initialise a structure to hold extra static information if - this has not already been done. */ - if( !statics ) { - statics = astMalloc( sizeof( Map3Statics ) ); - if( statics ) { - statics->pset1 = NULL; - statics->pset2 = NULL; - statics->ptr1 = NULL; - statics->ptr2[ 0 ] = NULL; - statics->ptr2[ 1 ] = NULL; - statics->nl = 0; - Map5_statics = statics; - } - } - -/* If the number of points to be mapped is different to last time, - set up some PointSets to store the specified number of points. */ - if( n != statics->nl ){ - statics->nl = n; - -/* Create a PointSet to hold the physical coordinates corresponding to - the supplied offsets. First annul any existing PointSet. */ - if( statics->pset1 ) statics->pset1 = astAnnul( statics->pset1 ); - statics->pset1 = astPointSet( n, Map5_ncoord, "", status ); - statics->ptr1 = astGetPoints( statics->pset1 ); - -/* Create a PointSet to hold the corresponding graphics coordinates. - The supplied "x" and "y" arrays will be used to store the data - so we do not need to get pointers to the data using astGetPoints. First - annul any existing PointSet. */ - if( statics->pset2 ) statics->pset2 = astAnnul( statics->pset2 ); - statics->pset2 = astPointSet( n, 2, "", status ); - } - -/* Get the physical coords at the required positions along the Region - border. */ - astRegTrace( Map5_region, n, dist, statics->ptr1 ); - -/* Store pointers to the results arrays in PointSet 2. */ - statics->ptr2[ 0 ] = x; - statics->ptr2[ 1 ] = y; - astSetPoints( statics->pset2, statics->ptr2 ); - -/* Map all the positions into graphics coordinates. */ - (void) Trans( Map5_plot, NULL, Map5_map, statics->pset1, 0, - statics->pset2, 1, method, class, status ); - -/* Return. */ - return; -} - -static void Mark( AstPlot *this, int nmark, int ncoord, int indim, - const double *in, int type, int *status ){ -/* -*++ -* Name: -c astMark -f AST_MARK - -* Purpose: -* Draw a set of markers for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astMark( AstPlot *this, int nmark, int ncoord, int indim, -c const double *in, int type ) -f CALL AST_MARK( THIS, NMARK, NCOORD, INDIM, IN, TYPE, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function draws a set of markers (symbols) at positions -f This routine draws a set of markers (symbols) at positions -* specified in the physical coordinate system of a Plot. The -* positions are transformed into graphical coordinates to -* determine where the markers should appear within the plotting -* area. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c nmark -f NMARK = INTEGER (Given) -* The number of markers to draw. This may be zero, in which -* case nothing will be drawn. -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinates being supplied for each mark -* (i.e. the number of axes in the current Frame of the Plot, as -* given by its Naxes attribute). -c indim -f INDIM = INTEGER (Given) -c The number of elements along the second dimension of the "in" -f The number of elements along the first dimension of the IN -* array (which contains the marker coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -c given should not be less than "nmark". -f given should not be less than NMARK. -c in -f IN( INDIM, NCOORD ) = DOUBLE PRECISION (Given) -c The address of the first element of a 2-dimensional array of -c shape "[ncoord][indim]" giving the -c physical coordinates of the points where markers are to be -c drawn. These should be stored such that the value of -c coordinate number "coord" for input mark number "mark" is -c found in element "in[coord][mark]". -f A 2-dimensional array giving the physical coordinates of the -f points where markers are to be drawn. These should be -f stored such that the value of coordinate number COORD for -f input mark number MARK is found in element IN(MARK,COORD). -c type -f TYPE = INTEGER (Given) -* A value specifying the type (e.g. shape) of marker to be -* drawn. The set of values which may be used (and the shapes -* that will result) is determined by the underlying graphics -* system. -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - Markers are not drawn at positions which have any coordinate -* equal to the value AST__BAD (or where the transformation into -* graphical coordinates yields coordinates containing the value -* AST__BAD). -c - If any marker position is clipped (see astClip), then the -f - If any marker position is clipped (see AST_CLIP), then the -* entire marker is not drawn. -* - An error results if the base Frame of the Plot is not 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPointSet *pset1; /* PointSet holding physical positions */ - AstPointSet *pset2; /* PointSet holding graphics positions */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **ptr1; /* Pointer to physical positions */ - double **ptr2; /* Pointer to graphics positions */ - double *xpd; /* Pointer to next double precision x value */ - double *ypd; /* Pointer to next double precision y value */ - double xx; /* X axis value */ - double yy; /* Y axis value */ - float *x; /* Pointer to single precision x values */ - float *xpf; /* Pointer to next single precision x value */ - float *y; /* Pointer to single precision y values */ - float *ypf; /* Pointer to next single precision y value */ - int axis; /* Axis index */ - int clip; /* Clips marks at plot boundary? */ - int i; /* Loop count */ - int naxes; /* No. of axes in the base Frame */ - int nn; /* Number of good marker positions */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astMark"; - class = astClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Also validate the input array dimension argument. */ - if ( astOK && ( indim < nmark ) ) { - astError( AST__DIMIN, "%s(%s): The input array dimension value " - "(%d) is invalid.", status, method, class, indim ); - astError( AST__DIMIN, "This should not be less than the number of " - "markers being drawn (%d).", status, nmark ); - } - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__MARKS_ID, 1, GRF__MARK, method, class ); - -/* Create a PointSet to hold the supplied physical coordinates. */ - pset1 = astPointSet( nmark, ncoord, "", status ); - -/* Allocate memory to hold pointers to the first value on each axis. */ - ptr1 = (const double **) astMalloc( sizeof( const double * )* - (size_t)( ncoord )); - -/* Check the pointer can be used, then store pointers to the first value - on each axis. */ - if( astOK ){ - for( axis = 0; axis < ncoord; axis++ ){ - ptr1[ axis ] = in + axis*indim; - } - } - -/* Store these pointers in the PointSet. */ - astSetPoints( pset1, (double **) ptr1 ); - -/* Transform the supplied data from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping defined by the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - pset2 = Trans( this, NULL, mapping, pset1, 0, NULL, 0, method, class, status ); - mapping = astAnnul( mapping ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - -/* Allocate memory to hold single precision versions of the graphics - coordinates. */ - x = (float *) astMalloc( sizeof( float )*(size_t) nmark ); - y = (float *) astMalloc( sizeof( float )*(size_t) nmark ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Store pointers to the next single and double precision x and y - values. */ - xpf = x; - ypf = y; - xpd = ptr2[ 0 ]; - ypd = ptr2[ 1 ]; - -/* Convert the double precision values to single precision, rejecting - any bad marker positions. If clipping is switched on, also clip any - markers with centres outside the plotting area. */ - clip = astGetClip( this ) & 2; - nn = 0; - for( i = 0; i < nmark; i++ ){ - if( *xpd != AST__BAD && *ypd != AST__BAD ){ - xx = *(xpd++); - yy = *(ypd++); - if( !clip || ( xx >= this->xlo && xx <= this->xhi && - yy >= this->ylo && yy <= this->yhi ) ) { - nn++; - *(xpf++) = (float) xx; - *(ypf++) = (float) yy; - } - } else { - xpd++; - ypd++; - } - } - -/* Draw the remaining markers. */ - GMark( this, nn, x, y, type, method, class, status ); - - } - -/* Free the memory used to store single precision graphics coordinates. */ - x = (float *) astFree( (void *) x ); - y = (float *) astFree( (void *) y ); - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the memory holding the pointers to the first value on each axis. */ - ptr1 = (const double **) astFree( (void *) ptr1 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__MARKS_ID, 0, GRF__MARK, method, class ); - -/* Return */ - return; -} - -static void Mirror( AstPlot *this, int axis, int *status ){ -/* -*+ -* Name: -* astMirror - -* Purpose: -* Flip a graphics axis of a Plot. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* void astMirror( AstPlot *this, int axis ) - -* Class Membership: -* Plot method. - -* Description: -* This function referses the direction of a specified graphics axis -* in the Plot. - -* Parameters: -* this -* Pointer to a Plot. -* axis -* The zero-based axis of the axis to mirror. - -*- -*/ - -/* Check the global status. */ - if( !astOK ) return; - - if( axis == 0 ) { - this->xrev = ( this->xrev == 0 ); - - } else if( axis == 1 ){ - this->yrev = ( this->yrev == 0 ); - - } else { - astError( AST__INTER, "astMirror(%s): Illegal axis index (%d) " - "supplied (internal AST programming error).", status, - astGetClass( this ), axis ); - } -} - -static void Norm1( AstMapping *map, int axis, int nv, double *vals, - double refval, double width, int *status ){ -/* -* Name: -* Norm1 - -* Purpose: -* Use a Mapping to normalize an array of axis values. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Norm1( AstMapping *map, int axis, int nv, double *vals, -* double refval, double width, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The normalization of a position in physical space has two parts; -* firstly, the Mapping may determine a form of normalization; -* secondly, the Frame may provide an additional normalizion by the -* astNorm method. This function implements normalization using a -* Mapping, by transforming the physical position into Graphics position, -* and then back into a physical position. For instance, if the Mapping -* represents a mapping of Cartesian graphics axes onto a 2D polar -* coordinate system, a physical theta value of 3.PI will be normalized by -* the Mapping into a theta value of 1.PI (probably, but it depends on -* the Mapping). In this case, the Mapping normalization may well be the -* only normalization available, since the 2D polar coord. system will -* probably use a simple Frame to represent the (radius,theta) system, -* and a simple Frame defines no normalization (i.e. the astNorm method -* returns the supplied position unchanged). -* -* Complications arise though because it is not possible to normalise -* a single axis value - you can only normalize a complete position. -* Therefore some value must be supplied for the other axis. We -* should use the LabelAt value, but we do not yet know what the LabelAt -* value will be. Instead, we try first using the supplied "refval" -* which should be close to the mode of the other aixs values. Usually -* the value used is not very important. However, for some complex -* projections (such as quad-cubes, TSC, etc) the choice can be more -* critical since some positions on the ksy correspond to undefined -* graphics positions (e.g the face edges in a TSC projection). -* Therefore, if the supplied refval results in any positions being -* undefined we refine the process by transforming the undefined -* positaons again using a different refval. We do this twice to bump -* up the likelihood of finding a suitable reference value. - -* Parameters: -* mapping -* The Mapping from Graphics Frame to the current Frame. -* axis -* The index of the axis for which values are supplied in "vals". -* nv -* The number of values supplied in "vals". -* vals -* Pointer to an array of axis values. On exit they are normalized. -* refval -* The preffered constant value to use for the other axis when -* normalizing the values in "vals". -* width -* The range of used values for the other axis. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPointSet *pset1; /* PointSet holding physical coords */ - AstPointSet *pset2; /* PointSet holding graphics coords */ - double **ptr1; /* Pointer to physical coords data */ - double *a; /* Pointer to next axis value */ - double *b; /* Pointer to next axis value */ - int i; /* Loop count */ - int itry; /* Loop count for re-try loop */ - int nbad; /* No. of bad values found after transformation */ - int *flags; /* Pointer to flags array */ - -/* Check the inherited global status. */ - if( !astOK ) return; - -/* Store the supplied positions in a PointSet. */ - pset1 = astPointSet( nv, 2, "", status ); - ptr1 = astGetPoints( pset1 ); - if( astOK ) { - a = ptr1[ axis ]; - b = ptr1[ 1 - axis ]; - for( i = 0; i < nv; i++){ - *(a++) = vals[ i ]; - *(b++) = refval; - } - } - -/* Transform the supplied positions into the Base Frame. */ - pset2 = astTransform( map, pset1, 0, NULL ); - -/* Transform the Base Frame positions back into the Current Frame. */ - (void) astTransform( map, pset2, 1, pset1 ); - -/* Allocate memory to hold a flag for each position which is non-zero if - we currently have a good axis value to return for the position. */ - flags = (int *) astMalloc( sizeof(int)* (size_t) nv ); - -/* If good, store these values back in the supplied array. If the - transformed values are bad, retain the original good values for the - moment in "vals", and also copy the good values back into pset1. So - at the end, pset1 will contain the original good values at any points - which produced bad values after the above transformation - the other - points in pset1 will be bad. */ - nbad = 0; - if( astOK ) { - a = ptr1[ axis ]; - for( i = 0; i < nv; i++, a++ ){ - if( *a != AST__BAD ) { - vals[ i ] = *a; - *a = AST__BAD; - flags[ i ] = 1; - } else if( vals[ i ] != AST__BAD ) { - nbad++; - *a = vals[ i ]; - flags[ i ] = 0; - } else { - flags[ i ] = 1; - } - } - } - -/* We now try normalising any remaining bad positions using different - values for the other axis. This may result in some or all of the - remaining points being normalised succesfully. */ - for( itry = 0; itry < 10; itry++ ) { - -/* If the above transformation produced any bad values, try again with a - different value on the other axis. */ - if( astOK && nbad > 0 ) { - b = ptr1[ 1 - axis ]; - for( i = 0; i < nv; i++){ - *(b++) = refval + 0.1*( itry + 1 )*width; - } - -/* Transform to graphics coords and back to world coords. */ - (void) astTransform( map, pset1, 0, pset2 ); - (void) astTransform( map, pset2, 1, pset1 ); - -/* Copy any good positions back into the returned vals array. Count - remaining bad positions. */ - a = ptr1[ axis ]; - nbad = 0; - for( i = 0; i < nv; i++, a++ ){ - if( *a != AST__BAD ) { - vals[ i ] = *a; - flags[ i ] = 1; - *a = AST__BAD; - } else if( !flags[ i ] ) { - nbad++; - *a = vals[ i ]; - } - } - } - -/* If the above transformation produced any bad values, try again with a - different value on the other axis. */ - if( astOK && nbad > 0 ) { - b = ptr1[ 1 - axis ]; - for( i = 0; i < nv; i++){ - *(b++) = refval - 0.1*( itry + 1 )*width; - } - -/* Transform to graphics coords and back to world coords. */ - (void) astTransform( map, pset1, 0, pset2 ); - (void) astTransform( map, pset2, 1, pset1 ); - -/* Copy any good positions back into the returned vals array. Count - remaining bad positions. */ - a = ptr1[ axis ]; - nbad = 0; - for( i = 0; i < nv; i++, a++ ){ - if( *a != AST__BAD ) { - vals[ i ] = *a; - flags[ i ] = 1; - *a = AST__BAD; - } else if( !flags[ i ] ) { - nbad++; - *a = vals[ i ]; - } - } - } - } - -/* Free resources. */ - flags = (int *) astFree( flags ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -} - -static void Opoly( AstPlot *this, int *status ){ -/* -* Name: -* Opoly - -* Purpose: -* Draws the current poly line. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Opoly( AstPlot *this, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function draws the current poly line, and empties the buffer. - -* Parameters: -* this -* Pointer to the Plot. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int ipoly; /* Index of new polyline */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Draw the poly-line if needed. */ - if( Poly_n > 0 ) { - -/* Extend the global arrays that hold pointers to the polylines already - drawn. */ - ipoly = Poly_npoly++; - astBeginPM; - Poly_xp = astGrow( Poly_xp, Poly_npoly, sizeof(float*) ); - Poly_yp = astGrow( Poly_yp, Poly_npoly, sizeof(float*) ); - Poly_np = astGrow( Poly_np, Poly_npoly, sizeof(int) ); - astEndPM; - - if( astOK ) { - -/* Add pointers to the new polyline to the end of the above extended - arrays. */ - Poly_xp[ ipoly ] = Poly_x; - Poly_yp[ ipoly ] = Poly_y; - Poly_np[ ipoly ] = Poly_n; - -/* Indicate that the current polyline is now empty. */ - Poly_x = NULL; - Poly_y = NULL; - Poly_n = 0; - } - } -} - -static int Overlap( AstPlot *this, int mode, int esc, const char *text, float x, - float y, const char *just, float upx, float upy, - float **work, const char *method, const char *class, int *status ){ -/* -* Name: -* Overlap - -* Purpose: -* See if a major tick value label would overlap any of the previously -* drawn labels. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Overlap( AstPlot *this, int mode, int esc, const char *text, float x, -* float y, const char *just, float upx, float upy, -* float **work, const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* The operation of this function is determined by the "mode" parameter. - -* A record is kept of the bounding boxes enclosing all the displayed -* labels. If the bounding box of the new label defined by the given -* parameter values would overlap any of the old bounding boxes, 0 is -* returned. Otherwise 1 is returned and the bounding box for the new -* label is added to the list of old bounding boxes. - -* This function also updates the external variables Box_lbnd and -* Box_ubnd which hold the lower and upper bounds of the area enclosing -* all used labels. - -* Parameters: -* this -* A pointer to the Plot. -* mode -* - If -1, find the bounding box of the supplied label, add it -* to the list of stored bounding box, and return 1 if it overlaps -* any previously stored bounding boxes. -* - If -2, leave the bounding boxes unchanged and return the -* number of bounding boxes currently stored. No other action is taken -* and all other arguments are ignored. -* - Otherwise, reset the number of stored bounding boxes to the -* value of mode, and return the new number of bounding boxes. No -* action is taken if mode is less than zero or greater than the current -* number of stored boxes. No other action is taken and all other -* arguments are ignored. -* esc -* Should escape sequences in the text be interpreted? -* text -* A pointer to the label text string. -* x -* The graphics X coordinate of the label's reference point. -* y -* The graphics Y coordinate of the label's reference point. -* just -* A character string which specifies the location within the -* text string which is to be placed at the reference position -* given by x and y. The first character may be 'T' for "top", -* 'C' for "centre", or 'B' for "bottom", and specifies the -* vertical location of the reference position. The second -* character may be 'L' for "left", 'C' for "centre", or 'R' -* for "right", and specifies the horizontal location of the -* reference position. If the string has less than 2 characters -* then 'C' is used for the missing characters. -* upx -* The x component of the up-vector for the text. -* upy -* The y component of the up-vector for the text. -* work -* A pointer to a place at which to store a pointer to an array of -* floats holding the old bounding boxes. Memory to hold this array -* is allocated automatically within this function. The pointer to -* the array should be supplied as NULL on the first call to this -* function, and the array should be freed using astFree when no -* longer needed. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* See parameter "mode." - -* Notes: -* - Zero is returned if an error has occurred, or if this function -* should fail for any reason. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - int nbox = 0; /* Number of boxes stored in "work" */ - int ret; /* Does the new label overlap a previous label? */ - int i; /* Box index */ - float *cx; /* Pointer to next corner's X value */ - float *cy; /* Pointer to next corner's Y value */ - float xbn[ 4 ]; /* X coords at corners of new label's bounding box */ - float ybn[ 4 ]; /* Y coords at corners of new label's bounding box */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Initialise the returned value to indicate no overlap has been found. */ - ret = 0; - -/* Get the number of bounding boxes in the supplied work array. */ - if( work && *work ) { - nbox = (*work)[ 0 ]; - } else { - nbox = 0; - } - -/* If required, return the number of bounding boxes currently stored. */ - if( mode == -2 ) return nbox; - -/* If required, reset the number of bounding boxes currently stored, and - return the new number. */ - if( mode >= 0 ) { - if( mode < nbox && work && *work ) { - nbox = mode; - (*work)[ 0 ] = nbox; - } - return nbox; - } - -/* If no work array has been supplied, allocate one now with room for - 10 boxes. Each box requires 8 floats, 2 for each of the 4 corners. The - X graphics coordinates at the 4 corners are stored in the first 4 floats, - and the corresponding Y graphics coordinates in the second group of 4 - floats. */ - if( work && !(*work) ) { - *work = (float *) astMalloc( 81*sizeof(float) ); - if( astOK ) { - nbox = 0; - (*work)[ 0 ] = 0; - } - } - -/* Check the global status. */ - if( !astOK ) return ret; - -/* Get the bounds of the box containing the new label. */ - DrawText( this, 0, esc, text, x, y, just, upx, upy, - xbn, ybn, NULL, method, class, status ); - -/* If the bounding box was obtained succesfully... */ - if( astOK ) { - -/* Check for an overlap between the box and each of the previous boxes. */ - cx = *work + 1; - cy = cx + 4; - for( i = 0; i < nbox; i++ ){ - - if( BoxCheck( xbn, ybn, cx, cy, status ) ) { - ret = 1; - break; - } - -/* Increment the pointers to the next box. */ - cx += 8; - cy += 8; - - } - -/* If no overlap was found, add the new box to the list. */ - if( !ret ){ - *work = (float *) astGrow( (void *) *work, 8*nbox + 9, sizeof(float) ); - cx = *work + 1 + 8*nbox; - cy = cx + 4; - for( i = 0; i < 4; i++ ){ - cx[ i ] = xbn[ i ]; - cy[ i ] = ybn[ i ]; - } - (*work)[ 0 ]++; - -/* Extend the bounds of the global bounding box held externally to include - the new box. */ - for( i = 0; i < 4; i++ ){ - Box_lbnd[ 0 ] = astMIN( xbn[ i ], Box_lbnd[ 0 ] ); - Box_ubnd[ 0 ] = astMAX( xbn[ i ], Box_ubnd[ 0 ] ); - Box_lbnd[ 1 ] = astMIN( ybn[ i ], Box_lbnd[ 1 ] ); - Box_ubnd[ 1 ] = astMAX( ybn[ i ], Box_ubnd[ 1 ] ); - } - } - } - -/* If an error has occur, return a value of 0. */ - if( !astOK ) ret = 0; - -/* Return the answer. */ - return ret; - -} - -static void PlotLabels( AstPlot *this, int esc, AstFrame *frame, int axis, - LabelList *list, char *fmt, int nlab, float **box, - const char *method, const char *class, int *status ) { -/* -* -* Name: -* PlotLabels - -* Purpose: -* Draws the numerical labels which have been selected for display. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void PlotLabels( AstPlot *this, int esc, AstFrame *frame, int axis, -* LabelList *list, char *fmt, int nlab, float **box, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function displays the numerical labels supplied in the -* structure pointed to by "list". Overlapping labels are omitted, -* and redundant leading fields are removed from adjacent labels. -* Nothing is plotted if the NumLab attribute for the axis is false. - -* Parameters: -* this -* A pointer to the Plot. -* esc -* Interpret escape sequences in labels? -* frame -* A pointer to the current Frame of the Plot. -* axis -* The axis index (0 or 1). -* list -* A pointer to the LabelList structure holding information about -* the selected numerical labels. -* fmt -* A pointer to a null terminated string holding the format -* specification used to create the labels. -* nlab -* The number of labels described by "list". -* box -* A pointer to a place at which to store a pointer to an array of -* floats holding the bounding boxes of displayed labels. Memory to -* hold this array is allocated automatically within this function. -* The pointer to the array should be supplied as NULL on the first -* call to this function, and the array should be freed using astFree -* when no longer needed. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - LabelList *ll; /* Pointer to next label structure */ - LabelList *llhi; /* Pointer to higher neighbouring label structure */ - LabelList *lllo; /* Pointer to lower neighbouring label structure */ - char *text; /* Pointer to label text */ - const char *latext; /* Axis label at previous label */ - const char *texthi; /* Pointer to text abbreviated with higher neighbour */ - const char *textlo; /* Pointer to text abbreviated with lower neighbour */ - float tolx; /* Min allowed X interval between labels */ - float toly; /* Min allowed Y interval between labels */ - float xbn[ 4 ]; /* X coords at corners of new label's bounding box */ - float ybn[ 4 ]; /* Y coords at corners of new label's bounding box */ - int abb; /* Abbreviate leading fields? */ - int dp; /* Number of decimal places */ - int found; /* Non-zero digit found? */ - int hilen; /* Length of texthi */ - int i; /* Label index */ - int j; /* Label index offset */ - int jgap; /* Gap in index between rejected labels */ - int lab0; /* Index of middle label */ - int lolen; /* Length of textlo */ - int mxdp; /* Maximum number of decimal places */ - int nbox; /* The number of boinding boxes supplied */ - int nexti; /* Index of next label to retain */ - int nleft; /* No. of labels left */ - int nz; /* Number of trailing zeros in this label */ - int nzmax; /* Max. number of trailing zeros */ - int odd; /* DO we have a strange axis? */ - int off; /* Offset from central label */ - int olap; /* Any overlap found? */ - int prio; /* Current priority */ - int root; /* Index of unabbreviated label */ - int root_found; /* Has the root label been decided on? */ - int rootoff; /* Distance from middle to root label */ - int split; /* Indicates whether to split labels into 2 lines */ - -/* Return without action if an error has occurred, or there are no labels to - draw. */ - if( !astOK || nlab == 0 || !list || !astGetNumLab( this, axis ) ) return; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - rootoff = 0; - -/* Get the number of bounding boxes describing the labels already drawn - (this will be non-zero only if this is the second axis to be labelled). */ - nbox = Overlap( this, -2, 0, NULL, 0.0, 0.0, NULL, 0.0, 0.0, box, method, - class, status ); - -/* Ensure the labels are sorted into increasing index order. */ - qsort( (void *) list, (size_t) nlab, sizeof(LabelList), Compare_LL ); - -/* Complex curves can have multiple edge crossings very close together. - This means that the same label can sometimes be included more than once - in the supplied list at the same (x,y) position. Purge duplicate labels - by setting their priority to -1. Initialise the priority of the remaining - labels to zero. */ - tolx = 0.02*fabs( this->xhi - this->xlo ); - toly = 0.02*fabs( this->yhi - this->ylo ); - ll = list; - ll->priority = 0; - ll->saved_prio = 0; - - for( i = 1; i < nlab; i++ ) { - ll++; - ll->priority = 0; - ll->saved_prio = 0; - for( j = 0; j < i; j++ ){ - if( !strcmp( ll->text, list[ j ].text ) ) { - if( fabs( ll->x - list[ j ].x ) < tolx && - fabs( ll->y - list[ j ].y ) < toly ) { - ll->priority = -1; - ll->saved_prio = -1; - break; - } - } - } - } - -/* Find the maximum number of decimal places in any label. */ - mxdp = 0; - ll = list - 1; - for( i = 0; i < nlab; i++ ) { - ll++; - FindDPTZ( frame, axis, fmt, ll->text, &dp, &nz, status ); - if( dp > mxdp ) mxdp = dp; - } - -/* Indicate that we do not yet know whether SplitValue should split labels - into two lines or not. */ - split = 0; - -/* Find the highest priority label (the "root" label). This label is - never abbreviated to remove leading fields, and is never omitted due to - overlaps with other labels. To find this label, each label is assigned a - priority equal to the number of trailing zeros in the label text. If the - text has fewer than the maximum number of decimal places, pretend the text - is padded with trailing zeros to bring the number of decimal places up to - the maximum. The root label is the highest priority label, giving - preference to labels which occur in the middle of the index order. At the - same time, initialize the abbreviated text for each label to be equal to - the unabbreviated text. */ - lab0 = nlab/2; - nzmax = -1; - ll = list - 1; - root = -1; - root_found = 0; - for( i = 0; i < nlab; i++ ) { - ll++; - if( ll->priority > -1 ) { - text = ll->text; - -/* Find the number of decimal places and the number of trailing zeros in - this label. Note if a non-zero digit was found in the label. */ - found = FindDPTZ( frame, axis, fmt, text, &dp, &nz, status ); - -/* Add on some extra trailing zeros to make the number of decimal places - up to the maximum value. */ - nz += mxdp - dp; - -/* Store the priority for this label. */ - ll->priority = nz; - ll->saved_prio = nz; - -/* Note the highest priority of any label. */ - if( nz > nzmax ) nzmax = nz; - -/* We will use this label as the root label if: - - - We have not already found the root label - - AND - - - It does not overlap any labels drawn for a previous axis - - AND - - - We do not currently have a candidate root label, or - - The priority for this label is higher than the priority of the current - root label, or - - The priority for this label is equal to the priority of the current - root label and this label is closer to the centre of the axis, or - - The label value is zero. */ - - if( root == -1 || - nz > list[ root ].priority || - ( nz == list[ root ].priority && abs( i - lab0 ) < rootoff ) || - !found ) { - - if( !root_found ) { - - if( axis == 0 || !Overlap( this, -1, esc, - SplitValue( this, ll->text, - axis, &split, status ), - (float) ll->x, (float) ll->y, - ll->just, (float) ll->upx, - (float) ll->upy, box, method, - class, status ) ) { - root = i; - rootoff = abs( i - lab0 ); - -/* If the label value was zero, we will use label as the root label, - regardless of the priorities of later labels. */ - if( !found ) root_found = 1; - } - -/* Reset the list of bounding boxes to exclude any box added above. */ - Overlap( this, nbox, esc, NULL, 0.0, 0.0, NULL, 0.0, 0.0, box, - method, class, status ); - - } - } - } - -/* Initialise the abbreviated text to be the same as the full text. */ - ll->atext = ll->text; - } - -/* If all the labels overlapped labels on a previous axis, arbitrarily - use the label with non-genative priority that is closest to the middle - as the root label (this should never happen but is included to avoid - segmentation violations occurring in error conditions such as the - txExt function being buggy and cuasing spurious overlaps). */ - if( root == -1 ) { - for( off = 0; off < (nlab-1)/2; off++ ) { - root = nlab/2 + off; - if( list[ root ].priority >= 0 ) break; - root = nlab/2 - off; - if( list[ root ].priority >= 0 ) break; - } - if( root == -1 ) { - astError( AST__PLFMT, "%s(%s): Cannot produce labels for axis %d.", - status, method, class, axis + 1 ); - root = nlab/2; - } - } - -/* Assign a priority higher than any other priority to the root label. */ - list[ root ].priority = nzmax + 1; - list[ root ].saved_prio = nzmax + 1; - -/* See if leading fields are to be abbreviated */ - abb = astGetAbbrev( this, axis ); - -/* The following process may have removed some labels which define the - missing fields in neighbouring abbreviated fields, so that the user - would not be able to tell what value the abbvreviated leading fields - should have. We therefore loop back and perform the abbreviation - process again, omitting the removed labels this time. Continue doing - this until no further labels are removed. */ - jgap = 1; - olap = 1; - odd = 0; - while( olap && !odd ) { - -/* We now attempt to abbreviate the remaining labels (i.e. those which - have not been rejected on an earlier pass through this loop). Labels - are abbreviated in order of their priority. Higher priority labels are - abbreviated first (except that the root label, which has the highest - priority, is never abbreviated). Each label is abbreviated by comparing - it with the nearest label with a higher priority. */ - -/* Loop through all the priority values, starting with the highest - priority (excluding the root label so that the root label is never - abbreviated), and working downwards to finish with zero priority. */ - prio = nzmax + 1; - while( prio-- > 0 ) { - -/* Look for labels which have the current priority. */ - ll = list - 1; - for( i = 0; i < nlab; i++ ) { - ll++; - if( ll->priority == prio ) { - -/* Find the closest label to this one on the high index side which has a - higher priority. */ - llhi = NULL; - for( j = i + 1; j < nlab; j++ ) { - if( list[ j ].priority > prio ) { - llhi = list + j; - break; - } - } - -/* If no higher priority neighbour was found on the high index side, - use the nearest label with the current priority on the high index side. */ - if( !llhi ) { - for( j = i + 1; j < nlab; j++ ) { - if( list[ j ].priority == prio ) { - llhi = list + j; - break; - } - } - } - -/* Find the closest label to this one on the low index side which has a - higher priority. */ - lllo = NULL; - for( j = i - 1; j >= 0; j-- ) { - if( list[ j ].priority > prio ) { - lllo = list + j; - break; - } - } - -/* If no higher priority neighbour was found on the low index side, - use the nearest label with the current priority on the low index side. */ - if( !lllo ) { - for( j = i - 1; j >= 0; j-- ) { - if( list[ j ].priority == prio ) { - lllo = list + j; - break; - } - } - } - -/* If we are not abbreviating, use the full text as the abbreviated text.*/ - if( !abb ) { - ll->atext = ll->text; - -/* Otherwise, if only one of these two neighbouring labels was found, we - abbreviate the current label by comparing it with the one found - neighbouring label. If they are identical, we use the last field as - the abbreviated text. */ - } else if( !lllo ) { - ll->atext = astAbbrev( frame, axis, fmt, llhi->text, - ll->text ); - - } else if( !llhi ) { - ll->atext = astAbbrev( frame, axis, fmt, lllo->text, - ll->text ); - -/* If two neighbouring labels were found, we abbreviate the current label - by comparing it with both neighbouring labels, and choosing the shorter - abbreviation. */ - } else { - textlo = abb ? astAbbrev( frame, axis, fmt, lllo->text, - ll->text ) : ll->text; - texthi = abb ? astAbbrev( frame, axis, fmt, llhi->text, - ll->text ) : ll->text; - - lolen = strlen( textlo ); - hilen = strlen( texthi ); - if( lolen > 0 && lolen < hilen ) { - ll->atext = textlo; - } else { - ll->atext = texthi; - } - } - -/* If the two fields are identical, the abbreviated text returned by - astAbbrev will be a null string. In this case, find the start of the - last field in the formatted value (using astAbbrev again), and use - that as the abbreviated text. */ - if( !(ll->atext)[0] ) { - ll->atext = astAbbrev( frame, axis, fmt, NULL, ll->text ); - } - } - } - } - -/* Find the bounding box of the root label and add it to the list of bounding - boxes. */ - nleft = 1; - ll = list + root; - olap = Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, (float) ll->upx, - (float) ll->upy, box, method, class, status ); - -/* Now look for labels which would overlap. First, check labels above the root - label. Do not count overlaps where the two abbreviated labels have the same text. */ - ll = list + root; - latext = ll->atext; - for( i = root + 1; i < nlab; i++ ) { - ll++; - if( ll->priority >= 0 ) { - if( strcmp( ll->atext, latext ) ) { - if( Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, - (float) ll->upx, (float) ll->upy, box, method, - class, status ) ){ - olap++; - } else { - nleft++; - } - } - latext = ll->atext; - } - } - -/* Now check the labels below the root label. */ - ll = list + root; - latext = ll->atext; - for( i = root - 1; i >= 0; i-- ) { - ll--; - if( ll->priority >= 0 ) { - if( strcmp( ll->atext, latext ) ) { - if( Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, - (float) ll->upx, (float) ll->upy, box, method, - class, status ) ){ - olap++; - } else { - nleft++; - } - } - latext = ll->atext; - } - } - -/* If only one overlap was found, and this is the second axis, ignore it - since it is probably caused by the crossing of the two axes. */ - if( axis == 1 && olap == 1 ) olap = 0; - -/* If we are now only plotting every 3rd label, or if there are less than - 3 labels left, and there are still overlapping labels, then we must have - a very odd axis (such as logarithmically spaced ticks on a linearly mapped - axis). In this case, we will re-instate the orignal label priorities and - then leave this loop so that we attempt to plot all labels. Also retain - original priorities if the axis is mapped logarithmically onto the - screen. */ - if( olap && ( jgap == 3 || nleft < 3 || astGetLogPlot( this, axis ) ) ){ - jgap = 0; - odd = 1; - } else { - odd = 0; - } - -/* If any labels overlapped, re-instate the priority of all previously - excluded labels (using the copy of the label's real priority stored in - "saved_prio"), and then remove labels (by setting their priorities - negative) to increase the gap between labels, and try again. */ - if( olap ) { - jgap++; - - nexti = root + jgap; - for( i = root + 1; i < nlab; i++ ) { - if( i == nexti ) { - nexti += jgap; - list[ i ].priority = list[ i ].saved_prio; - } else { - list[ i ].priority = -1; - } - } - - nexti = root - jgap; - for( i = root - 1; i >= 0; i-- ) { - if( i == nexti ) { - nexti -= jgap; - list[ i ].priority = list[ i ].saved_prio; - } else { - list[ i ].priority = -1; - } - } - -/* Reset the abbreviated text to be the full text. */ - for( i = 0; i < nlab - 1; i++ ) list[ i ].atext = list[ i ].text; - - } - -/* Rest the list of bounding boxes to exclude the boxes added above. */ - Overlap( this, nbox, esc, NULL, 0.0, 0.0, NULL, 0.0, 0.0, box, method, - class, status ); - } - -/* We can now draw the abbreviated labels (ignoring rejected labels). */ - ll = list-1; - for( i = 0; i < nlab; i++ ) { - ll++; - if( ll->priority >= 0 ) { - -/* Check that this label does not overlap any labels drawn for previous - axes (we know from the above processing that it will not overlap any - other label on the current axis). */ - if( !Overlap( this, -1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, (float) ll->upx, - (float) ll->upy, box, method, class, status ) ) { - -/* Draw the abbreviated label text, and get the bounds of the box containing - the new label, splitting long formatted values (such as produced by - TimeFrames) into two lines. */ - DrawText( this, 1, esc, - SplitValue( this, ll->atext, axis, &split, status ), - (float) ll->x, (float) ll->y, ll->just, (float) ll->upx, - (float) ll->upy, xbn, ybn, NULL, method, class, status ); - } - } - } -} - -static void PolyCurve( AstPlot *this, int npoint, int ncoord, int indim, - const double *in, int *status ){ -/* -*++ -* Name: -c astPolyCurve -f AST_POLYCURVE - -* Purpose: -* Draw a series of connected geodesic curves. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astPolyCurve( AstPlot *this, int npoint, int ncoord, int indim, -c const double *in ) -f CALL AST_POLYCURVE( THIS, NPOINT, NCOORD, INDIM, IN, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -c This function joins a series of points specified in the physical -c coordinate system of a Plot by drawing a sequence of geodesic -c curves. It is equivalent to making repeated use of the astCurve -c function (q.v.), except that astPolyCurve will generally be more -c efficient when drawing many geodesic curves end-to-end. A -c typical application of this might be in drawing contour lines. -f This routine joins a series of points specified in the physical -f coordinate system of a Plot by drawing a sequence of geodesic -f curves. It is equivalent to making repeated calls to the -f AST_CURVE routine (q.v.), except that AST_POLYCURVE will -f generally be more efficient when drawing many geodesic curves -f end-to-end. A typical application of this might be in drawing -f contour lines. -* -c As with astCurve, full account is taken of the Mapping between -c physical and graphical coordinate systems. This includes any -c discontinuities and clipping established using astClip. -f As with AST_CURVE, full account is taken of the Mapping between -f physical and graphical coordinate systems. This includes any -f discontinuities and clipping established using AST_CLIP. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c npoint -f NPOINT = INTEGER (Given) -* The number of points between which geodesic curves are to be drawn. -c ncoord -f NCOORD = INTEGER (Given) -* The number of coordinates being supplied for each point (i.e. -* the number of axes in the current Frame of the Plot, as given -* by its Naxes attribute). -c indim -f INDIM = INTEGER (Given) -c The number of elements along the second dimension of the "in" -f The number of elements along the first dimension of the IN -* array (which contains the input coordinates). This value is -* required so that the coordinate values can be correctly -* located if they do not entirely fill this array. The value -c given should not be less than "npoint". -f given should not be less than NPOINT. -c in -f IN( INDIM, NCOORD ) = DOUBLE PRECISION (Given) -c The address of the first element in a 2-dimensional array of shape -c "[ncoord][indim]" giving the -c physical coordinates of the points which are to be joined in -c sequence by geodesic curves. These should be stored such that -c the value of coordinate number "coord" for point number -c "point" is found in element "in[coord][point]". -f A 2-dimensional array giving the physical coordinates of the -f points which are to be joined in sequence by geodesic -f curves. These should be stored such that the value of -f coordinate number COORD for input point number POINT is found -f in element IN(POINT,COORD). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - No curve is drawn on either side of any point which has any -* coordinate equal to the value AST__BAD. -* - An error results if the base Frame of the Plot is not -* 2-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **in_ptr; /* Pointer to array of data pointers */ - double *finish; /* Pointer to array holding segment end position */ - double *start; /* Pointer to array holding segment start position */ - double d[ CRV_NPNT ]; /* Offsets to evenly spaced points along curve */ - double tol; /* Absolute tolerance value */ - double x[ CRV_NPNT ]; /* X coords at evenly spaced points along curve */ - double y[ CRV_NPNT ]; /* Y coords at evenly spaced points along curve */ - int coord; /* Loop counter for coordinates */ - int i; /* Loop count */ - int naxes; /* No. of Frame axes */ - int ok; /* Are all start and end coords good? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astPolyCurve"; - class = astGetClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Check the current Frame of the Plot has ncoord axes. */ - naxes = astGetNout( this ); - if( naxes != ncoord && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the current " - "Frame of the supplied %s is invalid - this number should " - "be %d (possible programming error).", status, method, class, naxes, - class, ncoord ); - } - -/* Check the array dimension argument. */ - if ( astOK && ( indim < npoint ) ) { - astError( AST__DIMIN, "%s(%s): The array dimension value " - "(%d) is invalid.", status, method, class, indim ); - astError( AST__DIMIN, "This should not be less than the number of " - "points being drawn (%d).", status, npoint ); - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Allocate memory to hold the array of data pointers, the start position, - and the end position. */ - if ( astOK ) { - in_ptr = (const double **) astMalloc( sizeof( const double * ) * - (size_t) ncoord ); - start = (double *) astMalloc( sizeof( double ) * (size_t) ncoord ); - finish = (double *) astMalloc( sizeof( double ) * (size_t) ncoord ); - -/* Set up externals used to communicate with the Map3 function... - The number of axes in the physical coordinate system (i.e. the current - Frame). */ - Map3_ncoord = ncoord; - -/* A pointer to the Plot, the Current Frame, and and Mapping. */ - Map3_plot = this; - Map3_frame = astGetFrame( this, AST__CURRENT ); - Map3_map = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Convert the tolerance from relative to absolute graphics coordinates. */ - tol = astGetTol( this )*astMAX( this->xhi - this->xlo, - this->yhi - this->ylo ); - -/* Ensure the globals holding the scaling from graphics coords to equally - scaled coords are available. */ - GScales( this, NULL, NULL, method, class, status ); - -/* Now set up the external variables used by the Crv and CrvLine function. */ - Crv_scerr = ( astGetLogPlot( this, 0 ) || - astGetLogPlot( this, 1 ) ) ? 100.0 : 1.5; - Crv_tol = tol; - Crv_limit = 0.5*tol*tol; - Crv_map = Map3; - Crv_ink = 1; - Crv_xlo = this->xlo; - Crv_xhi = this->xhi; - Crv_ylo = this->ylo; - Crv_yhi = this->yhi; - Crv_clip = astGetClip( this ) & 1; - -/* Set up a list of points spread evenly over each curve segment. */ - for( i = 0; i < CRV_NPNT; i++ ){ - d[ i ] = ( (double) i)/( (double) CRV_NSEG ); - } - -/* Initialise the data pointers to locate the coordinate data in - the "in" array. */ - if ( astOK ) { - for ( coord = 0; coord < ncoord; coord++ ) { - in_ptr[ coord ] = in + coord * indim; - } - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__CURVE_ID, 1, GRF__LINE, method, class ); - -/* Loop round each curve segment. */ - for( i = 1 ; i < npoint; i++ ) { - -/* Store the start position and check it for bad values. Increment the - pointers to the next position on each axis, so that they refer to the - finish point of the current curve segment. */ - ok = 1; - for( coord = 0; coord < ncoord; coord++ ) { - if( *( in_ptr[coord] ) == AST__BAD ){ - ok = 0; - } else { - start[ coord ] = *( in_ptr[coord] ); - } - ( in_ptr[coord] )++; - } - -/* Store the end position and check it for bad values. Do not increment - the axis pointers. This means that they will refer to the start position - of the next curve segment on the next pass through this loop. */ - for( coord = 0; coord < ncoord; coord++ ) { - if( *( in_ptr[coord] ) == AST__BAD ){ - ok = 0; - } else { - finish[ coord ] = *( in_ptr[coord] ); - } - } - -/* Pass on to the next curve segment if either the start or finish position - was bad. */ - if( ok ) { - -/* Set up the remaining externals used to communicate with the Map3 - function... */ - -/* The physical coordinates at the start of the curve. */ - Map3_origin = start; - -/* The physical coordinates at the end of the curve. */ - Map3_end = finish; - -/* The scale factor to convert "dist" values into physical offset values. */ - Map3_scale = astDistance( Map3_frame, start, finish ); - -/* Now set up the remaining external variables used by the Crv and CrvLine - function. */ - Crv_ux0 = AST__BAD; - Crv_out = 1; - Crv_xbrk = Curve_data.xbrk; - Crv_ybrk = Curve_data.ybrk; - Crv_vxbrk = Curve_data.vxbrk; - Crv_vybrk = Curve_data.vybrk; - -/* Map the evenly spread distances between "start" and "finish" into graphics - coordinates. */ - Map3( CRV_NPNT, d, x, y, method, class, status GLOBALS_NAME ); - -/* Use Crv and Map3 to draw the curve segment. */ - Crv( this, d, x, y, 0, NULL, NULL, method, class, status ); - -/* If no part of the curve could be drawn, set the number of breaks and the - length of the drawn curve to zero. */ - if( Crv_out ) { - Crv_nbrk = 0; - Crv_len = 0.0F; - -/* Otherwise, add an extra break to the returned structure at the position of - the last point to be plotted. */ - } else { - Crv_nbrk++; - if( Crv_nbrk > AST__PLOT_CRV_MXBRK ){ - astError( AST__CVBRK, "%s(%s): Number of breaks in curve " - "exceeds %d.", status, method, class, AST__PLOT_CRV_MXBRK ); - } else { - *(Crv_xbrk++) = (float) Crv_xl; - *(Crv_ybrk++) = (float) Crv_yl; - *(Crv_vxbrk++) = (float) -Crv_vxl; - *(Crv_vybrk++) = (float) -Crv_vyl; - } - } - -/* Store extra information about the curve in the returned structure, and - purge any zero length sections. */ - Curve_data.length = Crv_len; - Curve_data.out = Crv_out; - Curve_data.nbrk = Crv_nbrk; - PurgeCdata( &Curve_data, status ); - } - } - -/* End the last poly line. */ - Opoly( this, status ); - -/* Tidy up the static data used by Map3. */ - Map3( 0, NULL, NULL, NULL, method, class, status GLOBALS_NAME ); - -/* Ensure all lines are flushed to the graphics system. */ - Fpoly( this, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__CURVE_ID, 0, GRF__LINE, method, class ); - } - -/* Annul the Frame and Mapping. */ - Map3_frame = astAnnul( Map3_frame ); - Map3_map = astAnnul( Map3_map ); - -/* Free the memory used for the data pointers, and start and end positions. */ - in_ptr = (const double **) astFree( (void *) in_ptr ); - start = (double *) astFree( (void *) start ); - finish = (double *) astFree( (void *) finish ); - } -} - -static int PopGat( AstPlot *this, float *rise, const char *method, - const char *class, int *status ) { -/* -* Name: -* PopGat - -* Purpose: -* Pop current graphical attributes for text from a stack. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int PopGat( AstPlot *this, float *rise, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function restores the current graphical attributes for text -* from the values on a stack. Current attributes are left unchanged if -* the stack is empty. - -* Parameters: -* this -* Pointer to the Plot. -* rise -* Pointer to a location at which to return thhe height of the baseline -* above the normal baseline, expressed as a percentage of the normal -* character height. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Returns zero if the stack is empty, and 1 otherwise. - -*/ - -/* Local Variables: */ - AstGat *gat; - int result; - -/* Initialise */ - result = 0; - -/* Check inherited status */ - if( !astOK ) return result; - -/* Check there is at least one AstGat structure on the stack. */ - if( this->ngat ) { - -/* Decrement the number of entries in the stack, and get a pointer to the - AstGat structure. Nullify the pointer on the stack. */ - gat = (this->gat)[ --(this->ngat) ]; - (this->gat)[ this->ngat ] = NULL; - -/* Restore the values in the AstGat structure */ - *rise = gat->rise; - GAttr( this, GRF__SIZE, gat->size, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, gat->width, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, gat->col, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, gat->font, NULL, GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, gat->style, NULL, GRF__TEXT, method, class, status ); - -/* Free the AstGat structure. */ - gat = astFree( gat ); - -/* Indicate success.*/ - result = 1; - } - -/* Return the result. */ - return result; - -} - -static void PurgeCdata( AstPlotCurveData *cdata, int *status ){ -/* -* -* Name: -* AstPlotCurveData - -* Purpose: -* Remove any zero length sections from the description of a curve. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void PurgeCdata( AstPlotCurveData *cdata ) - -* Class Membership: -* Plot member function. - -* Description: -* This function removes any zero length sections from the supplied -* AstPlotCurveData struture, which describes a multi-section curve. - -* Parameters: -* cdata -* A pointer to the structure containing information about the -* breaks in a curve. - -*/ - -/* Local Variables: */ - int brk; /*Break index */ - int i; /*Break index */ - -/* Check the global error status. */ - if ( !astOK || !cdata ) return; - -/* Loop round all breaks. */ - brk = 0; - while( brk < cdata->nbrk ) { - -/* If this break and the next one are co-incident, remove both breaks. */ - if( cdata->xbrk[ brk ] == cdata->xbrk[ brk + 1 ] && - cdata->ybrk[ brk ] == cdata->ybrk[ brk + 1 ] ) { - -/* Shuffle down the higher elements of all the arrays in the curve data. */ - for( i = brk + 2; i < cdata->nbrk; i++ ){ - cdata->xbrk[ i - 2 ] = cdata->xbrk[ i ]; - cdata->ybrk[ i - 2 ] = cdata->ybrk[ i ]; - cdata->vxbrk[ i - 2 ] = cdata->vxbrk[ i ]; - cdata->vybrk[ i - 2 ] = cdata->vybrk[ i ]; - } - -/* Decrement the number of breaks in the curve data. */ - cdata->nbrk -= 2; - -/* If the section is not zero length, move on to the next pair of breaks. */ - } else { - brk += 2; - } - } -} - -static void PushGat( AstPlot *this, float rise, const char *method, - const char *class, int *status ) { -/* -* Name: -* PushGat - -* Purpose: -* Push current graphical attributes for text onto a stack. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void PushGat( AstPlot *this, float rise, const char *method, -* const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function stores the current graphical attributes for text -* on a stack. - -* Parameters: -* this -* Pointer to the Plot. -* rise -* The height of the baseline above the normal baseline, expressed -* as a percentage of the normal character height. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstGat *new_gat; - -/* Check inherited status */ - if( !astOK ) return; - -/* Allocate memory for a new AstGat structure to store the graphical - attributes. */ - new_gat = astMalloc( sizeof( AstGat ) ); - if( astOK ) { - -/* Store the height of the current baseline above the normal baseline, - expressed as a percentage of a normal character height. */ - new_gat->rise = rise; - -/* Store the current graphical attribute values. */ - GAttr( this, GRF__SIZE, AST__BAD, &(new_gat->size), GRF__TEXT, method, class, status ); - GAttr( this, GRF__WIDTH, AST__BAD, &(new_gat->width), GRF__TEXT, method, class, status ); - GAttr( this, GRF__FONT, AST__BAD, &(new_gat->font), GRF__TEXT, method, class, status ); - GAttr( this, GRF__STYLE, AST__BAD, &(new_gat->style), GRF__TEXT, method, class, status ); - GAttr( this, GRF__COLOUR, AST__BAD, &(new_gat->col), GRF__TEXT, method, class, status ); - -/* Increment the number of AstGat structures on the stack.*/ - this->ngat++; - -/* Extend the array of AstGat pointers in the Plot structure so that there - is room for the new one. */ - this->gat = (AstGat **) astGrow( this->gat, this->ngat, sizeof( AstGat * ) ); - if( astOK ) { - -/* Store the new pointer. */ - (this->gat)[ this->ngat - 1 ] = new_gat; - - } - } -} - -static void RegionOutline( AstPlot *this, AstRegion *region, int *status ){ -/* -*++ -* Name: -c astRegionOutline -f AST_RegionOutline - -* Purpose: -* Draw the outline of an AST Region. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astRegionOutline( AstPlot *this, AstRegion *region ) -f CALL AST_REGIONOUTLINE( THIS, REGION, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws an outline around the supplied AST Region object. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c region -f REGION = INTEGER (Given) -* Pointer to the Region. -f STATUS = INTEGER (Given and Returned) -f The global status. - -*-- -*/ -/* Local Variables: */ - AstFrameSet *fs; - AstMapping *map; - const char *class; - const char *method; - int ibase; - int icurr; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Store the current method, and the class of the supplied object for use - in error messages.*/ - method = "astRegionOutline"; - class = astGetClass( this ); - -/* Save the base Frame index within the Plot, since astConvert will - change it. */ - ibase = astGetBase( this ); - -/* Get the FrameSet that converts from the current Frame of the Plot, to the - Frame represented by the Region. Check a conversion was found. */ - fs = astConvert( this, region, " " ); - -/* Re-instate the original base Frame. */ - astSetBase( this, ibase ); - -/* Report an error if the Region could not be mapped into the current - Frame of the Plot. */ - if( !fs ) { - if( astOK ) { - astError( AST__NOCNV, "%s(%s): Cannot find a mapping from the " - "%d-dimensional Plot coordinate system (%s) to the " - "%d-dimensional Region coordinate system (%s).", status, - method, class, astGetNout( this ), astGetTitle( this ), - astGetNout( region ), astGetTitle( region ) ); - } - -/* If a transformation from Plot to Region was found... */ - } else { - -/* Add the Region as a new Frame into the Plot, connecting it to the - current Frame using the FrameSet found above. It becomes the new current - Frame. First record the index of the original current Frame since - astAddFrame will modify the FrameSet to use a different current Frame. */ - icurr = astGetCurrent( this ); - map = astGetMapping( fs, AST__BASE, AST__CURRENT ); - astAddFrame( this, icurr, map, region ); - -/* Draw the outline of the Region (now the current Frame in the Plot). */ - astBorder( this ); - -/* Tidy up by removing the Region (i.e. the current Frame) from the Plot and - re-instating the original current Frame. */ - astRemoveFrame( this, AST__CURRENT ); - astSetCurrent( this, icurr ); - -/* Free resources. */ - map = astAnnul( map ); - fs = astAnnul( fs ); - } -} - -static void RemoveFrame( AstFrameSet *this_fset, int iframe, int *status ) { -/* -* Name: -* RemoveFrame - -* Purpose: -* Remove a Frame from a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -* #include "plot.h" -* void RemoveFrame( AstFrameSet *this_fset, int iframe, int *status ) - -* Class Membership: -* Plot member function (over-rides the astRemoveFrame public -* method inherited from the FrameSet class). - -* Description: -* This function removes a Frame from a Plot. All other Frames -* in the Plot have their indices re-numbered from one (if -* necessary), but are otherwise unchanged. -* -* If the index of the clipping Frame is changed, the index value -* stored in the Plot is updated. If the clipping Frame itself is -* removed, all clipping information is removed from the Plot. - -* Parameters: -* this_fset -* Pointer to the FrameSet component of the Plot. -* iframe -* The index within the Plot of the Frame to be removed. -* This value should lie in the range from 1 to the number of -* Frames in the Plot (as given by its Nframe attribute). -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to Plot structure */ - int ifrm; /* Validated frame index */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_fset; - -/* Validate the frame index. */ - ifrm = astValidateFrameIndex( this_fset, iframe, "astRemoveFrame" ); - -/* Invoke the parent astRemoveFrame method to remove the Frame. */ - (*parent_removeframe)( this_fset, iframe, status ); - -/* If the index of the removed Frame is smaller than the clipping Frame - index, then decrement the clipping Frame index so that the same Frame - will be used in future. */ - if( astOK ){ - if( ifrm < this->clip_frame ){ - (this->clip_frame)--; - -/* If the clipping fgrame itself has been removed, indicate that no - clipping should nbow be performed. */ - } else if( ifrm == this->clip_frame ){ - astClip( this, AST__NOFRAME, NULL, NULL ); - } - } -} - -static void RightVector( AstPlot *this, float *ux, float *uy, float *rx, - float *ry, const char *method, const char *class, int *status ){ -/* -* Name: -* RightVector - -* Purpose: -* Return a vector in the direction of the base line of normal text. - -* Synopsis: -* #include "plot.h" -* void RightVector( AstPlot *this, float *ux, float *uy, float *rx, -* float *ry, const char *method, const char *class, int *status ) - -* Description: -* This function returns a vector which points from left to right along -* the text baseline, taking account of any difference in the scales of -* the x and y axes. It also scales the supplied up vector so that it has -* a length equal to the height of normal text, and scales the returned -* right vector to have the same length (on the screen) as the up vector. - -* Parameters: -* this -* The plot. -* ux -* Pointer to a float holding the x component of the up-vector for the -* text, in graphics coords. Scaled on exit so that the up vector has -* length equal to the height of normal text. -* uy -* Pointer to a float holding the y component of the up-vector for the -* text, in graphics coords. Scaled on exit so that the up vector has -* length equal to the height of normal text. -* rx -* Pointer to a double in which will be put the x component of a -* vector parallel to the baseline of normal text. -* ry -* Pointer to a double in which will be put the y component of a -* vector parallel to the baseline of normal text. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - - -/* Local Variables: */ - float alpha; /* Scale factor for X axis */ - float beta; /* Scale factor for Y axis */ - float chv; - float chh; - float l; /* Normalisation constant */ - float a; - float b; - float nl; /* Character height in standard coordinates */ - -/* Check inherited status */ - if( !astOK ) return; - -/* Find the scale factors for the two axes which scale graphics coordinates - into a "standard" coordinate system in which: 1) the axes have equal scale - in terms of (for instance) millimetres per unit distance, 2) X values - increase from left to right, 3) Y values increase from bottom to top. */ - GScales( this, &alpha, &beta, method, class, status ); - -/* Convert the up-vector into "standard" system in which the axes have - equal scales, and increase left-to-right, bottom-to-top. */ - *ux *= alpha; - *uy *= beta; - -/* Normalise this up-vector. */ - l = sqrt( (*ux)*(*ux) + (*uy)*(*uy) ); - if( l <= 0.0 ) { - *ux = 0.0; - *uy = 1.0; - } else { - *ux /= l; - *uy /= l; - } - -/* Find the height in "standard" coordinates of "normal" text draw with the - requested up-vector. */ - GQch( this, &chv, &chh, method, class, status ); - a = (*ux)/(chv*alpha); - b = (*uy)/(chh*beta); - nl = 1.0/sqrt( a*a + b*b ); - -/* Scale the up-vector so that is has length equal to the height of "normal" - text with the specified up-vector. */ - *ux *= nl; - *uy *= nl; - -/* Get the vector along the base-line of the text, by rotating the - up-vector by 90 degrees clockwise. */ - *rx = *uy; - *ry = -*ux; - -/* Convert both vectors back from standard coords to normal world coords */ - *ux /= alpha; - *uy /= beta; - *rx /= alpha; - *ry /= beta; - -} - -static void SaveTick( AstPlot *this, int axis, double gx, double gy, - int major, int *status ){ -/* -* Name: -* SaveTick - -* Purpose: -* Save info about a drawn tick in the Plot structure. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void SaveTick( AstPlot *this, int axis, double gx, double gy, -* int major, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function stores the start position and type of each drawn -* tick in the given Plot. - -* Parameters: -* this -* Pointer to the Plot. -* axis -* The zero-based axis index to which the tick refers. If a -* negative value is specified then all information about drawn ticks -* curently stored in the Plot is erased. -* gx -* The graphics X position at the start of the tick mark. -* gy -* The graphics Y position at the start of the tick mark. -* major -* Non-zero if the tick mark is a major tick. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int i; - int *count; - double *tickgx; - double *tickgy; - -/* Free the tick info in the supplied Plot if required. Do this before - checking the error status. */ - if( axis < 0 ) { - for( i = 0; i < 3; i++ ) { - this->majtickgx[ i ] = astFree( this->majtickgx[ i ] ); - this->majtickgy[ i ] = astFree( this->majtickgy[ i ] ); - this->mintickgx[ i ] = astFree( this->mintickgx[ i ] ); - this->mintickgy[ i ] = astFree( this->mintickgy[ i ] ); - this->mintickcount[ i ] = 0; - this->majtickcount[ i ] = 0; - } - return; - } - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Get pointers to the arrays to use, and ensure the arrays are big - enough to hold the new tick. */ - if( major ) { - count = this->majtickcount + axis; - tickgx = this->majtickgx[ axis ]; - tickgy = this->majtickgy[ axis ]; - } else { - count = this->mintickcount + axis; - tickgx = this->mintickgx[ axis ]; - tickgy = this->mintickgy[ axis ]; - } - -/* Ensure the arrays are big enough to hold the new tick. */ - i = *count; - tickgx = astGrow( tickgx, i + 1, sizeof( double ) ); - tickgy = astGrow( tickgy, i + 1, sizeof( double ) ); - -/* If memory was allocated succesfully, store the new tick information in - the expanded arrays. */ - if( astOK ) { - tickgx[ i ] = gx; - tickgy[ i ] = gy; - *count = i + 1; - -/* Store the potentially updated array pointers. */ - if( major ) { - this->majtickgx[ axis ] = tickgx; - this->majtickgy[ axis ] = tickgy; - } else { - this->mintickgx[ axis ] = tickgx; - this->mintickgy[ axis ] = tickgy; - } - } -} - -static void SetAttrib( AstObject *this_object, const char *setting, int *status ) { -/* -* Name: -* SetAttrib - -* Purpose: -* Set an attribute value for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void SetAttrib( AstObject *this, const char *setting, int *status ) - -* Class Membership: -* Plot member function (over-rides the astSetAttrib protected -* method inherited from the FrameSet class). - -* Description: -* This function assigns an attribute value for a Plot, the -* attribute and its value being specified by means of a string of -* the form: -* -* "attribute= value " -* -* Here, "attribute" specifies the attribute name and should be in -* lower case with no white space present. The value to the right -* of the "=" should be a suitable textual representation of the -* value to be assigned and this will be interpreted according to -* the attribute's data type. White space surrounding the value is -* only significant for string attributes. - -* Parameters: -* this -* Pointer to the Plot. -* setting -* Pointer to a null terminated string specifying the new attribute -* value. -* status -* Pointer to the inherited status variable. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char label[21]; /* Graphics item label */ - const char *class; /* Pointer to class string */ - double dval; /* Double attribute value */ - int axis; /* Index for the axis */ - int edge; /* Index of edge within list */ - int id1; /* Plot object id */ - int id2; /* Plot object id */ - int id; /* Plot object id */ - int ival; /* Int attribute value */ - int len; /* Length of setting string */ - int nax; /* Number of graphics frame axes */ - int nc; /* Number of characters read by astSscanf */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Obtain the length of the setting string. */ - len = (int) strlen( setting ); - -/* Test for each recognised attribute in turn, using "astSscanf" to parse - the setting string and extract the attribute value (or an offset to - it in the case of string values). In each case, use the value set - in "nc" to check that the entire string was matched. Once a value - has been obtained, use the appropriate method to set it. */ - -/* Tol. */ -/* ---- */ - if ( nc = 0, - ( 1 == astSscanf( setting, "tol= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTol( this, dval ); - -/* Grid. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "grid= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetGrid( this, ival ); - -/* TickAll. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "tickall= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetTickAll( this, ival ); - -/* ForceExterior */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "forceexterior= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetForceExterior( this, ival ); - -/* Invisible. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "invisible= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetInvisible( this, ival ); - -/* Border. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "border= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetBorder( this, ival ); - -/* ClipOp. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "clipop= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetClipOp( this, ival ); - -/* Clip. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "clip= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetClip( this, ival ); - -/* Grf. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "grf= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetGrf( this, ival ); - -/* DrawTitle. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "drawtitle= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetDrawTitle( this, ival ); - -/* DrawAxes. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "drawaxes= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetDrawAxes( this, axis, ival ); - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "drawaxes(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetDrawAxes( this, axis - 1, ival ); - -/* Abbrev. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "abbrev= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetAbbrev( this, axis, ival ); - -/* Abbrev(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "abbrev(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetAbbrev( this, axis - 1, ival ); - -/* Escape. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "escape= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetEscape( this, ival ); - -/* Edge(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "edge(%d)= %n%*s %n", &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - edge = FullForm( "left right top bottom", setting + ival, setting, - "astSet", astGetClass( this ), status ); - if( edge == 0 ) { - astSetEdge( this, axis - 1, LEFT ); - } else if( edge == 1 ) { - astSetEdge( this, axis - 1, RIGHT ); - } else if( edge == 2 ) { - astSetEdge( this, axis - 1, TOP ); - } else if( edge == 3 ) { - astSetEdge( this, axis - 1, BOTTOM ); - } - -/* LabelAt (axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "labelat(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetLabelAt( this, axis - 1, dval ); - -/* Centre(axis). */ -/* ------------ */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "centre(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetCentre( this, axis - 1, dval ); - -/* Gap. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "gap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetGap( this, axis, dval ); - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "gap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetGap( this, axis - 1, dval ); - -/* LogGap. */ -/* ---- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "loggap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogGap( this, axis, dval ); - -/* LogGap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "loggap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetLogGap( this, axis - 1, dval ); - -/* NumLabGap. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "numlabgap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetNumLabGap( this, axis, dval ); - -/* NumLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "numlabgap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetNumLabGap( this, axis - 1, dval ); - -/* TextLabGap. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "textlabgap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetTextLabGap( this, axis, dval ); - -/* TextLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "textlabgap(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTextLabGap( this, axis - 1, dval ); - -/* LabelUp. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "labelup= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLabelUp( this, axis, ival ); - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "labelup(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLabelUp( this, axis - 1, ival ); - -/* LogPlot. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "logplot= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogPlot( this, axis, ival ); - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "logplot(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLogPlot( this, axis - 1, ival ); - -/* LogTicks. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "logticks= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogTicks( this, axis, ival ); - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "logticks(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLogTicks( this, axis - 1, ival ); - -/* LogLabel. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "loglabel= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLogLabel( this, axis, ival ); - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "loglabel(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLogLabel( this, axis - 1, ival ); - -/* NumLab. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "numlab= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetNumLab( this, axis, ival ); - -/* NumLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "numlab(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetNumLab( this, axis - 1, ival ); - -/* MinTick. */ -/* -------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "mintick= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetMinTick( this, axis, ival ); - -/* MinTick(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "mintick(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetMinTick( this, axis - 1, ival ); - -/* TextLab. */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "textlab= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetTextLab( this, axis, ival ); - -/* TextLab(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "textlab(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetTextLab( this, axis - 1, ival ); - -/* LabelUnits. */ -/* --------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "labelunits= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetLabelUnits( this, axis, ival ); - -/* LabelUnits(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "labelunits(%d)= %d %n", - &axis, &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLabelUnits( this, axis - 1, ival ); - -/* Style. */ -/* ------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "style= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetStyle( this, id, ival ); - -/* Style(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "style(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Style", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetStyle( this, id1, ival ); - if( nid > 1 ) astSetStyle( this, id2, ival ); - if( nid > 2 ) astSetStyle( this, id3, ival ); - -/* Font. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "font= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetFont( this, id, ival ); - -/* Font(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "font(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Font", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetFont( this, id1, ival ); - if( nid > 1 ) astSetFont( this, id2, ival ); - if( nid > 2 ) astSetFont( this, id3, ival ); - -/* Colour. */ -/* ------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "colour= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetColour( this, id, ival ); - -/* Colour(label). */ -/* -------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "colour(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Colour", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetColour( this, id1, ival ); - if( nid > 1 ) astSetColour( this, id2, ival ); - if( nid > 2 ) astSetColour( this, id3, ival ); - -/* Color. */ -/* ------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "color= %d %n", &ival, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetColour( this, id, ival ); - -/* Color(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "color(%20[^()])= %d %n", - label, &ival, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Color", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetColour( this, id1, ival ); - if( nid > 1 ) astSetColour( this, id2, ival ); - if( nid > 2 ) astSetColour( this, id3, ival ); - -/* Width. */ -/* ------ */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "width= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetWidth( this, id, dval ); - -/* Width(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "width(%20[^()])= %lg %n", - label, &dval, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Width", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetWidth( this, id1, dval ); - if( nid > 1 ) astSetWidth( this, id2, dval ); - if( nid > 2 ) astSetWidth( this, id3, dval ); - -/* Size. */ -/* ----- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "size= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( id = 0; id < AST__NPID; id++ ) astSetSize( this, id, dval ); - -/* Size(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "size(%20[^()])= %lg %n", - label, &dval, &nc ) ) - && ( nc >= len ) ) { - class = astGetClass( this ); - - nid = IdFind( FullForm( GrfLabels, label, "Size", "astSet", class, status ), - nax, &id1, &id2, &id3, status ); - astSetSize( this, id1, dval ); - if( nid > 1 ) astSetSize( this, id2, dval ); - if( nid > 2 ) astSetSize( this, id3, dval ); - -/* TitleGap. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "titlegap= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - astSetTitleGap( this, dval ); - -/* MajTickLen. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "majticklen= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetMajTickLen( this, axis, dval ); - -/* MajTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "majticklen(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetMajTickLen( this, axis - 1, dval ); - -/* MinTickLen. */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( setting, "minticklen= %lg %n", &dval, &nc ) ) - && ( nc >= len ) ) { - for( axis = 0; axis < nax; axis++ ) astSetMinTickLen( this, axis, dval ); - -/* MinTickLen(axis). */ -/* ----------------- */ - } else if ( nc = 0, - ( 2 == astSscanf( setting, "minticklen(%d)= %lg %n", - &axis, &dval, &nc ) ) - && ( nc >= len ) ) { - astSetMinTickLen( this, axis - 1, dval ); - -/* Labelling. */ -/* -------- */ - } else if ( nc = 0, - ( 0 == astSscanf( setting, "labelling= %n%*s %n", &ival, &nc ) ) - && ( nc >= len ) ) { - astSetLabelling( this, FullForm( "exterior interior", - setting + ival, setting, - "astSet", astGetClass( this ), status ) - ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - (*parent_setattrib)( this_object, setting, status ); - } - -/* Undefine macros local to this function. */ -#undef MATCH -} - -static void SetLogPlot( AstPlot *this, int axis, int ival, int *status ){ -/* -* -* Name: -* SetLogPlot - -* Purpose: -* Set a new value for a LogPlot attribute - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void SetLogPlot( AstPlot *this, int axis, int ival, int *status ) - -* Class Membership: -* Plot member function - -* Description: -* Assigns a new value to the LogPlot attribute of the specified axis, -* and also re-maps the base Frame of the Plot if necessary. - -* Parameters: -* this -* The Plot. -* axis -* Zero based axis index. -* ival -* The new value for the ogPlot attribute. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - int oldval; /* Original attribute value */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Validate the axis index. */ - if( axis < 0 || axis >= 2 ){ - astError( AST__AXIIN, "astSetLogPlot(%s): Index (%d) is invalid for " - "attribute LogPlot - it should be in the range 1 to 2.", status, - astGetClass( this ), axis + 1 ); - -/* If the axis index is OK, store the original attribute value. We use - astGetLogPlot to get the value rather than directly accessing - "this->logplot" in order to get the any default value in the case of - no value having been set. */ - } else { - oldval = astGetLogPlot( this, axis ); - -/* If the current attribute value will change, attempt to re-map the plot - axis. If the attempt succeeds, toggle the current attribute value. */ - if( ( ival != 0 ) != ( oldval != 0 ) ){ - if( ToggleLogLin( this, axis, oldval, "astSetLogPlot", status ) ){ - this->logplot[ axis ] = ( !oldval ); - } - -/* If the current attribute value will not change, just store the supplied - value (this is not redundant because it may cause a previously defaulted - value to become an explicitly set value ). */ - } else { - this->logplot[ axis ] = oldval; - } - } -} - -static void SetTickValues( AstPlot *this, int axis, int nmajor, double *major, - int nminor, double *minor, int *status ){ -/* -*+ -* Name: -* astSetTickValues - -* Purpose: -* Store the tick mark values to use for a given Plot axis. - -* Type: -* Protected virtual function. - -* Synopsis: -* #include "plot.h" -* void astSetTickValues( AstPlot *this, int axis, int nmajor, -* double *major, int nminor, double *minor ) - -* Class Membership: -* Plot method. - -* Description: -* This function stores a set of tick mark values that should be used by -* subsequent calls to astGrid. - -* Parameters: -* this -* Pointer to a Plot. -* axis -* The zero-based index of the axis for which tick marks values -* have been supplied. -* nmajor -* The number of major tick mark values. If zero is supplied then -* the other parameters are ignored, and subsequent calls to -* astGrid will itself determine the tick values to be used. -* major -* Pointer to an array holding "nmajor" values for axis "axis" in -* the current Frame of the suppled Plot. Major tick marks will be -* drawn at these values. -* nminor -* The number of minor tick mark values. -* minor -* Pointer to an array holding "nminor" values for axis "axis" in -* the current Frame of the suppled Plot. Minor tick marks will be -* drawn at these values. - -*- -*/ - -/* Check the global status. */ - if( !astOK ) return; - -/* Report an error if the supplied axis value is incorrect. */ - if( axis < 0 || axis >= astGetNin( this ) ) { - astError( AST__INTER, "astSetTickValues(Plot): Supplied \"axis\" " - "value is %d - should in the range 0 to %d (internal AST " - "programming error).", status, axis, astGetNin( this ) - 1 ); - -/* Otherwise store or clear the values. */ - } else if( nmajor > 0 ){ - this->nmajtickval[ axis ] = nmajor; - this->majtickval[ axis ] = astStore( this->majtickval[ axis ], major, - sizeof( double )*nmajor ); - this->nmintickval[ axis ] = nminor; - this->mintickval[ axis ] = astStore( this->mintickval[ axis ], minor, - sizeof( double )*nminor ); - -/* Sort them into increasing order. */ - qsort( (void *) this->majtickval[ axis ], (size_t) nmajor, - sizeof(double), Compared ); - - qsort( (void *) this->mintickval[ axis ], (size_t) nminor, - sizeof(double), Compared ); - - } else { - this->nmajtickval[ axis ] = 0; - this->majtickval[ axis ] = astFree( this->majtickval[ axis ] ); - this->nmintickval[ axis ] = 0; - this->mintickval[ axis ] = astFree( this->mintickval[ axis ] ); - } -} - -const char *astStripEscapes_( const char *text, int *status ) { -/* -*++ -* Name: -c astStripEscapes -f AST_STRIPESCAPES - -* Purpose: -* Remove AST escape sequences from a string. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c const char *astStripEscapes( const char *text ) -f RESULT = AST_STRIPESCAPES( TEXT ) - -* Description: -* This function removes AST escape sequences from a supplied string, -* returning the resulting text as the function value. The behaviour -* of this function can be controlled by invoking the -c astEscapes function, -f AST_ESCAPES routine, -* which can be used to supress or enable the removal of escape -* sequences by this function. -* -* AST escape sequences are used by the Plot class to modify the -* appearance and position of sub-strings within a plotted text string. -* See the "Escape" attribute for further information. - -* Parameters: -c text -c Pointer to the string to be checked. -f TEXT -f The string to be checked. - -* Returned Value: -c astStripEscapes() -f AST_STRIPESCAPES = CHARACTER -c Pointer to the modified string. If no escape sequences were found -c in the supplied string, then a copy of the supplied pointer is -c returned. Otherwise, the pointer will point to a static buffer -c holding the modified text. This text will be over-written by -c subsequent invocations of this function. If the astEscapes function -f The modified string. If the AST_ESCAPES routine -* has been called indicating that escape sequences should not be -* stripped, then the supplied string is returned without change. - -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS - const char *a; - char *b; - int nc; - int ncc; - int type; - int value; - const char *result; - -/* Initialise */ - result= text; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check inherited status and supplied pointer. Also return if the - string contains no escape sequences or if stripping of escapes has - been supressed. */ - if( !astOK || astEscapes( -1 ) || !text || !HasEscapes( text, status ) ) return result; - -/* Initialise a pointer to the next character to be read from the - supplied string. */ - a = text; - -/* Initialise a pointer to the next character to be written to the - returned string. */ - b = stripescapes_buff; - -/* Note the available space left in the buffer. */ - ncc = AST__PLOT_STRIPESCAPES_BUFF_LEN; - -/* Loop until all the string has been read, or the buffer is full. */ - while( *a && ncc > 0 ){ - -/* If the remaining string starts with an escape sequence, increment the - read point by the length of the escape sequence, but leave the write - pointer where it is. */ - if( astFindEscape( a, &type, &value, &nc ) ) { - a += nc; - -/* If the remaining string does not start with an escape sequence, copy - the following text from the read position to the write position. */ - } else { - if( nc > ncc ) nc = ncc; - memcpy( b, a, sizeof( char )*nc ); - a += nc; - b += nc; - ncc -= nc; - } - } - -/* Terminate the returned string. */ - *b = 0; - -/* Return the result.*/ - return stripescapes_buff; -} - -static int swapEdges( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, int *status ) { -/* -* Name: -* swapEdges - -* Purpose: -* Determine if edges for text labels should be swapped. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int swapEdges( AstPlot *this, TickInfo **grid, AstPlotCurveData **cdata, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* or not it is necessary to swap the Edges(0) and Edges(1) attributes -* in order to place textual labels on appropriate edges. This should -* only be used if the attributes have not explicitly been set, and if -* interior labelling is being used. The sides are determines by -* looking at the bounding box of tick marks on axis 0, in graphics -* coordinates. The returned value causes the label for axis 0 to be -* placed on the edge parallel to the longest side of this bounding box. -* The label for axis 1 is placed parallel to the shortest side of this -* bounding box. - -* Parameters: -* this -* A pointer to the Plot. -* grid -* A pointer to an array of two TickInfo pointers (one for each axis), -* each pointing to a TickInfo structure holding information about -* tick marks on the axis. See function GridLines. -* cdata -* A pointer to an array of two AstPlotCurveData pointers (one for each axis), -* each pointing to an array of AstPlotCurveData structure (one for each -* major tick value on the axis), holding information about breaks -* in the curves drawn to mark the major tick values. See function -* DrawGrid. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if the edges should be swapped, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPlotCurveData *cdt; /* Pointer to the AstPlotCurveData for the next tick */ - TickInfo *info; /* Pointer to the TickInfo for the current axis */ - float xmax; /* Max graphics X value */ - float xmin; /* Min graphics X value */ - float ymax; /* Max graphics Y value */ - float ymin; /* Min graphics Y value */ - int oldedge; /* The original edge for axis 0 */ - int result; /* Swap edges? */ - int tick; /* Tick index */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get a pointer to the structure containing information describing the - positions of the major tick marks along axis 0. */ - info = grid[ 0 ]; - -/* Get a pointer to the structure containing information describing - the breaks in the curve which is parallel to axis 1 and passes - through the first major tick mark on axis 0. */ - cdt = cdata[ 0 ]; - -/* Initialise the graphiocs X and Y bounds of the area covered by the - axis. */ - xmax = -1.0E10; - xmin = 1.0E10; - ymax = -1.0E10; - ymin = 1.0E10; - -/* Loop round each of the major tick marks on axis 0. */ - for( tick = 0; cdt && info && tick < info->nmajor; tick++ ){ - -/* Update the max and min graphics X and Y coords covered by the axis. */ - if( cdt->nbrk > 0 ) { - xmax = astMAX( xmax, cdt->xbrk[0] ); - xmin = astMIN( xmin, cdt->xbrk[0] ); - ymax = astMAX( ymax, cdt->ybrk[0] ); - ymin = astMIN( ymin, cdt->ybrk[0] ); - } - -/* Get a pointer to the curve through the next major tick mark. */ - cdt++; - - } - -/* See which edge axis 0 would normally be labelled on. */ - oldedge = astGetEdge( this, 0 ); - -/* If the X range is larger than the Y range, the textual label should be - placed on the bottom edge. If required, indicate that the edges must - be swapped to achieve this. */ - if( xmax - xmin > ymax - ymin ) { - if( oldedge == 0 || oldedge == 2 ) result = 1; - -/* If the X range is smaller than the Y range, the textual label should be - placed on the left edge. If required, indicate that the edges must - be swapped to achieve this. */ - } else { - if( oldedge == 1 || oldedge == 3 ) result = 1; - } - - return result; -} - -static int TestAttrib( AstObject *this_object, const char *attrib, int *status ) { -/* -* Name: -* TestAttrib - -* Purpose: -* Test if a specified attribute value is set for a Plot. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestAttrib( AstObject *this, const char *attrib, int *status ) - -* Class Membership: -* Plot member function (over-rides the astTestAttrib protected -* method inherited from the FrameSet class). - -* Description: -* This function returns a boolean result (0 or 1) to indicate whether -* a value has been set for one of a Plot's attributes. - -* Parameters: -* this -* Pointer to the Plot. -* attrib -* Pointer to a null terminated string specifying the attribute -* name. This should be in lower case with no surrounding white -* space. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* One if a value has been set, otherwise zero. - -* Notes: -* - A value of zero will be returned if this function is invoked -* with the global status set, or if it should fail for any reason. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char label[21]; /* Graphics item label */ - int axis; /* Axis number */ - int len; /* Length of attrib string */ - int nax; /* Number of base Frame axes */ - int nc; /* No. characters read by astSscanf */ - int result; /* Result value to return */ - -/* Initialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of base Frame axis (2 for a Plot, 3 for a Plot3D). */ - nax = astGetNin( this ); - -/* Obtain the length of the attrib string. */ - len = strlen( attrib ); - -/* Check the attribute name and test the appropriate attribute. */ - -/* Tol. */ -/* ---- */ - if ( !strcmp( attrib, "tol" ) ) { - result = astTestTol( this ); - -/* Edge(axis). */ -/* ----------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "edge(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestEdge( this, axis - 1 ); - -/* Grid. */ -/* ----- */ - } else if ( !strcmp( attrib, "grid" ) ) { - result = astTestGrid( this ); - -/* TickAll. */ -/* -------- */ - } else if ( !strcmp( attrib, "tickall" ) ) { - result = astTestTickAll( this ); - -/* ForceExterior */ -/* ------------- */ - } else if ( !strcmp( attrib, "forceexterior" ) ) { - result = astTestForceExterior( this ); - -/* Invisible. */ -/* ---------- */ - } else if ( !strcmp( attrib, "invisible" ) ) { - result = astTestInvisible( this ); - -/* Border. */ -/* ------- */ - } else if ( !strcmp( attrib, "border" ) ) { - result = astTestBorder( this ); - -/* ClipOp. */ -/* ------- */ - } else if ( !strcmp( attrib, "clipop" ) ) { - result = astTestClipOp( this ); - -/* Clip. */ -/* ----- */ - } else if ( !strcmp( attrib, "clip" ) ) { - result = astTestClip( this ); - -/* Grf. */ -/* ---- */ - } else if ( !strcmp( attrib, "grf" ) ) { - result = astTestGrf( this ); - -/* DrawTitle. */ -/* ---------- */ - } else if ( !strcmp( attrib, "drawtitle" ) ) { - result = astTestDrawTitle( this ); - -/* DrawAxes. */ -/* --------- */ - } else if ( !strcmp( attrib, "drawaxes" ) ) { - result = astTestDrawAxes( this, 0 ); - -/* DrawAxes(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "drawaxes(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestDrawAxes( this, axis - 1 ); - -/* Abbrev. */ -/* --------- */ - } else if ( !strcmp( attrib, "abbrev" ) ) { - result = astTestAbbrev( this, 0 ); - -/* Abbrev(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "abbrev(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestAbbrev( this, axis - 1 ); - -/* Escape. */ -/* ------- */ - } else if ( !strcmp( attrib, "escape" ) ) { - result = astTestEscape( this ); - -/* Gap. */ -/* ---- */ - } else if ( !strcmp( attrib, "gap" ) ) { - result = astTestGap( this, 0 ); - -/* Gap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "gap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestGap( this, axis - 1 ); - -/* LabelAt(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelat(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLabelAt( this, axis - 1 ); - -/* LogGap. */ -/* ---- */ - } else if ( !strcmp( attrib, "loggap" ) ) { - result = astTestLogGap( this, 0 ); - -/* LogGap(axis). */ -/* ---------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loggap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogGap( this, axis - 1 ); - -/* NumLabGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "numlabgap" ) ) { - result = astTestNumLabGap( this, 0 ); - -/* NumLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestNumLabGap( this, axis - 1 ); - -/* TextLabGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "textlabgap" ) ) { - result = astTestTextLabGap( this, 0 ); - -/* TextLabGap(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlabgap(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestTextLabGap( this, axis - 1 ); - -/* LabelUp. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelup" ) ) { - result = astTestLabelUp( this, 0 ); - -/* LabelUp(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelup(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLabelUp( this, axis - 1 ); - -/* LogPlot. */ -/* -------- */ - } else if ( !strcmp( attrib, "logplot" ) ) { - result = astTestLogPlot( this, 0 ); - -/* LogPlot(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logplot(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogPlot( this, axis - 1 ); - -/* LogTicks. */ -/* -------- */ - } else if ( !strcmp( attrib, "logticks" ) ) { - result = astTestLogTicks( this, 0 ); - -/* LogTicks(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "logticks(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogTicks( this, axis - 1 ); - -/* LogLabel. */ -/* -------- */ - } else if ( !strcmp( attrib, "loglabel" ) ) { - result = astTestLogLabel( this, 0 ); - -/* LogLabel(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "loglabel(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLogLabel( this, axis - 1 ); - -/* NumLab. */ -/* -------- */ - } else if ( !strcmp( attrib, "numlab" ) ) { - result = astTestNumLab( this, 0 ); - -/* NumLab(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "numlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestNumLab( this, axis - 1 ); - -/* MinTick. */ -/* -------- */ - } else if ( !strcmp( attrib, "mintick" ) ) { - result = astTestMinTick( this, 0 ); - -/* MinTick(axis). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "mintick(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestMinTick( this, axis - 1 ); - -/* TextLab. */ -/* ---------- */ - } else if ( !strcmp( attrib, "textlab" ) ) { - result = astTestTextLab( this, 0 ); - -/* TextLab(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "textlab(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestTextLab( this, axis - 1 ); - -/* LabelUnits. */ -/* --------- */ - } else if ( !strcmp( attrib, "labelunits" ) ) { - result = astTestLabelUnits( this, 0 ); - -/* LabelUnits(axis). */ -/* --------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "labelunits(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestLabelUnits( this, axis - 1 ); - -/* Style. */ -/* ------ */ - } else if ( !strcmp( attrib, "style" ) ) { - result = TestUseStyle( this, AST__BORDER_ID, status ); - -/* Style(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "style(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseStyle( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Font. */ -/* ----- */ - } else if ( !strcmp( attrib, "font" ) ) { - result = TestUseFont( this, AST__TEXTLABS_ID, status ); - -/* Font(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "font(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseFont( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Colour. */ -/* ------- */ - } else if ( !strcmp( attrib, "colour" ) ) { - result = TestUseColour( this, AST__TEXTLABS_ID, status ); - -/* Color. */ -/* ------- */ - } else if ( !strcmp( attrib, "color" ) ) { - result = TestUseColour( this, AST__TEXTLABS_ID, status ); - -/* Colour(label). */ -/* -------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "colour(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseColour( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Color(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "color(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseColour( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Width. */ -/* ------ */ - } else if ( !strcmp( attrib, "width" ) ) { - result = TestUseWidth( this, AST__BORDER_ID, status ); - -/* Width(label). */ -/* ------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "width(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseWidth( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* Size. */ -/* ----- */ - } else if ( !strcmp( attrib, "size" ) ) { - result = TestUseSize( this, AST__TEXTLABS_ID, status ); - -/* Size(label). */ -/* ------------ */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "size(%20[^()])%n", label, &nc ) ) - && ( nc >= len ) ) { - result = TestUseSize( this, FullForm( GrfLabels, label, attrib, "astTest", astGetClass( this ), status ), status ); - -/* TitleGap. */ -/* --------- */ - } else if ( !strcmp( attrib, "titlegap" ) ) { - result = astTestTitleGap( this ); - -/* MajTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "majticklen" ) ) { - result = astTestMajTickLen( this, 0 ); - -/* MajTickLen(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "majticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestMajTickLen( this, axis - 1 ); - -/* MinTickLen. */ -/* ----------- */ - } else if ( !strcmp( attrib, "minticklen" ) ) { - result = astTestMinTickLen( this, 0 ); - -/* MinTickLen(axis). */ -/* ---------------- */ - } else if ( nc = 0, - ( 1 == astSscanf( attrib, "minticklen(%d)%n", &axis, &nc ) ) - && ( nc >= len ) ) { - result = astTestMinTickLen( this, axis - 1 ); - -/* Labelling. */ -/* -------- */ - } else if ( !strcmp( attrib, "labelling" ) ) { - result = astTestLabelling( this ); - -/* If the attribute is still not recognised, pass it on to the parent - method for further interpretation. */ - } else { - result = (*parent_testattrib)( this_object, attrib, status ); - } - -/* Return the result, */ - return result; -} - -static void Text( AstPlot *this, const char *text, const double pos[], - const float up[], const char *just, int *status ){ -/* -*++ -* Name: -c astText -f AST_TEXT - -* Purpose: -* Draw a text string for a Plot. - -* Type: -* Public virtual function. - -* Synopsis: -c #include "plot.h" -c void astText( AstPlot *this, const char *text, const double pos[], -c const float up[], const char *just ) -f CALL AST_TEXT( THIS, TEXT, POS, UP, JUST, STATUS ) - -* Class Membership: -* Plot method. - -* Description: -* This function draws a string of text at a position specified in -* the physical coordinate system of a Plot. The physical position -* is transformed into graphical coordinates to determine where the -* text should appear within the plotting area. - -* Parameters: -c this -f THIS = INTEGER (Given) -* Pointer to the Plot. -c text -f TEXT = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string containing the -f A character string containing the -* text to be drawn. Trailing white space is ignored. -c pos -f POS( * ) = DOUBLE PRECISION (Given) -* An array, with one element for each axis of the Plot, giving -* the physical coordinates of the point where the reference -* position of the text string is to be placed. -c up -f UP( * ) = REAL (Given) -* An array holding the components of a vector in the "up" -* direction of the text (in graphical coordinates). For -c example, to get horizontal text, the vector {0.0f,1.0f} should -f example, to get horizontal text, the vector [0.0,1.0] should -* be supplied. For a basic Plot, 2 values should be supplied. For -* a Plot3D, 3 values should be supplied, and the actual up vector -* used is the projection of the supplied up vector onto the text plane -* specified by the current value of the Plot3D's Norm attribute. -c just -f JUST = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated character string identifying the -f A character string identifying the -* reference point for the text being drawn. The first character in -* this string identifies the reference position in the "up" direction -* and may be "B" (baseline), "C" (centre), "T" (top) or "M" (bottom). -* The second character identifies the side-to-side reference position -* and may be "L" (left), "C" (centre) or "R" (right ). The string is -* case-insensitive, and only the first two characters are significant. -* -* For example, a value of "BL" means that the left end of the -* baseline of the original (un-rotated) text is to be drawn at the -c position given by "pos". -f position given by POS. - -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Notes: -* - The Plot3D class currently does not interpret graphical escape -* sequences contained within text displayed using this method. -* - Text is not drawn at positions which have any coordinate equal -* to the value AST__BAD (or where the transformation into -* graphical coordinates yields coordinates containing the value -* AST__BAD). -c - If the plotting position is clipped (see astClip), then no -f - If the plotting position is clipped (see AST_CLIP), then no -* text is drawn. -* - An error results if the base Frame of the Plot is not -* 2-dimensional or (for a Plot3D) 3-dimensional. -* - An error also results if the transformation between the -* current and base Frames of the Plot is not defined (i.e. the -* Plot's TranInverse attribute is zero). -*-- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstMapping *mapping; /* Pointer to graphics->physical mapping */ - AstPointSet *pset1; /* PointSet holding physical positions */ - AstPointSet *pset2; /* PointSet holding graphics positions */ - const char *class; /* Object class */ - const char *method; /* Current method */ - const double **ptr1; /* Pointer to physical positions */ - char ljust[3]; /* Upper case copy of "just" */ - char *ltext; /* Local copy of "text" excluding trailing spaces */ - double **ptr2; /* Pointer to graphics positions */ - float xbn[ 4 ]; /* X coords of text bounding box. */ - float ybn[ 4 ]; /* Y coord of text bounding box. */ - int axis; /* Axis index */ - int escs; /* Original astEscapes value */ - int naxes; /* No. of axes in the base Frame */ - int ncoord; /* No. of axes in the current Frame */ - int ulen; /* Length of "text" excluding trailing spaces */ - -/* Check the global error status. */ - if ( !astOK || !text ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Store the current method and class for inclusion in error messages - generated by lower level functions. */ - method = "astText"; - class = astClass( this ); - -/* Check the base Frame of the Plot is 2-D. */ - naxes = astGetNin( this ); - if( naxes != 2 && astOK ){ - astError( AST__NAXIN, "%s(%s): Number of axes (%d) in the base " - "Frame of the supplied %s is invalid - this number should " - "be 2.", status, method, class, naxes, class ); - } - -/* Ensure AST functions included graphical escape sequences in any - returned text strings. */ - escs = astEscapes( 1 ); - -/* Initialise the bounding box for primatives produced by this call. */ - if( !Boxp_freeze ) { - Boxp_lbnd[ 0 ] = FLT_MAX; - Boxp_lbnd[ 1 ] = FLT_MAX; - Boxp_ubnd[ 0 ] = FLT_MIN; - Boxp_ubnd[ 1 ] = FLT_MIN; - } - -/* Indicate that the GRF module should re-calculate it's cached values - (in case the state of the graphics system has changed since the last - thing was drawn). */ - RESET_GRF; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__TEXT_ID, 1, GRF__TEXT, method, class ); - -/* Get the number of coordinates in the physical coordinate frame. */ - ncoord = astGetNout( this ); - -/* Create a PointSet to hold the supplied physical coordinates. */ - pset1 = astPointSet( 1, ncoord, "", status ); - -/* Allocate memory to hold pointers to the first value on each axis. */ - ptr1 = (const double **) astMalloc( sizeof( const double * )* - (size_t)( ncoord )); - -/* Check the pointer can be used, then store pointers to the first value - on each axis. */ - if( astOK ){ - for( axis = 0; axis < ncoord; axis++ ){ - ptr1[ axis ] = pos + axis; - } - } - -/* Store these pointers in the PointSet. */ - astSetPoints( pset1, (double **) ptr1 ); - -/* Transform the supplied data from the current frame (i.e. physical - coordinates) to the base frame (i.e. graphics coordinates) using - the inverse Mapping defined by the Plot. */ - mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - pset2 = Trans( this, NULL, mapping, pset1, 0, NULL, 0, method, class, status ); - mapping = astAnnul( mapping ); - -/* Get pointers to the graphics coordinates. */ - ptr2 = astGetPoints( pset2 ); - -/* Take a copy of the string excluding any trailing white space. */ - ulen = ChrLen( text, status ); - ltext = (char *) astStore( NULL, (void *) text, ulen + 1 ); - -/* Check the pointers can be used. */ - if( astOK ){ - -/* Terminate the local copy of the text string. */ - ltext[ ulen ] = 0; - -/* Produce an upper-case copy of the first two characters in "just". */ - ljust[0] = (char) toupper( (int) just[0] ); - ljust[1] = (char) toupper( (int) just[1] ); - ljust[2] = 0; - -/* Convert the double precision values to single precision, checking for - bad positions. */ - if( ptr2[0][0] != AST__BAD && ptr2[1][0] != AST__BAD ){ - -/* Draw the text string. */ - DrawText( this, 1, astGetEscape( this ), ltext, (float) ptr2[0][0], - (float) ptr2[1][0], ljust, up[ 0 ], up[ 1 ], xbn, ybn, - NULL, method, class, status ); - } - -/* Free the local copy of the string. */ - ltext = (char *) astFree( (void *) ltext ); - - } - -/* Annul the PointSets. */ - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Free the memory holding the pointers to the first value on each axis. */ - ptr1 = (const double **) astFree( (void *) ptr1 ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__TEXT_ID, 0, GRF__TEXT, method, class ); - -/* Restore the original value of the flag which says whether graphical - escape sequences should be incldued in any returned text strings. */ - astEscapes( escs ); - -/* Return */ - return; -} - -static void TextLabels( AstPlot *this, int edgeticks, int dounits[2], - const char *method, const char *class, int *status ){ -/* -* -* Name: -* TextLabels - -* Purpose: -* Draw textual labels round a grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void TextLabels( AstPlot *this, int edgeticks, int dounits[2], -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function displays a textual label for each physical axis, and a -* title. The text strings are obtained from the Label and Title -* attributes of the current Frame in the Plot. - -* Parameters: -* this -* A pointer to the Plot. -* edgeticks -* If tick marks and numerical labels were drawn around the edges -* of the plotting area, this should be supplied as 1. Otherwise it -* should be supplied as zero. -* dounits -* Flags indicating if the axis Units string should be included in -* the edge labels. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - char *new_text; /* Pointer to complete text string (inc. units) */ - char *just; /* Pointer to axis label justification string */ - const char *text; /* Pointer to text string to be displayed */ - const char *units; /* Pointer to text string describing the units */ - double mindim; /* Minimum dimension of plotting area */ - double xrange; /* Width of plotting area */ - double yrange; /* Height of plotting area */ - float txtgap; /* Gap between bounding box and text string */ - float upx; /* X component of text up-vector */ - float upy; /* Y component of text up-vector */ - float xbn[ 4 ]; /* X coords at corners of new label's bounding box */ - float ybn[ 4 ]; /* Y coords at corners of new label's bounding box */ - float xref; /* Graphics X coord. at text ref. position */ - float yref; /* Graphics Y coord. at text ref. position */ - float xlo, xhi, ylo, yhi;/* The original bounding box (excluding labels) */ - int axis; /* Axis index */ - int draw; /* Should label be drawn? */ - int edge; /* Edge to be labelled */ - int esc; /* Interpret escape sequences? */ - int gelid; /* ID for next graphical element to be drawn */ - int tlen; /* No. of characetsr in label */ - int ulen; /* No. of characetsr in units */ - -/* Check the global status. */ - if( !astOK ) return; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(this); - -/* Get the minimum dimension of the plotting area. */ - xrange = this->xhi - this->xlo; - yrange = this->yhi - this->ylo; - mindim = astMIN( xrange, yrange ); - -/* Take a copy of the bounding box which encloses all other parts of the - annotated grid. If nothing has been plotted, use an area 20 % smaller - than the plotting area. */ - if( Box_lbnd[ 0 ] != FLT_MAX ) { - xlo = Box_lbnd[ 0 ]; - xhi = Box_ubnd[ 0 ]; - ylo = Box_lbnd[ 1 ]; - yhi = Box_ubnd[ 1 ]; - } else { - xlo = this->xlo + 0.2*xrange; - xhi = this->xhi - 0.2*xrange; - ylo = this->ylo + 0.2*yrange; - yhi = this->yhi - 0.2*yrange; - } - -/* See if escape sequences are to be interpreted within the labels. */ - esc = astGetEscape( this ); - -/* Initialize the id value for graphical element being drawn. */ - gelid = AST__TEXTLAB1_ID; - -/* Now write a label for each physical axis. */ - for( axis = 0; axis < 2 && astOK; axis++ ){ - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, gelid, 1, GRF__TEXT, method, class ); - -/* See if the label is to be drawn. If an explicit value has not been set - for the TextLab attribute, the default is to draw the label if tick - marks were draw round the edge of the plotting area, and not to - otherwise. */ - if( astTestTextLab( this, axis ) ){ - draw = astGetTextLab( this, axis ); - } else { - draw = edgeticks; - } - -/* If so get the label. */ - if( draw ){ - text = astGetLabel( this, axis ); - tlen = ChrLen( text, status ); - -/* If required, get the units string and concatenate it with the label (inside - parenthesise). Ignore trailing spaces. */ - if( dounits[ axis ] ){ - units = astGetUnit( this, axis ); - if( units && units[0] ){ - ulen = ChrLen( units, status ); - new_text = astMalloc( tlen + ulen + 4 ); - if( new_text ) memcpy( new_text, text, tlen ); - - text = new_text + tlen; - - memcpy( (void *) text, " (", 2 ); - text += 2; - - memcpy( (char *) text, units, ulen ); - text += ulen; - - memcpy( (char *) text, ")", 1 ); - text += 1; - - ( (char *) text )[0] = 0; - - text = new_text; - - } else { - new_text = astStore( NULL, (void *) text, tlen + 1 ); - new_text[ tlen ] = 0; - text = new_text; - units = NULL; - } - - } else { - new_text = astStore( NULL, (void *) text, tlen + 1 ); - new_text[ tlen ] = 0; - text = new_text; - units = NULL; - } - -/* Get the gap between the edge of the bounding box and the closest edge - of the text string. */ - txtgap = (float)( mindim*astGetTextLabGap( this, axis ) ); - -/* Get the edge to be labelled. Edge 0 is the left hand edge. Edge 1 is the - top edge. Edge 2 is the right-hand edge. Edge 3 is the bottom edge. */ - edge = astGetEdge( this, axis ) % 4; - if( edge < 0 ) edge = -edge; - -/* If the label is to be put on the left hand edge... */ - if( edge == 0 ){ - -/* Set the up vector so that the text is written from bottom to top. */ - upx = -1.0; - upy = 0.0; - -/* Justify the bottom of the whole bounding box (not just the text - base-line). */ - just = "MC"; - -/* Set the x reference position just outside the box enclosing all the - graphics drawn so far. The reference point refers to the centre of the - text string in both directions ("CC" justification). Take account of - whether or not the x axis is reversed. Do not allow the text to be - written outside the whole plotting surface. */ - if( this->xrev ){ - xref = xhi + txtgap; - } else { - xref = xlo - txtgap; - } - -/* The Y reference position is at the mid point vertically. */ - yref = 0.5*( astMIN( yhi, this->yhi ) + - astMAX( ylo, this->ylo ) ); - -/* Do the same for the top edge. */ - } else if( edge == 1 ){ - upx = 0.0; - upy = 1.0; - just = "MC"; - if( this->yrev ){ - yref = ylo - txtgap; - } else { - yref = yhi + txtgap; - } - xref = 0.5*( astMIN( xhi, this->xhi ) + - astMAX( xlo, this->xlo ) ); - -/* Do the same for the right-hand edge. */ - } else if( edge == 2 ){ - upx = 1.0; - upy = 0.0; - just = "MC"; - if( this->xrev ){ - xref = xlo - txtgap; - } else { - xref = xhi + txtgap; - } - yref = 0.5*( astMIN( yhi, this->yhi ) + - astMAX( ylo, this->ylo ) ); - -/* Do the same for the bottom edge. */ - } else { - upx = 0.0; - upy = 1.0; - just = "TC"; - if( this->yrev ){ - yref = yhi + txtgap; - } else { - yref = ylo - txtgap; - } - xref = 0.5*( astMIN( xhi, this->xhi ) + - astMAX( xlo, this->xlo ) ); - } - -/* Display the label. */ - DrawText( this, 1, esc, text, xref, yref, just, - upx, upy, xbn, ybn, NULL, method, class, status ); - -/* Release the memory allocated to store the axis label;. */ - new_text = (char *) astFree( (void *) new_text ); - text = NULL; - - } - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, gelid, 0, GRF__TEXT, method, class ); - -/* Set up the id for the next graphical element to be drawn. */ - gelid = AST__TEXTLAB2_ID; - - } - -/* See if the title is to be drawn. */ - if( astOK && astGetDrawTitle( this ) ){ - -/* If so get the title. */ - text = astGetTitle( this ); - -/* Create a copy from which trailing spaces have been removed. */ - tlen = ChrLen( text, status ); - new_text = (char *) astStore( NULL, (void *) text, tlen + 1 ); - new_text[ tlen ] = 0; - text = new_text; - -/* Establish the correct graphical attributes as defined by attributes - with the supplied Plot. */ - astGrfAttrs( this, AST__TITLE_ID, 1, GRF__TEXT, method, class ); - -/* Take a copy of the bounding box which encloses all other parts of the - annotated grid (this may have been extended by the above code). If - nothing has been plotted, use an area 20 % smaller than the plotting - area. */ - if( Box_lbnd[ 0 ] != FLT_MAX ) { - xlo = Box_lbnd[ 0 ]; - xhi = Box_ubnd[ 0 ]; - ylo = Box_lbnd[ 1 ]; - yhi = Box_ubnd[ 1 ]; - } else { - xlo = this->xlo + 0.2*xrange; - xhi = this->xhi - 0.2*xrange; - ylo = this->ylo + 0.2*yrange; - yhi = this->yhi - 0.2*yrange; - } - -/* Get the graphics coordinates of the bottom centre point of the title. - The X centre is put at the mid point of the used x axis range - (restricted to the range of the plotting area). */ - xref = 0.5*( astMIN( xhi, this->xhi ) + - astMAX( xlo, this->xlo ) ); - -/* The Y centre is put a "TitleGap" distance outside the box containing - the everything else. */ - if( this->yrev ){ - yref = ylo - (float)( mindim*astGetTitleGap( this ) ); - } else { - yref = yhi + (float)( mindim*astGetTitleGap( this ) ); - } - -/* Display the title. Justify the bottom of the whole bounding box (not - just the text base-line). */ - DrawText( this, 1, esc, text, xref, yref, "MC", 0.0F, 1.0F, - xbn, ybn, NULL, method, class, status ); - -/* Re-establish the original graphical attributes. */ - astGrfAttrs( this, AST__TITLE_ID, 0, GRF__TEXT, method, class ); - -/* Release the memory allocated to store the title. */ - new_text = (char *) astFree( (void *) new_text ); - text = NULL; - } - -/* Include the labels in the bounding box held in global variables - Box_lbnd/ubnd. */ - if( Box_lbnd[ 0 ] != FLT_MAX ) { - Box_lbnd[ 0 ] = astMIN( Box_lbnd[ 0 ], Boxp_lbnd[ 0 ] ); - Box_ubnd[ 0 ] = astMAX( Box_ubnd[ 0 ], Boxp_ubnd[ 0 ] ); - Box_lbnd[ 1 ] = astMIN( Box_lbnd[ 1 ], Boxp_lbnd[ 1 ] ); - Box_ubnd[ 1 ] = astMAX( Box_ubnd[ 1 ], Boxp_ubnd[ 1 ] ); - } else { - Box_lbnd[ 0 ] = Boxp_lbnd[ 0 ]; - Box_ubnd[ 0 ] = Boxp_ubnd[ 0 ]; - Box_lbnd[ 1 ] = Boxp_lbnd[ 1 ]; - Box_ubnd[ 1 ] = Boxp_ubnd[ 1 ]; - } - -/* Return. */ - return; - -} - -static void UpdateConcat( float *xbn, float *ybn, float ux, float uy, - float rx, float ry, float *x, float *y, - float x0, float y0, float *alpha_lo, - float *alpha_hi, float *beta_lo, float *beta_hi, - int *status ){ - -/* -* Name: -* UpdateConcat - -* Purpose: -* Update the concatenation point for a text string in preparation for -* appending another string. - -* Synopsis: -* #include "plot.h" -* void UpdateConcat( float *xbn, float *ybn, float ux, float uy, -* float rx, float ry, float *x, float *y, -* float x0, float y0, float *alpha_lo, float *alpha_hi, -* float *beta_lo, float *beta_hi, int *status ) - -* Description: -* This function modifies the supplied concatenation point (x,y) by moving -* it to the right along the baseline of the text by an amount equal -* to the width of the supplied sub-string bounding box. It also updates -* the supplied total bounding box so that it includes the supplied -* sub-string bounding box. - -* Parameters: -* xbn -* Pointer to an array holding the x coord at the four corners of -* the sub-string bounding box. -* ybn -* Pointer to an array holding the y coord at the four corners of -* the sub-string bounding box. -* ux -* The x component of the up-vector for the text, in graphics coords. -* The length of this vector should be equal to the height of normal -* text drawn with this up-vector. -* uy -* The y component of the up-vector for the text. See "ux". -* rx -* The x component of the right-vector for the text. The length of this -* vector should be equal to the height of normal text drawn with the -* supplied up-vector. -* ry -* The y component of the right-vector for the text. see "rx". -* x -* Pointer to a float holding the x coord of the concatenation point -* of the text just drawn. This is changed on exit so that the next -* string will be appended to the end of the text just drawn. -* y -* Pointer to a float holding the y coord of the concatenation point -* of the text just drawn. This is changed on exit so that the next -* string will be appended to the end of the text just drawn. -* x0 -* The X coord at the left end of the baseline of the total string. -* y0 -* The Y coord at the left end of the baseline of the total string. -* alpha_lo -* Pointer to a double holding a value which gives the position of the -* bottom edge of the total bounding box. The value is such that -* (x0,y0) + alpha_lo*(ux,uy) is a point on the bottom edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* alpha_hi -* Pointer to a double holding a value which gives the position of the -* top edge of the total bounding box. The value is such that -* (x0,y0) + alpha_hi*(ux,uy) is a point on the top edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* beta_lo -* Pointer to a double holding a value which gives the position of the -* left edge of the total bounding box. The value is such that -* (x0,y0) + beta_lo*(rx,ry) is a point on the left edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* beta_hi -* Pointer to a double holding a value which gives the position of the -* right edge of the total bounding box. The value is such that -* (x0,y0) + beta_hi*(rx,ry) is a point on the right edge of the -* total bounding box. The returned value is updated so that the -* total bounding box includes the supplied sub-string bounding box. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - float ahi; - float alo; - float alpha; - float beta; - float bhi; - float blo; - float denom; - float dx; - float dy; - float xc; - float yc; - int ic; - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Check the supplied up and right vectors are not parallel. */ - denom = ux*ry - uy*rx; - if( denom != 0.0 ) { - -/* Get the coords at the centre of the sub-string bounding box. */ - xc = ( xbn[ 0 ] + xbn[ 1 ] + xbn[ 2 ] + xbn[ 3 ] )/4.0; - yc = ( ybn[ 0 ] + ybn[ 1 ] + ybn[ 2 ] + ybn[ 3 ] )/4.0; - -/* For each of the 4 corners of the sub-string bounding box, we consider the - vector from the centre of the bounding box to the corner. We want to express - this vector, vx, as a sum of a vector in the up direction and a vector - in the right direction: - - vx = alpha*ux + beta+rx - vy = alpha*uy + beta+ry - - where alpha and beta are constants which are different for each - corner vector. We also want to find the minimum and maximum alpha and - beta covered by the box. First initialise the limits. */ - alo = 0.0; - ahi = 0.0; - blo = 0.0; - bhi = 0.0; - -/* Now find alpha and beta for each of the four corners. */ - for( ic = 0; ic < 4; ic++ ) { - dx = xbn[ ic ] - xc; - dy = ybn[ ic ] - yc; - alpha = ( dx*ry - dy*rx ) /denom; - beta = ( dy*ux - dx*uy ) /denom; - -/* Extend the bounds in alpha and beta. */ - if( alpha < alo ) alo = alpha; - if( alpha > ahi ) ahi = alpha; - if( beta < blo ) blo = beta; - if( beta > bhi ) bhi = beta; - -/* The bottom left corner has negative values for both alpha and beta. - Commence the process of updating the concatenation point by subtracting - off the coordinates at the bottom left corner. For zero height bounding - boxes (such as may be produced if the text is completely blank), the - "alpha" value should be zero, but may be slightly non-zero due to - rounding errors. Allow for this (assuming non-blank text will always - produce a boundiong box that is at least 1.0E-4 of the up vector in - height). We do the same for bounding box width (although zero width - boxes will probably not occur). */ - if( alpha < 1.0E-4 ) { - if( beta < 1.0E-4 ) { - *x -= xbn[ ic ]; - *y -= ybn[ ic ]; - -/* The bottom right corner has negative alpha and positive beta. Complete - the process of updating the concatenation point by adding on the - coordinates at the bottom right corner. */ - } else if( beta > -1.0E-4 ) { - *x += xbn[ ic ]; - *y += ybn[ ic ]; - } - } - } - -/* Also express the vector from (x0,y0) to (xc,yc) as a sum of a vector - in the up direction and a vector in the right direction: - - xc - x0 = alpha*ux + beta*rx - yc - y0 = alpha*uy + beta*ry - - Find alpha and beta. */ - - dx = xc - x0; - dy = yc - y0; - alpha = ( dx*ry - dy*rx ) /denom; - beta = ( dy*ux - dx*uy ) /denom; - -/* We can now express the vector from (x0,y0) to each of the 4 corners as - a sum of alpha*up and beta*right. Form the bounds of the sub-string in - terms of up-vectors and right vectors from (x0,y0) instead of from the - centre of the box. */ - alo += alpha; - ahi += alpha; - blo += beta; - bhi += beta; - -/* Extend the supplied alpha and beta bounding box to include these limits. */ - if( alo < *alpha_lo ) *alpha_lo = alo; - if( ahi > *alpha_hi ) *alpha_hi = ahi; - if( blo < *beta_lo ) *beta_lo = blo; - if( bhi > *beta_hi ) *beta_hi = bhi; - } -} - -static void Ticker( AstPlot *this, int edge, int axis, double value, - double *gap, double tklen, int majtick, int save, - EdgeCrossingsStatics **pstatics, const char *method, - const char *class, int *status ){ -/* -* -* Name: -* Ticker - -* Purpose: -* Draw edge tick marks for a given axis value. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* void Ticker( AstPlot *this, int edge, int axis, double value, -* double *gap, double tklen, int majtick, int save, -* EdgeCrossingsStatics **pstatics, const char *method, -* const char *class, int *status ){ - -* Class Membership: -* Plot member function. - -* Description: -* This function draws tick marks at all occurences of a given -* physical axis value on a given edge of the plotting area. - -* Parameters: -* this -* A pointer to the Plot. -* edge -* The edge of the plotting area to be ticked. Edge 0 is the left hand -* edge. Edge 1 is the top edge. Edge 2 is the right-hand edge. Edge 3 -* is the bottom edge. -* axis -* The index of the axis to which "value" refers. The tick mark extends -* parallel to this axis. -* value -* The physical axis value at which to place the tick mark. -* gap -* Pointer to array of two values holding the gap between major -* tick marks on the two axes. -* tklen -* The length of the tick, in graphics units. -* majtick -* Non-zero if the tick mark being drawn is a major tick, and zero -* if it is a minor tick. -* save -* If non-zero, the tick mark position will be saved in the Plot structure. -* pstatics -* Address of a pointer to a structure holding values for variables -* which were statically defined within this function prior to the -* thread-safe version of AST. If the pointer is supplied as NULL, -* then a new structure is allocated and initialised. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - double *cross; /* Pointer to crossings information */ - double *vx; /* Pointer to next X vector component value */ - double *vy; /* Pointer to next Y vector component value */ - double *x; /* Pointer to next X value */ - double *y; /* Pointer to next Y value */ - double xe; /* X at tick end */ - double ye; /* Y at tick end */ - int j; /* Crossing index */ - int ncross; /* No. of crossings of tick value and edge */ - -/* Check the global status. */ - if( !astOK ) return; - -/* See where the current major tick value crosses the edge. */ - ncross = EdgeCrossings( this, edge, axis, value, gap, &cross, pstatics, - method, class, status ); - -/* Do nothing if the supplied axis value does not occur on the specified - edge of the plotting area. */ - if( ncross ){ - -/* Draw major tick marks at the crossings. */ - x = cross; - y = cross + 1; - vx = cross + 2; - vy = cross + 3; - -/* Draw a tick mark at each occurence of the axis value on the specified - edge. */ - for( j = 0; j < ncross; j++ ){ - -/* Check the tick mark position and directionm are defined. */ - if( *vx != AST__BAD && *vy != AST__BAD && - *x != AST__BAD && *y != AST__BAD ){ - -/* Ensure the tick mark will point into the plotting area, no matter which - edge it is on. First ensure the direction vector refers to a system in - which X increases to the left and Y increases upwards. */ - if( this->xrev ) *vx = -*vx; - if( this->yrev ) *vy = -*vy; - -/* If necessary reverse the vector so that it points into the plotting - area. How to do this depends on which edge is being ticked. */ - if( ( edge == 0 && *vx < 0.0 ) || /* left-hand edge */ - ( edge == 1 && *vy > 0.0 ) || /* Top edge */ - ( edge == 2 && *vx > 0.0 ) || /* Right-hand edge */ - ( edge == 3 && *vy < 0.0 ) ){ /* Bottom edge */ - - *vx = -*vx; - *vy = -*vy; - } - -/* Now ensure the direction vector refers to a the native graphics system - taking account of any reversal of axes. */ - if( this->xrev ) *vx = -*vx; - if( this->yrev ) *vy = -*vy; - -/* Do not draw the tick if the start of the tick is outside the bounds of - the axis it is labelling. */ - if( ( ( edge == 1 || edge == 3 ) && - *x < this->xhi && *x > this->xlo ) || - ( ( edge == 0 || edge == 2 ) && - *y < this->yhi && *y > this->ylo ) ) { - -/* Store the x and y graphics coords of the far end of the tick mark */ - xe = *x + tklen*(*vx); - ye = *y + tklen*(*vy); - -/* Ensure the far end of the tick mark is within the bounds of the axis - it is labelling. If not, redice the length of the tick mark until it is.*/ - if( edge == 1 || edge == 3 ) { /* Top or bottom edge */ - if( xe > this->xhi ) { - ye = *y + tklen*(*vy)*( this->xhi - *x )/(xe - *x ); - xe = this->xhi; - } else if( xe < this->xlo ) { - ye = *y + tklen*(*vy)*( this->xlo - *x )/(xe - *x ); - xe = this->xlo; - } - - } else { /* Left or right edge */ - if( ye > this->yhi ) { - xe = *x + tklen*(*vx)*( this->yhi - *y )/(ye - *y ); - ye = this->yhi; - } else if( ye < this->ylo ) { - xe = *x + tklen*(*vx)*( this->ylo - *y )/(ye - *y ); - ye = this->ylo; - } - } - -/* Draw the tick mark as a straight line of the specified length. */ - if( save ) SaveTick( this, axis, *x, *y, majtick, status ); - if( *x != xe || *y != ye ) { - Bpoly( this, (float) *x, (float) *y, status ); - Apoly( this, (float) xe, (float) ye, status ); - Opoly( this, status ); - } - } - -/* Move on to the next crossing. */ - x += 4; - y += 4; - vx += 4; - vy += 4; - } - } - -/* Free the memory holding the crossings. */ - if( cross ) cross = (double *) astFree( (void *) cross ); - - } - -/* Return. */ - return; - -} - -static TickInfo *TickMarks( AstPlot *this, int axis, double *cen, double *gap, - int *inval, GetTicksStatics **pstatics, - const char *method, const char *class, int *status ){ -/* -* Name: -* TickMarks - -* Purpose: -* Obtain a list of tick mark values and labels for a single axis in a 2-D -* physical coordinate Frame. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* TickInfo *TickMarks( AstPlot *this, int axis, double *cen, double *gap, -* int *inval, GetTicksStatics **pstatics, -* const char *method, const char *class, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* A set of tick marks values and corresponding formatted labels are -* found for an axis which result in all adjacent labels being different, -* but using the minimum number of digits of precision in the formatting. -* This algorithm is over-ridden if the caller has set an explicit Format -* string for the axis. The gap between tick marks can be specified by -* the caller or a default value may be found automatically. - -* Parameters: -* this -* The Plot. -* axis -* The zero-based index of the axis to use. -* cen -* Pointer to the supplied axis value at which to put a single -* central tick. Other ticks will be placed evenly on either side of -* this tick. If AST__BAD is provided, a value will be used which -* would put a tick at an axis value of zero. The used value is -* returned. -* gap -* The supplied values for the gaps between ticks on the axis. If -* this is AST__BAD a suitable default value will be used and -* returned in place of the AST__BAD value. -* inval -* A pointer to a location at which to return a flag indicating if -* any invalid physical coordinates were encountered while deciding on -* the tick values. -* pstatics -* Address of a pointer to a structure holding static data values -* used within the GetTicks function. A NULL pointer should be supplied -* on the first invocation (dynamic memory will then be allocated to -* hold ths structure). The memory is freed when a NULL value for -* "this" is supplied. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A pointer to a TickInfo structure holding information about the tick -* marks (no. of major and minor ticks, the major tick mark values and -* labels). This structure should be freed, together with its contents, -* using astFree when it is no longer needed. - -* Notes: -* - The returned labels are NOT abbreviated to remove identical -* leading fields. -* - This function allocates some static resources on its first -* invocation, which should be released when no longer needed, or when -* a different Plot is supplied, by calling this function with a NULL -* pointer for parameter "this". All other parameters (except axis) are -* ignored. -* - This function assumes that the physical coordinate system is 2 -* dimensional, and it should not be used if this is not the case. -* - An error is reported if the region containing valid physical -* coordinates is too small to use. -* - If an error has already occurred, or if this function should fail -* for any reason, then a NULL pointer is returned. -*/ - -/* Local Constants: */ -#define MAXFLD 10 - -/* Local Variables: */ - AstAxis *ax; /* Pointer to the axis. */ - AstFrame *frame; /* Pointer to the current Frame in the Plot */ - TickInfo *ret; /* Pointer to the returned structure. */ - char **labels; /* Pointer to list of formatted labels */ - char **newlabels; /* Pointer to new list of shortened formatted labels */ - char **oldlabels; /* Pointer to old list of formatted labels */ - char *fields[ MAXFLD ]; /* Pointers to starts of fields in a label */ - char *old_format; /* Original Format string */ - char *used_fmt; /* Copy of format string actually used */ - const char *a; /* Pointer to next character to consider */ - const char *fmt; /* Format string actually used */ - double *ticks; /* Pointer to major tick mark values */ - double *minticks; /* Pointer to minor tick mark values */ - double cen0; /* Supplied value of cen */ - double junk; /* Unused value */ - double refval; /* Value for other axis to use when normalizing */ - double used_gap; /* The gap size actually used */ - int bot_digits; /* Digits value which makes labels as short as possible */ - int digits; /* New Digits value */ - int digset; /* Did the format string fix the no. of digits to use? */ - int fmtset; /* Was a format set? */ - int i; /* Tick index. */ - int nc[ MAXFLD ]; /* Lengths of fields in a label */ - int nf; /* Number of fields in a label */ - int nmajor; /* No. of major tick marks */ - int nminor; /* No. of minor tick marks */ - int ok; /* Are all adjacent labels different? */ - int reset_fmt; /* Re-instate the original state of the Format attribute? */ - - -/* If a NULL pointer has been supplied for "this", release the resources - allocated within GetTicks, and return. */ - if( !this ){ - (void) GetTicks( NULL, axis, NULL, &ticks, &nmajor, &minticks, &nminor, - 0, inval, &refval, pstatics, method, class, status ); - return NULL; - } - -/* Check the global status. */ - if( !astOK ) return NULL; - -/* Initialise the returned pointer. */ - ret = NULL; - -/* Store the supplied value of cen. */ - cen0 = cen ? *cen : AST__BAD ; - -/* Get a pointer to the current Frame from the Plot. */ - frame = astGetFrame( this, AST__CURRENT ); - -/* Initialise a flag to indicate that all adjacent labels are different. */ - ok = 0; - -/* Initialise the pointer to the list of formatted tick mark values to - indicate that no memory has yet been obtained. */ - labels = NULL; - -/* Initialise the pointer to a copy of the used format string to indicate - that no memory has yet been obtained. */ - used_fmt = NULL; - -/* Get a pointer to the axis. */ - ax = astGetAxis( frame, axis ); - -/* See if a value has been set for the axis Format. */ - fmtset = astTestFormat( frame, axis ); - -/* Get an initial set of tick mark values. This also establishes defaults for - LogTicks and LogLabel attributes, and so must be done before the - following block which uses the LogLabel attribute. */ - used_gap = GetTicks( this, axis, cen, &ticks, &nmajor, &minticks, &nminor, - fmtset, inval, &refval, pstatics, method, class, status ); - -/* See if exponential labels using superscript powers are required. */ - old_format = NULL; - reset_fmt = 0; - if( astGetLogLabel( this, axis ) && astGetEscape( this ) && - GCap( this, GRF__SCALES, 1, status ) ) { - -/* Save a copy of the Frame's Format value, if set. It will be - re-instated at the end of this function. */ - if( fmtset ) { - fmt = astGetFormat( frame, axis ); - old_format = astStore( NULL, (void *) fmt, strlen(fmt) + 1 ); - } - -/* Temporarily use a format of "%&g" to get "10**x" style axis labels, - with super-scripted "x". */ - astSetFormat( frame, axis, "%&g" ); - -/* Not all subclasses of Frame support this format specifier, so format a - test value, and see if it has two fields, the first of which is "10". - If not, we cannot use log labels so re-instate the original format. */ - nf = astFields( frame, axis, "%&g", astFormat( frame, axis, 1.0E4 ), - MAXFLD, fields, nc, &junk ); - if( nf != 2 || nc[ 0 ] != 2 || strncmp( fields[ 0 ], "10", 2 ) ) { - if( old_format ) { - astSetFormat( frame, axis, old_format ); - old_format = astFree( old_format); - } else { - astClearFormat( frame, axis ); - } - -/* If the "%&g" format is usable, note that we should reset the Format - back to its original state before leaving this function. */ - } else { - reset_fmt = 1; - } - } - -/* If a value has been set for the axis Format, see if the format string - contains a wildcard precision specifier ".*". If so, we are free to - vary the number of digits used in the label in order to produce - distinct labels. If no value has been set for the axis Format, we are - also free to vary the number of digits. */ - digset = 0; - if( fmtset ) { - fmt = astGetFormat( frame, axis ); - if( fmt ) { - digset = 1; - a = fmt; - while( (a = strchr( a, '.' )) ){ - if( *(++a) == '*' ) { - digset = 0; - break; - } - } - } - } - -/* If the axis precision has been specified, either through the Format string - or Digits value, or the Frame Digits value, we should use it so that the - user's attempts to get a specific result are not foiled. */ - if( digset || astTestAxisDigits( ax ) || astTestDigits( frame ) ){ - -/* Reserve memory to hold pointers to the formatted labels. */ - labels = (char **) astMalloc( sizeof(char *)*(size_t)nmajor ); - -/* Format the labels. We do not check that all adjacent labels are distinct - in order not to foil the users choice of format. That is, "ok" is set - non-zero by the call to CheckLabels, even if some identical adjacent - labels are found. */ - ok = CheckLabels( this, frame, axis, ticks, nmajor, 1, labels, refval, status ); - -/* Note the format used. */ - fmt = astGetFormat( frame, axis ); - if( fmt ) used_fmt = (char *) astStore( used_fmt, (void *) fmt, strlen( fmt ) + 1 ); - -/* If no precision has been specified for the axis, we need to find a - Digits value which gives different labels, but without using any more - digits than necessary. */ - } else if( astOK ){ - -/* Reserve memory to hold pointers to an initial set of labels formatted - with the default digits value. */ - labels = (char **) astMalloc( sizeof(char *)*(size_t)nmajor ); - -/* Produce these default labels. */ - CheckLabels( this, frame, axis, ticks, nmajor, 1, labels, refval, status ); - -/* The first task is to decide what the smallest usable number of digits - is. Starting at the default number of digits used above to produce the - default labels, we reduce the number of digits until one or more of the - formatted labels *increases* in length. This can happen for instance if - printf decides to include an exponent in the label. The *absolute* - minimum value 1. Set this first. */ - bot_digits = 1; - oldlabels = labels; - for( digits = astGetDigits( frame ) - 1; digits > 0; digits-- ){ - astSetAxisDigits( ax, digits ); - -/* CheckLabels2 formats the labels with the decreased number of digits, - and compares them with the old labels in "labels". If any of the new labels - are longer than the corresponding old labels, then a null pointer is - returned. Otherwise, a pointer is returned to the new set of labels. */ - newlabels = CheckLabels2( this, frame, axis, ticks, nmajor, - oldlabels, refval, status ); - -/* Free the old labels unless they are the orignal labels (which are - needed below). */ - if( oldlabels != labels ) { - for( i = 0; i < nmajor; i++ ){ - if( oldlabels[ i ] ) oldlabels[ i ] = (char *) astFree( (void *) oldlabels[ i ] ); - } - oldlabels = (char **) astFree( (void *) oldlabels ); - } - -/* If any of the labels got longer as a result of reducing the digits - value, then use the previous number of digits as the lowest possible - number of digits. Break out of the loop. */ - if( !newlabels ) { - bot_digits = digits + 1; - break; - } - -/* If none of the labels got longer, we arrive here. Use the shorter labels - for the next pass round this loop. */ - oldlabels = newlabels; - } - -/* Free any remaining labels. */ - if( oldlabels && oldlabels != labels ) { - for( i = 0; i < nmajor; i++ ){ - if( oldlabels[ i ] ) oldlabels[ i ] = (char *) astFree( (void *) oldlabels[ i ] ); - } - oldlabels = (char **) astFree( (void *) oldlabels ); - } - -/* Now loop round increasing the number of digits in the formatted labels - from the lowest usable value found above until all adjacent labels are - different. An arbitrary upper limit of 1000 is used for Digits to stop it - looping for ever. */ - for( digits = bot_digits; digits < 1000; digits++ ){ - -/* Store the new Digits value. */ - astSetAxisDigits( ax, digits ); - -/* Free memory used to hold the current set of labels. A new set will be - created by the following call to CheckLabels. */ - if( labels ) { - for( i = 0; i < nmajor; i++ ) labels[ i ] = astFree( labels[ i ] ); - } - -/* Break out of the loop if a Digits value has been found which results - in all adjacent labels being different. Note the format used (we know - the Format attribute is currently unset, but the default Format string - reflects the current value of the Digits attribute). */ - if( CheckLabels( this, frame, axis, ticks, nmajor, 0, labels, refval, status ) ) { - ok = 1; - fmt = astGetFormat( frame, axis ); - used_fmt = (char *) astStore( NULL, (void *) fmt, strlen( fmt ) + 1 ); - break; - } - } - -/* Clear the Digits value. */ - astClearAxisDigits( ax ); - } - -/* Annul the pointer to the Axis. */ - ax = astAnnul( ax ); - -/* Re-instate the original format specifier if required. */ - if( reset_fmt ) { - if( old_format ) { - astSetFormat( frame, axis, old_format ); - old_format = astFree( old_format); - } else { - astClearFormat( frame, axis ); - } - } - -/* If suitable labels were found... */ - if( ok && astOK ) { - -/* Store the used gap size. */ - *gap = used_gap; - -/* If the caller has specified the number of minor tick marks to use, - use the specified value rather than the value found above. */ - if( astTestMinTick( this, axis ) ){ - nminor = astGetMinTick( this, axis ); - } - -/* Allocate memory for the returned structure. */ - ret = (TickInfo *) astMalloc( sizeof( TickInfo ) ); - -/* If the pointer can be used, store the information. */ - if( astOK ){ - ret->nmajor = nmajor; - ret->nminor = nminor; - ret->ticks = ticks; - ret->minticks = minticks; - ret->labels = labels; - ret->fmt = used_fmt; - used_fmt = NULL; - ret->start = NULL; - ret->length = NULL; - ret->nsect = 0; - ret->gap = used_gap; - } - -/* If no suitable labels were found report an error. */ - } else if( astOK ){ - if( fmtset ){ - astError( AST__PLFMT, "%s(%s): No numerical labels can be produced " - "for axis %d using the supplied %s format string '%s'.", status, - method, class, axis + 1, astGetClass( frame ), - astGetFormat( frame, axis ) ); - } else { - astError( AST__PLFMT, "%s(%s): No suitable format can be found to " - "produce numerical labels for axis %d of a %s.", status, - method, class, axis + 1, astGetClass( frame ) ); - } - } - -/* Release any remaining resources. */ - frame = astAnnul( frame ); - if( used_fmt ) used_fmt = astFree( used_fmt ); - -/* If an error has occurred, release the returned information. */ - if( !astOK ){ - ticks = (double *) astFree( (void *) ticks ); - minticks = (double *) astFree( (void *) minticks ); - if( labels ){ - for( i = 0; i < nmajor; i++ ) { - labels[ i ] = (char *) astFree( (void *) labels[ i ] ); - } - labels = (char **) astFree( (void *) labels ); - if( ret ) (void ) astFree( (void *) ret->fmt ); - } - ret = (TickInfo *) astFree( (void *) ret ); - } - -/* Return the structure. */ - return ret; - -/* Undefine local constants. */ -#undef MAXFLD - -} - -static int TraceBorder( AstPlot *this, AstMapping *map, double xlo, double xhi, - double ylo, double yhi, int dim, double tol, - int edges[ 4 ], const char *method, const char *class, - int *status ) { -/* -* Name: -* TraceBorder - -* Purpose: -* Trace the boundary between good and bad physical coordinates through a -* fine grid. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TraceBorder( AstPlot *this, AstMapping *map, double xlo, double xhi, -* double ylo, double yhi, int dim, double tol, -* int edges[ 4 ], const char *method, const char *class, -* int *status ) { - -* Class Membership: -* Plot member function. - -* Description: -* A rectangular grid of points in graphics coords is created covering -* the region specified by (xlo,xhi,ylo,yhi), using "dim" points along -* each axis. This grid of points is converted into physical (WCS) -* coords, and a flag is associatred with each point saying whether -* the WCS coords are good or bad. The cells in this grid are then -* scanned from bottom left to top right in raster fashion (each cell -* has a grid point at each of its 4 corners). If a cell has a mix of -* bad and good corners, the good/bad boundary must pass through it. -* If the grid is sufficiently fine (as defined by "tol") then this -* function draws a single straight line through each cell as an -* approximation to the good bad boundary. This line joins the centres -* of the two cells edges through which the boundary passes (as -* indicated by the fact that one end of the edge has good WCS coords -* and the other end has bad WCS coords). If the grid is not -* sufficiently fine to meet the "tol" requirement, then this function -* is invoked recursively to draw the curve through each cell through -* which the boundary passes. - -* Parameters: -* this -* The plot. -* map -* The Graphics->WCS mapping. -* xlo -* The lower bounds on the graphics X axis of the rectangle being -* considered. -* xhi -* The upper bounds on the graphics X axis of the rectangle being -* considered. -* ylo -* The lower bounds on the graphics Y axis of the rectangle being -* considered. -* yhi -* The upper bounds on the graphics Y axis of the rectangle being -* considered. -* dim -* The number of points along one edge of the fine grid. -* tol -* The plotting tolerance. Once each cell is smaller than this -* distance (in graphics coords), the cell is drawn. Otherwise, -* this function is invoked recursively to draw the cell using a -* finer grid. -* edges -* A pointer to an array of 4 int, in which will be returned -* flags indicating if the good/bad boundary intersects any of the -* edges of the grid. These flags are stored in the order left, -* top, right, bottom. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. -* status -* Pointer to the inherited status variable. - -*/ - -/* Local Variables: */ - AstPointSet *pset1; - AstPointSet *pset2; - double **ptr2; - double *px1; - double *px2; - double *py1; - double *py2; - double cxhi; - double cxlo; - double cyhi; - double cylo; - double dx; - double dy; - float xc; - float yc; - int *bndry; - int *drawn; - int bad1; - int bad2; - int bad3; - int bad4; - int icell; - int icol; - int irow; - int lastcell; - int ncell; - int recurse; - int result; - int sedges[ 4 ]; - int totcells; - -/* Initialise returned edge flags */ - edges[ 0 ] = 0; - edges[ 1 ] = 0; - edges[ 2 ] = 0; - edges[ 3 ] = 0; - -/* Initialise the returned flag to indicate that no bad regions were - found. */ - result = 0; - -/* Check the global status. */ - if ( !astOK ) return result; - -/* Create a grid of graphics and WCS coords covering the specified region - of graphics coords. "ptr2" is used to access the WCS coords at each - point in the grid. */ - ptr2 = MakeGrid( this, NULL, map, 0, dim, xlo, xhi, ylo, yhi, - 2, &pset1, &pset2, 0, method, class, status ); - -/* The number of cells along each axis of the grid is one less than the - number of points. Also get the number of cells in the whole grid. */ - ncell = dim - 1; - totcells = ncell*ncell; - -/* Store the dimensions of each cell in graphics coords. */ - dx = ( xhi - xlo )/ncell; - dy = ( yhi - ylo )/ncell; - -/* Set a flag indicating if the cell size is larger than the required - plotting tolerance. If so, we will call this function recursively to - draw the curve using a finer grid. */ - recurse = ( dx > tol || dy > tol ); - -/* If we have not yet reached the plotting tolerance, allocate work arrays - with one element for each cell in the grid. */ - if( recurse ) { - bndry = astMalloc( sizeof( int )*totcells ); - drawn = astMalloc( sizeof( int )*totcells ); - } else { - bndry = NULL; - drawn = NULL; - } - -/* Check pointers can be used safely. */ - if( astOK ) { - -/* If required, initialise work arrays to hold zero. */ - if( recurse ) { - -/* Initialise "boundary passes through cell" flags to zero. */ - memset( bndry, 0, sizeof( int )*totcells ); - -/* Initialise "cell has been drawn" flags to zero. */ - memset( drawn, 0, sizeof( int )*totcells ); - } - -/* Store the Y graphics coords at the bottom and top of the first row. */ - cylo = ylo; - cyhi = ylo + dy; - -/* Store pointers to the physical coords at the bottom left corner of the - first cell in the first row. */ - px1 = ptr2[ 0 ]; - py1 = ptr2[ 1 ]; - -/* Store pointers to the physical coords at the top left corner of the - first cell in the first row. */ - px2 = px1 + dim; - py2 = py1 + dim; - -/* Store the index of the last cell in a row or column. */ - lastcell = ncell - 1; - -/* Initialise index of next cell. */ - icell = 0; - -/* Loop round every row of cells in this grid. */ - for( irow = 0; irow < ncell; irow++ ) { - -/* See if the physical coords are bad at the bottom left corner of the - first cell in this row. At the same time, increment the pointers so - they refer to the bottom right corner of the first cell in this row. */ - bad1 = ( *px1 == AST__BAD || *py1 == AST__BAD ); - -/* Increment the pointers. Do not do it in the above "if" statement since - the or (!!) means that the second expression may never be evaluated. */ - px1++; - py1++; - -/* See if the physical coords are bad at the top left corner of the - first cell in this row. At the same time, increment the pointers so - they refer to the top right corner of the first cell in this row. */ - bad2 = ( *px2 == AST__BAD || *py2 == AST__BAD ); - px2++; - py2++; - -/* Loop round every cell in the current row of cells. */ - for( icol = 0; icol < ncell; icol++, icell++ ) { - -/* See if the physical coords are bad at the bottom right corner of the - current cell in this row. At the same time, increment the pointers so - they refer to the bottom right corner of the next cell in this row. */ - bad3 = ( *px1 == AST__BAD || *py1 == AST__BAD ); - px1++; - py1++; - -/* See if the physical coords are bad at the top right corner of the - current cell in this row. At the same time, increment the pointers so - they refer to the top right corner of the next cell in this row. */ - bad4 = ( *px2 == AST__BAD || *py2 == AST__BAD ); - px2++; - py2++; - -/* Set the returned flag non-zero if any invalidpositions are found. */ - if( bad1 || bad2 || bad3 || bad4 ) result = 1; - -/* If there are a mixture of good and bad corners, the good/bad boundary - must pass through the current cell. */ - if( bad2 != bad1 || bad3 != bad1 || bad4 != bad1 ) { - -/* If we have not yet reached the required plotting tolerance, set a flag - to indicate that the boundary should be plotted through this cell - using a recirsive call to this function. */ - if( recurse ) { - bndry[ icell ] = 1; - -/* If we have reached the required plotting tolerance, draw the boundary - as a straight line between the centres of the edges through which the - boundary enteres and leaves the current cell. */ - } else { - -/* Get the upper and lower graphics X bounds of the current cell. */ - cxlo = xlo + icol*dx; - cxhi = cxlo + dx; - -/* If an edge of the current cell has good coords at one end but bad - coords at the other, the boundary is assumed to pass through the edge - at its centre. Normally, we expect only two cell edges to have this - property (i.e the boundary enters the cell through one edge and leaves - through the other). However, sometimes all four edges may have this - property. In this case, two sections of the boundary must pass through - the cell, and there is no way of knowing which edges connect together - (short of further recursion), and we arbitrarily decide to join opposite - edges. */ - if( bad1 == bad4 && bad2 == bad3 ) { - -/* Draw a horizontal line through the cell centre */ - yc = 0.5*( cylo + cyhi ); - Bpoly( this, (float) cxlo, yc, status ); - Apoly( this, (float) cxhi, yc, status ); - -/* Draw a vertical line through the cell centre */ - xc = 0.5*( cxlo + cxhi ); - Bpoly( this, xc, (float) cylo, status ); - Apoly( this, xc, (float) cyhi, status ); - -/* If the boundary passes through the left hand edge, it must also have - passed through the right edge of the previous cell in the row (unless - this is the first cell in the row), so we do not need to begin a new - polyline (we can just extend the existing polyline). */ - } else if( bad1 != bad2 ) { - -/* If this is the first cell in the row, begin a new polyline. */ - yc = 0.5*( cylo + cyhi ); - if( icol == 0 ) Bpoly( this, (float) cxlo, yc, status ); - -/* and through the top edge, draw a line between the centres of the left - and top edges. */ - if( bad2 != bad4 ) { - xc = 0.5*( cxlo + cxhi ); - Apoly( this, xc, (float) cyhi, status ); - -/* or through the right edge, draw a line between the centres of the left - and right edges. */ - } else if( bad3 != bad4 ) { - Apoly( this, (float) cxhi, yc, status ); - -/* Otherwise, draw a line between the centres of the left and bottom edges. */ - } else { - xc = 0.5*( cxlo + cxhi ); - Apoly( this, xc, (float) cylo, status ); - } - -/* If the boundary passes through the top edge (we do not need to check - the left edge because that was done above)... */ - } else if( bad4 != bad2 ) { - -/* and through the right edge, draw a line between the centres of the top - and right edges. */ - if( bad3 != bad4 ) { - xc = 0.5*( cxlo + cxhi ); - yc = 0.5*( cylo + cyhi ); - Bpoly( this, xc, (float) cyhi, status ); - Apoly( this, (float) cxhi, yc, status ); - -/* Otherwise, draw a line between the centres of the top and bottom edges. */ - } else { - xc = 0.5*( cxlo + cxhi ); - Bpoly( this, xc, (float) cyhi, status ); - Apoly( this, xc, (float) cylo, status ); - } - -/* If the boundary passes through the right edge it must also pass - throught the bottom edge since all other combinations will have been - trapped above. */ - } else { - xc = 0.5*( cxlo + cxhi ); - yc = 0.5*( cylo + cyhi ); - Bpoly( this, xc, (float) cylo, status ); - Apoly( this, (float) cxhi, yc, status ); - } - -/* If the current cell is on the edge of the grid, set flags in the - returned "edges" array to indicate that the boundary passes out of - the grid on the appropriate edge. */ - if( icol == 0 ) { - if( bad1 != bad2 ) edges[ 0 ] = 1; /* Left edge */ - } else if( icol == lastcell ) { - if( bad3 != bad4 ) edges[ 2 ] = 1; /* Right edge */ - } - - if( irow == 0 ) { - if( bad1 != bad3 ) edges[ 3 ] = 1; /* Bottom edge */ - } else if( irow == lastcell ) { - if( bad2 != bad4 ) edges[ 1 ] = 1; /* Top edge */ - } - } - } - -/* The flags for the right hand corners of the current cell can be - re-used as the flags for the left hand corners of the next cell. */ - bad1 = bad3; - bad2 = bad4; - } - -/* Store the Y graphics coords at the bottom and top of the next row. */ - cylo = cyhi; - cyhi = cylo + dy; - } - -/* If we have not yet reached the required plotting tolerance, call this - function recursively to draw the boundary through the cells identified - above. On each pass through this loop, we may discover more boundary - cells in the grid, in addition to those found above. Continue looping - until no further boundary cells are found. */ - while( recurse ) { - -/* Assume that the current pass though this loop will result in all boundary - cells being draw, in which case we can then leave the loop. */ - recurse = 0; - -/* Store the Y graphics coords at the bottom and top of the first row. */ - cylo = ylo; - cyhi = ylo + dy; - -/* Initialise the cell index */ - icell = 0; - -/* Loop round every row of cells in this grid. */ - for( irow = 0; irow < ncell; irow++ ) { - -/* Loop round every cell in the current row of cells. */ - for( icol = 0; icol < ncell; icol++, icell++ ) { - -/* If the good/bad boundary passes through the current cell we need to - draw it unless it has already been drawn. */ - if( bndry[ icell ] && ! drawn[ icell ] ){ - -/* Get the upper and lower graphics X bounds of the current cell. */ - cxlo = xlo + icol*dx; - cxhi = cxlo + dx; - -/* Call this function recursively to draw the boundary through the current - cell, setting the returned flag non-zero if any bad positions are found. */ - if( TraceBorder( this, map, cxlo, cxhi, cylo, cyhi, 3, tol, - sedges, method, class, status ) ) result = 1; - -/* The boundary may have passed out of the current cell and then back - into the cell on the same edge (i.e. a small loop that pokes out into - a neighbouring cell). Such neighbouring cells may not have been - identified by the earlier section of this function, so we now ensure - that any such cells are flagged as boundary cells. */ - -/* If the boundary passed out of the left edge of the cell... */ - if( sedges[ 0 ] ) { - -/* If the current cell is at the left edge of the grid, indicate that the - boundary passes out of the left edge of the grid. */ - if( icol == 0 ) { - edges[ 0 ] = 1; /* Left edge */ - -/* Otherwise, if the left hand neighbour of the current cell is not - flagged as a boundary cell, flag it now and indicate that another pass - though the loop is needed to draw the extra cell. */ - } else if( ! bndry[ icell - 1 ] ) { - bndry[ icell - 1 ] = 1; - recurse = 1; - } - } - -/* If the boundary passed out of the top edge of the cell... */ - if( sedges[ 1 ] ) { - -/* If the current cell is at the top edge of the grid, indicate that the - boundary passes out of the top edge of the grid. */ - if( irow == lastcell ) { - edges[ 1 ] = 1; /* Top edge */ - -/* Otherwise, ensure that the upper neighbour of the current cell is - flagged as a boundary cell. */ - } else { - bndry[ icell + ncell ] = 1; - } - } - -/* If the boundary passed out of the right edge of the cell... */ - if( sedges[ 2 ] ) { - -/* If the current cell is at the right edge of the grid, indicate that the - boundary passes out of the right edge of the grid. */ - if( icol == lastcell ) { - edges[ 2 ] = 1; /* Right edge */ - -/* Otherwise, ensure that the right hand neighbour of the current cell is - flagged as a boundary cell. */ - } else { - bndry[ icell + 1 ] = 1; - } - } - -/* If the boundary passed out of the bottom edge of the cell... */ - if( sedges[ 3 ] ) { - -/* If the current cell is at the bottom edge of the grid, indicate that the - boundary passes out of the bottom edge of the grid. */ - if( irow == 0 ) { - edges[ 3 ] = 1; /* Bottom edge */ - -/* Otherwise, if the lower neighbour of the current cell is not flagged - as a boundary cell, flag it now and indicate that another pass though - the loop is needed to draw the extra cell. */ - } else if( ! bndry[ icell - ncell ] ) { - bndry[ icell - ncell ] = 1; - recurse = 1; - } - } - -/* Indicate this cell has been drawn. */ - drawn[ icell ] = 1; - } - } - -/* Store the Y graphics coords at the bottom and top of the next row. */ - cylo += dy; - cyhi = cylo + dy; - } - } - } - -/* Free resources */ - bndry = astFree( bndry ); - drawn = astFree( drawn ); - pset1 = astAnnul( pset1 ); - pset2 = astAnnul( pset2 ); - -/* Return the result. */ - return result; -} - -static AstPointSet *Trans( AstPlot *this, AstFrame *frm, AstMapping *mapping, - AstPointSet *in, int forward, AstPointSet *out, - int norm, const char *method, const char *class, int *status ) { -/* -* Name: -* Trans - -* Purpose: -* Use a Mapping to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *Trans( AstPlot *this, AstFrame *frm, AstMapping *mapping, -* AstPointSet *in, int forward, AstPointSet *out, -* int norm, const char *method, const char *class ) - -* Class Membership: -* Plot member function. - -* Description: -* This performs the same task as the protected method astTransform -* but uses the astTransform method for the supplied Mapping instead -* the parent method for the Plot. This allows the Mapping to be -* extracted from the Plot using astGetMapping once, rather than every -* time a mapping is performed. - -* Parameters: -* this -* Pointer to the Plot (only used to access clipping attributes and -* other methods). -* frm -* Pointer to the Current Frame in the Plot. If this is NULL, then -* a pointer for the Current Frame is found within this function if -* required (i.e. if "forward" and "norm" are both non-zero). -* mapping -* Pointer to the Mapping extracted from the Plot. If this is NULL, then -* a pointer for the base->current Mapping is found within this function. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied while a zero value requests the -* inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. -* norm -* The normalisation of returned physical coordinates is only done -* if "norm" is non-zero. Otherwise they are left as returned by -* astTransform. -* method -* Pointer to a string holding the name of the calling method. -* This is only for use in constructing error messages. -* class -* Pointer to a string holding the name of the supplied object class. -* This is only for use in constructing error messages. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - Clipping is only performed as set up using the astClip method. -* In particular, the clipping specified by the arguments to the astPlot -* constructor function is NOT performed. This is done in order to improve -* the efficiency of the curve drawing method astGridLine. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Plot being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstFrame *cfr; /* Pointer to the Current Frame */ - AstFrame *fr; /* Pointer to the clipping Frame */ - AstMapping *map; /* Pointer to output->clip mapping */ - AstPointSet *clip; /* Positions in clipping Frame */ - AstPointSet *result; /* Positions in output Frame */ - double **ptr_clip; /* Pointer to clipping Frame data */ - double **ptr_out; /* Pointer to output coordinate data */ - double *work; /* Pointer to array holding an o/p position */ - double axval; /* Axis value in clipping frame */ - double lbnd; /* Lower bound on current clipping axis */ - double ubnd; /* Upper bound on current clipping axis */ - int axin; /* Is the axis value within the allowed range? */ - int clip_norm; /* Normalise the clipping positions? */ - int clip_or; /* Combine axes using a logical OR? */ - int clipit; /* Should the current point be clipped? */ - int i; /* Point index */ - int iframe; /* Validated index for clipping Frame */ - int j; /* Axis index */ - int naxes; /* Number of axes in clipping Frame */ - int ncoord_out; /* Number of coordinates per output point */ - int npoint; /* Number of points */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Ensure we have a Mapping */ - if( !mapping ) mapping = astGetMapping( this, AST__BASE, AST__CURRENT ); - -/* Apply the parent mapping using the stored pointer to the Transform member - function inherited from the parent FrameSet class. */ - result = astTransform( mapping, in, forward, out ); - -/* Get the dimensions of the returned data, and an array of pointers to - the axis values. */ - ncoord_out = astGetNcoord( result ); - npoint = astGetNpoint( result ); - ptr_out = astGetPoints( result ); - -/* If we have done a forward mapping, we now normalise the returned physical - positions if required using the astNorm method for the supplied object. */ - if( forward && norm ){ - -/* If no Frame was supplied, get a pointer to the Current Frame. Otherwise, - use the supplied pointer. */ - if( !frm ) { - cfr = astGetFrame( this, AST__CURRENT ); - } else { - cfr = frm; - } - -/* Get work space to hold a single positions. */ - work = (double *) astMalloc( sizeof(double)*(size_t)ncoord_out ); - -/* Check the work space and axis pointers can be used. */ - if( astOK ){ - -/* Now loop through every position, copying the axis values to the work array, - normalising them using astNorm, and copying them back to the returned - PointSet. */ - for( i = 0; i < npoint; i++ ){ - for( j = 0; j < ncoord_out; j++ ) work[ j ] = ptr_out[ j ][ i ]; - astNorm( cfr, work ); - for( j = 0; j < ncoord_out; j++ ) ptr_out[ j ][ i ] = work[ j ]; - } - } - -/* Free the work space. */ - work = (double *) astFree( (void *) work ); - -/* Annul the pointer to the Current Frame if it was obtained in this - function. */ - if( !frm ) cfr = astAnnul( cfr ); - - } - -/* Clipping is only performed if the bounds of a clipping region are - available for both axes. */ - if( this->clip_lbnd && this->clip_ubnd ){ - -/* Validate and translate the index of the clipping Frame. */ - iframe = astValidateFrameIndex( this, this->clip_frame, method ); - -/* Obtain a pointer to the clipping Frame and determine how many axes it - has. */ - fr = astGetFrame( this, iframe ); - naxes = astGetNaxes( fr ); - -/* Report an error if the number of bounds does not equal the number of - axes in the clipping Frame. */ - if( astOK && naxes != this->clip_axes ){ - astError( AST__CLPAX, "%s%s): The supplied %s specifies clipping " - "in %d dimensions, but the clipping Frame ('%s') has " - "%d axes.", status, method, class, class, this->clip_axes, - astGetTitle( fr ), naxes ); - } - -/* Set a flag indicating if the coordinates in the clipping frame need to - be normalised. */ - clip_norm = 1; - -/* We now obtain a pointer to a PointSet holding the corresponding - coordinates in the clipping frame. If the clipping frame is the - base frame, then take a clone of the PointSet holding base frame - coordinates. */ - if( iframe == astGetBase( this ) ){ - if( forward ){ - clip = astClone( in ); - } else { - clip = astClone( result ); - } - -/* If the clipping frame is the current frame, then take a clone of the - PointSet holding current coordinates. Note, if the returned physical - coordinates have already been normalised, we don't need to normalise - the clipping coordinates. */ - } else if( iframe == astGetCurrent( this ) ){ - if( forward ){ - clip = astClone( result ); - if( norm ) clip_norm = 0; - } else { - clip = astClone( in ); - } - -/* If the clipping Frame is neither the base nor the current Frame, we need - to map the returned normalised points into the clipping Frame. */ - } else { - if( forward ){ - map = astGetMapping( this, AST__CURRENT, iframe ); - } else { - map = astGetMapping( this, AST__BASE, iframe ); - } - clip = astTransform( map, result, 1, NULL ); - map = astAnnul( map ); - } - -/* Get a pointer to the coordinate data in the clipping Frame. */ - ptr_clip = astGetPoints( clip ); - -/* If necessary, normalise the coordinates in the clipping frame. */ - if( clip_norm ){ - -/* Get work space to hold a single position. */ - work = (double *) astMalloc( sizeof(double)*(size_t)naxes ); - -/* Check the work space and axis pointers can be used. */ - if( astOK ){ - -/* Now loop through every position, copying the axis values to the work array, - normalising them using astNorm, and copying them back to the clipping - PointSet. */ - for( i = 0; i < npoint; i++ ){ - for( j = 0; j < naxes; j++ ) work[ j ] = ptr_clip[ j ][ i ]; - astNorm( fr, work ); - for( j = 0; j < naxes; j++ ) ptr_clip[ j ][ i ] = work[ j ]; - } - } - -/* Free the work space. */ - work = (double *) astFree( (void *) work ); - - } - -/* If all has gone ok, we will now clip the returned points. */ - if( astOK ){ - -/* Get the logical operation to be used to determine if a point is to be - clipped. A zero value means that a logical AND is to be performed - between the axes (i.e. all axes must be within the supplied bounds for a - point to be retained). A non-zero value means that a logical OR is to be - performed between the axes (i.e. only a single axis need be within the - supplied bounds for a point to be retained). */ - clip_or = astGetClipOp( this ); - -/* Do each point in turn. */ - for( j = 0; j < npoint; j++ ){ - -/* If all axes must fall within the supplied range to avoid the point being - clipped (i.e. if clip_or is 0), then assume initially that the point - is not to be clipped. This will be toggled as soon as the first - out-of-bounds point is found. If, on the other hand, the point is - only clipped if all axis values are out-of-bounds, then assume - initially that the point is to be clipped. This will be toggled as - soon as the first axis value is found which is not out-of-bounds. */ - clipit = clip_or; - -/* Check each axis value for the current point. */ - for( i = 0; i < naxes; i++ ){ - axval = ptr_clip[ i ][ j ]; - -/* Chekc that it is not bad. */ - if( axval != AST__BAD ){ - -/* Store the bounds of the clipping volume on this axis. */ - lbnd = this->clip_lbnd[ i ]; - ubnd = this->clip_ubnd[ i ]; - -/* Set a flag indicating if the axis value is within the specified range. - If the supplied bounds are reversed, they specify the range to exclude, - otherwise they specify the range to include. */ - if( lbnd <= ubnd ){ - axin = ( axval >= lbnd && axval <= ubnd ); - } else { - axin = ( axval < ubnd || axval > lbnd ); - } - -/* If the point is within the range and only one such point is - required to avoid the point being clipped, indicate that the point - should not be clipped, and leave the loop. */ - if( axin && clip_or ){ - clipit = 0; - break; - -/* If the point is not within the range and we only one such point is - required to cause the point to be clipped, indicate that the point - should be clipped, and leave the loop. */ - } else if( !axin && !clip_or ){ - clipit = 1; - break; - } - -/* Clip the point if any axis value is bad in the clipping Frame. */ - } else { - clipit = 1; - break; - } - - } - -/* If the point is to be clipped, set all returned axis values bad. */ - if( clipit ) { - for( i = 0; i < naxes; i++ ) ptr_out[ i ][ j ] = AST__BAD; - } - - } - - } - -/* Annul the PointSet holding clipping Frame positions. */ - if( clip ) clip = astAnnul( clip ); - -/* Annul the clipping Frame pointer. */ - fr = astAnnul( fr ); - - } - -/* If an error has occurred, annul the result. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static AstPointSet *Transform( AstMapping *this, AstPointSet *in, - int forward, AstPointSet *out, int *status ) { -/* -* Name: -* Transform - -* Purpose: -* Use a Plot to transform a set of points. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* AstPointSet *Transform( AstMapping *this, AstPointSet *in, -* int forward, AstPointSet *out ) - -* Class Membership: -* Plot member function (over-rides the astTransform protected -* method inherited from the FrameSet class). - -* Description: -* This function takes a Plot and a set of points encapsulated in a -* PointSet and transforms the points from graphics coordinates to -* physical coordinates (in the forward direction). If the returned -* positions are physical coordinates (i.e. if a forward mapping is -* performed) they are normalised using the astNorm method of the supplied -* Plot. The returned axis values are set to AST__BAD for any positions -* which are outside the clipping volume set up by the astClip method. - -* Parameters: -* this -* Pointer to the Plot. -* in -* Pointer to the PointSet holding the input coordinate data. -* forward -* A non-zero value indicates that the forward coordinate -* transformation should be applied while a zero value requests the -* inverse transformation. -* out -* Pointer to a PointSet which will hold the transformed (output) -* coordinate values. A NULL value may also be given, in which case a -* new PointSet will be created by this function. - -* Returned Value: -* Pointer to the output (possibly new) PointSet. - -* Notes: -* - Clipping is only performed as set up using the astClip method. -* In particular, the clipping specified by the arguments to the astPlot -* constructor function is NOT performed. This is done in order to improve -* the efficiency of the curve drawing method astGridLine. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -* - The number of coordinate values per point in the input PointSet must -* match the number of coordinates for the Plot being applied. -* - If an output PointSet is supplied, it must have space for sufficient -* number of points and coordinate values per point to accommodate the -* result. Any excess space will be ignored. -*/ - -/* Local Variables: */ - AstMapping *map; /* Pointer to the mapping */ - AstPointSet *result; /* Positions in output Frame */ - AstPlot *plot; /* The Plot */ - -/* Check the global error status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the Plot. */ - plot = (AstPlot *) this; - -/* Get the Mapping from the base to the current Frame. */ - map = astGetMapping( plot, AST__BASE, AST__CURRENT ); - -/* Do the transformation. */ - result = Trans( plot, NULL, map, in, forward, out, 1, "astTransform", - astGetClass( this ), status ); - -/* Annul the mapping. */ - map = astAnnul( map ); - -/* If an error has occurred, annul the result. */ - if( !astOK ) result = astAnnul( result ); - -/* Return a pointer to the output PointSet. */ - return result; - -} - -static double Typical( int n, double *value, double lolim, double hilim, - double *width, int *status ) { -/* -* Name: -* Typical - -* Purpose: -* Return a typical value within the supplied array of values. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double Typical( int n, double *value, double lolim, double hilim, -* double *width, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This function locates the approximate mode of the supplied values, -* and returns one of the supplied values which is close to the modal -* value. Values outside an indicated range are ignored. - -* Parameters: -* n -* The number of data values. -* value -* A pointer to an array of "n" values. -* lolim -* Values less than lolim are ignored. Supply as -DBL_MAX if there -* is no lower limit. -* hilim -* Values greater than hilim are ignored. Supply as DBL_MAX if there -* is no upper limit. -* width -* Pointer to a double in which to return the width (i,e, data range) -* of the non-empty histogram cells. This is an estimate of the -* range of used values in the supplied array. NULL may be supplied. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* A typical value from the supplied array. AST__BAD is returned only -* if an error has occurred, or if all the supplied values are AST__BAD -* or outside the specified range. - -*/ - -/* Local Variables: */ - double *a; /* Pointer to next value */ - double cnt; /* Modified count */ - double delta; /* Bin size */ - double maxval; /* Maximum supplied value */ - double mean; /* Mean supplied value */ - double minval; /* Minimum supplied value */ - double result; /* The returned value. */ - double w0; /* Rate of increase of weight with dist from edge */ - double w1; /* Weight for left edge */ - double w2; /* Weight for right edge */ - double w; /* Weight for this bin */ - int *hist; /* Pointer to first cell of histogram array */ - int i; /* Loop count */ - int ibin; /* Bin index */ - int maxcnt; /* Maximum no. of values in any bin */ - int modify; /* Modify the effect of the edge bins? */ - int nbin; /* No. of bins in histogram */ - int nc; /* Total number of points in histogram */ - int ngood; /* No. of good values supplied */ - int nonemp; /* No. of non-empty bins in hstogram */ - -/* Initialise. */ - result = AST__BAD; - if( width ) *width = 0.0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - ibin = 0; - -/* Find the minimum and maximum value in the supplied array, which are - also within the supplied limits. Also store the first good value - encountered in "result". */ - minval = DBL_MAX; - maxval = -DBL_MAX; - a = value; - ngood = 0; - for( i = 0; i < n; i++, a++ ) { - if( *a != AST__BAD ) { - if( *a >= lolim && *a <= hilim ) { - if( *a < minval ) minval = *a; - if( *a > maxval ) maxval = *a; - if( ngood == 0 ) result = *a; - ngood++; - } - } - } - -/* Initialise the returned width to the total data range. */ - if( width && maxval != -DBL_MAX ) *width = maxval - minval; - -/* If less than 3 points were found, we will return the first. Otherwise, if - 3 or more good values were found, find a typical value. */ - if( ngood > 2 ) { - -/* We will form a histogram of the supplied values in order to find the - mode. The number of bins in this histogram is chosen so that there - is an average of 2 points per bin. Find the number of bins. */ - nbin = ( ngood + 1 )/2; - -/* Find the bin size. If zero (i.e. if all values are equal), return the - first good value established above. */ - delta = ( maxval - minval )/ nbin; - if( delta > 0.0 ) { - -/* Allocat ememory for the histogram. */ - hist = astMalloc( sizeof(int)*(size_t)nbin ); - if( hist ) { - -/* Initialise the histogram. */ - for( i = 0; i < nbin; i++ ) hist[ i ] = 0; - -/* Form the histogram. Form the mean data value at the same time. */ - mean = 0.0; - a = value; - nc = 0; - for( i = 0; i < n; i++, a++ ){ - if( *a != AST__BAD ) { - if( *a >= lolim && *a <= hilim ) { - mean += *a; - ibin = (int) ( ( *a - minval )/ delta ); - if( ibin == nbin ) ibin--; - hist[ ibin ]++; - nc++; - } - } - } - - mean /= ngood; - -/* We tend to prefer not to use reference values which are very close the - the limits since they can give problems with regard to normalization - (rounding errors can knock them over the edge), so we modify the counts - in each bin of the histogram to reduce the impact of bins near the edge. - However, we do not do this if the number of bins is very small or if - all the counts are in the edge bins. */ - modify = ( nbin > 4 && - ( hist[ 0 ] + hist[ nbin - 1 ] < 0.98*ngood ) ); - -/* Find the bin with the highest modified count. If there is more than one bin - with the highest modified count, choose the one which is closest to the - mean data value found above. Also count the number of non-empty bins. */ - nonemp = 0; - maxcnt = 0; - w0 = nbin/2; - for( i = 0; i < nbin; i++ ) { - - cnt = hist[ i ]; - if( cnt ) nonemp++; - - if( modify ) { - w1 = i*w0; - w2 = ( nbin - 1 - i )*w0; - w = ( w1 < w2 ) ? w1 :w2; - if( w < 1.0 ) cnt *= w; - } - - if( cnt > maxcnt ) { - maxcnt = cnt; - ibin = i; - - } else if( cnt == maxcnt ) { - if( fabs( minval + ( i - 0.5 )*delta - mean ) < - fabs( minval + ( ibin - 0.5 )*delta - mean ) ) { - maxcnt = cnt; - ibin = i; - } - } - } - -/* Free the histogram memory. */ - hist = astFree( hist ); - -/* If required, return the width of the non-empty bins. */ - if( width ) *width = nonemp*delta; - -/* Call this function recursively to refine the value, restricting - attention to those data values which are within the range of the bin - found above. */ - if( maxcnt < nc && ibin*delta > 1000.0*DBL_EPSILON*fabs(maxval) ) { - minval += ibin*delta; - maxval = minval + delta; - result = Typical( n, value, minval, maxval, NULL, status ); - } - } - } - } - -/* Return the result. */ - return result; -} - -static int GetUseColour( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseColour - -* Purpose: -* Get the Colour value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetUseColour( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Colour value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the colour -* for the first set specific value is returned. For example, if the -* Colour for AST__AXES_ID is requested, then the colour for AST__AXIS1_ID -* will be returned if set, and otherwise the colour for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Colour value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOCOLOUR; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first - set genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestColour( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestColour( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestColour( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetColour( this, id ); - -} - -static int GetUseFont( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseFont - -* Purpose: -* Get the Font value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetUseFont( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Font value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the Font -* for the first set specific value is returned. For example, if the -* Font for AST__AXES_ID is requested, then the Font for AST__AXIS1_ID -* will be returned if set, and otherwise the Font for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Font value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOFONT; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestFont( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestFont( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestFont( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetFont( this, id ); - -} - -static double GetUseSize( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseSize - -* Purpose: -* Get the Size value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GetUseSize( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Size value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the Size -* for the first set specific value is returned. For example, if the -* Size for AST__AXES_ID is requested, then the Size for AST__AXIS1_ID -* will be returned if set, and otherwise the Size for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Size value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOSIZE; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestSize( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestSize( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestSize( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetSize( this, id ); - -} - -static int GetUseStyle( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseStyle - -* Purpose: -* Get the Style value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int GetUseStyle( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Style value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the style -* for the first set specific value is returned. For example, if the -* Style for AST__AXES_ID is requested, then the style for AST__AXIS1_ID -* will be returned if set, and otherwise the style for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Style value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOSTYLE; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestStyle( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestStyle( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestStyle( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetStyle( this, id ); - -} - -static double GetUseWidth( AstPlot *this, int id, int *status ) { -/* -* Name: -* GetUseWidth - -* Purpose: -* Get the Width value to use for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* double GetUseWidth( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This returns the Width value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the Width -* for the first set specific value is returned. For example, if the -* Width for AST__AXES_ID is requested, then the Width for AST__AXIS1_ID -* will be returned if set, and otherwise the Width for AST__AXIS2_ID will -* be returned. If AST__AXIS2_ID is not set either, then the default for -* AST__AXIS2_ID will be returned. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Width value to use. - -*/ - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return NOWIDTH; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the value of the first set - genuine identifier. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - if( nid > 1 ) { - if( astTestWidth( this, id1 ) ) { - id = id1; - - } else if( nid > 1 && astTestWidth( this, id2 ) ) { - id = id2; - - } else if( nid > 2 && astTestWidth( this, id3 ) ) { - id = id3; - - } else { - id = id1; - } - } - -/* Return the result. */ - return astGetWidth( this, id ); - -} - -static int TestUseColour( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseColour - -* Purpose: -* Test the Colour value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseColour( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Colour value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Colour value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestColour( this, id1 ); - if( nid > 1 ) ret = ret && astTestColour( this, id2 ); - if( nid > 2 ) ret = ret && astTestColour( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseFont( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseFont - -* Purpose: -* Test the Font value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseFont( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Font value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Font value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestFont( this, id1 ); - if( nid > 1 ) ret = ret && astTestFont( this, id2 ); - if( nid > 2 ) ret = ret && astTestFont( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseSize( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseSize - -* Purpose: -* Test the Size value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseSize( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Size value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Size value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestSize( this, id1 ); - if( nid > 1 ) ret = ret && astTestSize( this, id2 ); - if( nid > 2 ) ret = ret && astTestSize( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseStyle( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseStyle - -* Purpose: -* Test the Style value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseStyle( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Style value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Style value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestStyle( this, id1 ); - if( nid > 1 ) ret = ret && astTestStyle( this, id2 ); - if( nid > 2 ) ret = ret && astTestStyle( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int TestUseWidth( AstPlot *this, int id, int *status ) { -/* -* Name: -* TestUseWidth - -* Purpose: -* Test the Width value for a specified graphical element. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int TestUseWidth( AstPlot *this, int id, int *status ) - -* Class Membership: -* Plot member function. - -* Description: -* This tests the Width value for the graphical element specified by -* id. If an element related to a generic value is being accessed (e.g -* "Axes" is generic, "Axis1" and "Axis2" are not), then the element -* is considered to be set if all the corresponding specific values are -* set. - -* Parameters: -* this -* Pointer to the Plot. -* id -* An integer specifying the graphical element to be drawn. -* status -* Pointer to the inherited status variable. - -* Returned Value: -* The Width value state (1 if set, zero otherwise). - -*/ - -/* Local Variables: */ - int ret; - -/* Local Variables: */ - int id1; /* First genuine identifier */ - int id2; /* Second genuine identifier */ - int id3; /* Third genuine identifier */ - int nid; /* Number of genuine attributes */ - -/* Check the global error status. */ - if ( !astOK ) return 0; - -/* See if the supplied identifier is a psuedo-identifier representing two - or three other genuine identifiers. If so, return the logical AND of the - test flags for the genuine identifiers. */ - nid = IdFind( id, astGetNin( this ), &id1, &id2, &id3, status ); - ret = astTestWidth( this, id1 ); - if( nid > 1 ) ret = ret && astTestWidth( this, id2 ); - if( nid > 2 ) ret = ret && astTestWidth( this, id3 ); - -/* Return the result. */ - return ret; - -} - -static int ToggleLogLin( AstPlot *this, int axis, int islog, - const char *method, int *status ){ -/* -* -* Name: -* ToggleLogLin - -* Purpose: -* Toggle the nature of the Plot axis mapping. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int ToggleLogLin( AstPlot *this, int axis, int islog, -* const char *method, int *status ) - -* Class Membership: -* Plot member function - -* Description: -* Each axis in the graphics Frame of a Plot can be mapped linearly or -* logarithmically onto the corresponding axis in the base Frame of -* the FrameSet supplied whtn the Plot was constructed. This function -* toggles the nature of the specified axis; if it is currently -* logarithmic it becomes linear, and if it is linear it becomes -* logarithmic. -* -* If the Frame canot be re-maped (for instance because the visible -* part of the axis includes the value zero), then zero is returned -* but no error is reported. - -* Parameters: -* this -* The Plot. -* axis -* Zero based axis index. -* islog -* Is the axis currently logarithmic? If so, this function remaps -* it so that it is linear (and vice-versa). -* method -* Pointer to a null-terminated string holding the name of the calling -* method (only used within error mesages). -* status -* Pointer to the inherited status variable. - -* Returned Value: -* Non-zero if the attempt to re-map the graphics Frame was succesful, -* zero otherwise. - -*/ - -/* Local Variables: */ - AstCmpMap *remap1; /* 1D Mapping to re-map the graphics Frame */ - AstCmpMap *remap2; /* 2D Mapping to re-map the graphics Frame */ - AstMathMap *logmap; /* 1D Logarithmic axis Mapping */ - AstUnitMap *unitmap; /* 1D Unit mapping */ - AstWinMap *linmap; /* 1D Linear axis Mapping */ - char fwdexp[ 25 + 2*DBL_DIG ]; /* Forward log mapping expression */ - char invexp[ 28 + 2*DBL_DIG ]; /* Inverse log mapping expression */ - const char *fwd[1]; /* Pointer to pass to MathMap constructor */ - const char *inv[1]; /* Pointer to pass to MathMap constructor */ - double a; /* Constant for log expression */ - double b1; /* Original base Frame axis value at first edge */ - double b2; /* Original base Frame axis value at second edge */ - double b; /* Constant for log expression */ - double c; /* Constant for log expression */ - double g1; /* Graphics axis value at first edge */ - double g2; /* Graphics axis value at second edge */ - int result; /* Returned value */ - -/* Inotialise. */ - result = 0; - -/* Check the global error status. */ - if ( !astOK ) return result; - -/* Get the corresponding axis limits in the graphics coordinate system - and the original base Frame coordinate system. */ - if( axis == 0 ) { - if( this->xrev ) { - g1 = this->xhi; - g2 = this->xlo; - } else { - g1 = this->xlo; - g2 = this->xhi; - } - b1 = this->bbox[ 0 ]; - b2 = this->bbox[ 2 ]; - - } else { - if( this->yrev ) { - g1 = this->yhi; - g2 = this->ylo; - } else { - g1 = this->ylo; - g2 = this->yhi; - } - b1 = this->bbox[ 1 ]; - b2 = this->bbox[ 3 ]; - } - -/* Check the limits are usable (e.g. the base Frame values will be bad - if this Plot was restored from a dump of a Plot created before the - LogPlot attributes were added). */ - if( b1 != AST__BAD && b2 != AST__BAD && g1 != g2 && b1 != b2 && - b1*b2 > 0.0 ) { - -/* Form the 1D Mapping which maps the specified axis linearly onto the plotting - surface. The forward transformation goes from graphics to base Frame. */ - linmap = astWinMap( 1, &g1, &g2, &b1, &b2, "", status ); - -/* Form the 1D Mapping which maps the specified axis logarithmically onto the - plotting surface. The forward transformation goes from graphics to base - Frame. */ - c = log10( b1/b2 ); - a = ( g1 - g2 )/c; - - if( b1 > 0.0 ) { - b = ( g2*log10( b1 ) - g1*log10( b2 ) )/c; - (void) sprintf( invexp, "g=%.*g*log10(b)+%.*g", DBL_DIG, a, DBL_DIG, b ); - (void) sprintf( fwdexp, "b=pow(10,(g-%.*g)/%.*g)", DBL_DIG, b, DBL_DIG, a ); - - } else { - b = ( g2*log10( -b1 ) - g1*log10( -b2 ) )/c; - (void) sprintf( invexp, "g=%.*g*log10(-b)+%.*g", DBL_DIG, a, DBL_DIG, b ); - (void) sprintf( fwdexp, "b=-pow(10,(g-%.*g)/%.*g)", DBL_DIG, b, DBL_DIG, a ); - } - - fwd[ 0 ] = (const char *) fwdexp; - inv[ 0 ] = (const char *) invexp; - logmap = astMathMap( 1, 1, 1, fwd, 1, inv, "SimpFI=1,SimpIF=1", status ); - -/* If the axis was previously logarithmic, get the Mapping with which to remap - the graphics Frame so that it becomes linearly related to the base Frame - in the FrameSet supplied when the Plot was constructed. */ - if( islog ) { - astInvert( linmap ); - remap1 = astCmpMap( logmap, linmap, 1, "", status ); - -/* If the axis was previously linear, store the new value and get the Mapping - with which to remap the graphics Frame so that it becomes logarithmically - related to the base Frame in the FrameSet supplied when the Plot was - constructed. */ - } else { - astInvert( logmap ); - remap1 = astCmpMap( linmap, logmap, 1, "", status ); - } - -/* Add a 1D UnitMap to map the unaltered mapping. */ - unitmap = astUnitMap( 1, "", status ); - if( axis == 0 ) { - remap2 = astCmpMap( remap1, unitmap, 0, "", status ); - } else { - remap2 = astCmpMap( unitmap, remap1, 0, "", status ); - } - -/* Remap the base (graphics) Frame in the Plot. */ - astRemapFrame( this, AST__BASE, remap2 ); - -/* Free resources. */ - remap1 = astAnnul( remap1 ); - remap2 = astAnnul( remap2 ); - logmap = astAnnul( logmap ); - linmap = astAnnul( linmap ); - unitmap = astAnnul( unitmap ); - -/* Indicate success. */ - if( astOK ) result = 1; - - } - -/* Return the result. */ - return result; -} - -static int Ustrcmp( const char *a, const char *b, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strcmp. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Ustrcmp( const char *a, const char *b ) - -* Class Membership: -* Plot member function. - -* Description: -* Returns 0 if there are no differences between the two strings, and 1 -* otherwise. Comparisons are case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference between -* the two strings, whereas "strcmp" does. -* - This function attempts to execute even if an error has occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Loop round each character. */ - while( 1 ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - -static int Ustrncmp( const char *a, const char *b, size_t n, int *status ){ -/* -* Name: -* Ustrncmp - -* Purpose: -* A case blind version of strncmp. - -* Type: -* Private function. - -* Synopsis: -* #include "plot.h" -* int Ustrncmp( const char *a, const char *b, size_t n ) - -* Class Membership: -* Plot member function. - -* Description: -* Returns 0 if there are no differences between the first "n" -* characters of the two strings, and 1 otherwise. Comparisons are -* case blind. - -* Parameters: -* a -* Pointer to first string. -* b -* Pointer to second string. -* n -* The maximum number of characters to compare. - -* Returned Value: -* Zero if the strings match, otherwise one. - -* Notes: -* - This function does not consider the sign of the difference -* between the two strings, whereas "strncmp" does. -* - This function attempts to execute even if an error has -* occurred. - -*/ - -/* Local Variables: */ - const char *aa; /* Pointer to next "a" character */ - const char *bb; /* Pointer to next "b" character */ - int i; /* Character index */ - int ret; /* Returned value */ - -/* Initialise the returned value to indicate that the strings match. */ - ret = 0; - -/* Initialise pointers to the start of each string. */ - aa = a; - bb = b; - -/* Compare up to "n" characters. */ - for( i = 0; i < (int) n; i++ ){ - -/* We leave the loop if either of the strings has been exhausted. */ - if( !(*aa ) || !(*bb) ){ - -/* If one of the strings has not been exhausted, indicate that the - strings are different. */ - if( *aa || *bb ) ret = 1; - -/* Break out of the loop. */ - break; - -/* If neither string has been exhausted, convert the next characters to - upper case and compare them, incrementing the pointers to the next - characters at the same time. If they are different, break out of the - loop. */ - } else { - - if( toupper( (int) *(aa++) ) != toupper( (int) *(bb++) ) ){ - ret = 1; - break; - } - - } - - } - -/* Return the result. */ - return ret; - -} - -/* Destructor. */ -/* ----------- */ -static void Delete( AstObject *obj, int *status ) { -/* -* Name: -* Delete - -* Purpose: -* Destructor for Plot objects. - -* Type: -* Private function. - -* Synopsis: -* void Delete( AstObject *obj, int *status ) - -* Description: -* This function implements the destructor for Plot objects. - -* Parameters: -* obj -* Pointer to the object to be deleted. -* status -* Pointer to the inherited status variable. - -* Notes: -* This function attempts to execute even if the global error status is -* set. -*/ - -/* Local Variables: */ - AstPlot *this; /* Pointer to Plot */ - int i; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) obj; - -/* Free the clipping bounds arrays. */ - this->clip_lbnd = (double *) astFree( (void *) this->clip_lbnd ); - this->clip_ubnd = (double *) astFree( (void *) this->clip_ubnd ); - -/* Free the Grf function stack */ - this->grfstack = (AstGrfPtrs *) astFree( (void *) this->grfstack ); - -/* Free the graphics attribute stack. */ - for( i = this->ngat - 1; i >= 0; i-- ) { - this->gat[ i ] = astFree( this->gat[ i ] ); - } - -/* Free the graphics context pointer. */ - if( this->grfcontext ) { - this->grfcontext = astAnnul( this->grfcontext ); - this->grfcontextID = astAnnulId( this->grfcontextID ); - } - -/* Free the information about the tick marks to draw. */ - for( i = 0; i < 3; i++ ) { - this->majtickval[ i ] = astFree( this->majtickval[ i ] ); - this->mintickval[ i ] = astFree( this->mintickval[ i ] ); - this->nmajtickval[ i ] = 0; - this->nmintickval[ i ] = 0; - } - -/* Free the information about the drawn tick marks. */ - SaveTick( this, -1, 0.0, 0.0, 0, status ); -} - -/* Copy constructor. */ -/* ----------------- */ -static void Copy( const AstObject *objin, AstObject *objout, int *status ) { -/* -* Name: -* Copy - -* Purpose: -* Copy constructor for Plot objects. - -* Type: -* Private function. - -* Synopsis: -* void Copy( const AstObject *objin, AstObject *objout, int *status ) - -* Description: -* This function implements the copy constructor for Plot objects. - -* Parameters: -* objin -* Pointer to the object to be copied. -* objout -* Pointer to the object being constructed. -* status -* Pointer to the inherited status variable. - -* Notes: -* - This constructor makes a deep copy. -*/ - -/* Local Variables: */ - AstPlot *in; /* Pointer to input Plot */ - AstPlot *out; /* Pointer to output Plot */ - int axis; /* Zero based axis index */ - int n; /* Number of ticks saved */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain pointers to the input and output Plots. */ - in = (AstPlot *) objin; - out = (AstPlot *) objout; - -/* For safety, first clear any references to the input memory from - the output Plot. */ - out->clip_lbnd = NULL; - out->clip_ubnd = NULL; - out->gat = NULL; - out->ngat = 0; - - for( axis = 0; axis < 3; axis++ ) { - out->majtickgx[ axis ] = NULL; - out->majtickgy[ axis ] = NULL; - out->majtickcount[ axis ] = 0; - out->mintickgx[ axis ] = NULL; - out->mintickgy[ axis ] = NULL; - out->mintickcount[ axis ] = 0; - out->majtickval[ axis ] = NULL; - out->nmajtickval[ axis ] = 0; - out->mintickval[ axis ] = NULL; - out->nmintickval[ axis ] = 0; - } - -/* Copy the clipping bounds arrays. */ - out->clip_lbnd = (double *) astStore( NULL, (void *) in->clip_lbnd, - sizeof(double)*(size_t)(in->clip_axes) ); - out->clip_ubnd = (double *) astStore( NULL, (void *) in->clip_ubnd, - sizeof(double)*(size_t)(in->clip_axes) ); - -/* Copy the Grf function stack */ - out->grfstack = (AstGrfPtrs *) astStore( NULL, (void *) in->grfstack, - sizeof(AstGrfPtrs)*(size_t)(in->grfnstack )); - -/* Copy the information about drawn tick marks. */ - for( axis = 0; axis < 3; axis++ ) { - n = in->majtickcount[ axis ]; - out->majtickgx[ axis ] = (double *) astStore( NULL, in->majtickgx[ axis ], - n*sizeof( double ) ); - out->majtickgy[ axis ] = (double *) astStore( NULL, in->majtickgy[ axis ], - n*sizeof( double ) ); - out->majtickcount[ axis ] = n; - - n = in->mintickcount[ axis ]; - out->mintickgx[ axis ] = (double *) astStore( NULL, in->mintickgx[ axis ], - n*sizeof( double ) ); - out->mintickgy[ axis ] = (double *) astStore( NULL, in->mintickgy[ axis ], - n*sizeof( double ) ); - out->mintickcount[ axis ] = n; - - n = in->nmajtickval[ axis ]; - out->majtickval[ axis ] = (double *) astStore( NULL, in->majtickval[ axis ], - n*sizeof( double ) ); - out->nmajtickval[ axis ] = n; - - n = in->nmintickval[ axis ]; - out->mintickval[ axis ] = (double *) astStore( NULL, in->mintickval[ axis ], - n*sizeof( double ) ); - out->nmintickval[ axis ] = n; - } - -/* If an error occurred, free any allocated memory. */ - if ( !astOK ) { - out->clip_lbnd = (double *) astFree( out->clip_lbnd ); - out->clip_ubnd = (double *) astFree( out->clip_ubnd ); - out->grfstack = (AstGrfPtrs *) astFree( out->grfstack ); - SaveTick( out, -1, 0.0, 0.0, 0, status ); - } -} - -/* Dump function. */ -/* -------------- */ -static void Dump( AstObject *this_object, AstChannel *channel, int *status ) { -/* -* Name: -* Dump - -* Purpose: -* Dump function for Plot objects. - -* Type: -* Private function. - -* Synopsis: -* void Dump( AstObject *this, AstChannel *channel, int *status ) - -* Description: -* This function implements the Dump function which writes out data -* for the Plot class to an output Channel. - -* Parameters: -* this -* Pointer to the Plot whose data are being written. -* channel -* Pointer to the Channel to which the data are being written. -* status -* Pointer to the inherited status variable. -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - AstPlot *this; /* Pointer to the Plot structure */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char *comment; /* Pointer to comment string */ - double dval; /* Double precision value */ - int ax; /* Axis to which element refers */ - int axis; /* Zero based axis index */ - int id; /* Zero based graphical object id */ - int ival; /* Integer value */ - int itick; /* Tick mark index */ - int nax; /* Number of base Frame axes */ - int set; /* Attribute value set? */ - -/* Check the global error status. */ - if ( !astOK ) return; - -/* Obtain a pointer to the Plot structure. */ - this = (AstPlot *) this_object; - -/* Get the number of graphics (base) frame axes - 2 for a Plot, 3 for a - Plot3D. */ - nax = astGetNin( this ); - -/* Write out values representing the instance variables for the - Plot class. Accompany these with appropriate comment strings, - possibly depending on the values being written.*/ - -/* In the case of attributes, we first use the appropriate (private) - Test... member function to see if they are set. If so, we then use - the (private) Get... function to obtain the value to be written - out. - - For attributes which are not set, we use the astGet... method to - obtain the value instead. This will supply a default value - (possibly provided by a derived class which over-rides this method) - which is more useful to a human reader as it corresponds to the - actual default attribute value. Since "set" will be zero, these - values are for information only and will not be read back. */ - -/* Tol. */ -/* ---- */ - set = TestTol( this, status ); - dval = set ? GetTol( this, status ) : astGetTol( this ); - astWriteDouble( channel, "Tol", set, 0, dval, "Plotting tolerance" ); - -/* Grid. */ -/* ----- */ - set = TestGrid( this, status ); - ival = set ? GetGrid( this, status ) : astGetGrid( this ); - astWriteInt( channel, "Grid", set, 0, ival, "Is a grid required?" ); - -/* TickAll. */ -/* -------- */ - set = TestTickAll( this, status ); - ival = set ? GetTickAll( this, status ) : astGetTickAll( this ); - astWriteInt( channel, "TckAll", set, 1, ival, "Put ticks on all edges?" ); - -/* ForceExterior. */ -/* -------------- */ - set = TestForceExterior( this, status ); - ival = set ? GetForceExterior( this, status ) : astGetForceExterior( this ); - astWriteInt( channel, "FrcExt", set, 1, ival, "Force exterior labelling?" ); - -/* Invisible. */ -/* ---------- */ - set = TestInvisible( this, status ); - ival = set ? GetInvisible( this, status ) : astGetInvisible( this ); - astWriteInt( channel, "Invsbl", set, 1, ival, "Use invisible ink?" ); - -/* Border. */ -/* ------- */ - set = TestBorder( this, status ); - ival = set ? GetBorder( this, status ) : astGetBorder( this ); - astWriteInt( channel, "Border", set, 0, ival, "Draw a border round the grid?" ); - -/* ClipOp. */ -/* ------- */ - set = TestClipOp( this, status ); - ival = set ? GetClipOp( this, status ) : astGetClipOp( this ); - astWriteInt( channel, "ClpOp", set, 0, ival, "Clip using logical OR?" ); - -/* Clip. */ -/* ----- */ - set = TestClip( this, status ); - ival = set ? GetClip( this, status ) : astGetClip( this ); - astWriteInt( channel, "Clip", set, 0, ival, - ((ival == 0)?"Do not clip at plot edges": - ((ival == 1)?"Clip curves at plot edges": - ((ival == 2)?"Clip markers at plot edges": - "Clip markers and curves at plot edges")))); - -/* DrawTitle. */ -/* --------- */ - set = TestDrawTitle( this, status ); - ival = set ? GetDrawTitle( this, status ) : astGetDrawTitle( this ); - astWriteInt( channel, "DrwTtl", set, 1, ival, "Add a title to the grid?" ); - -/* DrawAxesUnits(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestDrawAxes( this, axis, status ); - ival = set ? GetDrawAxes( this, axis, status ) : astGetDrawAxes( this, axis ); - (void) sprintf( buff, "DrwAxs%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Draw axis through ticks?" ); - } - -/* Abbrev(axis). */ -/* ------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestAbbrev( this, axis, status ); - ival = set ? GetAbbrev( this, axis, status ) : astGetAbbrev( this, axis ); - (void) sprintf( buff, "Abbrv%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Abbreviate numerical axis labels?" ); - } - -/* Escape. */ -/* ------- */ - set = TestEscape( this, status ); - ival = set ? GetEscape( this, status ) : astGetEscape( this ); - astWriteInt( channel, "Escape", set, 1, ival, "Interpret escape sequences?" ); - -/* LabelAt(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLabelAt( this, axis, status ); - dval = set ? GetLabelAt( this, axis, status ) : astGetLabelAt( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "LblAt%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Put numerical labels at" ); - } - } - -/* Centre(axis). */ -/* ------------ */ - for( axis = 0; axis < nax; axis++ ){ - set = TestCentre( this, axis, status ); - dval = set ? GetCentre( this, axis, status ) : astGetCentre( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "Cen%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Tick mark origin" ); - } - } - -/* Gap(axis). */ -/* ---------- */ -/* Discovering the default value requires a lot of calculation. Only - write out this attribute if an explicit value has been set. */ - for( axis = 0; axis < nax; axis++ ){ - if( astTestGap( this, axis ) ) { - dval = astGetGap( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "Gap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Difference between ticks" ); - } - } - } - -/* LogGap(axis). */ -/* ------------- */ -/* Discovering the default value requires a lot of calculation. Only - write out this attribute if an explicit value has been set. */ - for( axis = 0; axis < nax; axis++ ){ - if( astTestLogGap( this, axis ) ) { - dval = astGetLogGap( this, axis ); - if( dval != AST__BAD ){ - (void) sprintf( buff, "LgGap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Ratio between ticks" ); - } - } - } - -/* NumLabGap(axis). */ -/* ---------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestNumLabGap( this, axis, status ); - dval = set ? GetNumLabGap( this, axis, status ) : astGetNumLabGap( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "NmGap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 1, dval, "Spacing of numerical labels" ); - } - } - -/* TextLabGap(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestTextLabGap( this, axis, status ); - dval = set ? GetTextLabGap( this, axis, status ) : astGetTextLabGap( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "TxGap%d", axis + 1 ); - astWriteDouble( channel, buff, set, 1, dval, "Spacing of descriptive labels" ); - } - } - -/* LabelUp(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLabelUp( this, axis, status ); - ival = set ? GetLabelUp( this, axis, status ) : astGetLabelUp( this, axis ); - (void) sprintf( buff, "LblUp%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Draw numerical labels upright?" ); - } - -/* LogPlot(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLogPlot( this, axis, status ); - ival = set ? GetLogPlot( this, axis, status ) : astGetLogPlot( this, axis ); - (void) sprintf( buff, "LgPlt%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Map plot axis logarithmically?" ); - } - -/* LogTicks(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLogTicks( this, axis, status ); - ival = set ? GetLogTicks( this, axis, status ) : astGetLogTicks( this, axis ); - (void) sprintf( buff, "LgTck%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Space ticks logarithmically?" ); - } - -/* LogLabel(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLogLabel( this, axis, status ); - ival = set ? GetLogLabel( this, axis, status ) : astGetLogLabel( this, axis ); - (void) sprintf( buff, "LgLbl%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Scientific notation for labels?" ); - } - -/* NumLab(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestNumLab( this, axis, status ); - ival = set ? GetNumLab( this, axis, status ) : astGetNumLab( this, axis ); - (void) sprintf( buff, "NmLbl%d", axis + 1 ); - astWriteInt( channel, buff, set, 1, ival, "Draw numerical labels?" ); - } - -/* MinTick(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestMinTick( this, axis, status ); - ival = set ? GetMinTick( this, axis, status ) : astGetMinTick( this, axis ); - (void) sprintf( buff, "MnTks%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "No. of sub-divisions " - "between major tick marks" ); - } - -/* TextLab(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestTextLab( this, axis, status ); - ival = set ? GetTextLab( this, axis, status ) : astGetTextLab( this, axis ); - (void) sprintf( buff, "TxLbl%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Draw textual label?" ); - } - -/* LabelUnits(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestLabelUnits( this, axis, status ); - ival = set ? GetLabelUnits( this, axis, status ) : astGetLabelUnits( this, axis ); - (void) sprintf( buff, "LbUnt%d", axis + 1 ); - astWriteInt( channel, buff, set, 0, ival, "Add units to axis label?" ); - } - -/* Style(object). */ -/* -------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestStyle( this, id, status ); - ival = set ? GetStyle( this, id, status ) : astGetStyle( this, id ); - (void) sprintf( buff, "Style%d", id + 1 ); - comment = GrfItem( id, " line style", &ax, status ); - if( ax < nax ) astWriteInt( channel, buff, set, 0, ival, comment ); - comment = (char *) astFree( (void *) comment ); - } - -/* Font(object). */ -/* ------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestFont( this, id, status ); - ival = set ? GetFont( this, id, status ) : astGetFont( this, id ); - (void) sprintf( buff, "Font%d", id + 1 ); - comment = GrfItem( id, " character font", &ax, status ); - if( ax < nax ) astWriteInt( channel, buff, set, 0, ival, comment ); - comment = (char *) astFree( (void *) comment ); - } - -/* Colour(object). */ -/* --------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestColour( this, id, status ); - ival = set ? GetColour( this, id, status ) : astGetColour( this, id ); - (void) sprintf( buff, "Col%d", id + 1 ); - comment = GrfItem( id, " colour index", &ax, status ); - if( ax < nax ) astWriteInt( channel, buff, set, 0, ival, comment ); - comment = (char *) astFree( (void *) comment ); - } - -/* Width(object). */ -/* -------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestWidth( this, id, status ); - dval = set ? GetWidth( this, id, status ) : astGetWidth( this, id ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "Width%d", id + 1 ); - comment = GrfItem( id, " line width", &ax, status ); - if( ax < nax ) astWriteDouble( channel, buff, set, 0, dval, comment ); - comment = (char *) astFree( (void *) comment ); - } - } - -/* Size(object). */ -/* ------------- */ - for( id = 0; id < AST__NPID; id++ ){ - set = TestSize( this, id, status ); - dval = set ? GetSize( this, id, status ) : astGetSize( this, id ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "Size%d", id + 1 ); - comment = GrfItem( id, " character size", &ax, status ); - if( ax < nax ) astWriteDouble( channel, buff, set, 0, dval, comment ); - comment = (char *) astFree( (void *) comment ); - } - } - -/* TitleGap. */ -/* --------- */ - set = TestTitleGap( this, status ); - dval = set ? GetTitleGap( this, status ) : astGetTitleGap( this ); - if( dval != AST__BAD ) astWriteDouble( channel, "TtlGap", set, 1, dval, - "Gap between title and edge" ); - -/* MajTickLen(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestMajTickLen( this, axis, status ); - dval = set ? GetMajTickLen( this, axis, status ) : astGetMajTickLen( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "MjTkLn%d", axis + 1 ); - astWriteDouble( channel, buff, set, 0, dval, "Major tick length" ); - } - } - -/* MinTickLen(axis). */ -/* ----------------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestMinTickLen( this, axis, status ); - dval = set ? GetMinTickLen( this, axis, status ) : astGetMinTickLen( this, axis ); - if( dval != AST__BAD ) { - (void) sprintf( buff, "MnTkLn%d", axis + 1 ); - astWriteDouble( channel, buff, set, 1, dval, "Minor tick length" ); - } - } - -/* Labelling. */ -/* ---------- */ - set = TestLabelling( this, status ); - ival = set ? GetLabelling( this, status ) : astGetLabelling( this ); - comment = "Labelling scheme"; - astWriteString( channel, "Lbling", set, 0, xlbling[ival], comment ); - -/* Edge(axis). */ -/* ----------- */ - for( axis = 0; axis < nax; axis++ ){ - set = TestEdge( this, axis, status ); - ival = set ? GetEdge( this, axis, status ) : astGetEdge( this, axis ); - (void) sprintf( buff, "Edge%d", axis + 1 ); - comment = "Edge used to label an axis"; - astWriteString( channel, buff, set, 0, xedge[ival], comment ); - } - -/* Now do instance variables which are not attributes. */ -/* =================================================== */ - -/* Only write out clipping information if set. */ - if( this->clip_lbnd && this->clip_ubnd ){ - -/* The lower bounds of the clipping volume. */ - for( axis = 0; axis < this->clip_axes; axis++ ){ - (void) sprintf( buff, "ClpLb%d", axis + 1 ); - if( this->clip_lbnd && (this->clip_lbnd)[ axis ] != AST__BAD ){ - astWriteDouble( channel, buff, 1, 0, (this->clip_lbnd)[ axis ], - "Lower bound of clipping region" ); - } - } - -/* The upper bounds of the clipping volume. */ - for( axis = 0; axis < this->clip_axes; axis++ ){ - (void) sprintf( buff, "ClpUb%d", axis + 1 ); - if( this->clip_ubnd && (this->clip_ubnd)[ axis ] != AST__BAD ){ - astWriteDouble( channel, buff, 1, 0, (this->clip_ubnd)[ axis ], - "Upper bound of clipping region" ); - } - } - -/* The number of bounds supplied for the clipping volume. */ - astWriteInt( channel, "ClpAxs", 1, 0, this->clip_axes, - "No. of bounds for clipping region" ); - -/* The index of the clipping Frame within the Plot. */ - astWriteInt( channel, "ClpFrm", 1, 0, this->clip_frame, - "Index of clipping Frame" ); - } - -/* The bounds of the plotting area in graphics coords. */ - astWriteDouble( channel, "Xlo", 1, 1, this->xlo, - "Lower X bound of plotting area" ); - astWriteDouble( channel, "Ylo", 1, 1, this->ylo, - "Lower Y bound of plotting area" ); - astWriteDouble( channel, "Xhi", 1, 1, this->xhi, - "Upper X bound of plotting area" ); - astWriteDouble( channel, "Yhi", 1, 1, this->yhi, - "Upper Y bound of plotting area" ); - -/* Axis reversal flags. */ - astWriteInt( channel, "Xrev", 1, 0, this->xrev, "X axis reversed?" ); - astWriteInt( channel, "Yrev", 1, 0, this->yrev, "Y axis reversed?" ); - -/* The bounds of the plotting area in the base Frame of the FrameSet - supplied when the Plot was constructed. */ - astWriteDouble( channel, "Xb1", 1, 1, this->bbox[ 0 ], - "Lower X bound of supplied base Frame" ); - astWriteDouble( channel, "Yb1", 1, 1, this->bbox[ 1 ], - "Lower Y bound of supplied base Frame" ); - astWriteDouble( channel, "Xb2", 1, 1, this->bbox[ 2 ], - "Upper X bound of supplied base Frame" ); - astWriteDouble( channel, "Yb2", 1, 1, this->bbox[ 3 ], - "Upper Y bound of supplied base Frame" ); - -/* User-specified tick values */ - for( axis = 0; axis < 3; axis++ ) { - - if( this->nmajtickval[ axis ] > 0 ) { - sprintf( buff, "NMjTk%d", axis + 1 ); - astWriteInt( channel, buff, 1, 1, this->nmajtickval[ axis ], "" ); - - for( itick = 0; itick < this->nmajtickval[ axis ]; itick++ ) { - sprintf( buff, "MjTk%d_%d", axis + 1, itick + 1 ); - astWriteDouble( channel, buff, 1, 1, - this->majtickval[ axis ][ itick ], "" ); - } - } - - if( this->nmintickval[ axis ] > 0 ) { - sprintf( buff, "NMnTk%d", axis + 1 ); - astWriteInt( channel, buff, 1, 1, this->nmintickval[ axis ], "" ); - - for( itick = 0; itick < this->nmintickval[ axis ]; itick++ ) { - sprintf( buff, "MnTk%d_%d", axis + 1, itick + 1 ); - astWriteDouble( channel, buff, 1, 1, - this->mintickval[ axis ][ itick ], "" ); - } - } - } - -/* Return. */ - return; - -/* Undefine macros local to this function. */ -#undef KEY_LEN -} - - -/* Standard class functions. */ -/* ========================= */ -/* Implement the astIsAPlot and astCheckPlot functions using - the macros defined for this purpose in the "object.h" header - file. */ -astMAKE_ISA(Plot,FrameSet) -astMAKE_CHECK(Plot) - -AstPlot *astPlot_( void *frame_void, const float *graphbox, - const double *basebox, const char *options, int *status, ...) { -/* -*+ -* Name: -* astPlot - -* Purpose: -* Create a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* AstPlot *astPlot( AstFrame *frame, const float *graphbox, -* const double *basebox, const char *options, ..., int *status ) - -* Class Membership: -* Plot constructor. - -* Description: -* This function creates a new Plot and optionally initialises -* its attributes. -* -* The supplied Frame (or the base frame if a FrameSet was supplied) is -* assumed to be related to the graphics world coordinate system by a -* simple shift and scale along each axis. The mapping between graphics -* world coordinates and this Frame is specified by supplying the -* coordinates in both systems at the bottom left and top right corners -* of a box on the graphics device. By default, no graphics will be -* produced outside the supplied box, but this default behaviour can be -* changed by setting explicit values for the various clipping attributes. - -* Parameters: -* frame -* A pointer to a Frame or FrameSet to be annotated. If a NULL pointer -* is supplied, then a default 2-D Frame will be created to which labels, -* etc, can be attached by setting the relevant Frame attributes. -* graphbox -* A pointer to an array of 4 values giving the graphics world -* coordinates of the bottom left and top right corners of a box on -* the graphics output device. The first pair of values should be the -* coordinates of the bottom left corner of the box and the second -* pair of values should be the coordinates of the top right corner. -* The horizontal axis should be given first in each pair. -* basebox -* A pointer to an array of 4 values giving the coordinates in the -* supplied Frame, or base frame of the supplied FrameSet, at the -* bottom left and top right corners of the box specified by parameter -* graphbox. These should be supplied in the same order as for -* parameter "graphbox". -* options -* Pointer to a null terminated string containing an optional -* comma-separated list of attribute assignments to be used for -* initialising the new Plot. The syntax used is the same as -* for the astSet method and may include "printf" format -* specifiers identified by "%" symbols in the normal way. -* status -* Pointer to the inherited status variable. -* ... -* If the "options" string contains "%" format specifiers, then -* an optional list of arguments may follow it in order to -* supply values to be substituted for these specifiers. The -* rules for supplying these are identical to those for the -* astSet method (and for the C "printf" function). - -* Returned Value: -* A pointer to the new Plot. - -* Notes: -* - The base Frame of the created Plot corresponds to the graphics world -* coordinate system, and should not, in general, be changed. -* - The current Frame of the created Plot corresponds to the Frame -* given by parameter "frame". If a FrameSet was supplied then its -* current Frame becomes the current Frame of the created Plot. -* - If the supplied Frame, or base Frame if a FrameSet was supplied, -* has more than 2 axes, then the sub-Frame defined by the first 2 axes -* is used. -* - A NULL pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- - -* Implementation Notes: -* - This function implements the basic Plot constructor which -* is available via the protected interface to the Plot class. -* A public interface is provided by the astPlotId_ function. -* - Because this function has a variable argument list, it is -* invoked by a macro that evaluates to a function pointer (not a -* function invocation) and no checking or casting of arguments is -* performed before the function is invoked. Because of this, the -* "frame" parameter is of type (void *) and is converted and -* validated within the function itself. - -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPlot *new; /* Pointer to new Plot */ - va_list args; /* Variable argument list */ - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - new = NULL; - -/* Obtain and validate a pointer to any supplied Frame structure. */ - if( frame_void ){ - frame = astCheckFrame( frame_void ); - } else { - frame = NULL; - } - -/* Check the pointer can be used. */ - if ( astOK ) { - -/* Initialise the Plot, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPlot( NULL, sizeof( AstPlot ), !class_init, - &class_vtab, "Plot", frame, graphbox, - basebox ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Plot's attributes. */ - va_start( args, status ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return a pointer to the new Plot. */ - return new; -} - -AstPlot *astInitPlot_( void *mem, size_t size, int init, AstPlotVtab *vtab, - const char *name, AstFrame *frame, const float *graphbox, - const double *basebox, int *status ) { -/* -*+ -* Name: -* astInitPlot - -* Purpose: -* Initialise a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "plot.h" -* AstPlot *astInitPlot( void *mem, size_t size, int init, -* AstPlotVtab *vtab, const char *name, -* AstFrame *frame, const float *graphbox, -* const double *basebox ) - -* Class Membership: -* Plot initialiser. - -* Description: -* This function is provided for use by class implementations to initialise -* a new Plot object. It allocates memory (if necessary) to accommodate -* the Plot plus any additional data associated with the derived class. -* It then initialises a Plot structure at the start of this memory. If -* the "init" flag is set, it also initialises the contents of a virtual -* function table for a Plot at the start of the memory passed via the -* "vtab" parameter. - -* Parameters: -* mem -* A pointer to the memory in which the Plot is to be created. This -* must be of sufficient size to accommodate the Plot data -* (sizeof(Plot)) plus any data used by the derived class. If a value -* of NULL is given, this function will allocate the memory itself using -* the "size" parameter to determine its size. -* size -* The amount of memory used by the Plot (plus derived class data). -* This will be used to allocate memory if a value of NULL is given for -* the "mem" parameter. This value is also stored in the Plot -* structure, so a valid value must be supplied even if not required for -* allocating memory. -* init -* A logical flag indicating if the Plot's virtual function table is -* to be initialised. If this value is non-zero, the virtual function -* table will be initialised by this function. -* vtab -* Pointer to the start of the virtual function table to be associated -* with the new Plot. If NULL, the vtab associated with this class -* (Plot) will be used. -* name -* Pointer to a constant null-terminated character string which contains -* the name of the class to which the new object belongs (it is this -* pointer value that will subsequently be returned by the astGetClass -* method). -* frame -* A pointer to the Frame or Frameset to be annotated. -* graphbox -* A pointer to an array of 4 values giving the graphics coordinates -* of the bottom left and top right corners of a box on the graphics -* output device. The first pair of values should be the graphics -* coordinates of the bottom left corner of the box and the second -* pair of values are the graphics coordinates of the top right corner. -* The horizontal axis should be given first in each pair. -* basebox -* A pointer to an array of 4 values giving the coordinates in the -* supplied Frame or base Frame of the supplied FrameSet at the bottom -* left and top right corners of the box specified by parameter graphbox. -* These should be supplied in the same order as for parameter "graphbox". - -* Returned Value: -* A pointer to the new Plot. - -* Notes: -* - If the supplied Frame, or base Frame if a FrameSet was supplied, -* has more than 2 axes, then the sub-Frame defined by the first 2 axes -* is used. -* - The current Frame of the supplied FrameSet need not be 2-dimensional. -* - A null pointer will be returned if this function is invoked with the -* global error status set, or if it should fail for any reason. -*- -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *baseframe; /* Pointer to base frame */ - AstFrame *graphicsframe; /* Pointer to graphics frame */ - AstFrameSet *fset0; /* The n-D FrameSet to be annotated */ - AstFrameSet *fset; /* The 2-D FrameSet to be annotated */ - AstPlot *new; /* Pointer to new Plot */ - AstWinMap *map; /* Mapping for converting bbox -> gbox */ - char *mess; /* Pointer to a descriptive message */ - double gbox[ 4 ]; /* Double precision version of "graphbox" */ - int axis; /* Axis index, 0 or 1 */ - int bi; /* Index of base frame */ - int ci; /* Index of current frame */ - int i; /* Loop count */ - int id; /* Plot object id */ - int naxes; /* No. of axes in frame */ - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(frame); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - fset = NULL; - mess = NULL; - -/* If no vtab was supplied, use the vtab for this class (Plot). */ - if( !vtab ) { - vtab = &class_vtab; - if ( !class_init ) { - astInitPlotVtab( vtab, "Plot" ); - class_init = 1; - } - -/* If necessary, initialise the virtual function table. */ - } else if ( init ) { - astInitPlotVtab( vtab, name ); - } - -/* Initialise. */ - new = NULL; - baseframe = NULL; - -/* First of all we need to ensure that we have a FrameSet and a base - Frame on which to base the new Plot. If a NULL Frame pointer was - supplied, create a default 2-D Frame, and then create a FrameSet - containing just this default Frame. Also store a pointer to a - message which can be used to describe the object within error - messages. */ - if( !frame ){ - baseframe = astFrame( 2, "", status ); - fset = astFrameSet( baseframe, "", status ); - mess = "default 2-d Frame"; - -/* If an object was supplied, report an error if it is not a Frame or - an object derived from a Frame (such as a FrameSet). */ - } else if( !astIsAFrame( frame ) ){ - if( astOK ){ - astError( AST__BDOBJ, "astInitPlot(%s): Supplied Object (class '%s') " - "is not a Frame.", status, name, astGetClass( frame ) ); - } - -/* If the supplied object is a Plot or an object derived from a Plot (a Plot - is a sort of Frame and so will pass the above test), extract a - FrameSet from the Plot, and clear the Domain attribute for any existing - Frames which have Domain GRAPHICS. */ - } else if( astIsAPlot( frame ) ){ - fset0 = astFrameSet( frame, "", status ); - fset = astCopy( fset0 ); - fset0 = astAnnul( fset0 ); - - for( i = 0; i < astGetNframe( fset ); i++ ) { - graphicsframe = astGetFrame( fset, i ); - if( !strcmp( astGetDomain( graphicsframe ), "GRAPHICS" ) ) { - astClearDomain( graphicsframe ); - } - graphicsframe = astAnnul( graphicsframe ); - } - - baseframe = astGetFrame( fset, astGetBase( fset ) ); - mess = "base Frame of the supplied Plot"; - -/* If the object is not a FrameSet, create a FrameSet holding the - supplied Frame. If the Frame is not 2D, an extra 2D Frame is - included in the FrameSet derived from axes 1 and 2 of the supplied - Frame. This new Frame becomes the base Frame. */ - } else if( !astIsAFrameSet( frame ) ){ - fset0 = astFrameSet( frame, "", status ); - mess = "supplied Frame"; - fset = Fset2D( fset0, AST__BASE, status ); - fset0 = astAnnul( fset0 ); - baseframe = astGetFrame( fset, astGetBase( fset ) ); - -/* If a FrameSet was supplied, ensure it has a 2D base Frame. - If the supplied FrameSet is not 2D, then a new base Frame is - inserted into it which is derived from axes 1 and 2 of the - original base Frame. */ - } else { - fset = Fset2D( (AstFrameSet *) frame, AST__BASE, status ); - baseframe = astGetFrame( fset, astGetBase( fset ) ); - mess = "base Frame of the supplied FrameSet"; - } - -/* Check that there are 2 axes in the base frame of the FrameSet. */ - naxes = astGetNaxes( baseframe ); - if ( naxes != 2 && astOK ) { - astError( AST__NAXIN, "astInitPlot(%s): Number of axes (%d) in the %s " - "is invalid - this number should be 2.", status, name, naxes, mess ); - } - -/* Check that neither dimension of the graphbox is zero. */ - if( ( graphbox[ 2 ] == graphbox[ 0 ] || - graphbox[ 3 ] == graphbox[ 1 ] ) && astOK ){ - astError( AST__BADBX, "astInitPlot(%s): The plotting area has zero size " - "in the graphics world coordinate system.", status, name ); - } - -/* Check that neither dimension of the graphbox is bad. */ - if( astISBAD(graphbox[0]) || astISBAD(graphbox[1]) || - astISBAD(graphbox[2]) || astISBAD(graphbox[3]) ) { - astError( AST__BADBX, "astInitPlot(%s): The plotting area has undefined limits " - "in the graphics world coordinate system.", status, name ); - } - -/* Check that neither dimension of the basebox is zero. */ - if( astISBAD(basebox[2]) || astISBAD(basebox[0]) ) { - astError( AST__BADBX, "astInitPlot(%s): The limits of the horizontal " - "axis of the %s are undefined or bad.", status, name, name ); - } else if( astISBAD(basebox[3]) || astISBAD(basebox[1]) ) { - astError( AST__BADBX, "astInitPlot(%s): The limits of the vertical " - "axis of the %s are undefined or bad.", status, name, name ); - } - -/* Create a Frame which describes the graphics world coordinate system. */ - graphicsframe = astFrame( 2, - "Domain=GRAPHICS,Title=Graphical Coordinates", status ); - -/* Initialise a FrameSet structure (the parent class) as the first - component within the Plot structure, allocating memory if necessary. - The new FrameSet is initialised to hold the graphics Frame created - above. */ - new = (AstPlot *) astInitFrameSet( mem, size, 0, (AstFrameSetVtab *) vtab, - name, graphicsframe ); - - if ( astOK ) { - -/* Initialise the Plot data. */ -/* ----------------------------- */ - -/* Get a double precision version of "graphbox". */ - gbox[ 0 ] = (double) graphbox[ 0 ]; - gbox[ 1 ] = (double) graphbox[ 1 ]; - gbox[ 2 ] = (double) graphbox[ 2 ]; - gbox[ 3 ] = (double) graphbox[ 3 ]; - -/* Store the bounds in graphics coordinates of the clipping box, ensuring - that the low bound is lower than the high bound. Set flags to indicate - if the supplied bounds has to be reversed to do this (some graphics - system have the Y axis increasing from the top of the screen to the - bottom). */ - if( graphbox[ 0 ] <= graphbox[ 2 ] ){ - new->xlo = gbox[ 0 ]; - new->xhi = gbox[ 2 ]; - new->xrev = 0; - } else { - new->xhi = gbox[ 0 ]; - new->xlo = gbox[ 2 ]; - new->xrev = 1; - astSetDirection( graphicsframe, 0, 0 ); - } - if( graphbox[ 1 ] <= graphbox[ 3 ] ){ - new->ylo = gbox[ 1 ]; - new->yhi = gbox[ 3 ]; - new->yrev = 0; - } else { - new->yhi = gbox[ 1 ]; - new->ylo = gbox[ 3 ]; - new->yrev = 1; - astSetDirection( graphicsframe, 1, 0 ); - } - -/* Store the bounds of the Plot within the base Frame of the supplied - FrameSet. */ - new->bbox[ 0 ] = basebox[ 0 ]; - new->bbox[ 1 ] = basebox[ 1 ]; - new->bbox[ 2 ] = basebox[ 2 ]; - new->bbox[ 3 ] = basebox[ 3 ]; - -/* We initially assume that the base Frame of the supplied FrameSet is - mapped lineary onto the graphics frame. This may be changed later by - assigning values to the LogPlot attributes. Create a WinMap which - maps the base box (within the base Frame of the supplied FrameSet) - onto the graphics box. */ - map = astWinMap( 2, gbox, gbox + 2, basebox, basebox + 2, "", status ); - -/* Get the index of the current (physical) and base (pixel) Frames in - the supplied FrameSet. */ - bi = astGetBase( fset ); - ci = astGetCurrent( fset ); - -/* Temporarily set the current Frame to be the pixel frame. */ - astSetCurrent( fset, bi ); - -/* Add the supplied FrameSet into the Plot (i.e. FrameSet) created - earlier. This leaves the graphics frame with index 1 in the - returned Plot. We use the linear mapping initially. */ - astAddFrame( (AstFrameSet *) new, 1, map, fset ); - map = astAnnul( map ); - -/* Set the current Frame in the Plot to be the physical coordinate Frame - (with index incremented by one because the graphics Frame has been added). */ - astSetCurrent( (AstFrameSet *) new, ci + 1 ); - -/* Re-establish the original current Frame in the supplied FrameSet. */ - astSetCurrent( fset, ci ); - -/* Store a value of -1.0 for Tol to indicate that no value has yet been - set. This will cause a default value of 0.001 to be used. */ - new->tol = -1.0; - -/* Set up default clipping information which gives no clipping. */ - new->clip_frame = AST__NOFRAME; - new->clip_lbnd = NULL; - new->clip_ubnd = NULL; - new->clip_axes = 0; - -/* Is a grid covering the plotting area required? Store a value of -1 - to indicate that no value has yet been set. This will cause a default - value of 0 (no) to be used. */ - new->grid = -1; - -/* Are tick marks to be placed on both edges in a pair of opposite edges? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 1 (yes) to be used. */ - new->tickall = -1; - -/* Graphics context identifier */ - new->grfcontext = NULL; - new->grfcontextID = NULL; - -/* Shoudl ast Grid draw a boundary round the regions of valid coordinates? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 1 (yes) to be used. */ - new->border = -1; - -/* Should graphics be drawn invisible? Store a value of -1 to indicate that - no value has yet been set. This will cause a default value of 0 (no) to - be used. */ - new->invisible = -1; - -/* By default clip markers but not curves at the boundary of the plotting - area. This was the only behaviour available prior to the introduction of - the Clip attribute, and is chosen as the default to maintain backwards - compatibility. */ - new->clip = -1; - -/* Is clipping to be done using a logical OR operation between the axes? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 0 (no, i.e. a logical AND) to be used. */ - new->clipop = -1; - -/* Is the graphics interface registered using astGrfSet to be used? - Store a value of -1 to indicate that no value has yet been set. This will - cause a default value of 0 (no, i.e. use the graphics interface - selected at link-time) to be used. */ - new->grf = -1; - -/* Wrapper functions to call the drawing routines. These are the - default wrappers which call GRF routines written in C. Alternative - wrappers are defined in fplot.c for use with GRF routines written in - F77. */ - new->GAttr = CGAttrWrapper; - new->GBBuf = CGBBufWrapper; - new->GEBuf = CGEBufWrapper; - new->GFlush = CGFlushWrapper; - new->GLine = CGLineWrapper; - new->GMark = CGMarkWrapper; - new->GText = CGTextWrapper; - new->GCap = CGCapWrapper; - new->GTxExt = CGTxExtWrapper; - new->GScales = CGScalesWrapper; - new->GQch = CGQchWrapper; - - for( i = 0; i < AST__NGRFFUN; i++ ) new->grffun[i] = NULL; - new->grfstack = NULL; - new->grfnstack = 0; - -/* Is a title to be added to an annotated grid? Store a value of -1 to - indicate that no value has yet been set. This will cause a default value - of 1 (yes) to be used. */ - new->drawtitle = -1; - -/* Are escape sequences within text strings to be interpreted? If not, - they are printed literally. Store a value of -1 when not set. - This will cause a default value of 1 (yes) to be used. */ - new->escape = -1; - -/* A boolean attribute indicating where numerical labels are to be - placed; zero implies round the edges of the plotting area; non-zero - implies within the plotting area. The unset value of -9999 yields a - default of zero. */ - new->labelling = -9999; - -/* Graphics attributes. Default behaviour is to use the current values. */ - for( id = 0; id < AST__NPID; id++ ){ - new->style[ id ] = -1; - new->font[ id ] = -1; - new->colour[ id ] = -1; - new->width[ id ] = AST__BAD; - new->size[ id ] = AST__BAD; - } - -/* The space between the top edge and the grid title as a fraction of the - minimum dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.05 to be used. */ - new->titlegap = AST__BAD; - -/* Initialise the protected Ink attribute so that visible ink is used. */ - new->ink = -1; - -/* A stack of AstGat pointers used to store the graphical attributes for - text within strings which include graphical escape sequences. */ - new->gat = NULL; - new->ngat = 0; - -/* Now set the attribute values for each axis. The arrays stored in the - Plot struture allow for 3 graphics axes (e.g. as used by a Plot3D) so - we initialise 3 axes here even though the Plot class only uses 2. */ - for( axis = 0; axis < 3; axis++ ) { - -/* Are curves to be drawn through the tick marks even if no grid is - produced? Store a value of -1 to indicate that no value has yet been - set. This will cause a default value of 1 (yes) to be used. */ - new->drawaxes[ axis ] = -1; - -/* Are adjacent numerical axis labels to be abbreviated by removing matching - leading fields? Store a value of -1 to indicate that no value has yet been - set. This will cause a default value of 1 (yes) to be used. */ - new->abbrev[ axis ] = -1; - -/* The length of the major tick marks as a fraction of the minimum - dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.015 to be used. */ - new->majticklen[ axis ] = AST__BAD; - -/* The length of the minor tick marks as a fraction of the minimum - dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.007 to be used. */ - new->minticklen[ axis ] = AST__BAD; - -/* Are numeric labels to be drawn upright? Store a value of -1 to indicate - that no value has yet been set. This will cause a default value of 0 (no) - to be used. */ - new->labelup[ axis ] = -1; - -/* The space between an axis and its numeric labels as a fraction of the - minimum dimension of the plotting area. Store AST__BAD to indicate that no - value has been set. This will cause a default of 0.01 to be used. */ - new->numlabgap[ axis ] = AST__BAD; - new->textlabgap[ axis ] = AST__BAD; - -/* The edges on which to put labels for axes 1 and 2. Store values of -1 - to indicate that no values have been set. This will cause default values - to be used. */ - new->edge[ axis ] = -1; - -/* The placement of labels within the plotting area will be done - automatically by default. */ - new->labelat[ axis ] = AST__BAD; - -/* The central tick is placed automatically by default. */ - new->centre[ axis ] = AST__BAD; - -/* The gap between tick marks and the number of minor tick marks will be - found automatically by default. */ - new->gap[ axis ] = AST__BAD; - new->loggap[ axis ] = AST__BAD; - new->mintick[ axis ] = -1; - -/* Both axes will be labelled by default. */ - new->numlab[ axis ] = -1; - new->textlab[ axis ] = -1; - new->labelunits[ axis ] = -1; - -/* Log/lin attributes. Default value is to use linear axes. */ - new->logplot[ axis ] = -1; - new->logticks[ axis ] = -1; - new->loglabel[ axis ] = -1; - -/* Initialise the components used to store the values actually used - for attributes which have dynamic defaults. */ - new->ulglb[ axis ] = new->loglabel[ axis ]; - new->ulgtk[ axis ] = new->logticks[ axis ]; - new->uloggap[ axis ] = new->loggap[ axis ]; - new->ugap[ axis ] = new->gap[ axis ]; - new->ucentre[ axis ] = new->centre[ axis ]; - new->uedge[ axis ] = new->edge[ axis ]; - new->ulblat[ axis ] = new->labelat[ axis ]; - new->ulbunit[ axis ] = new->labelunits[ axis ]; - new->umintk[ axis ] = new->mintick[ axis ]; - new->utxtlb[ axis ] = new->textlab[ axis ]; - new->umjtkln[ axis ] = new->majticklen[ axis ]; - -/* Initialise the arrays used to hold information describing the tick - marks that have been drawn for the axis. */ - new->majtickgx[ axis ] = NULL; - new->majtickgy[ axis ] = NULL; - new->majtickcount[ axis ] = 0; - new->mintickgx[ axis ] = NULL; - new->mintickgy[ axis ] = NULL; - new->mintickcount[ axis ] = 0; - new->nmajtickval[ axis ] = 0; - new->majtickval[ axis ] = NULL; - new->nmintickval[ axis ] = 0; - new->mintickval[ axis ] = NULL; - } - - new->ugrid = new->grid; - new->ulbling = new->labelling; - new->uborder = new->border; - - } - -/* Annul the frame. */ - graphicsframe = astAnnul( graphicsframe ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - -/* Annul the pointer to the base Frame and FrameSet. */ - baseframe = astAnnul( baseframe ); - fset = astAnnul( fset ); - -/* Return a pointer to the new object. */ - return new; -} - -AstPlot *astLoadPlot_( void *mem, size_t size, - AstPlotVtab *vtab, const char *name, - AstChannel *channel, int *status ) { -/* -*+ -* Name: -* astLoadPlot - -* Purpose: -* Load a Plot. - -* Type: -* Protected function. - -* Synopsis: -* #include "Plot.h" -* AstPlot *astLoadPlot( void *mem, size_t size, -* AstPlotVtab *vtab, const char *name, -* AstChannel *channel ) - -* Class Membership: -* Plot loader. - -* Description: -* This function is provided to load a new Plot using data read -* from a Channel. It first loads the data used by the parent class -* (which allocates memory if necessary) and then initialises a -* Plot structure in this memory, using data read from the input -* Channel. -* -* If the "init" flag is set, it also initialises the contents of a -* virtual function table for a Plot at the start of the memory -* passed via the "vtab" parameter. - - -* Parameters: -* mem -* A pointer to the memory into which the Plot is to be -* loaded. This must be of sufficient size to accommodate the -* Plot data (sizeof(Plot)) plus any data used by derived -* classes. If a value of NULL is given, this function will -* allocate the memory itself using the "size" parameter to -* determine its size. -* size -* The amount of memory used by the Plot (plus derived class -* data). This will be used to allocate memory if a value of -* NULL is given for the "mem" parameter. This value is also -* stored in the Plot structure, so a valid value must be -* supplied even if not required for allocating memory. -* -* If the "vtab" parameter is NULL, the "size" value is ignored -* and sizeof(AstPlot) is used instead. -* vtab -* Pointer to the start of the virtual function table to be -* associated with the new Plot. If this is NULL, a pointer -* to the (static) virtual function table for the Plot class -* is used instead. -* name -* Pointer to a constant null-terminated character string which -* contains the name of the class to which the new object -* belongs (it is this pointer value that will subsequently be -* returned by the astGetClass method). -* -* If the "vtab" parameter is NULL, the "name" value is ignored -* and a pointer to the string "Plot" is used instead. - -* Returned Value: -* A pointer to the new Plot. - -* Notes: -* - A null pointer will be returned if this function is invoked -* with the global error status set, or if it should fail for any -* reason. -*- -*/ - -#define KEY_LEN 50 /* Maximum length of a keyword */ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstPlot *new; /* Pointer to the new Plot */ - char buff[ KEY_LEN + 1 ]; /* Buffer for keyword string */ - char *text; /* Textual version of integer value */ - int axis; /* Zero based axis index */ - int id; /* Zero based graphical object id */ - int i; /* Loop count */ - int itick; /* Tick mark index */ - int nax; /* Number of base Frame axes */ - int ntick; /* Total number of ticks */ - -/* Initialise. */ - new = NULL; - -/* Check the global error status. */ - if ( !astOK ) return new; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(channel); - -/* If a NULL virtual function table has been supplied, then this is - the first loader to be invoked for this Plot. In this case the - Plot belongs to this class, so supply appropriate values to be - passed to the parent class loader (and its parent, etc.). */ - if ( !vtab ) { - size = sizeof( AstPlot ); - vtab = &class_vtab; - name = "Plot"; - -/* If required, initialise the virtual function table for this class. */ - if ( !class_init ) { - astInitPlotVtab( vtab, name ); - class_init = 1; - } - } - -/* Invoke the parent class loader to load data for all the ancestral - classes of the current one, returning a pointer to the resulting - partly-built Plot. */ - new = astLoadFrameSet( mem, size, (AstFrameSetVtab *) vtab, name, - channel ); - - if ( astOK ) { - -/* Get the number of graphics (base) frame axes - 2 for a Plot, 3 for a - Plot3D. */ - nax = astGetNin( new ); - -/* Read input data. */ -/* ================ */ -/* Request the input Channel to read all the input data appropriate to - this class into the internal "values list". */ - astReadClassData( channel, "Plot" ); - -/* Now read each individual data item from this list and use it to - initialise the appropriate instance variable(s) for this class. */ - -/* In the case of attributes, we first read the "raw" input value, - supplying the "unset" value as the default. If a "set" value is - obtained, we then use the appropriate (private) Set... member - function to validate and set the value properly. */ - -/* Tol. */ -/* ---- */ - new->tol = astReadDouble( channel, "tol", -1.0 ); - if ( TestTol( new, status ) ) SetTol( new, new->tol, status ); - -/* Grid. */ -/* ----- */ - new->grid = astReadInt( channel, "grid", -1 ); - if ( TestGrid( new, status ) ) SetGrid( new, new->grid, status ); - -/* TickAll. */ -/* -------- */ - new->tickall = astReadInt( channel, "tckall", -1 ); - if ( TestTickAll( new, status ) ) SetTickAll( new, new->tickall, status ); - -/* ForceExterior. */ -/* -------- */ - new->forceexterior = astReadInt( channel, "frcext", -1 ); - if ( TestForceExterior( new, status ) ) SetForceExterior( new, new->forceexterior, status ); - -/* Invisible. */ -/* ---------- */ - new->invisible = astReadInt( channel, "invsbl", -1 ); - if ( TestInvisible( new, status ) ) SetInvisible( new, new->invisible, status ); - -/* Border. */ -/* -------- */ - new->border = astReadInt( channel, "border", -1 ); - if ( TestBorder( new, status ) ) SetBorder( new, new->border, status ); - -/* ClipOp. */ -/* ------- */ - new->clipop = astReadInt( channel, "clpop", -1 ); - if ( TestClipOp( new, status ) ) SetClipOp( new, new->clipop, status ); - -/* Clip. */ -/* ----- */ - new->clip = astReadInt( channel, "clip", -1 ); - if ( TestClip( new, status ) ) SetClip( new, new->clip, status ); - -/* DrawTitle. */ -/* --------- */ - new->drawtitle = astReadInt( channel, "drwttl", -1 ); - if ( TestDrawTitle( new, status ) ) SetDrawTitle( new, new->drawtitle, status ); - -/* LabelUp(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lblup%d", axis + 1 ); - new->labelup[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLabelUp( new, axis, status ) ) SetLabelUp( new, axis, - new->labelup[ axis ], status ); - } - -/* LogPlot(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lgplt%d", axis + 1 ); - new->logplot[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLogPlot( new, axis, status ) ) SetLogPlot( new, axis, - new->logplot[ axis ], status ); - } - -/* LogTicks(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lgtck%d", axis + 1 ); - new->logticks[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLogTicks( new, axis, status ) ) SetLogTicks( new, axis, - new->logticks[ axis ], status ); - } - -/* LogLabel(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lglbl%d", axis + 1 ); - new->loglabel[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLogLabel( new, axis, status ) ) SetLogLabel( new, axis, - new->loglabel[ axis ], status ); - } - -/* DrawAxes. */ -/* --------- */ - new->drawaxes[ 0 ] = astReadInt( channel, "drwaxs", -1 ); - - if( new->drawaxes[ 0 ] != -1 ) { - new->drawaxes[ 1 ] = new->drawaxes[ 0 ]; - if ( TestDrawAxes( new, 0, status ) ) SetDrawAxes( new, 0, new->drawaxes[ 0 ], status ); - if ( TestDrawAxes( new, 1, status ) ) SetDrawAxes( new, 1, new->drawaxes[ 1 ], status ); - - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "drwaxs%d", axis + 1 ); - new->drawaxes[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestDrawAxes( new, axis, status ) ) SetDrawAxes( new, axis, - new->drawaxes[ axis ], status ); - } - } - -/* Abbrev. */ -/* ------- */ - new->abbrev[ 0 ] = astReadInt( channel, "abbrv", -1 ); - - if( new->abbrev[ 0 ] != -1 ) { - new->abbrev[ 1 ] = new->abbrev[ 0 ]; - if ( TestAbbrev( new, 0, status ) ) SetAbbrev( new, 0, new->abbrev[ 0 ], status ); - if ( TestAbbrev( new, 1, status ) ) SetAbbrev( new, 1, new->abbrev[ 1 ], status ); - - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "abbrv%d", axis + 1 ); - new->abbrev[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestAbbrev( new, axis, status ) ) SetAbbrev( new, axis, - new->abbrev[ axis ], status ); - } - } - - -/* Escape. */ -/* ------- */ - new->escape = astReadInt( channel, "escape", -1 ); - if ( TestEscape( new, status ) ) SetEscape( new, new->escape, status ); - -/* LabelAt(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lblat%d", axis + 1 ); - new->labelat[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestLabelAt( new, axis, status ) ) SetLabelAt( new, axis, - new->labelat[ axis ], status ); - } - -/* Centre(axis). */ -/* ------------ */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "cen%d", axis + 1 ); - new->centre[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestCentre( new, axis, status ) ) SetCentre( new, axis, - new->centre[ axis ], status ); - } - -/* Gap(axis). */ -/* ---------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "gap%d", axis + 1 ); - new->gap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestGap( new, axis, status ) ) SetGap( new, axis, new->gap[ axis ], status ); - } - -/* LogGap(axis). */ -/* ------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lggap%d", axis + 1 ); - new->loggap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestLogGap( new, axis, status ) ) SetLogGap( new, axis, new->loggap[ axis ], status ); - } - -/* NumLabGap(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "nmgap%d", axis + 1 ); - new->numlabgap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestNumLabGap( new, axis, status ) ) SetNumLabGap( new, axis, - new->numlabgap[ axis ], status ); - } - -/* TextLabGap(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "txgap%d", axis + 1 ); - new->textlabgap[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestTextLabGap( new, axis, status ) ) SetTextLabGap( new, axis, - new->textlabgap[ axis ], status ); - } - -/* NumLab(axis). */ -/* ---------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "nmlbl%d", axis + 1 ); - new->numlab[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestNumLab( new, axis, status ) ) SetNumLab( new, axis, - new->numlab[ axis ], status ); - } - -/* MinTick(axis). */ -/* --------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "mntks%d", axis + 1 ); - new->mintick[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestMinTick( new, axis, status ) ) SetMinTick( new, axis, - new->mintick[ axis ], status ); - } - -/* TextLab(axis). */ -/* -------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "txlbl%d", axis + 1 ); - new->textlab[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestTextLab( new, axis, status ) ) SetTextLab( new, axis, - new->textlab[ axis ], status ); - } - -/* LabelUnits(axis). */ -/* --------------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "lbunt%d", axis + 1 ); - new->labelunits[ axis ] = astReadInt( channel, buff, -1 ); - if ( TestLabelUnits( new, axis, status ) ) SetLabelUnits( new, axis, - new->labelunits[ axis ], status ); - } - -/* Style(object). */ -/* ------------ */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "style%d", id + 1 ); - new->style[ id ] = astReadInt( channel, buff, -1 ); - if ( TestStyle( new, id, status ) ) SetStyle( new, id, new->style[ id ], status ); - } - -/* Font(object). */ -/* ----------- */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "font%d", id + 1 ); - new->font[ id ] = astReadInt( channel, buff, -1 ); - if ( TestFont( new, id, status ) ) SetFont( new, id, new->font[ id ], status ); - } - -/* Colour(object). */ -/* --------------- */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "col%d", id + 1 ); - new->colour[ id ] = astReadInt( channel, buff, -1 ); - if ( TestColour( new, id, status ) ) SetColour( new, id, new->colour[ id ], status ); - } - -/* Width(object). */ -/* ------------ */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "width%d", id + 1 ); - new->width[ id ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestWidth( new, id, status ) ) SetWidth( new, id, new->width[ id ], status ); - } - -/* Size(object). */ -/* ----------- */ - for( id = 0; id < AST__NPID; id++ ){ - (void) sprintf( buff, "size%d", id + 1 ); - new->size[ id ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestSize( new, id, status ) ) SetSize( new, id, new->size[ id ], status ); - } - -/* TitleGap. */ -/* --------- */ - new->titlegap = astReadDouble( channel, "ttlgap", AST__BAD ); - if ( TestTitleGap( new, status ) ) SetTitleGap( new, new->titlegap, status ); - -/* MajTickLen. */ -/* ----------- */ -/* Retained in order to read old Plots - new Plots use MajTickLen(axis). */ - new->majticklen[ 0 ] = astReadDouble( channel, "mjtkln", AST__BAD ); - if( new->majticklen[ 0 ] != AST__BAD ) { - new->majticklen[ 1 ] = new->majticklen[ 0 ]; - if ( TestMajTickLen( new, 0, status ) ) SetMajTickLen( new, 0, new->majticklen[ 0 ], status ); - if ( TestMajTickLen( new, 1, status ) ) SetMajTickLen( new, 1, new->majticklen[ 1 ], status ); - -/* MajTickLen(axis). */ -/* ----------------- */ - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "mjtkln%d", axis + 1 ); - new->majticklen[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestMajTickLen( new, axis, status ) ) SetMajTickLen( new, axis, - new->majticklen[ axis ], status ); - } - } - -/* MinTickLen. */ -/* ----------- */ -/* Retained in order to read old Plots - new Plots use MinTickLen(axis). */ - new->minticklen[ 0 ] = astReadDouble( channel, "mntkln", AST__BAD ); - if( new->minticklen[ 0 ] != AST__BAD ) { - new->minticklen[ 1 ] = new->minticklen[ 0 ]; - if ( TestMinTickLen( new, 0, status ) ) SetMinTickLen( new, 0, new->minticklen[ 0 ], status ); - if ( TestMinTickLen( new, 1, status ) ) SetMinTickLen( new, 1, new->minticklen[ 1 ], status ); - -/* MinTickLen(axis). */ -/* ----------------- */ - } else { - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "mntkln%d", axis + 1 ); - new->minticklen[ axis ] = astReadDouble( channel, buff, AST__BAD ); - if ( TestMinTickLen( new, axis, status ) ) SetMinTickLen( new, axis, - new->minticklen[ axis ], status ); - } - } - -/* Labelling. */ -/* ---------- */ - text = astReadString( channel, "lbling", " " ); - if( astOK && strcmp( text, " " ) ) { - new->labelling = FindString( 2, xlbling, text, - "the Plot component 'Lbling'", - "astRead", astGetClass( channel ), status ); - } else { - new->labelling = -9999; - } - if ( TestLabelling( new, status ) ) SetLabelling( new, new->labelling, status ); - text = astFree( text ); - -/* Edge(axis). */ -/* ----------- */ - for( axis = 0; axis < nax; axis++ ){ - (void) sprintf( buff, "edge%d", axis + 1 ); - text = astReadString( channel, buff, " " ); - if( astOK && strcmp( text, " " ) ) { - new->edge[ axis ] = FindString( 4, xedge, text, - "the Plot component 'Edge'", - "astRead", astGetClass( channel ), status ); - } else { - new->edge[ axis ] = -1; - } - if ( TestEdge( new, axis, status ) ) SetEdge( new, axis, - new->edge[ axis ], status ); - text = astFree( text ); - } - -/* Now do instance variables which are not attributes. */ -/* =================================================== */ - -/* We have no graphics context. */ - new->grfcontext = NULL; - new->grfcontextID = NULL; - -/* Initialise the protected Ink attribute so that visible ink is used. */ - new->ink = -1; - -/* The number of bounds supplied for the clipping volume. */ - new->clip_axes = astReadInt( channel, "clpaxs", 0 ); - if ( new->clip_axes < 0 ) new->clip_axes = 0; - -/* The index of the clipping Frame within the Plot. */ - new->clip_frame = astReadInt( channel, "clpfrm", AST__NOFRAME ); - -/* If necessary, allocate memory to hold the bounds of the clipping volume. */ - if( new->clip_axes > 0 ){ - new->clip_lbnd = astMalloc( sizeof( double ) * (size_t) new->clip_axes ); - new->clip_ubnd = astMalloc( sizeof( double ) * (size_t) new->clip_axes ); - -/* If an error occurs, ensure that all allocated memory is freed. */ - if ( !astOK ) { - new->clip_lbnd = (double *) astFree( (void *) new->clip_lbnd ); - new->clip_ubnd = (double *) astFree( (void *) new->clip_ubnd ); - -/* Otherwise, store the bounds. Use extreme defaults if no values are - available. */ - } else { - for( axis = 0; axis < new->clip_axes; axis++ ){ - (void) sprintf( buff, "clplb%d", axis + 1 ); - new->clip_lbnd[ axis ] = astReadDouble( channel, buff, -DBL_MAX ); - - (void) sprintf( buff, "clpub%d", axis + 1 ); - new->clip_ubnd[ axis ] = astReadDouble( channel, buff, DBL_MAX ); - } - } - -/* If there are no clipping axes, store NULL pointers for the bounds - arrays. */ - } else { - new->clip_lbnd = NULL; - new->clip_ubnd = NULL; - } - -/* The bounds of the plotting area in graphics coords. */ - new->xlo = astReadDouble( channel, "xlo", 0.0 ); - new->xhi = astReadDouble( channel, "xhi", 1.0 ); - new->ylo = astReadDouble( channel, "ylo", 0.0 ); - new->yhi = astReadDouble( channel, "yhi", 1.0 ); - -/* Axis reversal flags. */ - new->xrev = astReadInt( channel, "xrev", 0 ); - new->yrev = astReadInt( channel, "yrev", 0 ); - -/* The bounds of the plotting area in the base Frame of the FrameSet - supplied when the Plot was constructed. */ - new->bbox[ 0 ] = astReadDouble( channel, "xb1", AST__BAD ); - new->bbox[ 1 ] = astReadDouble( channel, "yb1", AST__BAD ); - new->bbox[ 2 ] = astReadDouble( channel, "xb2", AST__BAD ); - new->bbox[ 3 ] = astReadDouble( channel, "yb2", AST__BAD ); - -/* Grf. */ - new->grf = -1; - new->GAttr = CGAttrWrapper; - new->GBBuf = CGBBufWrapper; - new->GEBuf = CGEBufWrapper; - new->GFlush = CGFlushWrapper; - new->GLine = CGLineWrapper; - new->GMark = CGMarkWrapper; - new->GText = CGTextWrapper; - new->GCap = CGCapWrapper; - new->GTxExt = CGTxExtWrapper; - new->GScales = CGScalesWrapper; - new->GQch = CGQchWrapper; - for( i = 0; i < AST__NGRFFUN; i++ ) new->grffun[i] = NULL; - new->grfstack = NULL; - new->grfnstack = 0; - -/* A stack of AstGat pointers used to store the graphical attributes for - text within strings which include graphical escape sequences. */ - new->gat = NULL; - new->ngat = 0; - -/* Arrays holding user-specified major and minot tick mark values. */ - for( axis = 0; axis < 3; axis++ ) { - sprintf( buff, "nmjtk%d", axis + 1 ); - ntick = astReadInt( channel, buff, 0 ); - new->nmajtickval[ axis ] = ntick; - new->majtickval[ axis ] = astMalloc( ntick*sizeof( double ) ); - - for( itick = 0; itick < ntick; itick++ ) { - sprintf( buff, "mjtk%d_%d", axis + 1, itick + 1 ); - new->majtickval[ axis ][ itick ] = astReadDouble( channel, buff, - AST__BAD ); - } - - sprintf( buff, "nmntk%d", axis + 1 ); - ntick = astReadInt( channel, buff, 0 ); - new->nmintickval[ axis ] = ntick; - new->mintickval[ axis ] = astMalloc( ntick*sizeof( double ) ); - - for( itick = 0; itick < ntick; itick++ ) { - sprintf( buff, "mntk%d_%d", axis + 1, itick + 1 ); - new->mintickval[ axis ][ itick ] = astReadDouble( channel, buff, - AST__BAD ); - } - - } - -/* Initialise the arrays used to hold information describing the tick - marks that have already been drawn for each axis. */ - for( axis = 0; axis < 3; axis++ ) { - new->majtickgx[ axis ] = NULL; - new->majtickgy[ axis ] = NULL; - new->majtickcount[ axis ] = 0; - new->mintickgx[ axis ] = NULL; - new->mintickgy[ axis ] = NULL; - new->mintickcount[ axis ] = 0; - } - -/* If an error occurred, clean up by deleting the new Plot. */ - if ( !astOK ) new = astDelete( new ); - } - -/* Return the new Plot pointer. */ - return new; -} - -/* Virtual function interfaces. */ -/* ============================ */ -/* These provide the external interface to the virtual functions defined by - this class. Each simply checks the global error status and then locates and - executes the appropriate member function, using the function pointer stored - in the object's virtual function table (this pointer is located using the - astMEMBER macro defined in "object.h"). - Note that the member function may not be the one defined here, as it may - have been over-ridden by a derived class. However, it should still have the - same interface. */ - -void astBBuf_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,BBuf))(this, status ); -} - -int astBorder_( AstPlot *this, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,Plot,Border))(this, status ); -} - -void astBoundingBox_( AstPlot *this, float lbnd[2], float ubnd[2], int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,BoundingBox))(this,lbnd,ubnd, status ); -} - -void astClip_( AstPlot *this, int iframe, const double lbnd[], -const double ubnd[], int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Clip))(this,iframe,lbnd,ubnd, status ); -} - -void astGrid_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Grid))(this, status ); -} - -int astCvBrk_( AstPlot *this, int ibrk, double *brk, double *vbrk, - double *len, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,Plot,CvBrk))(this,ibrk,brk,vbrk,len, status ); -} - -void astEBuf_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,EBuf))(this, status ); -} - -void astMirror_( AstPlot *this, int axis, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Mirror))(this,axis, status ); -} - -AstPointSet *astGetDrawnTicks_( AstPlot *this, int axis, int major, int *status ){ - if( !astOK ) return NULL; - return (**astMEMBER(this,Plot,GetDrawnTicks))(this,axis,major, status ); -} - -void astSetTickValues_( AstPlot *this, int axis, int nmajor, double *major, - int nminor, double *minor, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,SetTickValues))(this,axis,nmajor,major,nminor,minor, status ); -} - -void astCopyPlotDefaults_( AstPlot *this, int axis, AstPlot *dplot, - int daxis, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,CopyPlotDefaults))(this,axis,dplot,daxis, status ); -} - -int astGetLabelUnits_( AstPlot *this, int axis, int *status ){ - if( !astOK ) return 0; - return (**astMEMBER(this,Plot,GetLabelUnits))(this,axis, status ); -} - -void astMark_( AstPlot *this, int nmark, int ncoord, int indim, - const double *in, int type, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot,Mark))( this, nmark, ncoord, indim, in, type, status ); -} - -void astText_( AstPlot *this, const char *text, const double pos[], - const float up[], const char *just, int *status ){ - if ( !astOK ) return; - (**astMEMBER(this,Plot,Text))( this, text, pos, up, just, status ); -} - -void astGridLine_( AstPlot *this, int axis, const double start[], double length, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GridLine))(this,axis,start,length, status ); -} - -void astCurve_( AstPlot *this, const double start[], const double finish[], int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,Curve))(this,start,finish, status ); -} - -void astGenCurve_( AstPlot *this, AstMapping *map, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GenCurve))(this,map, status ); -} - -void astPolyCurve_( AstPlot *this, int npoint, int ncoord, int dim, - const double *in, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,PolyCurve))(this,npoint,ncoord,dim,in, status ); -} - -void astRegionOutline_( AstPlot *this, AstRegion *region, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,RegionOutline))(this,region,status); -} - -void astGrfSet_( AstPlot *this, const char *name, AstGrfFun fun, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfSet))(this,name,fun, status ); -} - -void astGrfPush_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfPush))(this, status ); -} - -void astGrfPop_( AstPlot *this, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfPop))(this, status ); -} - -void astGrfWrapper_( AstPlot *this, const char *name, AstGrfWrap wrapper, int *status ){ - if( !astOK ) return; - (**astMEMBER(this,Plot,GrfWrapper))(this,name,wrapper, status ); -} - -void astSetLogPlot_( AstPlot *this, int axis, int value, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot,SetLogPlot))( this, axis, value, status ); -} - -void astClearLogPlot_( AstPlot *this, int axis, int *status ) { - if ( !astOK ) return; - (**astMEMBER(this,Plot,ClearLogPlot))( this, axis, status ); -} - -AstKeyMap *astGetGrfContext_( AstPlot *this, int *status ) { - if ( !astOK ) return NULL; - return (**astMEMBER(this,Plot,GetGrfContext))( this, status ); -} - -/* Special public interface functions. */ -/* =================================== */ -/* These provide the public interface to certain special functions - whose public interface cannot be handled using macros (such as - astINVOKE) alone. In general, they are named after the - corresponding protected version of the function, but with "Id" - appended to the name. */ - -/* Special interface function implementations. */ -/* ------------------------------------------- */ -AstPlot *astPlotId_( void *frame_void, const float graphbox[4], - const double basebox[4], const char *options, ... ) { -/* -*++ -* Name: -c astPlot -f AST_PLOT - -* Purpose: -* Create a Plot. - -* Type: -* Public function. - -* Synopsis: -c #include "plot.h" -c AstPlot *astPlot( AstFrame *frame, const float graphbox[ 4 ], -c const double basebox[ 4 ], const char *options, ... ) -f RESULT = AST_PLOT( FRAME, GRAPHBOX, BASEBOX, OPTIONS, STATUS ) - -* Class Membership: -* Plot constructor. - -* Description: -* This function creates a new Plot and optionally initialises its -* attributes. -* -* A Plot is a specialised form of FrameSet, in which the base -* Frame describes a "graphical" coordinate system and is -* associated with a rectangular plotting area in the underlying -* graphics system. This plotting area is where graphical output -* appears. It is defined when the Plot is created. -* -* The current Frame of a Plot describes a "physical" coordinate -* system, which is the coordinate system in which plotting -* operations are specified. The results of each plotting operation -* are automatically transformed into graphical coordinates so as -* to appear in the plotting area (subject to any clipping which -* may be in effect). -* -* Because the Mapping between physical and graphical coordinates -* may often be non-linear, or even discontinuous, most plotting -* does not result in simple straight lines. The basic plotting -* element is therefore not a straight line, but a geodesic curve -c (see astCurve). A Plot also provides facilities for drawing -c markers or symbols (astMark), text (astText) and grid lines -c (astGridLine). It is also possible to draw curvilinear axes with -c optional coordinate grids (astGrid). -f (see AST_CURVE). A Plot also provides facilities for drawing -f markers or symbols (AST_MARK), text (AST_TEXT) and grid lines -f (AST_GRIDLINE). It is also possible to draw curvilinear axes -f with optional coordinate grids (AST_GRID). -* A range of Plot attributes is available to allow precise control -* over the appearance of graphical output produced by these -c functions. -f routines. -* -* You may select different physical coordinate systems in which to -* plot (including the native graphical coordinate system itself) -* by selecting different Frames as the current Frame of a Plot, -* using its Current attribute. You may also set up clipping (see -c astClip) to limit the extent of any plotting you perform, and -f AST_CLIP) to limit the extent of any plotting you perform, and -* this may be done in any of the coordinate systems associated -* with the Plot, not necessarily the one you are plotting in. -* -* Like any FrameSet, a Plot may also be used as a Frame. In this -* case, it behaves like its current Frame, which describes the -* physical coordinate system. -* -* When used as a Mapping, a Plot describes the inter-relation -* between graphical coordinates (its base Frame) and physical -* coordinates (its current Frame). It differs from a normal -* FrameSet, however, in that an attempt to transform points which -* lie in clipped areas of the Plot will result in bad coordinate -* values (AST__BAD). - -* Parameters: -c frame -f FRAME = INTEGER (Given) -* Pointer to a Frame describing the physical coordinate system -* in which to plot. A pointer to a FrameSet may also be given, -* in which case its current Frame will be used to define the -* physical coordinate system and its base Frame will be mapped -* on to graphical coordinates (see below). -* -* If a null Object pointer (AST__NULL) is given, a default -* 2-dimensional Frame will be used to describe the physical -* coordinate system. Labels, etc. may then be attached to this -* by setting the appropriate Frame attributes -* (e.g. Label(axis)) for the Plot. -c graphbox -f GRAPHBOX( 4 ) = REAL (Given) -* An array giving the position and extent of the plotting area -* (on the plotting surface of the underlying graphics system) -* in which graphical output is to appear. This must be -* specified using graphical coordinates appropriate to the -* underlying graphics system. -* -* The first pair of values should give the coordinates of the -* bottom left corner of the plotting area and the second pair -* should give the coordinates of the top right corner. The -* coordinate on the horizontal axis should be given first in -* each pair. Note that the order in which these points are -* given is important because it defines up, down, left and -* right for subsequent graphical operations. -c basebox -f BASEBOX( 4 ) = DOUBLE PRECISION (Given) -* An array giving the coordinates of two points in the supplied -* Frame (or in the base Frame if a FrameSet was supplied) which -* correspond to the bottom left and top right corners of the -* plotting area, as specified above. This range of coordinates -* will be mapped linearly on to the plotting area. The -* coordinates should be given in the same order as above. -c options -f OPTIONS = CHARACTER * ( * ) (Given) -c Pointer to a null-terminated string containing an optional -c comma-separated list of attribute assignments to be used for -c initialising the new Plot. The syntax used is identical to -c that for the astSet function and may include "printf" format -c specifiers identified by "%" symbols in the normal way. -c If no initialisation is required, a zero-length string may be -c supplied. -f A character string containing an optional comma-separated -f list of attribute assignments to be used for initialising the -f new Plot. The syntax used is identical to that for the -f AST_SET routine. If no initialisation is required, a blank -f value may be supplied. -c ... -c If the "options" string contains "%" format specifiers, then -c an optional list of additional arguments may follow it in -c order to supply values to be substituted for these -c specifiers. The rules for supplying these are identical to -c those for the astSet function (and for the C "printf" -c function). -f STATUS = INTEGER (Given and Returned) -f The global status. - -* Returned Value: -c astPlot() -f AST_PLOT -* A pointer to the new Plot. - -* Notes: -* - The base Frame of the returned Plot will be a new Frame which -* is created by this function to represent the coordinate system -* of the underlying graphics system (graphical coordinates). It is -* given a Frame index of 1 within the Plot. The choice of base -* Frame (Base attribute) should not, in general, be changed once a -* Plot has been created (although you could use this as a way of -* moving the plotting area around on the plotting surface). -c - If a Frame is supplied (via the "frame" pointer), then it -f - If a Frame is supplied (via the FRAME pointer), then it -* becomes the current Frame of the new Plot and is given a Frame -* index of 2. -c - If a FrameSet is supplied (via the "frame" pointer), then -f - If a FrameSet is supplied (via the FRAME pointer), then -* all the Frames within this FrameSet become part of the new Plot -* (where their Frame indices are increased by 1), with the -* FrameSet's current Frame becoming the current Frame of the Plot. -* - If a null Object pointer (AST__NULL) is supplied (via the -c "frame" pointer), then the returned Plot will contain two -f FRAME pointer), then the returned Plot will contain two -* Frames, both created by this function. The base Frame will -* describe graphics coordinates (as above) and the current Frame -* will be a basic Frame with no attributes set (this will -* therefore give default values for such things as the Plot Title -* and the Label on each axis). Physical coordinates will be mapped -* linearly on to graphical coordinates. -* - An error will result if the Frame supplied (or the base Frame -* if a FrameSet was supplied) is not 2-dimensional. -* - A null Object pointer (AST__NULL) will be returned if this -c function is invoked with the AST error status set, or if it -f function is invoked with STATUS set to an error value, or if it -* should fail for any reason. -*-- - -* Implementation Notes: -* - This function implements the external (public) interface to -* the astPlot constructor function. It returns an ID value -* (instead of a true C pointer) to external users, and must be -* provided because astPlot_ has a variable argument list which -* cannot be encapsulated in a macro (where this conversion would -* otherwise occur). -* - Because no checking or casting of arguments is performed -* before the function is invoked, the "frame" parameter is of type -* (void *) and is converted from an ID value to a pointer and -* validated within the function itself. -* - The variable argument list also prevents this function from -* invoking astPlot_ directly, so it must be a -* re-implementation of it in all respects, except for the -* conversions between IDs and pointers on input/output of Objects. -*/ - -/* Local Variables: */ - astDECLARE_GLOBALS /* Pointer to thread-specific global data */ - AstFrame *frame; /* Pointer to Frame structure */ - AstPlot *new; /* Pointer to new Plot */ - va_list args; /* Variable argument list */ - int *status; /* Pointer to inherited status value */ - -/* Get apointer to the inherited status value. */ - status = astGetStatusPtr; - -/* Check the global status. */ - if ( !astOK ) return NULL; - -/* Get a pointer to the thread specific global data structure. */ - astGET_GLOBALS(NULL); - -/* Initialise variables to avoid "used of uninitialised variable" - messages from dumb compilers. */ - new = NULL; - -/* Obtain a Frame pointer from any ID supplied and validate the - pointer to ensure it identifies a valid Frame. */ - if( frame_void ){ - frame = astVerifyFrame( astMakePointer( frame_void ) ); - } else { - frame = NULL; - } - -/* Check the pointer can be used. */ - if ( astOK ) { - -/* Initialise the Plot, allocating memory and initialising the - virtual function table as well if necessary. */ - new = astInitPlot( NULL, sizeof( AstPlot ), !class_init, - &class_vtab, "Plot", frame, graphbox, - basebox ); - -/* If successful, note that the virtual function table has been - initialised. */ - if ( astOK ) { - class_init = 1; - -/* Obtain the variable argument list and pass it along with the - options string to the astVSet method to initialise the new - Plot's attributes. */ - - va_start( args, options ); - astVSet( new, options, NULL, args ); - va_end( args ); - -/* If an error occurred, clean up by deleting the new object. */ - if ( !astOK ) new = astDelete( new ); - } - } - -/* Return an ID value for the new Plot. */ - return astMakeId( new ); - -} - - - - |