summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorjoye <joye>2014-04-07 22:31:06 (GMT)
committerjoye <joye>2014-04-07 22:31:06 (GMT)
commitf9415123449b0a82143ec42be1fba0ab3b3b78fa (patch)
tree36f27dc9f2ede2a80f300dd6f6804e6befbcfa28 /src
parentae3cf41403223191dda5efcf6d3a4165649a4a68 (diff)
downloadblt-f9415123449b0a82143ec42be1fba0ab3b3b78fa.zip
blt-f9415123449b0a82143ec42be1fba0ab3b3b78fa.tar.gz
blt-f9415123449b0a82143ec42be1fba0ab3b3b78fa.tar.bz2
*** empty log message ***
Diffstat (limited to 'src')
-rw-r--r--src/bltGrAxis.C6
-rw-r--r--src/bltGrElem.C88
-rw-r--r--src/bltGrElem.h87
-rw-r--r--src/bltGrElemBar.C1405
-rw-r--r--src/bltGrElemBar.h86
-rw-r--r--src/bltGrElemLine.C2260
-rw-r--r--src/bltGrElemLine.h125
-rw-r--r--src/bltGrElemOp.C98
-rw-r--r--src/bltGrPen.C13
-rw-r--r--src/bltGrPenBar.C14
-rw-r--r--src/bltGrPenBar.h3
-rw-r--r--src/bltGrPenLine.C12
-rw-r--r--src/bltGrPenLine.h3
-rw-r--r--src/bltGraph.h8
14 files changed, 2043 insertions, 2165 deletions
diff --git a/src/bltGrAxis.C b/src/bltGrAxis.C
index fa5f0d0..1e8a22c 100644
--- a/src/bltGrAxis.C
+++ b/src/bltGrAxis.C
@@ -43,6 +43,8 @@ class Marker;
#include "bltConfig.h"
#include "bltGrElem.h"
+#include "bltGrElemBar.h"
+#include "bltGrElemLine.h"
#include "bltGrAxis.h"
#define AXIS_PAD_TITLE 2
@@ -1776,8 +1778,8 @@ void Blt_ResetAxes(Graph* graphPtr)
Region2d exts;
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- ElementOptions* ops = (ElementOptions*)elemPtr->ops;
- (*elemPtr->procsPtr->extentsProc) (elemPtr, &exts);
+ ElementOptions* ops = (ElementOptions*)elemPtr->ops();
+ elemPtr->extents(&exts);
GetDataLimits(ops->axes.x, exts.left, exts.right);
GetDataLimits(ops->axes.y, exts.top, exts.bottom);
}
diff --git a/src/bltGrElem.C b/src/bltGrElem.C
index 8a1b972..8156bc9 100644
--- a/src/bltGrElem.C
+++ b/src/bltGrElem.C
@@ -31,9 +31,73 @@
#include "bltGrElemOp.h"
#include "bltGrPenOp.h"
-PenStyle** Blt_StyleMap(Element* elemPtr)
+Element::Element(Graph* gPtr, const char* name, Tcl_HashEntry* hPtr)
{
- ElementOptions* ops = (ElementOptions*)elemPtr->ops;
+ obj.classId = CID_NONE;
+ obj.name = dupstr(name);
+ obj.className =NULL;
+ obj.graphPtr = gPtr;
+ obj.tags =NULL;
+
+ graphPtr_ = gPtr;
+ flags =0;
+ hide_ =0;
+ hashPtr = hPtr;
+ ops_ =NULL;
+
+ row_ =0;
+ col_ =0;
+ activeIndices_ =NULL;
+ nActiveIndices_ =0;
+ optionTable_ =NULL;
+ xRange_ =0;
+ yRange_ =0;
+ link =NULL;
+}
+
+Element::~Element()
+{
+ if (obj.name)
+ delete [] obj.name;
+ if (obj.className)
+ delete [] obj.className;
+
+ if (activeIndices_)
+ free(activeIndices_);
+
+ if (hashPtr)
+ Tcl_DeleteHashEntry(hashPtr);
+
+ Tk_FreeConfigOptions((char*)ops_, optionTable_, obj.graphPtr->tkwin);
+
+ if (ops_)
+ free(ops_);
+}
+
+double Blt_FindElemValuesMinimum(ElemValues* valuesPtr, double minLimit)
+{
+ double min = DBL_MAX;
+ if (!valuesPtr)
+ return min;
+
+ for (int ii=0; ii<valuesPtr->nValues; ii++) {
+ double x = valuesPtr->values[ii];
+ // What do you do about negative values when using log
+ // scale values seems like a grey area. Mirror.
+ if (x < 0.0)
+ x = -x;
+ if ((x > minLimit) && (min > x))
+ min = x;
+ }
+ if (min == DBL_MAX)
+ min = minLimit;
+
+ return min;
+}
+
+PenStyle** Element::StyleMap()
+{
+ ElementOptions* ops = (ElementOptions*)ops_;
int nPoints = NUMBEROFPOINTS(ops);
int nWeights = MIN(ops->w ? ops->w->nValues : 0, nPoints);
@@ -82,23 +146,3 @@ void Blt_FreeStylePalette(Blt_Chain stylePalette)
}
}
-double Blt_FindElemValuesMinimum(ElemValues* valuesPtr, double minLimit)
-{
- double min = DBL_MAX;
- if (!valuesPtr)
- return min;
-
- for (int ii=0; ii<valuesPtr->nValues; ii++) {
- double x = valuesPtr->values[ii];
- // What do you do about negative values when using log
- // scale values seems like a grey area. Mirror.
- if (x < 0.0)
- x = -x;
- if ((x > minLimit) && (min > x))
- min = x;
- }
- if (min == DBL_MAX)
- min = minLimit;
-
- return min;
-}
diff --git a/src/bltGrElem.h b/src/bltGrElem.h
index 637071e..1c8b161 100644
--- a/src/bltGrElem.h
+++ b/src/bltGrElem.h
@@ -58,7 +58,7 @@ extern "C" {
#define NORMALPEN(e) ((((e)->normalPenPtr == NULL) ? (e)->builtinPenPtr : (e)->normalPenPtr))
-typedef struct _Element Element;
+class Element;
typedef struct {
Blt_VectorId vector;
@@ -90,36 +90,6 @@ typedef struct {
Pen* penPtr;
} PenStyle;
-typedef void (ElementDrawProc) (Graph *graphPtr, Drawable drawable,
- Element* elemPtr);
-typedef void (ElementToPostScriptProc) (Graph *graphPtr, Blt_Ps ps,
- Element* elemPtr);
-typedef void (ElementDestroyProc) (Graph *graphPtr, Element* elemPtr);
-typedef int (ElementConfigProc) (Graph *graphPtr, Element* elemPtr);
-typedef void (ElementMapProc) (Graph *graphPtr, Element* elemPtr);
-typedef void (ElementExtentsProc) (Element* elemPtr, Region2d *extsPtr);
-typedef void (ElementClosestProc) (Graph *graphPtr, Element* elemPtr);
-typedef void (ElementDrawSymbolProc) (Graph *graphPtr, Drawable drawable,
- Element* elemPtr, int x, int y,
- int symbolSize);
-typedef void (ElementSymbolToPostScriptProc) (Graph *graphPtr, Blt_Ps ps,
- Element* elemPtr, double x,
- double y, int symSize);
-
-typedef struct {
- ElementClosestProc *closestProc;
- ElementConfigProc *configProc;
- ElementDestroyProc *destroyProc;
- ElementDrawProc *drawActiveProc;
- ElementDrawProc *drawNormalProc;
- ElementDrawSymbolProc *drawSymbolProc;
- ElementExtentsProc *extentsProc;
- ElementToPostScriptProc *printActiveProc;
- ElementToPostScriptProc *printNormalProc;
- ElementSymbolToPostScriptProc *printSymbolProc;
- ElementMapProc *mapProc;
-} ElementProcs;
-
typedef struct {
Element* elemPtr;
const char* label;
@@ -142,26 +112,49 @@ typedef struct {
PenOptions builtinPen;
} ElementOptions;
-typedef struct _Element {
+class Element {
+ public:
GraphObj obj;
+ Graph* graphPtr_;
unsigned int flags;
- int hide;
- Tcl_HashEntry *hashPtr;
- void* ops;
-
- unsigned short row;
- unsigned short col;
- int *activeIndices;
- int nActiveIndices;
- ElementProcs *procsPtr;
- Tk_OptionTable optionTable;
- double xRange;
- double yRange;
+ int hide_;
+ Tcl_HashEntry* hashPtr;
+
+ unsigned short row_;
+ unsigned short col_;
+ int *activeIndices_;
+ int nActiveIndices_;
+ Tk_OptionTable optionTable_;
+ double xRange_;
+ double yRange_;
Blt_ChainLink link;
-} Element;
-extern double Blt_FindElemValuesMinimum(ElemValues *vecPtr, double minLimit);
+ protected:
+ void* ops_;
+
+ protected:
+ double FindElemValuesMinimum(ElemValues*, double);
+ PenStyle** StyleMap();
+
+ public:
+ Element(Graph*, const char*, Tcl_HashEntry*);
+ virtual ~Element();
+
+ virtual int configure() =0;
+ virtual void map() =0;
+ virtual void extents(Region2d*) =0;
+ virtual void drawActive(Drawable) =0;
+ virtual void drawNormal(Drawable) =0;
+ virtual void drawSymbol(Drawable, int, int, int) =0;
+ virtual void closest() =0;
+ virtual void printActive(Blt_Ps) =0;
+ virtual void printNormal(Blt_Ps) =0;
+ virtual void printSymbol(Blt_Ps, double, double, int) =0;
+
+ void* ops() {return ops_;}
+ Tk_OptionTable optionTable() {return optionTable();}
+};
+
extern void Blt_FreeStylePalette (Blt_Chain stylePalette);
-extern PenStyle** Blt_StyleMap (Element* elemPtr);
#endif
diff --git a/src/bltGrElemBar.C b/src/bltGrElemBar.C
index 44c29ba..7e5db85 100644
--- a/src/bltGrElemBar.C
+++ b/src/bltGrElemBar.C
@@ -39,51 +39,6 @@
(((x0) <= (int)((r)->x + (r)->width - 1)) && ((x0) >= (int)(r)->x) && \
((y0) <= (int)((r)->y + (r)->height - 1)) && ((y0) >= (int)(r)->y))
-typedef struct {
- float x1, y1, x2, y2;
-} BarRegion;
-
-typedef struct {
- Weight weight;
- BarPen* penPtr;
- XRectangle *bars;
- int nBars;
- GraphSegments xeb;
- GraphSegments yeb;
- int symbolSize;
- int errorBarCapWidth;
-} BarStyle;
-
-// Defs
-
-static void ResetBar(BarElement* elemPtr);
-
-static ElementClosestProc ClosestBarProc;
-static ElementConfigProc ConfigureBarProc;
-static ElementDestroyProc DestroyBarProc;
-static ElementDrawProc DrawActiveBarProc;
-static ElementDrawProc DrawNormalBarProc;
-static ElementDrawSymbolProc DrawSymbolProc;
-static ElementExtentsProc GetBarExtentsProc;
-static ElementToPostScriptProc ActiveBarToPostScriptProc;
-static ElementToPostScriptProc NormalBarToPostScriptProc;
-static ElementSymbolToPostScriptProc SymbolToPostScriptProc;
-static ElementMapProc MapBarProc;
-
-static ElementProcs barProcs = {
- ClosestBarProc,
- ConfigureBarProc,
- DestroyBarProc,
- DrawActiveBarProc,
- DrawNormalBarProc,
- DrawSymbolProc,
- GetBarExtentsProc,
- ActiveBarToPostScriptProc,
- NormalBarToPostScriptProc,
- SymbolToPostScriptProc,
- MapBarProc,
-};
-
// OptionSpecs
static Tk_ObjCustomOption styleObjOption =
@@ -213,56 +168,71 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
};
-// Create
-
-Element* Blt_BarElement(Graph* graphPtr)
+BarElement::BarElement(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
+ : Element(graphPtr, name, hPtr)
{
- BarElement* bePtr = (BarElement*)calloc(1, sizeof(BarElement));
- bePtr->ops = (BarElementOptions*)calloc(1, sizeof(BarElementOptions));
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
- ops->elemPtr = (Element*)bePtr;
+ Blt_GraphSetObjectClass(&obj, CID_ELEM_BAR);
+
+ barToData_ =NULL;
+ bars_ =NULL;
+ activeToData_ =NULL;
+ activeRects_ =NULL;
+ nBars_ =0;
+ nActive_ =0;
+ xPad_ =0;
+
+ xeb_.segments =NULL;
+ xeb_.length =0;
+ xeb_.map =NULL;
+ yeb_.segments =NULL;
+ yeb_.length =0;
+ yeb_.map =NULL;
+
+ ops_ = (BarElementOptions*)calloc(1, sizeof(BarElementOptions));
+ BarElementOptions* ops = (BarElementOptions*)ops_;
+ ops->elemPtr = (Element*)this;
+
+ builtinPenPtr = new BarPen(graphPtr_, "builtin", &ops->builtinPen);
+ ops->builtinPenPtr = builtinPenPtr;
- bePtr->procsPtr = &barProcs;
- ops->builtinPenPtr = &bePtr->builtinPen;
-
- bePtr->builtinPen.init(graphPtr, "builtin", &ops->builtinPen);
Tk_InitOptions(graphPtr->interp, (char*)&(ops->builtinPen),
- bePtr->builtinPen.optionTable(), graphPtr->tkwin);
+ builtinPenPtr->optionTable(), graphPtr->tkwin);
- bePtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs);
+ optionTable_ = Tk_CreateOptionTable(graphPtr->interp, optionSpecs);
- return (Element*)bePtr;
+ ops->stylePalette = Blt_Chain_Create();
+ // this is an option and will be freed via Tk_FreeConfigOptions
+ // By default an element's name and label are the same
+ ops->label = Tcl_Alloc(strlen(name)+1);
+ if (name)
+ strcpy((char*)ops->label,(char*)name);
}
-static void DestroyBarProc(Graph* graphPtr, Element* elemPtr)
+BarElement::~BarElement()
{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
if (ops->activePenPtr)
Blt_FreePen((Pen*)ops->activePenPtr);
if (ops->normalPenPtr)
Blt_FreePen((Pen*)ops->normalPenPtr);
+ if (ops->builtinPenPtr)
+ delete builtinPenPtr;
- ResetBar(bePtr);
+ ResetBar();
if (ops->stylePalette) {
Blt_FreeStylePalette(ops->stylePalette);
Blt_Chain_Destroy(ops->stylePalette);
}
- if (bePtr->activeIndices)
- free(bePtr->activeIndices);
}
-// Configure
-
-static int ConfigureBarProc(Graph* graphPtr, Element* elemPtr)
+int BarElement::configure()
{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
- if (bePtr->builtinPen.configure() != TCL_OK)
+ if (builtinPenPtr->configure() != TCL_OK)
return TCL_ERROR;
// Point to the static normal pen if no external pens have been selected.
@@ -277,50 +247,234 @@ static int ConfigureBarProc(Graph* graphPtr, Element* elemPtr)
return TCL_OK;
}
-// Support
-
-static void ResetStylePalette(Blt_Chain stylePalette)
+void BarElement::map()
{
- for (Blt_ChainLink link = Blt_Chain_FirstLink(stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
- BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
- stylePtr->xeb.length = 0;
- stylePtr->yeb.length = 0;
- stylePtr->nBars = 0;
- }
-}
+ BarElementOptions* ops = (BarElementOptions*)ops_;
-static void CheckBarStacks(Graph* graphPtr, Axis2d *pairPtr,
- double *minPtr, double *maxPtr)
-{
- if ((graphPtr->barMode != BARS_STACKED) || (graphPtr->nBarGroups == 0))
+ ResetBar();
+ if (!ops->coords.x || !ops->coords.y ||
+ !ops->coords.x->nValues || !ops->coords.y->nValues)
return;
+ int nPoints = NUMBEROFPOINTS(ops);
- BarGroup *gp, *gend;
- for (gp = graphPtr->barGroups, gend = gp + graphPtr->nBarGroups; gp < gend;
- gp++) {
- if ((gp->axes.x == pairPtr->x) && (gp->axes.y == pairPtr->y)) {
+ // double barWidth = graphPtr->barWidth;
+ double barWidth = (ops->barWidth > 0.0f) ?
+ ops->barWidth : graphPtr_->barWidth;
+ double baseline = (ops->axes.y->logScale) ? 0.0 : graphPtr_->baseline;
+ double barOffset = barWidth * 0.5;
- // Check if any of the y-values (because of stacking) are greater
- // than the current limits of the graph.
- if (gp->sum < 0.0f) {
- if (*minPtr > gp->sum)
- *minPtr = gp->sum;
+ // Create an array of bars representing the screen coordinates of all the
+ // segments in the bar.
+ XRectangle* bars = (XRectangle*)calloc(nPoints, sizeof(XRectangle));
+ int* barToData = (int*)calloc(nPoints, sizeof(int));
+
+ double* x = ops->coords.x->values;
+ double* y = ops->coords.y->values;
+ int count = 0;
+
+ int i;
+ XRectangle *rp;
+ for (rp = bars, i = 0; i < nPoints; i++) {
+ Point2d c1, c2; /* Two opposite corners of the rectangle
+ * in graph coordinates. */
+ double dx, dy;
+ int height;
+ double right, left, top, bottom;
+
+ if (((x[i] - barWidth) > ops->axes.x->axisRange.max) ||
+ ((x[i] + barWidth) < ops->axes.x->axisRange.min)) {
+ continue; /* Abscissa is out of range of the
+ * x-axis */
+ }
+ c1.x = x[i] - barOffset;
+ c1.y = y[i];
+ c2.x = c1.x + barWidth;
+ c2.y = baseline;
+
+ /*
+ * If the mode is "aligned" or "stacked" we need to adjust the x or y
+ * coordinates of the two corners.
+ */
+
+ if ((graphPtr_->nBarGroups > 0) && (graphPtr_->barMode != BARS_INFRONT) &&
+ (!graphPtr_->stackAxes)) {
+ Tcl_HashEntry *hPtr;
+ BarSetKey key;
+
+ key.value = (float)x[i];
+ key.axes = ops->axes;
+ key.axes.y = NULL;
+ hPtr = Tcl_FindHashEntry(&graphPtr_->setTable, (char *)&key);
+ if (hPtr) {
+
+ Tcl_HashTable *tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
+ const char *name = (ops->groupName) ?
+ ops->groupName : ops->axes.y->obj.name;
+ hPtr = Tcl_FindHashEntry(tablePtr, name);
+ if (hPtr) {
+ double slice, width, offset;
+
+ BarGroup *groupPtr = (BarGroup*)Tcl_GetHashValue(hPtr);
+ slice = barWidth / (double)graphPtr_->maxBarSetSize;
+ offset = (slice * groupPtr->index);
+ if (graphPtr_->maxBarSetSize > 1) {
+ offset += slice * 0.05;
+ slice *= 0.90;
+ }
+ switch (graphPtr_->barMode) {
+ case BARS_STACKED:
+ groupPtr->count++;
+ c2.y = groupPtr->lastY;
+ c1.y += c2.y;
+ groupPtr->lastY = c1.y;
+ c1.x += offset;
+ c2.x = c1.x + slice;
+ break;
+
+ case BARS_ALIGNED:
+ slice /= groupPtr->nSegments;
+ c1.x += offset + (slice * groupPtr->count);
+ c2.x = c1.x + slice;
+ groupPtr->count++;
+ break;
+
+ case BARS_OVERLAP:
+ slice /= (groupPtr->nSegments + 1);
+ width = slice + slice;
+ groupPtr->count++;
+ c1.x += offset +
+ (slice * (groupPtr->nSegments - groupPtr->count));
+ c2.x = c1.x + width;
+ break;
+
+ case BARS_INFRONT:
+ break;
+ }
+ }
}
- else {
- if (*maxPtr < gp->sum)
- *maxPtr = gp->sum;
+ }
+ int invertBar = 0;
+ if (c1.y < c2.y) {
+ double temp;
+
+ /* Handle negative bar values by swapping ordinates */
+ temp = c1.y, c1.y = c2.y, c2.y = temp;
+ invertBar = 1;
+ }
+ /*
+ * Get the two corners of the bar segment and compute the rectangle
+ */
+ double ybot = c2.y;
+ c1 = Blt_Map2D(graphPtr_, c1.x, c1.y, &ops->axes);
+ c2 = Blt_Map2D(graphPtr_, c2.x, c2.y, &ops->axes);
+ if ((ybot == 0.0) && (ops->axes.y->logScale)) {
+ c2.y = graphPtr_->bottom;
+ }
+
+ if (c2.y < c1.y) {
+ double t;
+ t = c1.y, c1.y = c2.y, c2.y = t;
+ }
+ if (c2.x < c1.x) {
+ double t;
+ t = c1.x, c1.x = c2.x, c2.x = t;
+ }
+ if ((c1.x > graphPtr_->right) || (c2.x < graphPtr_->left) ||
+ (c1.y > graphPtr_->bottom) || (c2.y < graphPtr_->top)) {
+ continue;
+ }
+ /* Bound the bars horizontally by the width of the graph window */
+ /* Bound the bars vertically by the position of the axis. */
+ if (graphPtr_->stackAxes) {
+ top = ops->axes.y->screenMin;
+ bottom = ops->axes.y->screenMin + ops->axes.y->screenRange;
+ left = graphPtr_->left;
+ right = graphPtr_->right;
+ } else {
+ left = top = 0;
+ bottom = right = 10000;
+ /* Shouldn't really have a call to Tk_Width or Tk_Height in
+ * mapping routine. We only want to clamp the bar segment to the
+ * size of the window if we're actually mapped onscreen. */
+ if (Tk_Height(graphPtr_->tkwin) > 1) {
+ bottom = Tk_Height(graphPtr_->tkwin);
+ }
+ if (Tk_Width(graphPtr_->tkwin) > 1) {
+ right = Tk_Width(graphPtr_->tkwin);
}
}
+ CLAMP(c1.y, top, bottom);
+ CLAMP(c2.y, top, bottom);
+ CLAMP(c1.x, left, right);
+ CLAMP(c2.x, left, right);
+ dx = fabs(c1.x - c2.x);
+ dy = fabs(c1.y - c2.y);
+ if ((dx == 0) || (dy == 0)) {
+ continue;
+ }
+ height = (int)dy;
+ if (invertBar) {
+ rp->y = (short int)MIN(c1.y, c2.y);
+ } else {
+ rp->y = (short int)(MAX(c1.y, c2.y)) - height;
+ }
+ rp->x = (short int)MIN(c1.x, c2.x);
+ rp->width = (short int)dx + 1;
+ rp->width |= 0x1;
+ if (rp->width < 1) {
+ rp->width = 1;
+ }
+ rp->height = height + 1;
+ if (rp->height < 1) {
+ rp->height = 1;
+ }
+ barToData[count] = i; /* Save the data index corresponding to
+ * the rectangle */
+ count++;
+ rp++;
}
+ nBars_ = count;
+ bars_ = bars;
+ barToData_ = barToData;
+ if (nActiveIndices_ > 0) {
+ MapActiveBars();
+ }
+
+ int size = 20;
+ if (count > 0)
+ size = bars->width;
+
+ // Set the symbol size of all the pen styles
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
+ BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
+ BarPen* penPtr = stylePtr->penPtr;
+ BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
+ stylePtr->symbolSize = size;
+ stylePtr->errorBarCapWidth =
+ (penOps->errorBarCapWidth > 0)
+ ? penOps->errorBarCapWidth : (size * 66666) / 100000;
+ stylePtr->errorBarCapWidth /= 2;
+ }
+
+ BarStyle** dataToStyle = (BarStyle**)StyleMap();
+ if (((ops->yHigh && ops->yHigh->nValues > 0) &&
+ (ops->yLow && ops->yLow->nValues > 0)) ||
+ ((ops->xHigh && ops->xHigh->nValues > 0) &&
+ (ops->xLow && ops->xLow->nValues > 0)) ||
+ (ops->xError && ops->xError->nValues > 0) ||
+ (ops->yError && ops->yError->nValues > 0)) {
+ MapErrorBars(dataToStyle);
+ }
+
+ MergePens(dataToStyle);
+ free(dataToStyle);
}
-static void GetBarExtentsProc(Element* elemPtr, Region2d *regPtr)
+void BarElement::extents(Region2d *regPtr)
{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
- Graph* graphPtr = bePtr->obj.graphPtr;
regPtr->top = regPtr->left = DBL_MAX;
regPtr->bottom = regPtr->right = -DBL_MAX;
@@ -329,7 +483,7 @@ static void GetBarExtentsProc(Element* elemPtr, Region2d *regPtr)
return;
int nPoints = NUMBEROFPOINTS(ops);
- double barWidth = graphPtr->barWidth;
+ double barWidth = graphPtr_->barWidth;
if (ops->barWidth > 0.0f)
barWidth = ops->barWidth;
@@ -339,18 +493,18 @@ static void GetBarExtentsProc(Element* elemPtr, Region2d *regPtr)
regPtr->top = ops->coords.y->min;
regPtr->bottom = ops->coords.y->max;
- if (regPtr->bottom < graphPtr->baseline)
- regPtr->bottom = graphPtr->baseline;
+ if (regPtr->bottom < graphPtr_->baseline)
+ regPtr->bottom = graphPtr_->baseline;
// Handle stacked bar elements specially.
// If element is stacked, the sum of its ordinates may be outside the
// minimum/maximum limits of the element's data points.
- if ((graphPtr->barMode == BARS_STACKED) && (graphPtr->nBarGroups > 0))
- CheckBarStacks(graphPtr, &ops->axes, &regPtr->top, &regPtr->bottom);
+ if ((graphPtr_->barMode == BARS_STACKED) && (graphPtr_->nBarGroups > 0))
+ CheckBarStacks(&ops->axes, &regPtr->top, &regPtr->bottom);
// Warning: You get what you deserve if the x-axis is logScale
if (ops->axes.x->logScale)
- regPtr->left = Blt_FindElemValuesMinimum(ops->coords.x, DBL_MIN) + middle;
+ regPtr->left = FindElemValuesMinimum(ops->coords.x, DBL_MIN) + middle;
// Fix y-min limits for barchart
if (ops->axes.y->logScale) {
@@ -393,7 +547,7 @@ static void GetBarExtentsProc(Element* elemPtr, Region2d *regPtr)
if (ops->xLow && (ops->xLow->nValues > 0)) {
double left;
if ((ops->xLow->min <= 0.0) && (ops->axes.x->logScale))
- left = Blt_FindElemValuesMinimum(ops->xLow, DBL_MIN);
+ left = FindElemValuesMinimum(ops->xLow, DBL_MIN);
else
left = ops->xLow->min;
@@ -434,7 +588,7 @@ static void GetBarExtentsProc(Element* elemPtr, Region2d *regPtr)
double top;
if ((ops->yLow->min <= 0.0) &&
(ops->axes.y->logScale))
- top = Blt_FindElemValuesMinimum(ops->yLow, DBL_MIN);
+ top = FindElemValuesMinimum(ops->yLow, DBL_MIN);
else
top = ops->yLow->min;
@@ -444,20 +598,19 @@ static void GetBarExtentsProc(Element* elemPtr, Region2d *regPtr)
}
}
-static void ClosestBarProc(Graph* graphPtr, Element* elemPtr)
+void BarElement::closest()
{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
- ClosestSearch* searchPtr = &graphPtr->search;
+ ClosestSearch* searchPtr = &graphPtr_->search;
double minDist = searchPtr->dist;
int imin = 0;
int i;
XRectangle *bp;
- for (bp = bePtr->bars, i = 0; i < bePtr->nBars; i++, bp++) {
+ for (bp = bars_, i = 0; i < nBars_; i++, bp++) {
if (PointInRectangle(bp, searchPtr->x, searchPtr->y)) {
- imin = bePtr->barToData[i];
+ imin = barToData_[i];
minDist = 0.0;
break;
}
@@ -488,12 +641,12 @@ static void ClosestBarProc(Graph* graphPtr, Element* elemPtr)
double dist = hypot((t.x - searchPtr->x), (t.y - searchPtr->y));
if (dist < minDist) {
minDist = dist;
- imin = bePtr->barToData[i];
+ imin = barToData_[i];
}
}
}
if (minDist < searchPtr->dist) {
- searchPtr->elemPtr = (Element*)bePtr;
+ searchPtr->elemPtr = (Element*)this;
searchPtr->dist = minDist;
searchPtr->index = imin;
searchPtr->point.x =
@@ -503,209 +656,406 @@ static void ClosestBarProc(Graph* graphPtr, Element* elemPtr)
}
}
-static void MergePens(BarElement* bePtr, BarStyle **dataToStyle)
+void BarElement::drawActive(Drawable drawable)
+{
+ BarElementOptions* ops = (BarElementOptions*)ops_;
+
+ if (ops->activePenPtr) {
+ BarPen* penPtr = ops->activePenPtr;
+ BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
+
+ if (nActiveIndices_ > 0) {
+ if (flags & ACTIVE_PENDING) {
+ MapActiveBars();
+ }
+ DrawBarSegments(drawable, penPtr, activeRects_, nActive_);
+ if (penOps->valueShow != SHOW_NONE)
+ DrawBarValues(drawable, penPtr, activeRects_, nActive_, activeToData_);
+ }
+ else if (nActiveIndices_ < 0) {
+ DrawBarSegments(drawable, penPtr, bars_, nBars_);
+ if (penOps->valueShow != SHOW_NONE)
+ DrawBarValues(drawable, penPtr, bars_, nBars_, barToData_);
+ }
+ }
+}
+
+void BarElement::drawNormal(Drawable drawable)
+{
+ BarElementOptions* ops = (BarElementOptions*)ops_;
+
+ int count = 0;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
+
+ BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
+ BarPen* penPtr = (BarPen*)stylePtr->penPtr;
+ BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
+
+ if (stylePtr->nBars > 0)
+ DrawBarSegments(drawable, penPtr, stylePtr->bars, stylePtr->nBars);
+
+ if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X))
+ Blt_Draw2DSegments(graphPtr_->display, drawable, penPtr->errorBarGC_,
+ stylePtr->xeb.segments, stylePtr->xeb.length);
+
+ if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y))
+ Blt_Draw2DSegments(graphPtr_->display, drawable, penPtr->errorBarGC_,
+ stylePtr->yeb.segments, stylePtr->yeb.length);
+
+ if (penOps->valueShow != SHOW_NONE)
+ DrawBarValues(drawable, penPtr, stylePtr->bars, stylePtr->nBars,
+ barToData_ + count);
+
+ count += stylePtr->nBars;
+ }
+}
+
+void BarElement::drawSymbol(Drawable drawable, int x, int y, int size)
+{
+ BarElementOptions* ops = (BarElementOptions*)ops_;
+
+ BarPen* penPtr = NORMALPEN(ops);
+ BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
+
+ if (!penOps->fill && !penOps->outlineColor)
+ return;
+
+ int radius = (size / 2);
+ size--;
+
+ x -= radius;
+ y -= radius;
+ if (penPtr->fillGC_)
+ XSetTSOrigin(graphPtr_->display, penPtr->fillGC_, x, y);
+
+ if (penOps->stipple != None)
+ XFillRectangle(graphPtr_->display, drawable, penPtr->fillGC_, x, y,
+ size, size);
+ else
+ Tk_Fill3DRectangle(graphPtr_->tkwin, drawable, penOps->fill,
+ x, y, size, size, penOps->borderWidth, penOps->relief);
+
+ XDrawRectangle(graphPtr_->display, drawable, penPtr->outlineGC_, x, y,
+ size, size);
+ if (penPtr->fillGC_)
+ XSetTSOrigin(graphPtr_->display, penPtr->fillGC_, 0, 0);
+}
+
+void BarElement::printActive(Blt_Ps ps)
{
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
+
+ if (ops->activePenPtr) {
+ BarPen* penPtr = ops->activePenPtr;
+ BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
+
+ if (nActiveIndices_ > 0) {
+ if (flags & ACTIVE_PENDING)
+ MapActiveBars();
+ SegmentsToPostScript(ps, penPtr, activeRects_, nActive_);
+ if (penOps->valueShow != SHOW_NONE)
+ BarValuesToPostScript(ps, penPtr, activeRects_, nActive_,activeToData_);
+ }
+ else if (nActiveIndices_ < 0) {
+ SegmentsToPostScript(ps, penPtr, bars_, nBars_);
+ if (penOps->valueShow != SHOW_NONE)
+ BarValuesToPostScript(ps, penPtr, bars_, nBars_, barToData_);
+ }
+ }
+}
+
+void BarElement::printNormal(Blt_Ps ps)
+{
+ BarElementOptions* ops = (BarElementOptions*)ops_;
+
+ int count = 0;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
+
+ BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
+ BarPen* penPtr = (BarPen*)stylePtr->penPtr;
+ BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
+ if (stylePtr->nBars > 0)
+ SegmentsToPostScript(ps, penPtr, stylePtr->bars, stylePtr->nBars);
+
+ XColor* colorPtr = penOps->errorBarColor;
+ if (!colorPtr)
+ colorPtr = penOps->outlineColor;
+
+ if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X)) {
+ Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
+ NULL, CapButt, JoinMiter);
+ Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments,
+ stylePtr->xeb.length);
+ }
+
+ if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y)) {
+ Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
+ NULL, CapButt, JoinMiter);
+ Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments,
+ stylePtr->yeb.length);
+ }
+
+ if (penOps->valueShow != SHOW_NONE)
+ BarValuesToPostScript(ps, penPtr, stylePtr->bars, stylePtr->nBars,
+ barToData_ + count);
+
+ count += stylePtr->nBars;
+ }
+}
+
+void BarElement::printSymbol(Blt_Ps ps, double x, double y, int size)
+{
+ BarElementOptions* ops = (BarElementOptions*)ops_;
+
+ BarPen* penPtr = NORMALPEN(ops);
+ BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
+
+ if (!penOps->fill && !penOps->outlineColor)
+ return;
+
+ /*
+ * Build a PostScript procedure to draw the fill and outline of the symbol
+ * after the path of the symbol shape has been formed
+ */
+ Blt_Ps_Append(ps, "\n"
+ "/DrawSymbolProc {\n"
+ "gsave\n ");
+ if (penOps->stipple != None) {
+ if (penOps->fill) {
+ Blt_Ps_XSetBackground(ps, Tk_3DBorderColor(penOps->fill));
+ Blt_Ps_Append(ps, " gsave fill grestore\n ");
+ }
+ if (penOps->outlineColor) {
+ Blt_Ps_XSetForeground(ps, penOps->outlineColor);
+ } else {
+ Blt_Ps_XSetForeground(ps, Tk_3DBorderColor(penOps->fill));
+ }
+ Blt_Ps_XSetStipple(ps, graphPtr_->display, penOps->stipple);
+ } else if (penOps->outlineColor) {
+ Blt_Ps_XSetForeground(ps, penOps->outlineColor);
+ Blt_Ps_Append(ps, " fill\n");
+ }
+ Blt_Ps_Append(ps, " grestore\n");
+ Blt_Ps_Append(ps, "} def\n\n");
+ Blt_Ps_Format(ps, "%g %g %d Sq\n", x, y, size);
+}
+
+// Support
+
+void BarElement::ResetStylePalette(Blt_Chain stylePalette)
+{
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
+ BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
+ stylePtr->xeb.length = 0;
+ stylePtr->yeb.length = 0;
+ stylePtr->nBars = 0;
+ }
+}
+
+void BarElement::CheckBarStacks(Axis2d *pairPtr, double *minPtr, double *maxPtr)
+{
+ if ((graphPtr_->barMode != BARS_STACKED) || (graphPtr_->nBarGroups == 0))
+ return;
+
+ BarGroup *gp, *gend;
+ for (gp = graphPtr_->barGroups, gend = gp + graphPtr_->nBarGroups; gp < gend;
+ gp++) {
+ if ((gp->axes.x == pairPtr->x) && (gp->axes.y == pairPtr->y)) {
+
+ // Check if any of the y-values (because of stacking) are greater
+ // than the current limits of the graph.
+ if (gp->sum < 0.0f) {
+ if (*minPtr > gp->sum)
+ *minPtr = gp->sum;
+ }
+ else {
+ if (*maxPtr < gp->sum)
+ *maxPtr = gp->sum;
+ }
+ }
+ }
+}
+
+void BarElement::MergePens(BarStyle** dataToStyle)
+{
+ BarElementOptions* ops = (BarElementOptions*)ops_;
if (Blt_Chain_GetLength(ops->stylePalette) < 2) {
Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
- stylePtr->nBars = bePtr->nBars;
- stylePtr->bars = bePtr->bars;
- stylePtr->symbolSize = bePtr->bars->width / 2;
- stylePtr->xeb.length = bePtr->xeb.length;
- stylePtr->xeb.segments = bePtr->xeb.segments;
- stylePtr->yeb.length = bePtr->yeb.length;
- stylePtr->yeb.segments = bePtr->yeb.segments;
+ stylePtr->nBars = nBars_;
+ stylePtr->bars = bars_;
+ stylePtr->symbolSize = bars_->width / 2;
+ stylePtr->xeb.length = xeb_.length;
+ stylePtr->xeb.segments = xeb_.segments;
+ stylePtr->yeb.length = yeb_.length;
+ stylePtr->yeb.segments = yeb_.segments;
return;
}
// We have more than one style. Group bar segments of like pen styles
// together
- if (bePtr->nBars > 0) {
- Blt_ChainLink link;
- XRectangle *bars, *bp;
- int *ip, *barToData;
-
- bars = (XRectangle*)malloc(bePtr->nBars * sizeof(XRectangle));
- barToData = (int*)malloc(bePtr->nBars * sizeof(int));
- bp = bars, ip = barToData;
- for (link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ if (nBars_ > 0) {
+ XRectangle* bars = (XRectangle*)malloc(nBars_ * sizeof(XRectangle));
+ int* barToData = (int*)malloc(nBars_ * sizeof(int));
+ XRectangle* bp = bars;
+ int* ip = barToData;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
link = Blt_Chain_NextLink(link)) {
- int i;
-
BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
stylePtr->symbolSize = bp->width / 2;
stylePtr->bars = bp;
- for (i = 0; i < bePtr->nBars; i++) {
- int iData;
-
- iData = bePtr->barToData[i];
+ for (int ii=0; ii<nBars_; ii++) {
+ int iData = barToData[ii];
if (dataToStyle[iData] == stylePtr) {
- *bp++ = bePtr->bars[i];
+ *bp++ = bars[ii];
*ip++ = iData;
}
}
stylePtr->nBars = bp - stylePtr->bars;
}
- free(bePtr->bars);
- free(bePtr->barToData);
- bePtr->bars = bars;
- bePtr->barToData = barToData;
+ free(bars_);
+ free(barToData_);
+ bars_ = bars;
+ barToData_ = barToData;
}
- if (bePtr->xeb.length > 0) {
- Blt_ChainLink link;
- Segment2d *sp;
- int *ip;
-
- Segment2d* bars =
- (Segment2d*)malloc(bePtr->xeb.length * sizeof(Segment2d));
- int* map = (int*)malloc(bePtr->xeb.length * sizeof(int));
- sp = bars, ip = map;
- for (link = Blt_Chain_FirstLink(ops->stylePalette);
+ if (xeb_.length > 0) {
+ Segment2d* bars = (Segment2d*)malloc(xeb_.length * sizeof(Segment2d));
+ int* map = (int*)malloc(xeb_.length * sizeof(int));
+ Segment2d *sp = bars;
+ int* ip = map;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
link; link = Blt_Chain_NextLink(link)) {
- int i;
-
BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
stylePtr->xeb.segments = sp;
- for (i = 0; i < bePtr->xeb.length; i++) {
- int iData;
-
- iData = bePtr->xeb.map[i];
+ for (int ii=0; ii<xeb_.length; ii++) {
+ int iData = xeb_.map[ii];
if (dataToStyle[iData] == stylePtr) {
- *sp++ = bePtr->xeb.segments[i];
+ *sp++ = xeb_.segments[ii];
*ip++ = iData;
}
}
stylePtr->xeb.length = sp - stylePtr->xeb.segments;
}
- free(bePtr->xeb.segments);
- bePtr->xeb.segments = bars;
- free(bePtr->xeb.map);
- bePtr->xeb.map = map;
+ free(xeb_.segments);
+ xeb_.segments = bars;
+ free(xeb_.map);
+ xeb_.map = map;
}
- if (bePtr->yeb.length > 0) {
- Blt_ChainLink link;
- Segment2d *sp;
- int *ip;
-
- Segment2d* bars =
- (Segment2d*)malloc(bePtr->yeb.length * sizeof(Segment2d));
- int* map = (int*)malloc(bePtr->yeb.length * sizeof(int));
- sp = bars, ip = map;
- for (link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
- int i;
+ if (yeb_.length > 0) {
+ Segment2d* bars = (Segment2d*)malloc(yeb_.length * sizeof(Segment2d));
+ int* map = (int*)malloc(yeb_.length * sizeof(int));
+ Segment2d* sp = bars;
+ int* ip = map;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
stylePtr->yeb.segments = sp;
- for (i = 0; i < bePtr->yeb.length; i++) {
- int iData;
-
- iData = bePtr->yeb.map[i];
+ for (int ii=0; ii<yeb_.length; ii++) {
+ int iData = yeb_.map[ii];
if (dataToStyle[iData] == stylePtr) {
- *sp++ = bePtr->yeb.segments[i];
+ *sp++ = yeb_.segments[ii];
*ip++ = iData;
}
}
stylePtr->yeb.length = sp - stylePtr->yeb.segments;
}
- free(bePtr->yeb.segments);
- bePtr->yeb.segments = bars;
- free(bePtr->yeb.map);
- bePtr->yeb.map = map;
+ free(yeb_.segments);
+ yeb_.segments = bars;
+ free(yeb_.map);
+ yeb_.map = map;
}
}
-static void MapActiveBars(BarElement* bePtr)
+void BarElement::MapActiveBars()
{
- if (bePtr->activeRects) {
- free(bePtr->activeRects);
- bePtr->activeRects = NULL;
+ if (activeRects_) {
+ free(activeRects_);
+ activeRects_ = NULL;
}
- if (bePtr->activeToData) {
- free(bePtr->activeToData);
- bePtr->activeToData = NULL;
+ if (activeToData_) {
+ free(activeToData_);
+ activeToData_ = NULL;
}
- bePtr->nActive = 0;
-
- if (bePtr->nActiveIndices > 0) {
- int i;
- int count;
+ nActive_ = 0;
+ if (nActiveIndices_ > 0) {
XRectangle *activeRects =
- (XRectangle*)malloc(sizeof(XRectangle) * bePtr->nActiveIndices);
- int* activeToData = (int*)malloc(sizeof(int) * bePtr->nActiveIndices);
- count = 0;
- for (i = 0; i < bePtr->nBars; i++) {
+ (XRectangle*)malloc(sizeof(XRectangle) * nActiveIndices_);
+ int* activeToData = (int*)malloc(sizeof(int) * nActiveIndices_);
+ int count = 0;
+ for (int ii=0; ii<nBars_; ii++) {
int *ip, *iend;
-
- for (ip = bePtr->activeIndices,
- iend = ip + bePtr->nActiveIndices; ip < iend; ip++) {
- if (bePtr->barToData[i] == *ip) {
- activeRects[count] = bePtr->bars[i];
- activeToData[count] = i;
+ for (ip = activeIndices_, iend = ip + nActiveIndices_; ip < iend; ip++) {
+ if (barToData_[ii] == *ip) {
+ activeRects[count] = bars_[ii];
+ activeToData[count] = ii;
count++;
}
}
}
- bePtr->nActive = count;
- bePtr->activeRects = activeRects;
- bePtr->activeToData = activeToData;
+ nActive_ = count;
+ activeRects_ = activeRects;
+ activeToData_ = activeToData;
}
- bePtr->flags &= ~ACTIVE_PENDING;
+ flags &= ~ACTIVE_PENDING;
}
-static void ResetBar(BarElement* bePtr)
+void BarElement::ResetBar()
{
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
ResetStylePalette(ops->stylePalette);
- if (bePtr->activeRects)
- free(bePtr->activeRects);
+ if (activeRects_)
+ free(activeRects_);
+ activeRects_ = NULL;
- if (bePtr->activeToData)
- free(bePtr->activeToData);
+ if (activeToData_)
+ free(activeToData_);
+ activeToData_ = NULL;
- if (bePtr->xeb.segments)
- free(bePtr->xeb.segments);
+ if (xeb_.segments)
+ free(xeb_.segments);
+ xeb_.segments = NULL;
- if (bePtr->xeb.map)
- free(bePtr->xeb.map);
+ if (xeb_.map)
+ free(xeb_.map);
+ xeb_.map = NULL;
- if (bePtr->yeb.segments)
- free(bePtr->yeb.segments);
+ if (yeb_.segments)
+ free(yeb_.segments);
+ yeb_.segments = NULL;
- if (bePtr->yeb.map)
- free(bePtr->yeb.map);
+ if (yeb_.map)
+ free(yeb_.map);
+ yeb_.map = NULL;
- if (bePtr->bars)
- free(bePtr->bars);
+ if (bars_)
+ free(bars_);
+ bars_ = NULL;
- if (bePtr->barToData)
- free(bePtr->barToData);
+ if (barToData_)
+ free(barToData_);
+ barToData_ = NULL;
- bePtr->activeToData = bePtr->xeb.map = bePtr->yeb.map =
- bePtr->barToData = NULL;
- bePtr->activeRects = NULL;
- bePtr->bars = NULL;
- bePtr->xeb.segments = NULL;
- bePtr->yeb.segments = NULL;
- bePtr->nActive = 0;
- bePtr->xeb.length = 0;
- bePtr->yeb.length = 0;
- bePtr->nBars = 0;
+ nActive_ = 0;
+ xeb_.length = 0;
+ yeb_.length = 0;
+ nBars_ = 0;
}
-static void MapErrorBars(Graph* graphPtr, BarElement* bePtr,
- BarStyle **dataToStyle)
+void BarElement::MapErrorBars(BarStyle **dataToStyle)
{
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
Region2d reg;
- Blt_GraphExtents(graphPtr, &reg);
+ Blt_GraphExtents(graphPtr_, &reg);
int nPoints = NUMBEROFPOINTS(ops);
int n =0;
@@ -739,8 +1089,8 @@ static void MapErrorBars(Graph* graphPtr, BarElement* bePtr,
low = ops->xLow ? ops->xLow->values[ii] : 0;
}
if ((isfinite(high)) && (isfinite(low))) {
- Point2d p = Blt_Map2D(graphPtr, high, y, &ops->axes);
- Point2d q = Blt_Map2D(graphPtr, low, y, &ops->axes);
+ Point2d p = Blt_Map2D(graphPtr_, high, y, &ops->axes);
+ Point2d q = Blt_Map2D(graphPtr_, low, y, &ops->axes);
segPtr->p = p;
segPtr->q = q;
if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
@@ -766,9 +1116,9 @@ static void MapErrorBars(Graph* graphPtr, BarElement* bePtr,
}
}
}
- bePtr->xeb.segments = bars;
- bePtr->xeb.length = segPtr - bars;
- bePtr->xeb.map = map;
+ xeb_.segments = bars;
+ xeb_.length = segPtr - bars;
+ xeb_.map = map;
}
n =0;
@@ -801,8 +1151,8 @@ static void MapErrorBars(Graph* graphPtr, BarElement* bePtr,
low = ops->yLow->values[ii];
}
if ((isfinite(high)) && (isfinite(low))) {
- Point2d p = Blt_Map2D(graphPtr, x, high, &ops->axes);
- Point2d q = Blt_Map2D(graphPtr, x, low, &ops->axes);
+ Point2d p = Blt_Map2D(graphPtr_, x, high, &ops->axes);
+ Point2d q = Blt_Map2D(graphPtr_, x, low, &ops->axes);
segPtr->p = p;
segPtr->q = q;
if (Blt_LineRectClip(&reg, &segPtr->p, &segPtr->q)) {
@@ -828,278 +1178,17 @@ static void MapErrorBars(Graph* graphPtr, BarElement* bePtr,
}
}
}
- bePtr->yeb.segments = bars;
- bePtr->yeb.length = segPtr - bars;
- bePtr->yeb.map = map;
- }
-}
-
-static void MapBarProc(Graph* graphPtr, Element* elemPtr)
-{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
-
- ResetBar(bePtr);
- if (!ops->coords.x || !ops->coords.y ||
- !ops->coords.x->nValues || !ops->coords.y->nValues)
- return;
- int nPoints = NUMBEROFPOINTS(ops);
-
- // double barWidth = graphPtr->barWidth;
- double barWidth = (ops->barWidth > 0.0f) ?
- ops->barWidth : graphPtr->barWidth;
- double baseline = (ops->axes.y->logScale) ? 0.0 : graphPtr->baseline;
- double barOffset = barWidth * 0.5;
-
- // Create an array of bars representing the screen coordinates of all the
- // segments in the bar.
- XRectangle* bars = (XRectangle*)calloc(nPoints, sizeof(XRectangle));
- int* barToData = (int*)calloc(nPoints, sizeof(int));
-
- double* x = ops->coords.x->values;
- double* y = ops->coords.y->values;
- int count = 0;
-
- int i;
- XRectangle *rp;
- for (rp = bars, i = 0; i < nPoints; i++) {
- Point2d c1, c2; /* Two opposite corners of the rectangle
- * in graph coordinates. */
- double dx, dy;
- int height;
- double right, left, top, bottom;
-
- if (((x[i] - barWidth) > ops->axes.x->axisRange.max) ||
- ((x[i] + barWidth) < ops->axes.x->axisRange.min)) {
- continue; /* Abscissa is out of range of the
- * x-axis */
- }
- c1.x = x[i] - barOffset;
- c1.y = y[i];
- c2.x = c1.x + barWidth;
- c2.y = baseline;
-
- /*
- * If the mode is "aligned" or "stacked" we need to adjust the x or y
- * coordinates of the two corners.
- */
-
- if ((graphPtr->nBarGroups > 0) && (graphPtr->barMode != BARS_INFRONT) &&
- (!graphPtr->stackAxes)) {
- Tcl_HashEntry *hPtr;
- BarSetKey key;
-
- key.value = (float)x[i];
- key.axes = ops->axes;
- key.axes.y = NULL;
- hPtr = Tcl_FindHashEntry(&graphPtr->setTable, (char *)&key);
- if (hPtr) {
-
- Tcl_HashTable *tablePtr = (Tcl_HashTable*)Tcl_GetHashValue(hPtr);
- const char *name = (ops->groupName) ?
- ops->groupName : ops->axes.y->obj.name;
- hPtr = Tcl_FindHashEntry(tablePtr, name);
- if (hPtr) {
- double slice, width, offset;
-
- BarGroup *groupPtr = (BarGroup*)Tcl_GetHashValue(hPtr);
- slice = barWidth / (double)graphPtr->maxBarSetSize;
- offset = (slice * groupPtr->index);
- if (graphPtr->maxBarSetSize > 1) {
- offset += slice * 0.05;
- slice *= 0.90;
- }
- switch (graphPtr->barMode) {
- case BARS_STACKED:
- groupPtr->count++;
- c2.y = groupPtr->lastY;
- c1.y += c2.y;
- groupPtr->lastY = c1.y;
- c1.x += offset;
- c2.x = c1.x + slice;
- break;
-
- case BARS_ALIGNED:
- slice /= groupPtr->nSegments;
- c1.x += offset + (slice * groupPtr->count);
- c2.x = c1.x + slice;
- groupPtr->count++;
- break;
-
- case BARS_OVERLAP:
- slice /= (groupPtr->nSegments + 1);
- width = slice + slice;
- groupPtr->count++;
- c1.x += offset +
- (slice * (groupPtr->nSegments - groupPtr->count));
- c2.x = c1.x + width;
- break;
-
- case BARS_INFRONT:
- break;
- }
- }
- }
- }
- int invertBar = 0;
- if (c1.y < c2.y) {
- double temp;
-
- /* Handle negative bar values by swapping ordinates */
- temp = c1.y, c1.y = c2.y, c2.y = temp;
- invertBar = 1;
- }
- /*
- * Get the two corners of the bar segment and compute the rectangle
- */
- double ybot = c2.y;
- c1 = Blt_Map2D(graphPtr, c1.x, c1.y, &ops->axes);
- c2 = Blt_Map2D(graphPtr, c2.x, c2.y, &ops->axes);
- if ((ybot == 0.0) && (ops->axes.y->logScale)) {
- c2.y = graphPtr->bottom;
- }
-
- if (c2.y < c1.y) {
- double t;
- t = c1.y, c1.y = c2.y, c2.y = t;
- }
- if (c2.x < c1.x) {
- double t;
- t = c1.x, c1.x = c2.x, c2.x = t;
- }
- if ((c1.x > graphPtr->right) || (c2.x < graphPtr->left) ||
- (c1.y > graphPtr->bottom) || (c2.y < graphPtr->top)) {
- continue;
- }
- /* Bound the bars horizontally by the width of the graph window */
- /* Bound the bars vertically by the position of the axis. */
- if (graphPtr->stackAxes) {
- top = ops->axes.y->screenMin;
- bottom = ops->axes.y->screenMin + ops->axes.y->screenRange;
- left = graphPtr->left;
- right = graphPtr->right;
- } else {
- left = top = 0;
- bottom = right = 10000;
- /* Shouldn't really have a call to Tk_Width or Tk_Height in
- * mapping routine. We only want to clamp the bar segment to the
- * size of the window if we're actually mapped onscreen. */
- if (Tk_Height(graphPtr->tkwin) > 1) {
- bottom = Tk_Height(graphPtr->tkwin);
- }
- if (Tk_Width(graphPtr->tkwin) > 1) {
- right = Tk_Width(graphPtr->tkwin);
- }
- }
- CLAMP(c1.y, top, bottom);
- CLAMP(c2.y, top, bottom);
- CLAMP(c1.x, left, right);
- CLAMP(c2.x, left, right);
- dx = fabs(c1.x - c2.x);
- dy = fabs(c1.y - c2.y);
- if ((dx == 0) || (dy == 0)) {
- continue;
- }
- height = (int)dy;
- if (invertBar) {
- rp->y = (short int)MIN(c1.y, c2.y);
- } else {
- rp->y = (short int)(MAX(c1.y, c2.y)) - height;
- }
- rp->x = (short int)MIN(c1.x, c2.x);
- rp->width = (short int)dx + 1;
- rp->width |= 0x1;
- if (rp->width < 1) {
- rp->width = 1;
- }
- rp->height = height + 1;
- if (rp->height < 1) {
- rp->height = 1;
- }
- barToData[count] = i; /* Save the data index corresponding to
- * the rectangle */
- count++;
- rp++;
- }
- bePtr->nBars = count;
- bePtr->bars = bars;
- bePtr->barToData = barToData;
- if (bePtr->nActiveIndices > 0) {
- MapActiveBars(bePtr);
- }
-
- int size = 20;
- if (count > 0)
- size = bars->width;
-
- // Set the symbol size of all the pen styles
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
- BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
- BarPen* penPtr = stylePtr->penPtr;
- BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
- stylePtr->symbolSize = size;
- stylePtr->errorBarCapWidth =
- (penOps->errorBarCapWidth > 0)
- ? penOps->errorBarCapWidth : (size * 66666) / 100000;
- stylePtr->errorBarCapWidth /= 2;
- }
-
- BarStyle** dataToStyle = (BarStyle**)Blt_StyleMap((Element*)bePtr);
- if (((ops->yHigh && ops->yHigh->nValues > 0) &&
- (ops->yLow && ops->yLow->nValues > 0)) ||
- ((ops->xHigh && ops->xHigh->nValues > 0) &&
- (ops->xLow && ops->xLow->nValues > 0)) ||
- (ops->xError && ops->xError->nValues > 0) ||
- (ops->yError && ops->yError->nValues > 0)) {
- MapErrorBars(graphPtr, bePtr, dataToStyle);
+ yeb_.segments = bars;
+ yeb_.length = segPtr - bars;
+ yeb_.map = map;
}
-
- MergePens(bePtr, dataToStyle);
- free(dataToStyle);
-}
-
-static void DrawSymbolProc(Graph* graphPtr, Drawable drawable,
- Element* elemPtr, int x, int y, int size)
-{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
-
- BarPen* penPtr = NORMALPEN(ops);
- BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
-
- if (!penOps->fill && !penOps->outlineColor)
- return;
-
- int radius = (size / 2);
- size--;
-
- x -= radius;
- y -= radius;
- if (penPtr->fillGC_)
- XSetTSOrigin(graphPtr->display, penPtr->fillGC_, x, y);
-
- if (penOps->stipple != None)
- XFillRectangle(graphPtr->display, drawable, penPtr->fillGC_, x, y,
- size, size);
- else
- Tk_Fill3DRectangle(graphPtr->tkwin, drawable, penOps->fill,
- x, y, size, size, penOps->borderWidth, penOps->relief);
-
- XDrawRectangle(graphPtr->display, drawable, penPtr->outlineGC_, x, y,
- size, size);
- if (penPtr->fillGC_)
- XSetTSOrigin(graphPtr->display, penPtr->fillGC_, 0, 0);
}
-static void SetBackgroundClipRegion(Tk_Window tkwin, Tk_3DBorder border,
- TkRegion rgn)
+void BarElement::SetBackgroundClipRegion(Tk_Window tkwin, Tk_3DBorder border,
+ TkRegion rgn)
{
- Display *display;
- GC gc;
-
- display = Tk_Display(tkwin);
- gc = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+ Display* display = Tk_Display(tkwin);
+ GC gc = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
TkSetRegion(display, gc, rgn);
gc = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
TkSetRegion(display, gc, rgn);
@@ -1107,13 +1196,10 @@ static void SetBackgroundClipRegion(Tk_Window tkwin, Tk_3DBorder border,
TkSetRegion(display, gc, rgn);
}
-static void UnsetBackgroundClipRegion(Tk_Window tkwin, Tk_3DBorder border)
+void BarElement::UnsetBackgroundClipRegion(Tk_Window tkwin, Tk_3DBorder border)
{
- Display *display;
- GC gc;
-
- display = Tk_Display(tkwin);
- gc = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
+ Display* display = Tk_Display(tkwin);
+ GC gc = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC);
XSetClipMask(display, gc, None);
gc = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC);
XSetClipMask(display, gc, None);
@@ -1121,17 +1207,17 @@ static void UnsetBackgroundClipRegion(Tk_Window tkwin, Tk_3DBorder border)
XSetClipMask(display, gc, None);
}
-static void DrawBarSegments(Graph* graphPtr, Drawable drawable, BarPen* penPtr,
- XRectangle *bars, int nBars)
+void BarElement::DrawBarSegments(Drawable drawable, BarPen* penPtr,
+ XRectangle *bars, int nBars)
{
BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
TkRegion rgn;
XRectangle clip;
- clip.x = graphPtr->left;
- clip.y = graphPtr->top;
- clip.width = graphPtr->right - graphPtr->left + 1;
- clip.height = graphPtr->bottom - graphPtr->top + 1;
+ clip.x = graphPtr_->left;
+ clip.y = graphPtr_->top;
+ clip.width = graphPtr_->right - graphPtr_->left + 1;
+ clip.height = graphPtr_->bottom - graphPtr_->top + 1;
rgn = TkCreateRegion();
TkUnionRectWithRegion(&clip, rgn, rgn);
@@ -1141,53 +1227,51 @@ static void DrawBarSegments(Graph* graphPtr, Drawable drawable, BarPen* penPtr,
int hasOutline = ((relief == TK_RELIEF_FLAT) && penOps->outlineColor);
if (penOps->stipple != None)
- TkSetRegion(graphPtr->display, penPtr->fillGC_, rgn);
+ TkSetRegion(graphPtr_->display, penPtr->fillGC_, rgn);
- SetBackgroundClipRegion(graphPtr->tkwin, penOps->fill, rgn);
+ SetBackgroundClipRegion(graphPtr_->tkwin, penOps->fill, rgn);
if (hasOutline)
- TkSetRegion(graphPtr->display, penPtr->outlineGC_, rgn);
+ TkSetRegion(graphPtr_->display, penPtr->outlineGC_, rgn);
XRectangle *rp, *rend;
for (rp = bars, rend = rp + nBars; rp < rend; rp++) {
if (penOps->stipple != None)
- XFillRectangle(graphPtr->display, drawable, penPtr->fillGC_,
+ XFillRectangle(graphPtr_->display, drawable, penPtr->fillGC_,
rp->x, rp->y, rp->width, rp->height);
else
- Tk_Fill3DRectangle(graphPtr->tkwin, drawable,
+ Tk_Fill3DRectangle(graphPtr_->tkwin, drawable,
penOps->fill, rp->x, rp->y, rp->width, rp->height,
penOps->borderWidth, relief);
if (hasOutline)
- XDrawRectangle(graphPtr->display, drawable, penPtr->outlineGC_,
+ XDrawRectangle(graphPtr_->display, drawable, penPtr->outlineGC_,
rp->x, rp->y, rp->width, rp->height);
}
- UnsetBackgroundClipRegion(graphPtr->tkwin, penOps->fill);
+ UnsetBackgroundClipRegion(graphPtr_->tkwin, penOps->fill);
if (hasOutline)
- XSetClipMask(graphPtr->display, penPtr->outlineGC_, None);
+ XSetClipMask(graphPtr_->display, penPtr->outlineGC_, None);
if (penOps->stipple != None)
- XSetClipMask(graphPtr->display, penPtr->fillGC_, None);
+ XSetClipMask(graphPtr_->display, penPtr->fillGC_, None);
}
else if (penOps->outlineColor) {
- TkSetRegion(graphPtr->display, penPtr->outlineGC_, rgn);
- XDrawRectangles(graphPtr->display, drawable, penPtr->outlineGC_, bars,
+ TkSetRegion(graphPtr_->display, penPtr->outlineGC_, rgn);
+ XDrawRectangles(graphPtr_->display, drawable, penPtr->outlineGC_, bars,
nBars);
- XSetClipMask(graphPtr->display, penPtr->outlineGC_, None);
+ XSetClipMask(graphPtr_->display, penPtr->outlineGC_, None);
}
TkDestroyRegion(rgn);
}
-static void DrawBarValues(Graph* graphPtr, Drawable drawable,
- BarElement* bePtr,
- BarPen* penPtr, XRectangle *bars, int nBars,
- int *barToData)
+void BarElement::DrawBarValues(Drawable drawable, BarPen* penPtr,
+ XRectangle *bars, int nBars, int *barToData)
{
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
const char *fmt = penOps->valueFormat;
@@ -1214,132 +1298,25 @@ static void DrawBarValues(Graph* graphPtr, Drawable drawable,
sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
}
- if (graphPtr->inverted) {
+ if (graphPtr_->inverted) {
anchorPos.y = rp->y + rp->height * 0.5;
anchorPos.x = rp->x + rp->width;
- if (x < graphPtr->baseline)
+ if (x < graphPtr_->baseline)
anchorPos.x -= rp->width;
}
else {
anchorPos.x = rp->x + rp->width * 0.5;
anchorPos.y = rp->y;
- if (y < graphPtr->baseline)
+ if (y < graphPtr_->baseline)
anchorPos.y += rp->height;
}
- Blt_DrawText(graphPtr->tkwin, drawable, string, &penOps->valueStyle,
+ Blt_DrawText(graphPtr_->tkwin, drawable, string, &penOps->valueStyle,
(int)anchorPos.x, (int)anchorPos.y);
}
}
-static void DrawNormalBarProc(Graph* graphPtr, Drawable drawable,
- Element* elemPtr)
-{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
-
- int count = 0;
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
-
- BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
- BarPen* penPtr = (BarPen*)stylePtr->penPtr;
- BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
-
- if (stylePtr->nBars > 0)
- DrawBarSegments(graphPtr, drawable, penPtr, stylePtr->bars,
- stylePtr->nBars);
-
- if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X))
- Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC_,
- stylePtr->xeb.segments, stylePtr->xeb.length);
-
- if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y))
- Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC_,
- stylePtr->yeb.segments, stylePtr->yeb.length);
-
- if (penOps->valueShow != SHOW_NONE)
- DrawBarValues(graphPtr, drawable, bePtr, penPtr,
- stylePtr->bars, stylePtr->nBars,
- bePtr->barToData + count);
-
- count += stylePtr->nBars;
- }
-}
-
-static void DrawActiveBarProc(Graph* graphPtr, Drawable drawable,
- Element* elemPtr)
-{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
-
- if (ops->activePenPtr) {
- BarPen* penPtr = ops->activePenPtr;
- BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
-
- if (bePtr->nActiveIndices > 0) {
- if (bePtr->flags & ACTIVE_PENDING) {
- MapActiveBars(bePtr);
- }
- DrawBarSegments(graphPtr, drawable, penPtr, bePtr->activeRects,
- bePtr->nActive);
- if (penOps->valueShow != SHOW_NONE) {
- DrawBarValues(graphPtr, drawable, bePtr, penPtr,
- bePtr->activeRects, bePtr->nActive,
- bePtr->activeToData);
- }
- }
- else if (bePtr->nActiveIndices < 0) {
- DrawBarSegments(graphPtr, drawable, penPtr, bePtr->bars,
- bePtr->nBars);
- if (penOps->valueShow != SHOW_NONE) {
- DrawBarValues(graphPtr, drawable, bePtr, penPtr,
- bePtr->bars, bePtr->nBars, bePtr->barToData);
- }
- }
- }
-}
-
-static void SymbolToPostScriptProc(Graph* graphPtr, Blt_Ps ps, Element* elemPtr,
- double x, double y, int size)
-{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
-
- BarPen* penPtr = NORMALPEN(ops);
- BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
-
- if (!penOps->fill && !penOps->outlineColor)
- return;
-
- /*
- * Build a PostScript procedure to draw the fill and outline of the symbol
- * after the path of the symbol shape has been formed
- */
- Blt_Ps_Append(ps, "\n"
- "/DrawSymbolProc {\n"
- "gsave\n ");
- if (penOps->stipple != None) {
- if (penOps->fill) {
- Blt_Ps_XSetBackground(ps, Tk_3DBorderColor(penOps->fill));
- Blt_Ps_Append(ps, " gsave fill grestore\n ");
- }
- if (penOps->outlineColor) {
- Blt_Ps_XSetForeground(ps, penOps->outlineColor);
- } else {
- Blt_Ps_XSetForeground(ps, Tk_3DBorderColor(penOps->fill));
- }
- Blt_Ps_XSetStipple(ps, graphPtr->display, penOps->stipple);
- } else if (penOps->outlineColor) {
- Blt_Ps_XSetForeground(ps, penOps->outlineColor);
- Blt_Ps_Append(ps, " fill\n");
- }
- Blt_Ps_Append(ps, " grestore\n");
- Blt_Ps_Append(ps, "} def\n\n");
- Blt_Ps_Format(ps, "%g %g %d Sq\n", x, y, size);
-}
-
-static void SegmentsToPostScript(Graph* graphPtr, Blt_Ps ps, BarPen* penPtr,
- XRectangle *bars, int nBars)
+void BarElement::SegmentsToPostScript(Blt_Ps ps, BarPen* penPtr,
+ XRectangle *bars, int nBars)
{
BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
XRectangle *rp, *rend;
@@ -1362,7 +1339,7 @@ static void SegmentsToPostScript(Graph* graphPtr, Blt_Ps ps, BarPen* penPtr,
} else {
Blt_Ps_XSetForeground(ps, Tk_3DBorderColor(penOps->fill));
}
- Blt_Ps_XSetStipple(ps, graphPtr->display, penOps->stipple);
+ Blt_Ps_XSetStipple(ps, graphPtr_->display, penOps->stipple);
} else if (penOps->outlineColor) {
Blt_Ps_XSetForeground(ps, penOps->outlineColor);
Blt_Ps_XFillRectangle(ps, (double)rp->x, (double)rp->y,
@@ -1377,13 +1354,12 @@ static void SegmentsToPostScript(Graph* graphPtr, Blt_Ps ps, BarPen* penPtr,
}
}
-static void BarValuesToPostScript(Graph* graphPtr, Blt_Ps ps,
- BarElement* bePtr,
- BarPen* penPtr, XRectangle *bars, int nBars,
- int *barToData)
+void BarElement::BarValuesToPostScript(Blt_Ps ps, BarPen* penPtr,
+ XRectangle *bars, int nBars,
+ int *barToData)
{
BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
+ BarElementOptions* ops = (BarElementOptions*)ops_;
XRectangle *rp, *rend;
char string[TCL_DOUBLE_SPACE * 2 + 2];
@@ -1408,16 +1384,16 @@ static void BarValuesToPostScript(Graph* graphPtr, Blt_Ps ps,
strcat(string, ",");
sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
}
- if (graphPtr->inverted) {
+ if (graphPtr_->inverted) {
anchorPos.y = rp->y + rp->height * 0.5;
anchorPos.x = rp->x + rp->width;
- if (x < graphPtr->baseline) {
+ if (x < graphPtr_->baseline) {
anchorPos.x -= rp->width;
}
} else {
anchorPos.x = rp->x + rp->width * 0.5;
anchorPos.y = rp->y;
- if (y < graphPtr->baseline) {
+ if (y < graphPtr_->baseline) {
anchorPos.y += rp->height;
}
}
@@ -1426,80 +1402,7 @@ static void BarValuesToPostScript(Graph* graphPtr, Blt_Ps ps,
}
}
-static void ActiveBarToPostScriptProc(Graph* graphPtr, Blt_Ps ps,
- Element* elemPtr)
-{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
-
- if (ops->activePenPtr) {
- BarPen* penPtr = ops->activePenPtr;
- BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
-
- if (bePtr->nActiveIndices > 0) {
- if (bePtr->flags & ACTIVE_PENDING) {
- MapActiveBars(bePtr);
- }
- SegmentsToPostScript(graphPtr, ps, penPtr, bePtr->activeRects,
- bePtr->nActive);
- if (penOps->valueShow != SHOW_NONE) {
- BarValuesToPostScript(graphPtr, ps, bePtr, penPtr,
- bePtr->activeRects, bePtr->nActive, bePtr->activeToData);
- }
- } else if (bePtr->nActiveIndices < 0) {
- SegmentsToPostScript(graphPtr, ps, penPtr, bePtr->bars,
- bePtr->nBars);
- if (penOps->valueShow != SHOW_NONE) {
- BarValuesToPostScript(graphPtr, ps, bePtr, penPtr,
- bePtr->bars, bePtr->nBars, bePtr->barToData);
- }
- }
- }
-}
-
-static void NormalBarToPostScriptProc(Graph* graphPtr, Blt_Ps ps,
- Element* elemPtr)
-{
- BarElement* bePtr = (BarElement*)elemPtr;
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
-
- int count = 0;
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
-
- BarStyle *stylePtr = (BarStyle*)Blt_Chain_GetValue(link);
- BarPen* penPtr = (BarPen*)stylePtr->penPtr;
- BarPenOptions* penOps = (BarPenOptions*)penPtr->ops();
- if (stylePtr->nBars > 0)
- SegmentsToPostScript(graphPtr, ps, penPtr, stylePtr->bars,
- stylePtr->nBars);
-
- XColor* colorPtr = penOps->errorBarColor;
- if (!colorPtr)
- colorPtr = penOps->outlineColor;
-
- if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X)) {
- Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
- NULL, CapButt, JoinMiter);
- Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments,
- stylePtr->xeb.length);
- }
-
- if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y)) {
- Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
- NULL, CapButt, JoinMiter);
- Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments,
- stylePtr->yeb.length);
- }
-
- if (penOps->valueShow != SHOW_NONE)
- BarValuesToPostScript(graphPtr, ps, bePtr, penPtr,
- stylePtr->bars, stylePtr->nBars,
- bePtr->barToData + count);
-
- count += stylePtr->nBars;
- }
-}
+// External
void Blt_InitBarSetTable(Graph* graphPtr)
{
@@ -1532,8 +1435,8 @@ void Blt_InitBarSetTable(Graph* graphPtr)
int nPoints;
BarElement* bePtr = (BarElement*)Blt_Chain_GetValue(link);
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
- if ((bePtr->hide) || (bePtr->obj.classId != CID_ELEM_BAR))
+ BarElementOptions* ops = (BarElementOptions*)bePtr->ops();
+ if ((bePtr->hide_) || (bePtr->obj.classId != CID_ELEM_BAR))
continue;
nSegs++;
@@ -1651,8 +1554,8 @@ void Blt_ComputeBarStacks(Graph* graphPtr)
double *x, *y, *xend;
BarElement* bePtr = (BarElement*)Blt_Chain_GetValue(link);
- BarElementOptions* ops = (BarElementOptions*)bePtr->ops;
- if ((bePtr->hide) || (bePtr->obj.classId != CID_ELEM_BAR))
+ BarElementOptions* ops = (BarElementOptions*)bePtr->ops();
+ if ((bePtr->hide_) || (bePtr->obj.classId != CID_ELEM_BAR))
continue;
if (ops->coords.x && ops->coords.y) {
diff --git a/src/bltGrElemBar.h b/src/bltGrElemBar.h
index cbe044c..c998484 100644
--- a/src/bltGrElemBar.h
+++ b/src/bltGrElemBar.h
@@ -39,6 +39,21 @@ using namespace std;
#include "bltGrPenBar.h"
typedef struct {
+ float x1, y1, x2, y2;
+} BarRegion;
+
+typedef struct {
+ Weight weight;
+ BarPen* penPtr;
+ XRectangle *bars;
+ int nBars;
+ GraphSegments xeb;
+ GraphSegments yeb;
+ int symbolSize;
+ int errorBarCapWidth;
+} BarStyle;
+
+typedef struct {
Element* elemPtr;
const char *label;
char** tags;
@@ -64,34 +79,51 @@ typedef struct {
const char *groupName;
} BarElementOptions;
-typedef struct {
- GraphObj obj;
- unsigned int flags;
- int hide;
- Tcl_HashEntry *hashPtr;
- void* ops;
+class BarElement : public Element {
+ public:
+ BarPen* builtinPenPtr;
+ int* barToData_;
+ XRectangle* bars_;
+ int* activeToData_;
+ XRectangle* activeRects_;
+ int nBars_;
+ int nActive_;
+ int xPad_;
+ GraphSegments xeb_;
+ GraphSegments yeb_;
- unsigned short row;
- unsigned short col;
- int *activeIndices;
- int nActiveIndices;
- ElementProcs *procsPtr;
- Tk_OptionTable optionTable;
- double xRange;
- double yRange;
- Blt_ChainLink link;
+ void ResetStylePalette(Blt_Chain);
+ void CheckBarStacks(Axis2d*, double*, double*);
+ void MergePens(BarStyle**);
+ void MapActiveBars();
+ void ResetBar();
+ void MapErrorBars(BarStyle**);
+ void SetBackgroundClipRegion(Tk_Window, Tk_3DBorder, TkRegion);
+ void UnsetBackgroundClipRegion(Tk_Window, Tk_3DBorder);
+ void DrawBarSegments(Drawable, BarPen*, XRectangle*, int);
+ void DrawBarValues(Drawable, BarPen*, XRectangle*, int, int*);
+ void SegmentsToPostScript(Blt_Ps, BarPen*, XRectangle*, int);
+ void BarValuesToPostScript(Blt_Ps, BarPen*, XRectangle*, int, int*);
- // Fields specific to Bar Element
- BarPen builtinPen;
- int *barToData;
- XRectangle *bars;
- int *activeToData;
- XRectangle *activeRects;
- int nBars;
- int nActive;
- int xPad;
- GraphSegments xeb;
- GraphSegments yeb;
-} BarElement;
+ public:
+ BarElement(Graph*, const char*, Tcl_HashEntry*);
+ virtual ~BarElement();
+
+ int configure();
+ void map();
+ void extents(Region2d*);
+ void closest();
+ void drawActive(Drawable);
+ void drawNormal(Drawable);
+ void drawSymbol(Drawable, int, int, int);
+ void printActive(Blt_Ps);
+ void printNormal(Blt_Ps);
+ void printSymbol(Blt_Ps, double, double, int);
+};
+
+extern void Blt_InitBarSetTable(Graph* graphPtr);
+extern void Blt_ComputeBarStacks(Graph* graphPtr);
+extern void Blt_ResetBarGroups(Graph* graphPtr);
+extern void Blt_DestroyBarSets(Graph* graphPtr);
#endif
diff --git a/src/bltGrElemLine.C b/src/bltGrElemLine.C
index 79ac361..54eba89 100644
--- a/src/bltGrElemLine.C
+++ b/src/bltGrElemLine.C
@@ -61,72 +61,9 @@ extern "C" {
#define DRAW_SYMBOL(linePtr) \
(((linePtr)->symbolCounter % (linePtr)->symbolInterval) == 0)
-typedef enum {
- PEN_INCREASING, PEN_DECREASING, PEN_BOTH_DIRECTIONS
-} PenDirection;
-
-typedef struct {
- Point2d *screenPts;
- int nScreenPts;
- int *styleMap;
- int *map;
-} MapInfo;
-
-typedef struct {
- int start;
- GraphPoints screenPts;
-} bltTrace;
-
-typedef struct {
- Weight weight;
- LinePen* penPtr;
- GraphPoints symbolPts;
- GraphSegments lines;
- GraphSegments xeb;
- GraphSegments yeb;
- int symbolSize;
- int errorBarCapWidth;
-} LineStyle;
-
// Defs
-typedef double (DistanceProc)(int x, int y, Point2d *p, Point2d *q, Point2d *t);
-static void ResetLine(LineElement* elemPtr);
-
-static ElementClosestProc ClosestLineProc;
-static ElementConfigProc ConfigureLineProc;
-static ElementDestroyProc DestroyLineProc;
-static ElementDrawProc DrawActiveLineProc;
-static ElementDrawProc DrawNormalLineProc;
-static ElementDrawSymbolProc DrawSymbolProc;
-static ElementExtentsProc GetLineExtentsProc;
-static ElementToPostScriptProc ActiveLineToPostScriptProc;
-static ElementToPostScriptProc NormalLineToPostScriptProc;
-static ElementSymbolToPostScriptProc SymbolToPostScriptProc;
-static ElementMapProc MapLineProc;
-static DistanceProc DistanceToYProc;
-static DistanceProc DistanceToXProc;
-static DistanceProc DistanceToLineProc;
-
-static ElementProcs lineProcs =
- {
- ClosestLineProc, /* Finds the closest element/data
- * point */
- ConfigureLineProc, /* Configures the element. */
- DestroyLineProc, /* Destroys the element. */
- DrawActiveLineProc, /* Draws active element */
- DrawNormalLineProc, /* Draws normal element */
- DrawSymbolProc, /* Draws the element symbol. */
- GetLineExtentsProc, /* Find the extents of the element's
- * data. */
- ActiveLineToPostScriptProc, /* Prints active element. */
- NormalLineToPostScriptProc, /* Prints normal element. */
- SymbolToPostScriptProc, /* Prints the line's symbol. */
- MapLineProc /* Compute element's screen
- * coordinates. */
- };
-
-INLINE static int Round(double x)
+static int Round(double x)
{
return (int) (x + ((x < 0.0) ? -0.5 : 0.5));
}
@@ -291,61 +228,89 @@ static Tk_OptionSpec optionSpecs[] = {
{TK_OPTION_END, NULL, NULL, NULL, NULL, -1, 0, 0, NULL, 0}
};
-// Create
-
-Element* Blt_LineElement(Graph* graphPtr)
+LineElement::LineElement(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
+ : Element(graphPtr, name, hPtr)
{
- LineElement* lePtr = (LineElement*)calloc(1, sizeof(LineElement));
- lePtr->ops = (LineElementOptions*)calloc(1, sizeof(LineElementOptions));
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
- ops->elemPtr = (Element*)lePtr;
-
- lePtr->procsPtr = &lineProcs;
- ops->builtinPenPtr = &lePtr->builtinPen;
+ Blt_GraphSetObjectClass(&obj, CID_ELEM_LINE);
+
+ smooth_ = PEN_SMOOTH_LINEAR;
+ fillBgColor_ =NULL;
+ fillGC_ = NULL;
+ fillPts_ =NULL;
+ nFillPts_ = 0;
+
+ symbolPts_.points =NULL;
+ symbolPts_.length =0;
+ symbolPts_.map =NULL;
+ activePts_.points =NULL;
+ activePts_.length =0;
+ activePts_.map =NULL;
+
+ xeb_.segments =NULL;
+ xeb_.length =0;
+ xeb_.map =NULL;
+ yeb_.segments =NULL;
+ yeb_.length =0;
+ yeb_.map =NULL;
+ lines_.segments =NULL;
+ lines_.length =0;
+ lines_.map =NULL;
+
+ symbolInterval_ =0;
+ symbolCounter_ =0;
+ traces_ =NULL;
+
+ ops_ = (LineElementOptions*)calloc(1, sizeof(LineElementOptions));
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+ ops->elemPtr = (Element*)this;
+
+ builtinPenPtr = new LinePen(graphPtr, "builtin", &ops->builtinPen);
+ ops->builtinPenPtr = builtinPenPtr;
- lePtr->builtinPen.init(graphPtr, "builtin", &ops->builtinPen);
Tk_InitOptions(graphPtr->interp, (char*)&(ops->builtinPen),
- lePtr->builtinPen.optionTable(), graphPtr->tkwin);
+ builtinPenPtr->optionTable(), graphPtr->tkwin);
- lePtr->optionTable = Tk_CreateOptionTable(graphPtr->interp, optionSpecs);
+ optionTable_ = Tk_CreateOptionTable(graphPtr->interp, optionSpecs);
- lePtr->flags = SCALE_SYMBOL;
- return (Element*)lePtr;
+ ops->stylePalette = Blt_Chain_Create();
+ // this is an option and will be freed via Tk_FreeConfigOptions
+ // By default an element's name and label are the same
+ ops->label = Tcl_Alloc(strlen(name)+1);
+ if (name)
+ strcpy((char*)ops->label,(char*)name);
+
+ flags = SCALE_SYMBOL;
}
-static void DestroyLineProc(Graph* graphPtr, Element* elemPtr)
+LineElement::~LineElement()
{
- LineElement* lePtr = (LineElement*)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops_;
if (ops->activePenPtr)
Blt_FreePen((Pen *)ops->activePenPtr);
if (ops->normalPenPtr)
Blt_FreePen((Pen *)ops->normalPenPtr);
+ if (ops->builtinPenPtr)
+ delete builtinPenPtr;
+
+ ResetLine();
- ResetLine(lePtr);
if (ops->stylePalette) {
Blt_FreeStylePalette(ops->stylePalette);
Blt_Chain_Destroy(ops->stylePalette);
}
- if (lePtr->activeIndices)
- free(lePtr->activeIndices);
-
- if (lePtr->fillPts)
- free(lePtr->fillPts);
- if (lePtr->fillGC)
- Tk_FreeGC(graphPtr->display, lePtr->fillGC);
+ if (fillPts_)
+ free(fillPts_);
+ if (fillGC_)
+ Tk_FreeGC(graphPtr_->display, fillGC_);
}
-// Configure
-
-static int ConfigureLineProc(Graph* graphPtr, Element *elemPtr)
+int LineElement::configure()
{
- LineElement* lePtr = (LineElement*)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops_;
- if (lePtr->builtinPen.configure() != TCL_OK)
+ if (builtinPenPtr->configure() != TCL_OK)
return TCL_ERROR;
// Point to the static normal/active pens if no external pens have been
@@ -366,48 +331,700 @@ static int ConfigureLineProc(Graph* graphPtr, Element *elemPtr)
gcMask |= GCForeground;
gcValues.foreground = ops->fillFgColor->pixel;
}
- if (lePtr->fillBgColor) {
+ if (fillBgColor_) {
gcMask |= GCBackground;
- gcValues.background = lePtr->fillBgColor->pixel;
+ gcValues.background = fillBgColor_->pixel;
}
- GC newGC = Tk_GetGC(graphPtr->tkwin, gcMask, &gcValues);
- if (lePtr->fillGC)
- Tk_FreeGC(graphPtr->display, lePtr->fillGC);
- lePtr->fillGC = newGC;
+ GC newGC = Tk_GetGC(graphPtr_->tkwin, gcMask, &gcValues);
+ if (fillGC_)
+ Tk_FreeGC(graphPtr_->display, fillGC_);
+ fillGC_ = newGC;
return TCL_OK;
}
-// Support
+void LineElement::map()
+{
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ ResetLine();
+ if (!ops->coords.x || !ops->coords.y ||
+ !ops->coords.x->nValues || !ops->coords.y->nValues)
+ return;
+ int np = NUMBEROFPOINTS(ops);
+
+ MapInfo mi;
+ GetScreenPoints(&mi);
+ MapSymbols(&mi);
+
+ if ((flags & ACTIVE_PENDING) && (nActiveIndices_ > 0))
+ MapActiveSymbols();
+
+ // Map connecting line segments if they are to be displayed.
+ smooth_ = ops->reqSmooth;
+ if ((np > 1) && (ops->builtinPen.traceWidth > 0)) {
+ // Do smoothing if necessary. This can extend the coordinate array,
+ // so both mi.points and mi.nPoints may change.
+ switch (smooth_) {
+ case PEN_SMOOTH_STEP:
+ GenerateSteps(&mi);
+ break;
+
+ case PEN_SMOOTH_NATURAL:
+ case PEN_SMOOTH_QUADRATIC:
+ // Can't interpolate with less than three points
+ if (mi.nScreenPts < 3)
+ smooth_ = PEN_SMOOTH_LINEAR;
+ else
+ GenerateSpline(&mi);
+ break;
+
+ case PEN_SMOOTH_CATROM:
+ // Can't interpolate with less than three points
+ if (mi.nScreenPts < 3)
+ smooth_ = PEN_SMOOTH_LINEAR;
+ else
+ GenerateParametricSpline(&mi);
+ break;
+
+ default:
+ break;
+ }
+ if (ops->rTolerance > 0.0)
+ ReducePoints(&mi, ops->rTolerance);
+
+ if (ops->fillBg)
+ MapFillArea(&mi);
+
+ MapTraces(&mi);
+ }
+ free(mi.screenPts);
+ free(mi.map);
+
+ // Set the symbol size of all the pen styles
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
+ LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
+ LinePen* penPtr = (LinePen *)stylePtr->penPtr;
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+ int size = ScaleSymbol(penOps->symbol.size);
+ stylePtr->symbolSize = size;
+ stylePtr->errorBarCapWidth = (penOps->errorBarCapWidth > 0)
+ ? penOps->errorBarCapWidth : Round(size * 0.6666666);
+ stylePtr->errorBarCapWidth /= 2;
+ }
-static void ResetStylePalette(Blt_Chain styles)
+ LineStyle **styleMap = (LineStyle**)StyleMap();
+ if (((ops->yHigh && ops->yHigh->nValues > 0) &&
+ (ops->yLow && ops->yLow->nValues > 0)) ||
+ ((ops->xHigh && ops->xHigh->nValues > 0) &&
+ (ops->xLow && ops->xLow->nValues > 0)) ||
+ (ops->xError && ops->xError->nValues > 0) ||
+ (ops->yError && ops->yError->nValues > 0)) {
+ MapErrorBars(styleMap);
+ }
+
+ MergePens(styleMap);
+ free(styleMap);
+}
+
+void LineElement::extents(Region2d *extsPtr)
{
- for (Blt_ChainLink link = Blt_Chain_FirstLink(styles); link;
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ extsPtr->top = extsPtr->left = DBL_MAX;
+ extsPtr->bottom = extsPtr->right = -DBL_MAX;
+
+ if (!ops->coords.x || !ops->coords.y ||
+ !ops->coords.x->nValues || !ops->coords.y->nValues)
+ return;
+ int np = NUMBEROFPOINTS(ops);
+
+ extsPtr->right = ops->coords.x->max;
+ if ((ops->coords.x->min <= 0.0) && (ops->axes.x->logScale))
+ extsPtr->left = FindElemValuesMinimum(ops->coords.x, DBL_MIN);
+ else
+ extsPtr->left = ops->coords.x->min;
+
+ extsPtr->bottom = ops->coords.y->max;
+ if ((ops->coords.y->min <= 0.0) && (ops->axes.y->logScale))
+ extsPtr->top = FindElemValuesMinimum(ops->coords.y, DBL_MIN);
+ else
+ extsPtr->top = ops->coords.y->min;
+
+ // Correct the data limits for error bars
+ if (ops->xError && ops->xError->nValues > 0) {
+ int i;
+
+ np = MIN(ops->xError->nValues, np);
+ for (i = 0; i < np; i++) {
+ double x;
+
+ x = ops->coords.x->values[i] + ops->xError->values[i];
+ if (x > extsPtr->right) {
+ extsPtr->right = x;
+ }
+ x = ops->coords.x->values[i] - ops->xError->values[i];
+ if (ops->axes.x->logScale) {
+ // Mirror negative values, instead of ignoring them
+ if (x < 0.0)
+ x = -x;
+ if ((x > DBL_MIN) && (x < extsPtr->left))
+ extsPtr->left = x;
+ }
+ else if (x < extsPtr->left)
+ extsPtr->left = x;
+ }
+ }
+ else {
+ if (ops->xHigh &&
+ (ops->xHigh->nValues > 0) &&
+ (ops->xHigh->max > extsPtr->right)) {
+ extsPtr->right = ops->xHigh->max;
+ }
+ if (ops->xLow && ops->xLow->nValues > 0) {
+ double left;
+
+ if ((ops->xLow->min <= 0.0) &&
+ (ops->axes.x->logScale))
+ left = FindElemValuesMinimum(ops->xLow, DBL_MIN);
+ else
+ left = ops->xLow->min;
+
+ if (left < extsPtr->left)
+ extsPtr->left = left;
+ }
+ }
+
+ if (ops->yError && ops->yError->nValues > 0) {
+ int i;
+
+ np = MIN(ops->yError->nValues, np);
+ for (i = 0; i < np; i++) {
+ double y;
+
+ y = ops->coords.y->values[i] + ops->yError->values[i];
+ if (y > extsPtr->bottom) {
+ extsPtr->bottom = y;
+ }
+ y = ops->coords.y->values[i] - ops->yError->values[i];
+ if (ops->axes.y->logScale) {
+ if (y < 0.0) {
+ y = -y; /* Mirror negative values, instead of
+ * ignoring them. */
+ }
+ if ((y > DBL_MIN) && (y < extsPtr->left)) {
+ extsPtr->top = y;
+ }
+ } else if (y < extsPtr->top) {
+ extsPtr->top = y;
+ }
+ }
+ }
+ else {
+ if (ops->yHigh &&
+ (ops->yHigh->nValues > 0) &&
+ (ops->yHigh->max > extsPtr->bottom)) {
+ extsPtr->bottom = ops->yHigh->max;
+ }
+ if (ops->yLow && ops->yLow->nValues > 0) {
+ double top;
+ if ((ops->yLow->min <= 0.0) &&
+ (ops->axes.y->logScale))
+ top = FindElemValuesMinimum(ops->yLow, DBL_MIN);
+ else
+ top = ops->yLow->min;
+
+ if (top < extsPtr->top)
+ extsPtr->top = top;
+ }
+ }
+}
+
+void LineElement::closest()
+{
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ ClosestSearch* searchPtr = &graphPtr_->search;
+ int mode = searchPtr->mode;
+ if (mode == SEARCH_AUTO) {
+ LinePen* penPtr = NORMALPEN(ops);
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+ mode = SEARCH_POINTS;
+ if ((NUMBEROFPOINTS(ops) > 1) && (penOps->traceWidth > 0))
+ mode = SEARCH_TRACES;
+ }
+ if (mode == SEARCH_POINTS)
+ ClosestPoint(searchPtr);
+ else {
+ int found = ClosestTrace();
+ if ((!found) && (searchPtr->along != SEARCH_BOTH))
+ ClosestPoint(searchPtr);
+ }
+}
+
+void LineElement::drawActive(Drawable drawable)
+{
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+ LinePen* penPtr = (LinePen *)ops->activePenPtr;
+
+ if (!penPtr)
+ return;
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ int symbolSize = ScaleSymbol(penOps->symbol.size);
+
+ /*
+ * nActiveIndices
+ * > 0 Some points are active. Uses activeArr.
+ * < 0 All points are active.
+ * == 0 No points are active.
+ */
+ if (nActiveIndices_ > 0) {
+ if (flags & ACTIVE_PENDING)
+ MapActiveSymbols();
+
+ if (penOps->symbol.type != SYMBOL_NONE)
+ DrawSymbols(drawable, penPtr, symbolSize, activePts_.length,
+ activePts_.points);
+ if (penOps->valueShow != SHOW_NONE)
+ DrawValues(drawable, penPtr, activePts_.length, activePts_.points,
+ activePts_.map);
+ }
+ else if (nActiveIndices_ < 0) {
+ if (penOps->traceWidth > 0) {
+ if (lines_.length > 0)
+ Blt_Draw2DSegments(graphPtr_->display, drawable,
+ penPtr->traceGC_, lines_.segments,
+ lines_.length);
+ else if (Blt_Chain_GetLength(traces_) > 0)
+ DrawTraces(drawable, penPtr);
+ }
+ if (penOps->symbol.type != SYMBOL_NONE)
+ DrawSymbols(drawable, penPtr, symbolSize, symbolPts_.length,
+ symbolPts_.points);
+
+ if (penOps->valueShow != SHOW_NONE) {
+ DrawValues(drawable, penPtr, symbolPts_.length, symbolPts_.points,
+ symbolPts_.map);
+ }
+ }
+}
+
+void LineElement::drawNormal(Drawable drawable)
+{
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ // Fill area under the curve
+ if (fillPts_) {
+ XPoint *points = (XPoint*)malloc(sizeof(XPoint) * nFillPts_);
+
+ unsigned int count =0;
+ Point2d *endp, *pp;
+ for (pp = fillPts_, endp = pp + nFillPts_;
+ pp < endp; pp++) {
+ points[count].x = Round(pp->x);
+ points[count].y = Round(pp->y);
+ count++;
+ }
+ if (ops->fillBg)
+ Tk_Fill3DPolygon(graphPtr_->tkwin, drawable, ops->fillBg, points,
+ nFillPts_, 0, TK_RELIEF_FLAT);
+ free(points);
+ }
+
+ // Lines: stripchart segments or graph traces
+ if (lines_.length > 0) {
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
+ link; link = Blt_Chain_NextLink(link)) {
+
+ LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
+ LinePen* penPtr = (LinePen*)stylePtr->penPtr;
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+ if ((stylePtr->lines.length > 0) &&
+ (penOps->errorBarLineWidth > 0)) {
+ Blt_Draw2DSegments(graphPtr_->display, drawable, penPtr->traceGC_,
+ stylePtr->lines.segments, stylePtr->lines.length);
+ }
+ }
+ }
+ else {
+ LinePen* penPtr = NORMALPEN(ops);
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ if ((Blt_Chain_GetLength(traces_) > 0) && (penOps->traceWidth > 0))
+ DrawTraces(drawable, penPtr);
+ }
+
+ if (ops->reqMaxSymbols > 0) {
+ int total = 0;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
+ link; link = Blt_Chain_NextLink(link)) {
+ LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
+ total += stylePtr->symbolPts.length;
+ }
+ symbolInterval_ = total / ops->reqMaxSymbols;
+ symbolCounter_ = 0;
+ }
+
+ // Symbols, error bars, values
+
+ unsigned int count =0;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
link = Blt_Chain_NextLink(link)) {
LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- stylePtr->lines.length = stylePtr->symbolPts.length = 0;
- stylePtr->xeb.length = stylePtr->yeb.length = 0;
+ LinePen* penPtr = (LinePen *)stylePtr->penPtr;
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X))
+ Blt_Draw2DSegments(graphPtr_->display, drawable, penPtr->errorBarGC_,
+ stylePtr->xeb.segments, stylePtr->xeb.length);
+
+ if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y))
+ Blt_Draw2DSegments(graphPtr_->display, drawable, penPtr->errorBarGC_,
+ stylePtr->yeb.segments, stylePtr->yeb.length);
+
+ if ((stylePtr->symbolPts.length > 0) &&
+ (penOps->symbol.type != SYMBOL_NONE))
+ DrawSymbols(drawable, penPtr, stylePtr->symbolSize,
+ stylePtr->symbolPts.length, stylePtr->symbolPts.points);
+
+ if (penOps->valueShow != SHOW_NONE)
+ DrawValues(drawable, penPtr, stylePtr->symbolPts.length,
+ stylePtr->symbolPts.points, symbolPts_.map + count);
+
+ count += stylePtr->symbolPts.length;
+ }
+
+ symbolInterval_ = 0;
+}
+
+void LineElement::drawSymbol(Drawable drawable, int x, int y, int size)
+{
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ LinePen* penPtr = NORMALPEN(ops);
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ if (penOps->traceWidth > 0) {
+ /*
+ * Draw an extra line offset by one pixel from the previous to give a
+ * thicker appearance. This is only for the legend entry. This routine
+ * is never called for drawing the actual line segments.
+ */
+ XDrawLine(graphPtr_->display, drawable, penPtr->traceGC_, x - size, y,
+ x + size, y);
+ XDrawLine(graphPtr_->display, drawable, penPtr->traceGC_, x - size, y + 1,
+ x + size, y + 1);
+ }
+ if (penOps->symbol.type != SYMBOL_NONE) {
+ Point2d point;
+ point.x = x;
+ point.y = y;
+ DrawSymbols(drawable, penPtr, size, 1, &point);
+ }
+}
+
+void LineElement::printActive(Blt_Ps ps)
+{
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ LinePen* penPtr = (LinePen *)ops->activePenPtr;
+ if (!penPtr)
+ return;
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ int symbolSize = ScaleSymbol(penOps->symbol.size);
+ if (nActiveIndices_ > 0) {
+ if (flags & ACTIVE_PENDING)
+ MapActiveSymbols();
+
+ if (penOps->symbol.type != SYMBOL_NONE)
+ SymbolsToPostScript(ps, penPtr, symbolSize, activePts_.length,
+ activePts_.points);
+
+ if (penOps->valueShow != SHOW_NONE)
+ ValuesToPostScript(ps, penPtr, activePts_.length, activePts_.points,
+ activePts_.map);
+ }
+ else if (nActiveIndices_ < 0) {
+ if (penOps->traceWidth > 0) {
+ if (lines_.length > 0) {
+ SetLineAttributes(ps, penPtr);
+ Blt_Ps_Draw2DSegments(ps, lines_.segments, lines_.length);
+ }
+ if (Blt_Chain_GetLength(traces_) > 0)
+ TracesToPostScript(ps, (LinePen*)penPtr);
+ }
+ if (penOps->symbol.type != SYMBOL_NONE)
+ SymbolsToPostScript(ps, penPtr, symbolSize, symbolPts_.length,
+ symbolPts_.points);
+ if (penOps->valueShow != SHOW_NONE) {
+ ValuesToPostScript(ps, penPtr, symbolPts_.length,
+ symbolPts_.points, symbolPts_.map);
+ }
+ }
+}
+
+void LineElement::printNormal(Blt_Ps ps)
+{
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ // Draw fill area
+ if (fillPts_) {
+ // Create a path to use for both the polygon and its outline
+ Blt_Ps_Append(ps, "% start fill area\n");
+ Blt_Ps_Polyline(ps, fillPts_, nFillPts_);
+
+ // If the background fill color was specified, draw the polygon in a
+ // solid fashion with that color
+ if (fillBgColor_) {
+ Blt_Ps_XSetBackground(ps, fillBgColor_);
+ Blt_Ps_Append(ps, "gsave fill grestore\n");
+ }
+ Blt_Ps_XSetForeground(ps, ops->fillFgColor);
+ if (ops->fillBg)
+ Blt_Ps_Append(ps, "gsave fill grestore\n");
+ else
+ Blt_Ps_Append(ps, "gsave fill grestore\n");
+
+ Blt_Ps_Append(ps, "% end fill area\n");
+ }
+
+ // Draw lines (strip chart) or traces (xy graph)
+ if (lines_.length > 0) {
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
+ LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
+ LinePen* penPtr = (LinePen *)stylePtr->penPtr;
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ if ((stylePtr->lines.length > 0) && (penOps->traceWidth > 0)) {
+ SetLineAttributes(ps, penPtr);
+ Blt_Ps_Append(ps, "% start segments\n");
+ Blt_Ps_Draw2DSegments(ps, stylePtr->lines.segments,
+ stylePtr->lines.length);
+ Blt_Ps_Append(ps, "% end segments\n");
+ }
+ }
+ }
+ else {
+ LinePen* penPtr = NORMALPEN(ops);
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ if ((Blt_Chain_GetLength(traces_) > 0) &&
+ (penOps->traceWidth > 0)) {
+ TracesToPostScript(ps, penPtr);
+ }
+ }
+
+ // Draw symbols, error bars, values
+
+ unsigned int count =0;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
+ link = Blt_Chain_NextLink(link)) {
+
+ LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
+ LinePen* penPtr = (LinePen *)stylePtr->penPtr;
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+ XColor* colorPtr = penOps->errorBarColor;
+ if (!colorPtr)
+ colorPtr = penOps->traceColor;
+
+ if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X)) {
+ Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
+ NULL, CapButt, JoinMiter);
+ Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments,
+ stylePtr->xeb.length);
+ }
+ if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y)) {
+ Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
+ NULL, CapButt, JoinMiter);
+ Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments,
+ stylePtr->yeb.length);
+ }
+ if ((stylePtr->symbolPts.length > 0) &&
+ (penOps->symbol.type != SYMBOL_NONE)) {
+ SymbolsToPostScript(ps, penPtr, stylePtr->symbolSize,
+ stylePtr->symbolPts.length,
+ stylePtr->symbolPts.points);
+ }
+ if (penOps->valueShow != SHOW_NONE) {
+ ValuesToPostScript(ps, penPtr, stylePtr->symbolPts.length,
+ stylePtr->symbolPts.points,
+ symbolPts_.map + count);
+ }
+ count += stylePtr->symbolPts.length;
+ }
+}
+
+void printSymbol(Blt_Ps ps, double x, double y, int size)
+{
+ LineElementOptions* ops = (LineElementOptions*)ops;
+
+ LinePen* penPtr = NORMALPEN(ops);
+ LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
+
+ if (penOps->traceWidth > 0) {
+ /*
+ * Draw an extra line offset by one pixel from the previous to give a
+ * thicker appearance. This is only for the legend entry. This routine
+ * is never called for drawing the actual line segments.
+ */
+ Blt_Ps_XSetLineAttributes(ps, penOps->traceColor, penOps->traceWidth,
+ &penOps->traceDashes, CapButt, JoinMiter);
+ Blt_Ps_Format(ps, "%g %g %d Li\n", x, y, size + size);
+ }
+ if (penOps->symbol.type != SYMBOL_NONE) {
+ Point2d point;
+ point.x = x;
+ point.y = y;
+ SymbolsToPostScript(ps, penPtr, size, 1, &point);
+ }
+}
+
+// Support
+
+double LineElement::DistanceToLine(int x, int y, Point2d *p, Point2d *q,
+ Point2d *t)
+{
+ double right, left, top, bottom;
+
+ *t = Blt_GetProjection(x, y, p, q);
+ if (p->x > q->x)
+ right = p->x, left = q->x;
+ else
+ left = p->x, right = q->x;
+
+ if (p->y > q->y)
+ bottom = p->y, top = q->y;
+ else
+ top = p->y, bottom = q->y;
+
+ if (t->x > right)
+ t->x = right;
+ else if (t->x < left)
+ t->x = left;
+
+ if (t->y > bottom)
+ t->y = bottom;
+ else if (t->y < top)
+ t->y = top;
+
+ return hypot((t->x - x), (t->y - y));
+}
+
+double LineElement::DistanceToX(int x, int y, Point2d *p, Point2d *q,
+ Point2d *t)
+{
+ double dx, dy;
+ double d;
+
+ if (p->x > q->x) {
+ if ((x > p->x) || (x < q->x)) {
+ return DBL_MAX; /* X-coordinate outside line segment. */
+ }
+ } else {
+ if ((x > q->x) || (x < p->x)) {
+ return DBL_MAX; /* X-coordinate outside line segment. */
+ }
+ }
+ dx = p->x - q->x;
+ dy = p->y - q->y;
+ t->x = (double)x;
+ if (fabs(dx) < DBL_EPSILON) {
+ double d1, d2;
+ /*
+ * Same X-coordinate indicates a vertical line. Pick the closest end
+ * point.
+ */
+ d1 = p->y - y;
+ d2 = q->y - y;
+ if (fabs(d1) < fabs(d2)) {
+ t->y = p->y, d = d1;
+ } else {
+ t->y = q->y, d = d2;
+ }
}
+ else if (fabs(dy) < DBL_EPSILON) {
+ /* Horizontal line. */
+ t->y = p->y, d = p->y - y;
+ }
+ else {
+ double m = dy / dx;
+ double b = p->y - (m * p->x);
+ t->y = (x * m) + b;
+ d = y - t->y;
+ }
+
+ return fabs(d);
}
-static int ScaleSymbol(LineElement* lePtr, int normalSize)
+double LineElement::DistanceToY(int x, int y, Point2d *p, Point2d *q,
+ Point2d *t)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ double dx, dy;
+ double d;
+
+ if (p->y > q->y) {
+ if ((y > p->y) || (y < q->y)) {
+ return DBL_MAX;
+ }
+ }
+ else {
+ if ((y > q->y) || (y < p->y)) {
+ return DBL_MAX;
+ }
+ }
+ dx = p->x - q->x;
+ dy = p->y - q->y;
+ t->y = y;
+ if (fabs(dy) < DBL_EPSILON) {
+ double d1, d2;
+
+ /* Save Y-coordinate indicates an horizontal line. Pick the closest end
+ * point. */
+ d1 = p->x - x;
+ d2 = q->x - x;
+ if (fabs(d1) < fabs(d2)) {
+ t->x = p->x, d = d1;
+ }
+ else {
+ t->x = q->x, d = d2;
+ }
+ }
+ else if (fabs(dx) < DBL_EPSILON) {
+ /* Vertical line. */
+ t->x = p->x, d = p->x - x;
+ }
+ else {
+ double m = dy / dx;
+ double b = p->y - (m * p->x);
+ t->x = (y - b) / m;
+ d = x - t->x;
+ }
+
+ return fabs(d);
+}
+
+int LineElement::ScaleSymbol(int normalSize)
+{
+ LineElementOptions* ops = (LineElementOptions*)ops;
double scale = 1.0;
if (ops->scaleSymbols) {
double xRange = (ops->axes.x->max - ops->axes.x->min);
double yRange = (ops->axes.y->max - ops->axes.y->min);
// Save the ranges as a baseline for future scaling
- if (lePtr->flags & SCALE_SYMBOL) {
- lePtr->xRange = xRange;
- lePtr->yRange = yRange;
- lePtr->flags &= ~SCALE_SYMBOL;
+ if (flags & SCALE_SYMBOL) {
+ xRange_ = xRange;
+ yRange_ = yRange;
+ flags &= ~SCALE_SYMBOL;
}
else {
// Scale the symbol by the smallest change in the X or Y axes
- double xScale = lePtr->xRange / xRange;
- double yScale = lePtr->yRange / yRange;
+ double xScale = xRange / xRange;
+ double yScale = yRange / yRange;
scale = MIN(xScale, yScale);
}
}
@@ -415,8 +1032,7 @@ static int ScaleSymbol(LineElement* lePtr, int normalSize)
// Don't let the size of symbols go unbounded. Both X and Win32 drawing
// routines assume coordinates to be a signed short int.
- int maxSize = (int)MIN(lePtr->obj.graphPtr->hRange,
- lePtr->obj.graphPtr->vRange);
+ int maxSize = (int)MIN(obj.graphPtr->hRange, obj.graphPtr->vRange);
if (newSize > maxSize)
newSize = maxSize;
@@ -426,10 +1042,9 @@ static int ScaleSymbol(LineElement* lePtr, int normalSize)
return newSize;
}
-static void GetScreenPoints(Graph* graphPtr, LineElement* lePtr,
- MapInfo *mapPtr)
+void LineElement::GetScreenPoints(MapInfo *mapPtr)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
if (!ops->coords.x || !ops->coords.y) {
mapPtr->screenPts = NULL;
@@ -444,7 +1059,7 @@ static void GetScreenPoints(Graph* graphPtr, LineElement* lePtr,
int* map = (int*)malloc(sizeof(int) * np);
int count = 0;
- if (graphPtr->inverted) {
+ if (graphPtr_->inverted) {
for (int i = 0; i < np; i++) {
if ((isfinite(x[i])) && (isfinite(y[i]))) {
points[count].x = Blt_HMap(ops->axes.y, y[i]);
@@ -469,19 +1084,17 @@ static void GetScreenPoints(Graph* graphPtr, LineElement* lePtr,
mapPtr->map = map;
}
-static void ReducePoints(MapInfo *mapPtr, double tolerance)
+void LineElement::ReducePoints(MapInfo *mapPtr, double tolerance)
{
int* simple = (int*)malloc(mapPtr->nScreenPts * sizeof(int));
int* map = (int*)malloc(mapPtr->nScreenPts * sizeof(int));
Point2d *screenPts = (Point2d*)malloc(mapPtr->nScreenPts * sizeof(Point2d));
int np = Blt_SimplifyLine(mapPtr->screenPts, 0, mapPtr->nScreenPts - 1,
tolerance, simple);
- for (int i = 0; i < np; i++) {
- int k;
-
- k = simple[i];
- screenPts[i] = mapPtr->screenPts[k];
- map[i] = mapPtr->map[k];
+ for (int ii=0; ii<np; ii++) {
+ int kk = simple[ii];
+ screenPts[ii] = mapPtr->screenPts[kk];
+ map[ii] = mapPtr->map[kk];
}
free(mapPtr->screenPts);
free(mapPtr->map);
@@ -491,7 +1104,7 @@ static void ReducePoints(MapInfo *mapPtr, double tolerance)
mapPtr->nScreenPts = np;
}
-static void GenerateSteps(MapInfo *mapPtr)
+void LineElement::GenerateSteps(MapInfo *mapPtr)
{
int newSize = ((mapPtr->nScreenPts - 1) * 2) + 1;
Point2d *screenPts = (Point2d*)malloc(newSize * sizeof(Point2d));
@@ -518,8 +1131,7 @@ static void GenerateSteps(MapInfo *mapPtr)
mapPtr->nScreenPts = newSize;
}
-static void GenerateSpline(Graph* graphPtr, LineElement* lePtr,
- MapInfo *mapPtr)
+void LineElement::GenerateSpline(MapInfo *mapPtr)
{
Point2d *origPts, *iPts;
int *map;
@@ -536,8 +1148,8 @@ static void GenerateSpline(Graph* graphPtr, LineElement* lePtr,
* increasing */
}
}
- if (((origPts[0].x > (double)graphPtr->right)) ||
- ((origPts[mapPtr->nScreenPts - 1].x < (double)graphPtr->left))) {
+ if (((origPts[0].x > (double)graphPtr_->right)) ||
+ ((origPts[mapPtr->nScreenPts - 1].x < (double)graphPtr_->left))) {
return; /* All points are clipped */
}
@@ -546,7 +1158,7 @@ static void GenerateSpline(Graph* graphPtr, LineElement* lePtr,
* that we can select the abscissas of the interpolated points from each
* pixel horizontally across the plotting area.
*/
- extra = (graphPtr->right - graphPtr->left) + 1;
+ extra = (graphPtr_->right - graphPtr_->left) + 1;
if (extra < 1) {
return;
}
@@ -567,8 +1179,8 @@ static void GenerateSpline(Graph* graphPtr, LineElement* lePtr,
count++;
/* Is any part of the interval (line segment) in the plotting area? */
- if ((origPts[j].x >= (double)graphPtr->left) ||
- (origPts[i].x <= (double)graphPtr->right)) {
+ if ((origPts[j].x >= (double)graphPtr_->left) ||
+ (origPts[i].x <= (double)graphPtr_->right)) {
double x, last;
x = origPts[i].x + 1.0;
@@ -584,8 +1196,8 @@ static void GenerateSpline(Graph* graphPtr, LineElement* lePtr,
* Pick the max of the starting X-coordinate and the left edge and
* the min of the last X-coordinate and the right edge.
*/
- x = MAX(x, (double)graphPtr->left);
- last = MIN(origPts[j].x, (double)graphPtr->right);
+ x = MAX(x, (double)graphPtr_->left);
+ last = MIN(origPts[j].x, (double)graphPtr_->right);
/* Add the extra x-coordinates to the interval. */
while (x < last) {
@@ -597,18 +1209,19 @@ static void GenerateSpline(Graph* graphPtr, LineElement* lePtr,
}
niPts = count;
result = 0;
- if (lePtr->smooth == PEN_SMOOTH_NATURAL) {
+ if (smooth_ == PEN_SMOOTH_NATURAL)
result = Blt_NaturalSpline(origPts, nOrigPts, iPts, niPts);
- } else if (lePtr->smooth == PEN_SMOOTH_QUADRATIC) {
+ else if (smooth_ == PEN_SMOOTH_QUADRATIC)
result = Blt_QuadraticSpline(origPts, nOrigPts, iPts, niPts);
- }
+
if (!result) {
/* The spline interpolation failed. We'll fallback to the current
* coordinates and do no smoothing (standard line segments). */
- lePtr->smooth = PEN_SMOOTH_LINEAR;
+ smooth_ = PEN_SMOOTH_LINEAR;
free(iPts);
free(map);
- } else {
+ }
+ else {
free(mapPtr->screenPts);
free(mapPtr->map);
mapPtr->map = map;
@@ -617,8 +1230,7 @@ static void GenerateSpline(Graph* graphPtr, LineElement* lePtr,
}
}
-static void GenerateParametricSpline(Graph* graphPtr, LineElement* lePtr,
- MapInfo *mapPtr)
+void LineElement::GenerateParametricSpline(MapInfo *mapPtr)
{
Region2d exts;
Point2d *origPts, *iPts;
@@ -629,7 +1241,7 @@ static void GenerateParametricSpline(Graph* graphPtr, LineElement* lePtr,
nOrigPts = mapPtr->nScreenPts;
origPts = mapPtr->screenPts;
- Blt_GraphExtents(graphPtr, &exts);
+ Blt_GraphExtents(graphPtr_, &exts);
/*
* Populate the x2 array with both the original X-coordinates and extra
@@ -704,19 +1316,20 @@ static void GenerateParametricSpline(Graph* graphPtr, LineElement* lePtr,
count++;
niPts = count;
result = 0;
- if (lePtr->smooth == PEN_SMOOTH_NATURAL) {
+ if (smooth_ == PEN_SMOOTH_NATURAL)
result = Blt_NaturalParametricSpline(origPts, nOrigPts, &exts, 0,
iPts, niPts);
- } else if (lePtr->smooth == PEN_SMOOTH_CATROM) {
+ else if (smooth_ == PEN_SMOOTH_CATROM)
result = Blt_CatromParametricSpline(origPts, nOrigPts, iPts, niPts);
- }
+
if (!result) {
/* The spline interpolation failed. We will fall back to the current
* coordinates and do no smoothing (standard line segments). */
- lePtr->smooth = PEN_SMOOTH_LINEAR;
+ smooth_ = PEN_SMOOTH_LINEAR;
free(iPts);
free(map);
- } else {
+ }
+ else {
free(mapPtr->screenPts);
free(mapPtr->map);
mapPtr->map = map;
@@ -725,7 +1338,7 @@ static void GenerateParametricSpline(Graph* graphPtr, LineElement* lePtr,
}
}
-static void MapSymbols(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
+void LineElement::MapSymbols(MapInfo *mapPtr)
{
Region2d exts;
Point2d *pp;
@@ -734,7 +1347,7 @@ static void MapSymbols(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
Point2d* points = (Point2d*)malloc(sizeof(Point2d) * mapPtr->nScreenPts);
int *map = (int*)malloc(sizeof(int) * mapPtr->nScreenPts);
- Blt_GraphExtents(graphPtr, &exts);
+ Blt_GraphExtents(graphPtr_, &exts);
int count = 0;
for (pp = mapPtr->screenPts, i = 0; i < mapPtr->nScreenPts; i++, pp++) {
@@ -745,40 +1358,40 @@ static void MapSymbols(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
count++;
}
}
- lePtr->symbolPts.points = points;
- lePtr->symbolPts.length = count;
- lePtr->symbolPts.map = map;
+ symbolPts_.points = points;
+ symbolPts_.length = count;
+ symbolPts_.map = map;
}
-static void MapActiveSymbols(Graph* graphPtr, LineElement* lePtr)
+void LineElement::MapActiveSymbols()
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
- if (lePtr->activePts.points) {
- free(lePtr->activePts.points);
- lePtr->activePts.points = NULL;
+ if (activePts_.points) {
+ free(activePts_.points);
+ activePts_.points = NULL;
}
- if (lePtr->activePts.map) {
- free(lePtr->activePts.map);
- lePtr->activePts.map = NULL;
+ if (activePts_.map) {
+ free(activePts_.map);
+ activePts_.map = NULL;
}
Region2d exts;
- Blt_GraphExtents(graphPtr, &exts);
+ Blt_GraphExtents(graphPtr_, &exts);
- Point2d *points = (Point2d*)malloc(sizeof(Point2d) * lePtr->nActiveIndices);
- int* map = (int*)malloc(sizeof(int) * lePtr->nActiveIndices);
+ Point2d *points = (Point2d*)malloc(sizeof(Point2d) * nActiveIndices_);
+ int* map = (int*)malloc(sizeof(int) * nActiveIndices_);
int np = NUMBEROFPOINTS(ops);
int count = 0;
if (ops->coords.x && ops->coords.y) {
- for (int ii=0; ii<lePtr->nActiveIndices; ii++) {
- int iPoint = lePtr->activeIndices[ii];
+ for (int ii=0; ii<nActiveIndices_; ii++) {
+ int iPoint = activeIndices_[ii];
if (iPoint >= np)
continue;
double x = ops->coords.x->values[iPoint];
double y = ops->coords.y->values[iPoint];
- points[count] = Blt_Map2D(graphPtr, x, y, &ops->axes);
+ points[count] = Blt_Map2D(graphPtr_, x, y, &ops->axes);
map[count] = iPoint;
if (PointInRegion(&exts, points[count].x, points[count].y)) {
count++;
@@ -787,152 +1400,131 @@ static void MapActiveSymbols(Graph* graphPtr, LineElement* lePtr)
}
if (count > 0) {
- lePtr->activePts.points = points;
- lePtr->activePts.map = map;
+ activePts_.points = points;
+ activePts_.map = map;
}
else {
free(points);
free(map);
}
- lePtr->activePts.length = count;
- lePtr->flags &= ~ACTIVE_PENDING;
+ activePts_.length = count;
+ flags &= ~ACTIVE_PENDING;
}
-static void MergePens(LineElement* lePtr, LineStyle **styleMap)
+void LineElement::MergePens(LineStyle **styleMap)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
if (Blt_Chain_GetLength(ops->stylePalette) < 2) {
Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- stylePtr->lines.length = lePtr->lines.length;
- stylePtr->lines.segments = lePtr->lines.segments;
- stylePtr->symbolPts.length = lePtr->symbolPts.length;
- stylePtr->symbolPts.points = lePtr->symbolPts.points;
- stylePtr->xeb.length = lePtr->xeb.length;
- stylePtr->xeb.segments = lePtr->xeb.segments;
- stylePtr->yeb.length = lePtr->yeb.length;
- stylePtr->yeb.segments = lePtr->yeb.segments;
+ stylePtr->lines.length = lines_.length;
+ stylePtr->lines.segments = lines_.segments;
+ stylePtr->symbolPts.length = symbolPts_.length;
+ stylePtr->symbolPts.points = symbolPts_.points;
+ stylePtr->xeb.length = xeb_.length;
+ stylePtr->xeb.segments = xeb_.segments;
+ stylePtr->yeb.length = yeb_.length;
+ stylePtr->yeb.segments = yeb_.segments;
return;
}
/* We have more than one style. Group line segments and points of like pen
* styles. */
- if (lePtr->lines.length > 0) {
- Blt_ChainLink link;
- Segment2d *sp;
- int *ip;
-
- Segment2d* segments =
- (Segment2d*)malloc(lePtr->lines.length * sizeof(Segment2d));
- int* map = (int*)malloc(lePtr->lines.length * sizeof(int));
- sp = segments, ip = map;
- for (link = Blt_Chain_FirstLink(ops->stylePalette);
+ if (lines_.length > 0) {
+ Segment2d* segments = (Segment2d*)malloc(lines_.length * sizeof(Segment2d));
+ int* map = (int*)malloc(lines_.length * sizeof(int));
+ Segment2d *sp = segments;
+ int* ip = map;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
link; link = Blt_Chain_NextLink(link)) {
LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
stylePtr->lines.segments = sp;
- for (int i = 0; i < lePtr->lines.length; i++) {
- int iData;
-
- iData = lePtr->lines.map[i];
+ for (int ii=0; ii<lines_.length; ii++) {
+ int iData = lines_.map[ii];
if (styleMap[iData] == stylePtr) {
- *sp++ = lePtr->lines.segments[i];
+ *sp++ = lines_.segments[ii];
*ip++ = iData;
}
}
stylePtr->lines.length = sp - stylePtr->lines.segments;
}
- free(lePtr->lines.segments);
- lePtr->lines.segments = segments;
- free(lePtr->lines.map);
- lePtr->lines.map = map;
- }
- if (lePtr->symbolPts.length > 0) {
- Blt_ChainLink link;
- int *ip;
- Point2d *pp;
-
- Point2d* points =
- (Point2d*)malloc(lePtr->symbolPts.length * sizeof(Point2d));
- int* map = (int*)malloc(lePtr->symbolPts.length * sizeof(int));
- pp = points, ip = map;
- for (link = Blt_Chain_FirstLink(ops->stylePalette);
+ free(lines_.segments);
+ lines_.segments = segments;
+ free(lines_.map);
+ lines_.map = map;
+ }
+
+ if (symbolPts_.length > 0) {
+ Point2d* points = (Point2d*)malloc(symbolPts_.length * sizeof(Point2d));
+ int* map = (int*)malloc(symbolPts_.length * sizeof(int));
+ Point2d *pp = points;
+ int* ip = map;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
link; link = Blt_Chain_NextLink(link)) {
LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
stylePtr->symbolPts.points = pp;
- for (int i = 0; i < lePtr->symbolPts.length; i++) {
- int iData;
-
- iData = lePtr->symbolPts.map[i];
+ for (int ii=0; ii<symbolPts_.length; ii++) {
+ int iData = symbolPts_.map[ii];
if (styleMap[iData] == stylePtr) {
- *pp++ = lePtr->symbolPts.points[i];
+ *pp++ = symbolPts_.points[ii];
*ip++ = iData;
}
}
stylePtr->symbolPts.length = pp - stylePtr->symbolPts.points;
}
- free(lePtr->symbolPts.points);
- free(lePtr->symbolPts.map);
- lePtr->symbolPts.points = points;
- lePtr->symbolPts.map = map;
- }
- if (lePtr->xeb.length > 0) {
- Segment2d *sp;
- int *ip;
- Blt_ChainLink link;
-
- Segment2d *segments =
- (Segment2d*)malloc(lePtr->xeb.length * sizeof(Segment2d));
- int* map = (int*)malloc(lePtr->xeb.length * sizeof(int));
- sp = segments, ip = map;
- for (link = Blt_Chain_FirstLink(ops->stylePalette);
+ free(symbolPts_.points);
+ free(symbolPts_.map);
+ symbolPts_.points = points;
+ symbolPts_.map = map;
+ }
+
+ if (xeb_.length > 0) {
+ Segment2d *segments = (Segment2d*)malloc(xeb_.length * sizeof(Segment2d));
+ int* map = (int*)malloc(xeb_.length * sizeof(int));
+ Segment2d *sp = segments;
+ int* ip = map;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
link; link = Blt_Chain_NextLink(link)) {
LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
stylePtr->xeb.segments = sp;
- for (int i = 0; i < lePtr->xeb.length; i++) {
- int iData;
-
- iData = lePtr->xeb.map[i];
+ for (int ii=0; ii<xeb_.length; ii++) {
+ int iData = xeb_.map[ii];
if (styleMap[iData] == stylePtr) {
- *sp++ = lePtr->xeb.segments[i];
+ *sp++ = xeb_.segments[ii];
*ip++ = iData;
}
}
stylePtr->xeb.length = sp - stylePtr->xeb.segments;
}
- free(lePtr->xeb.segments);
- free(lePtr->xeb.map);
- lePtr->xeb.segments = segments;
- lePtr->xeb.map = map;
- }
- if (lePtr->yeb.length > 0) {
- Segment2d *sp;
- int *ip;
- Blt_ChainLink link;
-
- Segment2d *segments =
- (Segment2d*)malloc(lePtr->yeb.length * sizeof(Segment2d));
- int* map = (int*)malloc(lePtr->yeb.length * sizeof(int));
- sp = segments, ip = map;
- for (link = Blt_Chain_FirstLink(ops->stylePalette);
+ free(xeb_.segments);
+ free(xeb_.map);
+ xeb_.segments = segments;
+ xeb_.map = map;
+ }
+
+ if (yeb_.length > 0) {
+ Segment2d *segments = (Segment2d*)malloc(yeb_.length * sizeof(Segment2d));
+ int* map = (int*)malloc(yeb_.length * sizeof(int));
+ Segment2d *sp = segments;
+ int* ip = map;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
link; link = Blt_Chain_NextLink(link)) {
LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
stylePtr->yeb.segments = sp;
- for (int i = 0; i < lePtr->yeb.length; i++) {
- int iData;
-
- iData = lePtr->yeb.map[i];
+ for (int ii=0; ii<yeb_.length; ii++) {
+ int iData = yeb_.map[ii];
if (styleMap[iData] == stylePtr) {
- *sp++ = lePtr->yeb.segments[i];
+ *sp++ = yeb_.segments[ii];
*ip++ = iData;
}
}
stylePtr->yeb.length = sp - stylePtr->yeb.segments;
}
- free(lePtr->yeb.segments);
- lePtr->yeb.segments = segments;
- free(lePtr->yeb.map);
- lePtr->yeb.map = map;
+ free(yeb_.segments);
+ yeb_.segments = segments;
+ free(yeb_.map);
+ yeb_.map = map;
}
}
@@ -941,31 +1533,27 @@ static void MergePens(LineElement* lePtr, LineStyle **styleMap)
#define CLIP_RIGHT (1<<2)
#define CLIP_LEFT (1<<3)
-INLINE static int OutCode(Region2d *extsPtr, Point2d *p)
+int LineElement::OutCode(Region2d *extsPtr, Point2d *p)
{
- int code;
-
- code = 0;
- if (p->x > extsPtr->right) {
+ int code =0;
+ if (p->x > extsPtr->right)
code |= CLIP_RIGHT;
- } else if (p->x < extsPtr->left) {
+ else if (p->x < extsPtr->left)
code |= CLIP_LEFT;
- }
- if (p->y > extsPtr->bottom) {
+
+ if (p->y > extsPtr->bottom)
code |= CLIP_BOTTOM;
- } else if (p->y < extsPtr->top) {
+ else if (p->y < extsPtr->top)
code |= CLIP_TOP;
- }
+
return code;
}
-static int ClipSegment(Region2d *extsPtr, int code1, int code2,
- Point2d *p, Point2d *q)
+int LineElement::ClipSegment(Region2d *extsPtr, int code1, int code2,
+ Point2d *p, Point2d *q)
{
- int inside, outside;
-
- inside = ((code1 | code2) == 0);
- outside = ((code1 & code2) != 0);
+ int inside = ((code1 | code2) == 0);
+ int outside = ((code1 & code2) != 0);
/*
* In the worst case, we'll clip the line segment against each of the four
@@ -1005,61 +1593,56 @@ static int ClipSegment(Region2d *extsPtr, int code1, int code2,
return (!inside);
}
-static void SaveTrace(LineElement* lePtr, int start, int length,
- MapInfo *mapPtr)
+void LineElement::SaveTrace(int start, int length, MapInfo *mapPtr)
{
- int i, j;
-
bltTrace *tracePtr = (bltTrace*)malloc(sizeof(bltTrace));
Point2d *screenPts = (Point2d*)malloc(sizeof(Point2d) * length);
int* map = (int*)malloc(sizeof(int) * length);
- /* Copy the screen coordinates of the trace into the point array */
+ // Copy the screen coordinates of the trace into the point array
if (mapPtr->map) {
- for (i = 0, j = start; i < length; i++, j++) {
- screenPts[i].x = mapPtr->screenPts[j].x;
- screenPts[i].y = mapPtr->screenPts[j].y;
- map[i] = mapPtr->map[j];
+ for (int ii=0, jj=start; ii<length; ii++, jj++) {
+ screenPts[ii].x = mapPtr->screenPts[jj].x;
+ screenPts[ii].y = mapPtr->screenPts[jj].y;
+ map[ii] = mapPtr->map[jj];
}
} else {
- for (i = 0, j = start; i < length; i++, j++) {
- screenPts[i].x = mapPtr->screenPts[j].x;
- screenPts[i].y = mapPtr->screenPts[j].y;
- map[i] = j;
+ for (int ii=0, jj=start; ii<length; ii++, jj++) {
+ screenPts[ii].x = mapPtr->screenPts[jj].x;
+ screenPts[ii].y = mapPtr->screenPts[jj].y;
+ map[ii] = jj;
}
}
tracePtr->screenPts.length = length;
tracePtr->screenPts.points = screenPts;
tracePtr->screenPts.map = map;
tracePtr->start = start;
- if (lePtr->traces == NULL) {
- lePtr->traces = Blt_Chain_Create();
- }
- Blt_Chain_Append(lePtr->traces, tracePtr);
+ if (traces_ == NULL)
+ traces_ = Blt_Chain_Create();
+
+ Blt_Chain_Append(traces_, tracePtr);
}
-static void FreeTraces(LineElement* lePtr)
+void LineElement::FreeTraces()
{
- Blt_ChainLink link;
-
- for (link = Blt_Chain_FirstLink(lePtr->traces); link;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(traces_); link;
link = Blt_Chain_NextLink(link)) {
bltTrace *tracePtr = (bltTrace*)Blt_Chain_GetValue(link);
free(tracePtr->screenPts.map);
free(tracePtr->screenPts.points);
free(tracePtr);
}
- Blt_Chain_Destroy(lePtr->traces);
- lePtr->traces = NULL;
+ Blt_Chain_Destroy(traces_);
+ traces_ = NULL;
}
-static void MapTraces(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
+void LineElement::MapTraces(MapInfo *mapPtr)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
Region2d exts;
- Blt_GraphExtents(graphPtr, &exts);
+ Blt_GraphExtents(graphPtr_, &exts);
int count = 1;
int code1 = OutCode(&exts, mapPtr->screenPts);
Point2d* p = mapPtr->screenPts;
@@ -1089,7 +1672,7 @@ static void MapTraces(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
if (count > 1) {
start = ii - count;
- SaveTrace(lePtr, start, count, mapPtr);
+ SaveTrace(start, count, mapPtr);
count = 1;
}
}
@@ -1104,7 +1687,7 @@ static void MapTraces(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
*/
start = ii - (count - 1);
- SaveTrace(lePtr, start, count, mapPtr);
+ SaveTrace(start, count, mapPtr);
mapPtr->screenPts[ii] = s;
count = 1;
}
@@ -1113,28 +1696,28 @@ static void MapTraces(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
}
if (count > 1) {
start = ii - count;
- SaveTrace(lePtr, start, count, mapPtr);
+ SaveTrace(start, count, mapPtr);
}
}
-static void MapFillArea(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
+void LineElement::MapFillArea(MapInfo *mapPtr)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
- if (lePtr->fillPts) {
- free(lePtr->fillPts);
- lePtr->fillPts = NULL;
- lePtr->nFillPts = 0;
+ if (fillPts_) {
+ free(fillPts_);
+ fillPts_ = NULL;
+ nFillPts_ = 0;
}
if (mapPtr->nScreenPts < 3)
return;
int np = mapPtr->nScreenPts + 3;
Region2d exts;
- Blt_GraphExtents(graphPtr, &exts);
+ Blt_GraphExtents(graphPtr_, &exts);
Point2d* origPts = (Point2d*)malloc(sizeof(Point2d) * np);
- if (graphPtr->inverted) {
+ if (graphPtr_->inverted) {
double minX;
int i;
@@ -1155,11 +1738,11 @@ static void MapFillArea(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
origPts[i].y = origPts[0].y;
i++;
origPts[i] = origPts[0];
- } else {
- double maxY;
+ }
+ else {
int i;
- maxY = (double)ops->axes.y->bottom;
+ double maxY = (double)ops->axes.y->bottom;
for (i = 0; i < mapPtr->nScreenPts; i++) {
origPts[i].x = mapPtr->screenPts[i].x + 1;
origPts[i].y = mapPtr->screenPts[i].y;
@@ -1182,74 +1765,80 @@ static void MapFillArea(Graph* graphPtr, LineElement* lePtr, MapInfo *mapPtr)
np = Blt_PolyRectClip(&exts, origPts, np - 1, clipPts);
free(origPts);
- if (np < 3) {
+ if (np < 3)
free(clipPts);
- } else {
- lePtr->fillPts = clipPts;
- lePtr->nFillPts = np;
+ else {
+ fillPts_ = clipPts;
+ nFillPts_ = np;
}
}
-static void ResetLine(LineElement* lePtr)
+void LineElement::ResetLine()
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- FreeTraces(lePtr);
- ResetStylePalette(ops->stylePalette);
- if (lePtr->symbolPts.points) {
- free(lePtr->symbolPts.points);
- lePtr->symbolPts.points = NULL;
- }
-
- if (lePtr->symbolPts.map)
- free(lePtr->symbolPts.map);
- lePtr->symbolPts.map = NULL;
- lePtr->symbolPts.length = 0;
-
- if (lePtr->lines.segments)
- free(lePtr->lines.segments);
- lePtr->lines.segments = NULL;
- lePtr->lines.length = 0;
-
- if (lePtr->lines.map)
- free(lePtr->lines.map);
- lePtr->lines.map = NULL;
-
- if (lePtr->activePts.points)
- free(lePtr->activePts.points);
- lePtr->activePts.points = NULL;
- lePtr->activePts.length = 0;
-
- if (lePtr->activePts.map)
- free(lePtr->activePts.map);
- lePtr->activePts.map = NULL;
-
- if (lePtr->xeb.segments)
- free(lePtr->xeb.segments);
- lePtr->xeb.segments = NULL;
-
- if (lePtr->xeb.map)
- free(lePtr->xeb.map);
- lePtr->xeb.map = NULL;
- lePtr->xeb.length = 0;
-
- if (lePtr->yeb.segments)
- free(lePtr->yeb.segments);
- lePtr->yeb.segments = NULL;
- lePtr->yeb.length = 0;
-
- if (lePtr->yeb.map)
- free(lePtr->yeb.map);
- lePtr->yeb.map = NULL;
+ LineElementOptions* ops = (LineElementOptions*)ops_;
+
+ FreeTraces();
+
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(styles); link;
+ link = Blt_Chain_NextLink(link)) {
+ LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
+ stylePtr->lines.length = stylePtr->symbolPts.length = 0;
+ stylePtr->xeb.length = stylePtr->yeb.length = 0;
+ }
+
+ if (symbolPts_.points) {
+ free(symbolPts_.points);
+ symbolPts_.points = NULL;
+ }
+
+ if (symbolPts_.map)
+ free(symbolPts_.map);
+ symbolPts_.map = NULL;
+ symbolPts_.length = 0;
+
+ if (lines_.segments)
+ free(lines_.segments);
+ lines_.segments = NULL;
+ lines_.length = 0;
+
+ if (lines_.map)
+ free(lines_.map);
+ lines_.map = NULL;
+
+ if (activePts_.points)
+ free(activePts_.points);
+ activePts_.points = NULL;
+ activePts_.length = 0;
+
+ if (activePts_.map)
+ free(activePts_.map);
+ activePts_.map = NULL;
+
+ if (xeb_.segments)
+ free(xeb_.segments);
+ xeb_.segments = NULL;
+
+ if (xeb_.map)
+ free(xeb_.map);
+ xeb_.map = NULL;
+ xeb_.length = 0;
+
+ if (yeb_.segments)
+ free(yeb_.segments);
+ yeb_.segments = NULL;
+ yeb_.length = 0;
+
+ if (yeb_.map)
+ free(yeb_.map);
+ yeb_.map = NULL;
}
-static void MapErrorBars(Graph* graphPtr, LineElement* lePtr,
- LineStyle **styleMap)
+void LineElement::MapErrorBars(LineStyle **styleMap)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
Region2d exts;
- Blt_GraphExtents(graphPtr, &exts);
+ Blt_GraphExtents(graphPtr_, &exts);
int n =0;
int np = NUMBEROFPOINTS(ops);
@@ -1289,8 +1878,8 @@ static void MapErrorBars(Graph* graphPtr, LineElement* lePtr,
if ((isfinite(high)) && (isfinite(low))) {
Point2d p, q;
- p = Blt_Map2D(graphPtr, high, y, &ops->axes);
- q = Blt_Map2D(graphPtr, low, y, &ops->axes);
+ p = Blt_Map2D(graphPtr_, high, y, &ops->axes);
+ q = Blt_Map2D(graphPtr_, low, y, &ops->axes);
segPtr->p = p;
segPtr->q = q;
if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
@@ -1316,9 +1905,9 @@ static void MapErrorBars(Graph* graphPtr, LineElement* lePtr,
}
}
}
- lePtr->xeb.segments = errorBars;
- lePtr->xeb.length = segPtr - errorBars;
- lePtr->xeb.map = errorToData;
+ xeb_.segments = errorBars;
+ xeb_.length = segPtr - errorBars;
+ xeb_.map = errorToData;
}
n =0;
@@ -1358,8 +1947,8 @@ static void MapErrorBars(Graph* graphPtr, LineElement* lePtr,
if ((isfinite(high)) && (isfinite(low))) {
Point2d p, q;
- p = Blt_Map2D(graphPtr, x, high, &ops->axes);
- q = Blt_Map2D(graphPtr, x, low, &ops->axes);
+ p = Blt_Map2D(graphPtr_, x, high, &ops->axes);
+ q = Blt_Map2D(graphPtr_, x, low, &ops->axes);
segPtr->p = p;
segPtr->q = q;
if (Blt_LineRectClip(&exts, &segPtr->p, &segPtr->q)) {
@@ -1385,220 +1974,16 @@ static void MapErrorBars(Graph* graphPtr, LineElement* lePtr,
}
}
}
- lePtr->yeb.segments = errorBars;
- lePtr->yeb.length = segPtr - errorBars;
- lePtr->yeb.map = errorToData;
- }
-}
-
-static void MapLineProc(Graph* graphPtr, Element *elemPtr)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- ResetLine(lePtr);
- if (!ops->coords.x || !ops->coords.y ||
- !ops->coords.x->nValues || !ops->coords.y->nValues)
- return;
- int np = NUMBEROFPOINTS(ops);
-
- MapInfo mi;
- GetScreenPoints(graphPtr, lePtr, &mi);
- MapSymbols(graphPtr, lePtr, &mi);
-
- if ((lePtr->flags & ACTIVE_PENDING) && (lePtr->nActiveIndices > 0))
- MapActiveSymbols(graphPtr, lePtr);
-
- // Map connecting line segments if they are to be displayed.
- lePtr->smooth = ops->reqSmooth;
- if ((np > 1) && (ops->builtinPen.traceWidth > 0)) {
- // Do smoothing if necessary. This can extend the coordinate array,
- // so both mi.points and mi.nPoints may change.
- switch (lePtr->smooth) {
- case PEN_SMOOTH_STEP:
- GenerateSteps(&mi);
- break;
-
- case PEN_SMOOTH_NATURAL:
- case PEN_SMOOTH_QUADRATIC:
- // Can't interpolate with less than three points
- if (mi.nScreenPts < 3)
- lePtr->smooth = PEN_SMOOTH_LINEAR;
- else
- GenerateSpline(graphPtr, lePtr, &mi);
- break;
-
- case PEN_SMOOTH_CATROM:
- // Can't interpolate with less than three points
- if (mi.nScreenPts < 3)
- lePtr->smooth = PEN_SMOOTH_LINEAR;
- else
- GenerateParametricSpline(graphPtr, lePtr, &mi);
- break;
-
- default:
- break;
- }
- if (ops->rTolerance > 0.0) {
- ReducePoints(&mi, ops->rTolerance);
- }
- if (ops->fillBg) {
- MapFillArea(graphPtr, lePtr, &mi);
- }
- MapTraces(graphPtr, lePtr, &mi);
- }
- free(mi.screenPts);
- free(mi.map);
-
- // Set the symbol size of all the pen styles
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
- LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- LinePen* penPtr = (LinePen *)stylePtr->penPtr;
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
- int size = ScaleSymbol(lePtr, penOps->symbol.size);
- stylePtr->symbolSize = size;
- stylePtr->errorBarCapWidth = (penOps->errorBarCapWidth > 0)
- ? penOps->errorBarCapWidth : Round(size * 0.6666666);
- stylePtr->errorBarCapWidth /= 2;
- }
-
- LineStyle **styleMap = (LineStyle **)Blt_StyleMap((Element *)lePtr);
- if (((ops->yHigh && ops->yHigh->nValues > 0) &&
- (ops->yLow && ops->yLow->nValues > 0)) ||
- ((ops->xHigh && ops->xHigh->nValues > 0) &&
- (ops->xLow && ops->xLow->nValues > 0)) ||
- (ops->xError && ops->xError->nValues > 0) ||
- (ops->yError && ops->yError->nValues > 0)) {
- MapErrorBars(graphPtr, lePtr, styleMap);
- }
-
- MergePens(lePtr, styleMap);
- free(styleMap);
-}
-
-static double DistanceToLineProc(int x, int y, Point2d *p, Point2d *q,
- Point2d *t)
-{
- double right, left, top, bottom;
-
- *t = Blt_GetProjection(x, y, p, q);
- if (p->x > q->x) {
- right = p->x, left = q->x;
- } else {
- left = p->x, right = q->x;
- }
- if (p->y > q->y) {
- bottom = p->y, top = q->y;
- } else {
- top = p->y, bottom = q->y;
- }
- if (t->x > right) {
- t->x = right;
- } else if (t->x < left) {
- t->x = left;
- }
- if (t->y > bottom) {
- t->y = bottom;
- } else if (t->y < top) {
- t->y = top;
- }
- return hypot((t->x - x), (t->y - y));
-}
-
-static double DistanceToXProc(int x, int y, Point2d *p, Point2d *q,
- Point2d *t)
-{
- double dx, dy;
- double d;
-
- if (p->x > q->x) {
- if ((x > p->x) || (x < q->x)) {
- return DBL_MAX; /* X-coordinate outside line segment. */
- }
- } else {
- if ((x > q->x) || (x < p->x)) {
- return DBL_MAX; /* X-coordinate outside line segment. */
- }
- }
- dx = p->x - q->x;
- dy = p->y - q->y;
- t->x = (double)x;
- if (fabs(dx) < DBL_EPSILON) {
- double d1, d2;
- /*
- * Same X-coordinate indicates a vertical line. Pick the closest end
- * point.
- */
- d1 = p->y - y;
- d2 = q->y - y;
- if (fabs(d1) < fabs(d2)) {
- t->y = p->y, d = d1;
- } else {
- t->y = q->y, d = d2;
- }
- } else if (fabs(dy) < DBL_EPSILON) {
- /* Horizontal line. */
- t->y = p->y, d = p->y - y;
- } else {
- double m, b;
-
- m = dy / dx;
- b = p->y - (m * p->x);
- t->y = (x * m) + b;
- d = y - t->y;
- }
- return fabs(d);
-}
-
-static double DistanceToYProc(int x, int y, Point2d *p, Point2d *q, Point2d *t)
-{
- double dx, dy;
- double d;
-
- if (p->y > q->y) {
- if ((y > p->y) || (y < q->y)) {
- return DBL_MAX;
- }
- } else {
- if ((y > q->y) || (y < p->y)) {
- return DBL_MAX;
- }
- }
- dx = p->x - q->x;
- dy = p->y - q->y;
- t->y = y;
- if (fabs(dy) < DBL_EPSILON) {
- double d1, d2;
-
- /* Save Y-coordinate indicates an horizontal line. Pick the closest end
- * point. */
- d1 = p->x - x;
- d2 = q->x - x;
- if (fabs(d1) < fabs(d2)) {
- t->x = p->x, d = d1;
- } else {
- t->x = q->x, d = d2;
- }
- } else if (fabs(dx) < DBL_EPSILON) {
- /* Vertical line. */
- t->x = p->x, d = p->x - x;
- } else {
- double m, b;
-
- m = dy / dx;
- b = p->y - (m * p->x);
- t->x = (y - b) / m;
- d = x - t->x;
+ yeb_.segments = errorBars;
+ yeb_.length = segPtr - errorBars;
+ yeb_.map = errorToData;
}
- return fabs(d);
}
-static int ClosestTrace(Graph* graphPtr, LineElement* lePtr,
- DistanceProc *distProc)
+int LineElement::ClosestTrace()
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
- ClosestSearch* searchPtr = &graphPtr->search;
+ LineElementOptions* ops = (LineElementOptions*)ops;
+ ClosestSearch* searchPtr = &graphPtr_->search;
Blt_ChainLink link;
Point2d closest;
@@ -1608,7 +1993,7 @@ static int ClosestTrace(Graph* graphPtr, LineElement* lePtr,
iClose = -1; /* Suppress compiler warning. */
dMin = searchPtr->dist;
closest.x = closest.y = 0; /* Suppress compiler warning. */
- for (link = Blt_Chain_FirstLink(lePtr->traces); link;
+ for (link = Blt_Chain_FirstLink(traces_); link;
link = Blt_Chain_NextLink(link)) {
Point2d *p, *pend;
@@ -1618,7 +2003,13 @@ static int ClosestTrace(Graph* graphPtr, LineElement* lePtr,
Point2d b;
double d;
- d = (*distProc)(searchPtr->x, searchPtr->y, p, p + 1, &b);
+ if (search->along == SEARCH_X)
+ d = DistanceToX(searchPtr->x, searchPtr->y, p, p + 1, &b);
+ else if (search->along == SEARCH_Y)
+ d = DistanceToY(searchPtr->x, searchPtr->y, p, p + 1, &b);
+ else
+ d = DistanceToLine(searchPtr->x, searchPtr->y, p, p + 1, &b);
+
if (d < dMin) {
closest = b;
iClose = tracePtr->screenPts.map[p-tracePtr->screenPts.points];
@@ -1628,17 +2019,18 @@ static int ClosestTrace(Graph* graphPtr, LineElement* lePtr,
}
if (dMin < searchPtr->dist) {
searchPtr->dist = dMin;
- searchPtr->elemPtr = (Element*)lePtr;
+ searchPtr->elemPtr = (Element*)this;
searchPtr->index = iClose;
- searchPtr->point = Blt_InvMap2D(graphPtr, closest.x, closest.y, &ops->axes);
+ searchPtr->point = Blt_InvMap2D(graphPtr_, closest.x, closest.y, &ops->axes);
return 1;
}
+
return 0;
}
-static void ClosestPoint(LineElement* lePtr, ClosestSearch *searchPtr)
+void LineElement::ClosestPoint(ClosestSearch *searchPtr)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
double dMin = searchPtr->dist;
int iClose = 0;
@@ -1649,8 +2041,8 @@ static void ClosestPoint(LineElement* lePtr, ClosestSearch *searchPtr)
// 2) the computed distance is already in screen coordinates.
int count;
Point2d *pp;
- for (pp = lePtr->symbolPts.points, count = 0;
- count < lePtr->symbolPts.length; count++, pp++) {
+ for (pp = symbolPts_.points, count = 0;
+ count < symbolPts_.length; count++, pp++) {
double dx = (double)(searchPtr->x - pp->x);
double dy = (double)(searchPtr->y - pp->y);
double d;
@@ -1664,12 +2056,12 @@ static void ClosestPoint(LineElement* lePtr, ClosestSearch *searchPtr)
continue;
if (d < dMin) {
- iClose = lePtr->symbolPts.map[count];
+ iClose = symbolPts_.map[count];
dMin = d;
}
}
if (dMin < searchPtr->dist) {
- searchPtr->elemPtr = (Element*)lePtr;
+ searchPtr->elemPtr = (Element*)this;
searchPtr->dist = dMin;
searchPtr->index = iClose;
searchPtr->point.x = ops->coords.x->values[iClose];
@@ -1677,152 +2069,6 @@ static void ClosestPoint(LineElement* lePtr, ClosestSearch *searchPtr)
}
}
-static void GetLineExtentsProc(Element *elemPtr, Region2d *extsPtr)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- extsPtr->top = extsPtr->left = DBL_MAX;
- extsPtr->bottom = extsPtr->right = -DBL_MAX;
-
- if (!ops->coords.x || !ops->coords.y ||
- !ops->coords.x->nValues || !ops->coords.y->nValues)
- return;
- int np = NUMBEROFPOINTS(ops);
-
- extsPtr->right = ops->coords.x->max;
- if ((ops->coords.x->min <= 0.0) && (ops->axes.x->logScale))
- extsPtr->left = Blt_FindElemValuesMinimum(ops->coords.x, DBL_MIN);
- else
- extsPtr->left = ops->coords.x->min;
-
- extsPtr->bottom = ops->coords.y->max;
- if ((ops->coords.y->min <= 0.0) && (ops->axes.y->logScale))
- extsPtr->top = Blt_FindElemValuesMinimum(ops->coords.y, DBL_MIN);
- else
- extsPtr->top = ops->coords.y->min;
-
- // Correct the data limits for error bars
- if (ops->xError && ops->xError->nValues > 0) {
- int i;
-
- np = MIN(ops->xError->nValues, np);
- for (i = 0; i < np; i++) {
- double x;
-
- x = ops->coords.x->values[i] + ops->xError->values[i];
- if (x > extsPtr->right) {
- extsPtr->right = x;
- }
- x = ops->coords.x->values[i] - ops->xError->values[i];
- if (ops->axes.x->logScale) {
- // Mirror negative values, instead of ignoring them
- if (x < 0.0)
- x = -x;
- if ((x > DBL_MIN) && (x < extsPtr->left))
- extsPtr->left = x;
- }
- else if (x < extsPtr->left)
- extsPtr->left = x;
- }
- }
- else {
- if (ops->xHigh &&
- (ops->xHigh->nValues > 0) &&
- (ops->xHigh->max > extsPtr->right)) {
- extsPtr->right = ops->xHigh->max;
- }
- if (ops->xLow && ops->xLow->nValues > 0) {
- double left;
-
- if ((ops->xLow->min <= 0.0) &&
- (ops->axes.x->logScale))
- left = Blt_FindElemValuesMinimum(ops->xLow, DBL_MIN);
- else
- left = ops->xLow->min;
-
- if (left < extsPtr->left)
- extsPtr->left = left;
- }
- }
-
- if (ops->yError && ops->yError->nValues > 0) {
- int i;
-
- np = MIN(ops->yError->nValues, np);
- for (i = 0; i < np; i++) {
- double y;
-
- y = ops->coords.y->values[i] + ops->yError->values[i];
- if (y > extsPtr->bottom) {
- extsPtr->bottom = y;
- }
- y = ops->coords.y->values[i] - ops->yError->values[i];
- if (ops->axes.y->logScale) {
- if (y < 0.0) {
- y = -y; /* Mirror negative values, instead of
- * ignoring them. */
- }
- if ((y > DBL_MIN) && (y < extsPtr->left)) {
- extsPtr->top = y;
- }
- } else if (y < extsPtr->top) {
- extsPtr->top = y;
- }
- }
- } else {
- if (ops->yHigh &&
- (ops->yHigh->nValues > 0) &&
- (ops->yHigh->max > extsPtr->bottom)) {
- extsPtr->bottom = ops->yHigh->max;
- }
- if (ops->yLow && ops->yLow->nValues > 0) {
- double top;
-
- if ((ops->yLow->min <= 0.0) &&
- (ops->axes.y->logScale))
- top = Blt_FindElemValuesMinimum(ops->yLow, DBL_MIN);
- else
- top = ops->yLow->min;
-
- if (top < extsPtr->top)
- extsPtr->top = top;
- }
- }
-}
-
-static void ClosestLineProc(Graph* graphPtr, Element *elemPtr)
-{
- LineElement* lePtr = (LineElement*)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- ClosestSearch* searchPtr = &graphPtr->search;
- int mode = searchPtr->mode;
- if (mode == SEARCH_AUTO) {
- LinePen* penPtr = NORMALPEN(ops);
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
- mode = SEARCH_POINTS;
- if ((NUMBEROFPOINTS(ops) > 1) && (penOps->traceWidth > 0))
- mode = SEARCH_TRACES;
- }
- if (mode == SEARCH_POINTS)
- ClosestPoint(lePtr, searchPtr);
- else {
- DistanceProc *distProc;
- if (searchPtr->along == SEARCH_X)
- distProc = DistanceToXProc;
- else if (searchPtr->along == SEARCH_Y)
- distProc = DistanceToYProc;
- else
- distProc = DistanceToLineProc;
-
- int found = ClosestTrace(graphPtr, lePtr, distProc);
- if ((!found) && (searchPtr->along != SEARCH_BOTH)) {
- ClosestPoint(lePtr, searchPtr);
- }
- }
-}
-
/*
* XDrawLines() points: XMaxRequestSize(dpy) - 3
* XFillPolygon() points: XMaxRequestSize(dpy) - 4
@@ -1838,8 +2084,8 @@ static void ClosestLineProc(Graph* graphPtr, Element *elemPtr)
#define MAX_DRAWRECTANGLES(d) Blt_MaxRequestSize(d, sizeof(XRectangle))
#define MAX_DRAWARCS(d) Blt_MaxRequestSize(d, sizeof(XArc))
-static void DrawCircles(Display *display, Drawable drawable,
- LineElement* lePtr, LinePen* penPtr,
+void LineElement::DrawCircles(Display *display, Drawable drawable,
+ LinePen* penPtr,
int nSymbolPts, Point2d *symbolPts, int radius)
{
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
@@ -1848,7 +2094,7 @@ static void DrawCircles(Display *display, Drawable drawable,
int s = radius + radius;
XArc *arcs = (XArc*)malloc(nSymbolPts * sizeof(XArc));
- if (lePtr->symbolInterval > 0) {
+ if (symbolInterval > 0) {
XArc* ap = arcs;
Point2d *pp, *pend;
for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) {
@@ -1860,7 +2106,7 @@ static void DrawCircles(Display *display, Drawable drawable,
ap->angle2 = 23040;
ap++, count++;
}
- lePtr->symbolCounter++;
+ symbolCounter++;
}
}
else {
@@ -1890,9 +2136,9 @@ static void DrawCircles(Display *display, Drawable drawable,
free(arcs);
}
-static void DrawSquares(Display *display, Drawable drawable,
- LineElement* lePtr, LinePen* penPtr,
- int nSymbolPts, Point2d *symbolPts, int r)
+void LineElement::DrawSquares(Display *display, Drawable drawable,
+ LinePen* penPtr,
+ int nSymbolPts, Point2d *symbolPts, int r)
{
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
@@ -1900,7 +2146,7 @@ static void DrawSquares(Display *display, Drawable drawable,
int s = r + r;
XRectangle *rectangles = (XRectangle*)malloc(nSymbolPts * sizeof(XRectangle));
- if (lePtr->symbolInterval > 0) {
+ if (symbolInterval > 0) {
XRectangle* rp = rectangles;
Point2d *pp, *pend;
for (pp = symbolPts, pend = pp + nSymbolPts; pp < pend; pp++) {
@@ -1910,7 +2156,7 @@ static void DrawSquares(Display *display, Drawable drawable,
rp->width = rp->height = (unsigned short)s;
rp++, count++;
}
- lePtr->symbolCounter++;
+ symbolCounter++;
}
}
else {
@@ -1944,9 +2190,8 @@ static void DrawSquares(Display *display, Drawable drawable,
#define SQRT_PI 1.77245385090552
#define S_RATIO 0.886226925452758
-static void DrawSymbols(Graph* graphPtr, Drawable drawable,
- LineElement* lePtr, LinePen* penPtr,
- int size, int nSymbolPts, Point2d *symbolPts)
+void LineElement::DrawSymbols(Drawable drawable, LinePen* penPtr,
+ int size, int nSymbolPts, Point2d *symbolPts)
{
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
@@ -1963,7 +2208,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
xpp->y = Round(pp->y);
xpp++;
}
- XDrawPoints(graphPtr->display, drawable, penOps->symbol.fillGC,
+ XDrawPoints(graphPtr_->display, drawable, penOps->symbol.fillGC,
points, nSymbolPts, CoordModeOrigin);
free(points);
}
@@ -1978,12 +2223,12 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
break;
case SYMBOL_SQUARE:
- DrawSquares(graphPtr->display, drawable, lePtr, penPtr, nSymbolPts,
+ DrawSquares(graphPtr_->display, drawable, lePtr, penPtr, nSymbolPts,
symbolPts, r2);
break;
case SYMBOL_CIRCLE:
- DrawCircles(graphPtr->display, drawable, lePtr, penPtr, nSymbolPts,
+ DrawCircles(graphPtr_->display, drawable, lePtr, penPtr, nSymbolPts,
symbolPts, r1);
break;
@@ -2002,7 +2247,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
}
XSegment *segments = (XSegment*)malloc(nSymbolPts * 2 * sizeof(XSegment));
- if (lePtr->symbolInterval > 0) {
+ if (symbolInterval > 0) {
XSegment* sp = segments;
count = 0;
Point2d *pp, *endp;
@@ -2022,7 +2267,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
sp++;
count++;
}
- lePtr->symbolCounter++;
+ symbolCounter++;
}
}
else {
@@ -2046,10 +2291,10 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
}
int nSegs = count * 2;
// Always draw skinny symbols regardless of the outline width
- int reqSize = MAX_DRAWSEGMENTS(graphPtr->display);
+ int reqSize = MAX_DRAWSEGMENTS(graphPtr_->display);
for (int ii=0; ii<nSegs; ii+=reqSize) {
int chunk = ((ii + reqSize) > nSegs) ? (nSegs - ii) : reqSize;
- XDrawSegments(graphPtr->display, drawable,
+ XDrawSegments(graphPtr_->display, drawable,
penOps->symbol.outlineGC, segments + ii, chunk);
}
free(segments);
@@ -2097,7 +2342,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
pattern[12] = pattern[0];
}
polygon = (XPoint*)malloc(nSymbolPts * 13 * sizeof(XPoint));
- if (lePtr->symbolInterval > 0) {
+ if (symbolInterval > 0) {
count = 0;
XPoint* xpp = polygon;
Point2d *pp, *endp;
@@ -2112,7 +2357,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
}
count++;
}
- lePtr->symbolCounter++;
+ symbolCounter++;
}
}
else {
@@ -2133,7 +2378,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
int ii;
XPoint *xpp;
for (xpp = polygon, ii = 0; ii<count; ii++, xpp += 13)
- XFillPolygon(graphPtr->display, drawable,
+ XFillPolygon(graphPtr_->display, drawable,
penOps->symbol.fillGC, xpp, 13, Complex,
CoordModeOrigin);
}
@@ -2141,7 +2386,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
int ii;
XPoint *xpp;
for (xpp = polygon, ii=0; ii<count; ii++, xpp += 13)
- XDrawLines(graphPtr->display, drawable,
+ XDrawLines(graphPtr_->display, drawable,
penOps->symbol.outlineGC, xpp, 13, CoordModeOrigin);
}
free(polygon);
@@ -2168,7 +2413,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
pattern[4] = pattern[0];
polygon = (XPoint*)malloc(nSymbolPts * 5 * sizeof(XPoint));
- if (lePtr->symbolInterval > 0) {
+ if (symbolInterval > 0) {
Point2d *pp, *endp;
XPoint *xpp;
@@ -2188,7 +2433,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
}
count++;
}
- lePtr->symbolCounter++;
+ symbolCounter++;
}
} else {
Point2d *pp, *endp;
@@ -2213,7 +2458,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
int i;
for (xpp = polygon, i = 0; i < count; i++, xpp += 5)
- XFillPolygon(graphPtr->display, drawable,
+ XFillPolygon(graphPtr_->display, drawable,
penOps->symbol.fillGC, xpp, 5, Convex, CoordModeOrigin);
}
if (penOps->symbol.outlineWidth > 0) {
@@ -2221,7 +2466,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
int i;
for (xpp = polygon, i = 0; i < count; i++, xpp += 5) {
- XDrawLines(graphPtr->display, drawable,
+ XDrawLines(graphPtr_->display, drawable,
penOps->symbol.outlineGC, xpp, 5, CoordModeOrigin);
}
}
@@ -2269,7 +2514,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
pattern[2].x = -b2;
}
polygon = (XPoint*)malloc(nSymbolPts * 4 * sizeof(XPoint));
- if (lePtr->symbolInterval > 0) {
+ if (symbolInterval > 0) {
Point2d *pp, *endp;
XPoint *xpp;
@@ -2289,7 +2534,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
}
count++;
}
- lePtr->symbolCounter++;
+ symbolCounter++;
}
} else {
Point2d *pp, *endp;
@@ -2315,7 +2560,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
xpp = polygon;
for (xpp = polygon, i = 0; i < count; i++, xpp += 4)
- XFillPolygon(graphPtr->display, drawable,
+ XFillPolygon(graphPtr_->display, drawable,
penOps->symbol.fillGC, xpp, 4, Convex, CoordModeOrigin);
}
if (penOps->symbol.outlineWidth > 0) {
@@ -2324,7 +2569,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
xpp = polygon;
for (xpp = polygon, i = 0; i < count; i++, xpp += 4) {
- XDrawLines(graphPtr->display, drawable,
+ XDrawLines(graphPtr_->display, drawable,
penOps->symbol.outlineGC, xpp, 4, CoordModeOrigin);
}
}
@@ -2338,7 +2583,7 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
double scale, sx, sy;
int dx, dy;
- Tk_SizeOfBitmap(graphPtr->display, penOps->symbol.bitmap, &w, &h);
+ Tk_SizeOfBitmap(graphPtr_->display, penOps->symbol.bitmap, &w, &h);
// Compute the size of the scaled bitmap. Stretch the bitmap to fit
// a nxn bounding box.
@@ -2348,19 +2593,19 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
bw = (int)(w * scale);
bh = (int)(h * scale);
- XSetClipMask(graphPtr->display, penOps->symbol.outlineGC, None);
+ XSetClipMask(graphPtr_->display, penOps->symbol.outlineGC, None);
if (penOps->symbol.mask != None)
- XSetClipMask(graphPtr->display, penOps->symbol.outlineGC,
+ XSetClipMask(graphPtr_->display, penOps->symbol.outlineGC,
penOps->symbol.mask);
if (penOps->symbol.fillGC == NULL)
- XSetClipMask(graphPtr->display, penOps->symbol.outlineGC,
+ XSetClipMask(graphPtr_->display, penOps->symbol.outlineGC,
penOps->symbol.bitmap);
dx = bw / 2;
dy = bh / 2;
- if (lePtr->symbolInterval > 0) {
+ if (symbolInterval > 0) {
Point2d *pp, *endp;
for (pp = symbolPts, endp = pp + nSymbolPts; pp < endp; pp++) {
if (DRAW_SYMBOL(lePtr)) {
@@ -2368,12 +2613,12 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
int y = Round(pp->y) - dy;
if ((penOps->symbol.fillGC == NULL) ||
(penOps->symbol.mask != None))
- XSetClipOrigin(graphPtr->display,
+ XSetClipOrigin(graphPtr_->display,
penOps->symbol.outlineGC, x, y);
- XCopyPlane(graphPtr->display, penOps->symbol.bitmap, drawable,
+ XCopyPlane(graphPtr_->display, penOps->symbol.bitmap, drawable,
penOps->symbol.outlineGC, 0, 0, bw, bh, x, y, 1);
}
- lePtr->symbolCounter++;
+ symbolCounter++;
}
}
else {
@@ -2383,9 +2628,9 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
int y = Round(pp->y) - dy;
if ((penOps->symbol.fillGC == NULL) ||
(penOps->symbol.mask != None))
- XSetClipOrigin(graphPtr->display,
+ XSetClipOrigin(graphPtr_->display,
penOps->symbol.outlineGC, x, y);
- XCopyPlane(graphPtr->display, penOps->symbol.bitmap, drawable,
+ XCopyPlane(graphPtr_->display, penOps->symbol.bitmap, drawable,
penOps->symbol.outlineGC, 0, 0, bw, bh, x, y, 1);
}
}
@@ -2394,48 +2639,15 @@ static void DrawSymbols(Graph* graphPtr, Drawable drawable,
}
}
-static void DrawSymbolProc(Graph* graphPtr, Drawable drawable,
- Element *elemPtr, int x, int y, int size)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- LinePen* penPtr = NORMALPEN(ops);
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- if (penOps->traceWidth > 0) {
- /*
- * Draw an extra line offset by one pixel from the previous to give a
- * thicker appearance. This is only for the legend entry. This routine
- * is never called for drawing the actual line segments.
- */
- XDrawLine(graphPtr->display, drawable, penPtr->traceGC_, x - size, y,
- x + size, y);
- XDrawLine(graphPtr->display, drawable, penPtr->traceGC_, x - size, y + 1,
- x + size, y + 1);
- }
- if (penOps->symbol.type != SYMBOL_NONE) {
- Point2d point;
-
- point.x = x, point.y = y;
- DrawSymbols(graphPtr, drawable, lePtr, penPtr, size, 1, &point);
- }
-}
-
-static void DrawTraces(Graph* graphPtr, Drawable drawable,
- LineElement* lePtr, LinePen* penPtr)
+void LineElement::DrawTraces(Drawable drawable, LinePen* penPtr)
{
- Blt_ChainLink link;
- int np;
-
- np = Blt_MaxRequestSize(graphPtr->display, sizeof(XPoint)) - 1;
+ int np = Blt_MaxRequestSize(graphPtr_->display, sizeof(XPoint)) - 1;
XPoint *points = (XPoint*)malloc((np + 1) * sizeof(XPoint));
- for (link = Blt_Chain_FirstLink(lePtr->traces); link;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(traces); link;
link = Blt_Chain_NextLink(link)) {
XPoint *xpp;
int remaining, count;
- int n;
bltTrace *tracePtr = (bltTrace*)Blt_Chain_GetValue(link);
@@ -2447,12 +2659,12 @@ static void DrawTraces(Graph* graphPtr, Drawable drawable,
/* Step 1. Convert and draw the first section of the trace.
* It may contain the entire trace. */
- n = MIN(np, tracePtr->screenPts.length);
+ int n = MIN(np, tracePtr->screenPts.length);
for (xpp = points, count = 0; count < n; count++, xpp++) {
xpp->x = Round(tracePtr->screenPts.points[count].x);
xpp->y = Round(tracePtr->screenPts.points[count].y);
}
- XDrawLines(graphPtr->display, drawable, penPtr->traceGC_, points,
+ XDrawLines(graphPtr_->display, drawable, penPtr->traceGC_, points,
count, CoordModeOrigin);
/* Step 2. Next handle any full-size chunks left. */
@@ -2468,7 +2680,7 @@ static void DrawTraces(Graph* graphPtr, Drawable drawable,
xpp->x = Round(tracePtr->screenPts.points[count].x);
xpp->y = Round(tracePtr->screenPts.points[count].y);
}
- XDrawLines(graphPtr->display, drawable, penPtr->traceGC_, points,
+ XDrawLines(graphPtr_->display, drawable, penPtr->traceGC_, points,
np + 1, CoordModeOrigin);
}
@@ -2484,205 +2696,53 @@ static void DrawTraces(Graph* graphPtr, Drawable drawable,
xpp->x = Round(tracePtr->screenPts.points[count].x);
xpp->y = Round(tracePtr->screenPts.points[count].y);
}
- XDrawLines(graphPtr->display, drawable, penPtr->traceGC_, points,
+ XDrawLines(graphPtr_->display, drawable, penPtr->traceGC_, points,
remaining + 1, CoordModeOrigin);
}
}
free(points);
}
-static void DrawValues(Graph* graphPtr, Drawable drawable,
- LineElement* lePtr, LinePen* penPtr,
- int length, Point2d *points, int *map)
+void LineElement::DrawValues(Drawable drawable, LinePen* penPtr,
+ int length, Point2d *points, int *map)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
Point2d *pp, *endp;
double *xval, *yval;
const char* fmt;
char string[TCL_DOUBLE_SPACE * 2 + 2];
- int count;
fmt = penOps->valueFormat;
if (fmt == NULL)
fmt = "%g";
- count = 0;
+ int count = 0;
xval = ops->coords.x->values, yval = ops->coords.y->values;
// be sure to update style->gc, things might have changed
penOps->valueStyle.flags |= UPDATE_GC;
for (pp = points, endp = points + length; pp < endp; pp++) {
- double x, y;
-
- x = xval[map[count]];
- y = yval[map[count]];
+ double x = xval[map[count]];
+ double y = yval[map[count]];
count++;
- if (penOps->valueShow == SHOW_X) {
+ if (penOps->valueShow == SHOW_X)
sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x);
- } else if (penOps->valueShow == SHOW_Y) {
+ else if (penOps->valueShow == SHOW_Y)
sprintf_s(string, TCL_DOUBLE_SPACE, fmt, y);
- } else if (penOps->valueShow == SHOW_BOTH) {
+ else if (penOps->valueShow == SHOW_BOTH) {
sprintf_s(string, TCL_DOUBLE_SPACE, fmt, x);
strcat(string, ",");
sprintf_s(string + strlen(string), TCL_DOUBLE_SPACE, fmt, y);
}
- Blt_DrawText(graphPtr->tkwin, drawable, string, &penOps->valueStyle,
+
+ Blt_DrawText(graphPtr_->tkwin, drawable, string, &penOps->valueStyle,
Round(pp->x), Round(pp->y));
}
}
-static void DrawActiveLineProc(Graph* graphPtr, Drawable drawable,
- Element *elemPtr)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
- LinePen* penPtr = (LinePen *)ops->activePenPtr;
-
- if (!penPtr)
- return;
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- int symbolSize = ScaleSymbol(lePtr, penOps->symbol.size);
-
- /*
- * nActiveIndices
- * > 0 Some points are active. Uses activeArr.
- * < 0 All points are active.
- * == 0 No points are active.
- */
- if (lePtr->nActiveIndices > 0) {
- if (lePtr->flags & ACTIVE_PENDING) {
- MapActiveSymbols(graphPtr, lePtr);
- }
- if (penOps->symbol.type != SYMBOL_NONE) {
- DrawSymbols(graphPtr, drawable, lePtr, penPtr, symbolSize,
- lePtr->activePts.length, lePtr->activePts.points);
- }
- if (penOps->valueShow != SHOW_NONE) {
- DrawValues(graphPtr, drawable, lePtr, penPtr,
- lePtr->activePts.length,
- lePtr->activePts.points,
- lePtr->activePts.map);
- }
- } else if (lePtr->nActiveIndices < 0) {
- if (penOps->traceWidth > 0) {
- if (lePtr->lines.length > 0) {
- Blt_Draw2DSegments(graphPtr->display, drawable,
- penPtr->traceGC_, lePtr->lines.segments,
- lePtr->lines.length);
- } else if (Blt_Chain_GetLength(lePtr->traces) > 0) {
- DrawTraces(graphPtr, drawable, lePtr, penPtr);
- }
- }
- if (penOps->symbol.type != SYMBOL_NONE) {
- DrawSymbols(graphPtr, drawable, lePtr, penPtr, symbolSize,
- lePtr->symbolPts.length, lePtr->symbolPts.points);
- }
- if (penOps->valueShow != SHOW_NONE) {
- DrawValues(graphPtr, drawable, lePtr, penPtr,
- lePtr->symbolPts.length, lePtr->symbolPts.points,
- lePtr->symbolPts.map);
- }
- }
-}
-
-static void DrawNormalLineProc(Graph* graphPtr, Drawable drawable,
- Element *elemPtr)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- // Fill area under the curve
- if (lePtr->fillPts) {
- XPoint *points = (XPoint*)malloc(sizeof(XPoint) * lePtr->nFillPts);
-
- unsigned int count =0;
- Point2d *endp, *pp;
- for (pp = lePtr->fillPts, endp = pp + lePtr->nFillPts;
- pp < endp; pp++) {
- points[count].x = Round(pp->x);
- points[count].y = Round(pp->y);
- count++;
- }
- if (ops->fillBg)
- Tk_Fill3DPolygon(graphPtr->tkwin, drawable, ops->fillBg, points,
- lePtr->nFillPts, 0, TK_RELIEF_FLAT);
- free(points);
- }
-
- // Lines: stripchart segments or graph traces
- if (lePtr->lines.length > 0) {
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
- link; link = Blt_Chain_NextLink(link)) {
-
- LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- LinePen* penPtr = (LinePen *)stylePtr->penPtr;
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
- if ((stylePtr->lines.length > 0) &&
- (penOps->errorBarLineWidth > 0)) {
- Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->traceGC_,
- stylePtr->lines.segments, stylePtr->lines.length);
- }
- }
- }
- else {
- LinePen* penPtr = NORMALPEN(ops);
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- if ((Blt_Chain_GetLength(lePtr->traces) > 0) &&
- (penOps->traceWidth > 0)) {
- DrawTraces(graphPtr, drawable, lePtr, penPtr);
- }
- }
-
- if (ops->reqMaxSymbols > 0) {
- int total = 0;
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette);
- link; link = Blt_Chain_NextLink(link)) {
- LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- total += stylePtr->symbolPts.length;
- }
- lePtr->symbolInterval = total / ops->reqMaxSymbols;
- lePtr->symbolCounter = 0;
- }
-
- // Symbols, error bars, values
-
- unsigned int count =0;
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
- LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- LinePen* penPtr = (LinePen *)stylePtr->penPtr;
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X))
- Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC_,
- stylePtr->xeb.segments, stylePtr->xeb.length);
-
- if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y))
- Blt_Draw2DSegments(graphPtr->display, drawable, penPtr->errorBarGC_,
- stylePtr->yeb.segments, stylePtr->yeb.length);
-
- if ((stylePtr->symbolPts.length > 0) &&
- (penOps->symbol.type != SYMBOL_NONE))
- DrawSymbols(graphPtr, drawable, lePtr, penPtr,
- stylePtr->symbolSize, stylePtr->symbolPts.length,
- stylePtr->symbolPts.points);
-
- if (penOps->valueShow != SHOW_NONE)
- DrawValues(graphPtr, drawable, lePtr, penPtr,
- stylePtr->symbolPts.length, stylePtr->symbolPts.points,
- lePtr->symbolPts.map + count);
-
- count += stylePtr->symbolPts.length;
- }
- lePtr->symbolInterval = 0;
-}
-
-static void GetSymbolPostScriptInfo(Graph* graphPtr, Blt_Ps ps,
- LinePen* penPtr, int size)
+void GetSymbolPostScriptInfo(Blt_Ps ps, LinePen* penPtr, int size)
{
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
@@ -2721,24 +2781,24 @@ static void GetSymbolPostScriptInfo(Graph* graphPtr, Blt_Ps ps,
* Compute how much to scale the bitmap. Don't let the scaled
* bitmap exceed the bounding square for the symbol.
*/
- Tk_SizeOfBitmap(graphPtr->display, penOps->symbol.bitmap, &w, &h);
+ Tk_SizeOfBitmap(graphPtr_->display, penOps->symbol.bitmap, &w, &h);
sx = (double)size / (double)w;
sy = (double)size / (double)h;
scale = MIN(sx, sy);
if (penOps->symbol.mask != None) {
Blt_Ps_VarAppend(ps, "\n % Bitmap mask is \"",
- Tk_NameOfBitmap(graphPtr->display, penOps->symbol.mask),
+ Tk_NameOfBitmap(graphPtr_->display, penOps->symbol.mask),
"\"\n\n ", NULL);
Blt_Ps_XSetBackground(ps, fillColor);
- Blt_Ps_DrawBitmap(ps, graphPtr->display, penOps->symbol.mask,
+ Blt_Ps_DrawBitmap(ps, graphPtr_->display, penOps->symbol.mask,
scale, scale);
}
Blt_Ps_VarAppend(ps, "\n % Bitmap symbol is \"",
- Tk_NameOfBitmap(graphPtr->display, penOps->symbol.bitmap),
+ Tk_NameOfBitmap(graphPtr_->display, penOps->symbol.bitmap),
"\"\n\n ", NULL);
Blt_Ps_XSetForeground(ps, outlineColor);
- Blt_Ps_DrawBitmap(ps, graphPtr->display, penOps->symbol.bitmap,
+ Blt_Ps_DrawBitmap(ps, graphPtr_->display, penOps->symbol.bitmap,
scale, scale);
}
break;
@@ -2757,8 +2817,8 @@ static void GetSymbolPostScriptInfo(Graph* graphPtr, Blt_Ps ps,
Blt_Ps_Append(ps, "} def\n\n");
}
-static void SymbolsToPostScript(Graph* graphPtr, Blt_Ps ps, LinePen* penPtr,
- int size, int nSymbolPts, Point2d *symbolPts)
+void LineElement::SymbolsToPostScript(Blt_Ps ps, LinePen* penPtr, int size,
+ int nSymbolPts, Point2d *symbolPts)
{
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
@@ -2767,7 +2827,7 @@ static void SymbolsToPostScript(Graph* graphPtr, Blt_Ps ps, LinePen* penPtr,
{
"Li", "Sq", "Ci", "Di", "Pl", "Cr", "Sp", "Sc", "Tr", "Ar", "Bm", NULL
};
- GetSymbolPostScriptInfo(graphPtr, ps, penPtr, size);
+ GetSymbolPostScriptInfo(graphPtr_, ps, penPtr, size);
symbolSize = (double)size;
switch (penOps->symbol.type) {
@@ -2789,45 +2849,15 @@ static void SymbolsToPostScript(Graph* graphPtr, Blt_Ps ps, LinePen* penPtr,
default:
break;
}
- {
- Point2d *pp, *endp;
-
- for (pp = symbolPts, endp = symbolPts + nSymbolPts; pp < endp; pp++) {
- Blt_Ps_Format(ps, "%g %g %g %s\n", pp->x, pp->y,
- symbolSize, symbolMacros[penOps->symbol.type]);
- }
- }
-}
-
-static void SymbolToPostScriptProc(Graph* graphPtr, Blt_Ps ps,
- Element *elemPtr, double x, double y,
- int size)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- LinePen* penPtr = NORMALPEN(ops);
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- if (penOps->traceWidth > 0) {
- /*
- * Draw an extra line offset by one pixel from the previous to give a
- * thicker appearance. This is only for the legend entry. This routine
- * is never called for drawing the actual line segments.
- */
- Blt_Ps_XSetLineAttributes(ps, penOps->traceColor, penOps->traceWidth,
- &penOps->traceDashes, CapButt, JoinMiter);
- Blt_Ps_Format(ps, "%g %g %d Li\n", x, y, size + size);
- }
- if (penOps->symbol.type != SYMBOL_NONE) {
- Point2d point;
- point.x = x, point.y = y;
- SymbolsToPostScript(graphPtr, ps, penPtr, size, 1, &point);
+ Point2d *pp, *endp;
+ for (pp = symbolPts, endp = symbolPts + nSymbolPts; pp < endp; pp++) {
+ Blt_Ps_Format(ps, "%g %g %g %s\n", pp->x, pp->y,
+ symbolSize, symbolMacros[penOps->symbol.type]);
}
}
-static void SetLineAttributes(Blt_Ps ps, LinePen* penPtr)
+void LineElement::SetLineAttributes(Blt_Ps ps, LinePen* penPtr)
{
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
@@ -2846,12 +2876,10 @@ static void SetLineAttributes(Blt_Ps ps, LinePen* penPtr)
}
}
-static void TracesToPostScript(Blt_Ps ps, LineElement* lePtr, LinePen* penPtr)
+void LineElement::TracesToPostScript(Blt_Ps ps, LinePen* penPtr)
{
- Blt_ChainLink link;
-
SetLineAttributes(ps, penPtr);
- for (link = Blt_Chain_FirstLink(lePtr->traces); link;
+ for (Blt_ChainLink link = Blt_Chain_FirstLink(traces); link;
link = Blt_Chain_NextLink(link)) {
bltTrace *tracePtr = (bltTrace*)Blt_Chain_GetValue(link);
if (tracePtr->screenPts.length > 0) {
@@ -2863,11 +2891,11 @@ static void TracesToPostScript(Blt_Ps ps, LineElement* lePtr, LinePen* penPtr)
}
}
-static void ValuesToPostScript(Blt_Ps ps, LineElement* lePtr, LinePen* penPtr,
- int nSymbolPts, Point2d *symbolPts,
- int *pointToData)
+void LineElement::ValuesToPostScript(Blt_Ps ps, LinePen* penPtr,
+ int nSymbolPts, Point2d *symbolPts,
+ int *pointToData)
{
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
+ LineElementOptions* ops = (LineElementOptions*)ops;
LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
const char* fmt = penOps->valueFormat;
@@ -2897,144 +2925,4 @@ static void ValuesToPostScript(Blt_Ps ps, LineElement* lePtr, LinePen* penPtr,
}
}
-static void ActiveLineToPostScriptProc(Graph* graphPtr, Blt_Ps ps,
- Element *elemPtr)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- LinePen* penPtr = (LinePen *)ops->activePenPtr;
- if (!penPtr)
- return;
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- int symbolSize = ScaleSymbol(lePtr, penOps->symbol.size);
- if (lePtr->nActiveIndices > 0) {
- if (lePtr->flags & ACTIVE_PENDING) {
- MapActiveSymbols(graphPtr, lePtr);
- }
- if (penOps->symbol.type != SYMBOL_NONE) {
- SymbolsToPostScript(graphPtr, ps, penPtr, symbolSize,
- lePtr->activePts.length, lePtr->activePts.points);
- }
- if (penOps->valueShow != SHOW_NONE) {
- ValuesToPostScript(ps, lePtr, penPtr, lePtr->activePts.length,
- lePtr->activePts.points, lePtr->activePts.map);
- }
- }
- else if (lePtr->nActiveIndices < 0) {
- if (penOps->traceWidth > 0) {
- if (lePtr->lines.length > 0) {
- SetLineAttributes(ps, penPtr);
- Blt_Ps_Draw2DSegments(ps, lePtr->lines.segments,
- lePtr->lines.length);
- }
- if (Blt_Chain_GetLength(lePtr->traces) > 0) {
- TracesToPostScript(ps, lePtr, (LinePen *)penPtr);
- }
- }
- if (penOps->symbol.type != SYMBOL_NONE) {
- SymbolsToPostScript(graphPtr, ps, penPtr, symbolSize,
- lePtr->symbolPts.length, lePtr->symbolPts.points);
- }
- if (penOps->valueShow != SHOW_NONE) {
- ValuesToPostScript(ps, lePtr, penPtr, lePtr->symbolPts.length,
- lePtr->symbolPts.points, lePtr->symbolPts.map);
- }
- }
-}
-
-static void NormalLineToPostScriptProc(Graph* graphPtr, Blt_Ps ps,
- Element *elemPtr)
-{
- LineElement* lePtr = (LineElement *)elemPtr;
- LineElementOptions* ops = (LineElementOptions*)lePtr->ops;
-
- // Draw fill area
- if (lePtr->fillPts) {
- // Create a path to use for both the polygon and its outline
- Blt_Ps_Append(ps, "% start fill area\n");
- Blt_Ps_Polyline(ps, lePtr->fillPts, lePtr->nFillPts);
-
- // If the background fill color was specified, draw the polygon in a
- // solid fashion with that color
- if (lePtr->fillBgColor) {
- Blt_Ps_XSetBackground(ps, lePtr->fillBgColor);
- Blt_Ps_Append(ps, "gsave fill grestore\n");
- }
- Blt_Ps_XSetForeground(ps, ops->fillFgColor);
- if (ops->fillBg)
- Blt_Ps_Append(ps, "gsave fill grestore\n");
- else
- Blt_Ps_Append(ps, "gsave fill grestore\n");
-
- Blt_Ps_Append(ps, "% end fill area\n");
- }
-
- // Draw lines (strip chart) or traces (xy graph)
- if (lePtr->lines.length > 0) {
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
- LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- LinePen* penPtr = (LinePen *)stylePtr->penPtr;
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- if ((stylePtr->lines.length > 0) && (penOps->traceWidth > 0)) {
- SetLineAttributes(ps, penPtr);
- Blt_Ps_Append(ps, "% start segments\n");
- Blt_Ps_Draw2DSegments(ps, stylePtr->lines.segments,
- stylePtr->lines.length);
- Blt_Ps_Append(ps, "% end segments\n");
- }
- }
- }
- else {
- LinePen* penPtr = NORMALPEN(ops);
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
-
- if ((Blt_Chain_GetLength(lePtr->traces) > 0) &&
- (penOps->traceWidth > 0)) {
- TracesToPostScript(ps, lePtr, penPtr);
- }
- }
-
- // Draw symbols, error bars, values
-
- unsigned int count =0;
- for (Blt_ChainLink link = Blt_Chain_FirstLink(ops->stylePalette); link;
- link = Blt_Chain_NextLink(link)) {
-
- LineStyle *stylePtr = (LineStyle*)Blt_Chain_GetValue(link);
- LinePen* penPtr = (LinePen *)stylePtr->penPtr;
- LinePenOptions* penOps = (LinePenOptions*)penPtr->ops();
- XColor* colorPtr = penOps->errorBarColor;
- if (!colorPtr)
- colorPtr = penOps->traceColor;
-
- if ((stylePtr->xeb.length > 0) && (penOps->errorBarShow & SHOW_X)) {
- Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
- NULL, CapButt, JoinMiter);
- Blt_Ps_Draw2DSegments(ps, stylePtr->xeb.segments,
- stylePtr->xeb.length);
- }
- if ((stylePtr->yeb.length > 0) && (penOps->errorBarShow & SHOW_Y)) {
- Blt_Ps_XSetLineAttributes(ps, colorPtr, penOps->errorBarLineWidth,
- NULL, CapButt, JoinMiter);
- Blt_Ps_Draw2DSegments(ps, stylePtr->yeb.segments,
- stylePtr->yeb.length);
- }
- if ((stylePtr->symbolPts.length > 0) &&
- (penOps->symbol.type != SYMBOL_NONE)) {
- SymbolsToPostScript(graphPtr, ps, penPtr, stylePtr->symbolSize,
- stylePtr->symbolPts.length,
- stylePtr->symbolPts.points);
- }
- if (penOps->valueShow != SHOW_NONE) {
- ValuesToPostScript(ps, lePtr, penPtr, stylePtr->symbolPts.length,
- stylePtr->symbolPts.points,
- lePtr->symbolPts.map + count);
- }
- count += stylePtr->symbolPts.length;
- }
-}
diff --git a/src/bltGrElemLine.h b/src/bltGrElemLine.h
index 56aa92d..2238006 100644
--- a/src/bltGrElemLine.h
+++ b/src/bltGrElemLine.h
@@ -34,6 +34,17 @@
#include "bltGrPenLine.h"
typedef enum {
+ PEN_INCREASING, PEN_DECREASING, PEN_BOTH_DIRECTIONS
+} PenDirection;
+
+typedef struct {
+ Point2d *screenPts;
+ int nScreenPts;
+ int *styleMap;
+ int *map;
+} MapInfo;
+
+typedef enum {
PEN_SMOOTH_LINEAR, PEN_SMOOTH_STEP, PEN_SMOOTH_NATURAL,
PEN_SMOOTH_QUADRATIC, PEN_SMOOTH_CATROM
} Smoothing;
@@ -45,6 +56,22 @@ typedef struct {
} GraphPoints;
typedef struct {
+ int start;
+ GraphPoints screenPts;
+} bltTrace;
+
+typedef struct {
+ Weight weight;
+ LinePen* penPtr;
+ GraphPoints symbolPts;
+ GraphSegments lines;
+ GraphSegments xeb;
+ GraphSegments yeb;
+ int symbolSize;
+ int errorBarCapWidth;
+} LineStyle;
+
+typedef struct {
Element* elemPtr;
const char* label;
char** tags;
@@ -75,38 +102,70 @@ typedef struct {
int penDir;
} LineElementOptions;
-typedef struct {
- GraphObj obj;
- unsigned int flags;
- int hide;
- Tcl_HashEntry *hashPtr;
- void* ops;
-
- unsigned short row;
- unsigned short col;
- int *activeIndices;
- int nActiveIndices;
- ElementProcs *procsPtr;
- Tk_OptionTable optionTable;
- double xRange;
- double yRange;
- Blt_ChainLink link;
-
- // Fields specific to Line Element
- LinePen builtinPen;
- Smoothing smooth;
- XColor* fillBgColor;
- GC fillGC;
- Point2d *fillPts;
- int nFillPts;
- GraphPoints symbolPts;
- GraphPoints activePts;
- GraphSegments xeb;
- GraphSegments yeb;
- int symbolInterval;
- int symbolCounter;
- Blt_Chain traces;
- GraphSegments lines;
-} LineElement;
+class LineElement : public Element {
+ public:
+ LinePen* builtinPenPtr;
+ Smoothing smooth_;
+ XColor* fillBgColor_;
+ GC fillGC_;
+ Point2d *fillPts_;
+ int nFillPts_;
+ GraphPoints symbolPts_;
+ GraphPoints activePts_;
+ GraphSegments xeb_;
+ GraphSegments yeb_;
+ GraphSegments lines_;
+ int symbolInterval_;
+ int symbolCounter_;
+ Blt_Chain traces_;
+
+ protected:
+ int ScaleSymbol(int);
+ void GetScreenPoints(MapInfo*);
+ void ReducePoints(MapInfo*, double);
+ void GenerateSteps(MapInfo*);
+ void GenerateSpline(MapInfo*);
+ void GenerateParametricSpline(MapInfo*);
+ void MapSymbols(MapInfo*);
+ void MapActiveSymbols();
+ void MergePens(LineStyle**);
+ int OutCode(Region2d*, Point2d*);
+ int ClipSegment(Region2d*, int, int, Point2d*, Point2d*);
+ void SaveTrace(int, int, MapInfo*);
+ void FreeTraces();
+ void MapTraces(MapInfo*);
+ void MapFillArea(MapInfo*);
+ void ResetLine();
+ void MapErrorBars(LineStyle**);
+ int ClosestTrace();
+ void ClosestPoint(ClosestSearch*);
+ void DrawCircles(Display*, Drawable, LinePen*, int, Point2d*, int);
+ void DrawSquares(Display*, Drawable, LinePen*, int, Point2d*, int);
+ void DrawSymbols(Drawable, LinePen*, int, int, Point2d*);
+ void DrawTraces(Drawable, LinePen*);
+ void DrawValues(Drawable, LinePen*, int, Point2d*, int*);
+ void SetLineAttributes(Blt_Ps, LinePen*);
+ void TracesToPostScript(Blt_Ps, LinePen*);
+ void ValuesToPostScript(Blt_Ps, LinePen*, int, Point2d*, int*);
+ double DistanceToLine(int, int, Point2d*, Point2d*, Point2d*);
+ double DistanceToX(int, int, Point2d*, Point2d*, Point2d*);
+ double DistanceToY(int, int, Point2d*, Point2d*, Point2d*);
+ void SymbolsToPostScript(Blt_Ps, Pen*, int, int, Point2d*);
+
+ public:
+ LineElement(Graph*, const char*, Tcl_HashEntry*);
+ virtual ~LineElement();
+
+ int configure();
+ void map();
+ void extents(Region2d*);
+ void closest();
+ void drawActive(Drawable);
+ void drawNormal(Drawable);
+ void drawSymbol(Drawable, int, int, int);
+ void printActive(Blt_Ps);
+ void printNormal(Blt_Ps);
+ void printSymbol(Blt_Ps, double, double, int);
+};
#endif
diff --git a/src/bltGrElemOp.C b/src/bltGrElemOp.C
index 23a6a22..4258825 100644
--- a/src/bltGrElemOp.C
+++ b/src/bltGrElemOp.C
@@ -33,12 +33,12 @@ extern "C" {
};
#include "bltGrElem.h"
+#include "bltGrElemBar.h"
+#include "bltGrElemLine.h"
#include "bltGrElemOp.h"
// Defs
-extern Element *Blt_LineElement(Graph* graphPtr);
-extern Element *Blt_BarElement(Graph* graphPtr);
extern int Blt_GetPenFromObj(Tcl_Interp* interp, Graph* graphPtr,
Tcl_Obj *objPtr, ClassId classId, Pen **penPtrPtr);
@@ -78,10 +78,10 @@ static int CreateElement(Graph* graphPtr, Tcl_Interp* interp, int objc,
Element* elemPtr;
switch (classId) {
case CID_ELEM_BAR:
- elemPtr = Blt_BarElement(graphPtr);
+ elemPtr = new BarElement(graphPtr,name,hPtr);
break;
case CID_ELEM_LINE:
- elemPtr = Blt_LineElement(graphPtr);
+ elemPtr = new LineElement(graphPtr,name,hPtr);
break;
default:
return TCL_ERROR;
@@ -89,22 +89,9 @@ static int CreateElement(Graph* graphPtr, Tcl_Interp* interp, int objc,
if (!elemPtr)
return TCL_ERROR;
- ElementOptions* ops = (ElementOptions*)elemPtr->ops;
- elemPtr->obj.graphPtr = graphPtr;
- elemPtr->obj.name = Blt_Strdup(name);
-
- // this is an option and will be freed via Tk_FreeConfigOptions
- // By default an element's name and label are the same
- ops->label = Tcl_Alloc(strlen(name)+1);
- if (name)
- strcpy((char*)ops->label,(char*)name);
- Blt_GraphSetObjectClass(&elemPtr->obj, classId);
- ops->stylePalette = Blt_Chain_Create();
-
- elemPtr->hashPtr = hPtr;
Tcl_SetHashValue(hPtr, elemPtr);
- if ((Tk_InitOptions(graphPtr->interp, (char*)elemPtr->ops, elemPtr->optionTable, graphPtr->tkwin) != TCL_OK) || (ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4) != TCL_OK)) {
+ if ((Tk_InitOptions(graphPtr->interp, (char*)elemPtr->ops(), elemPtr->optionTable(), graphPtr->tkwin) != TCL_OK) || (ElementObjConfigure(interp, graphPtr, elemPtr, objc-4, objv+4) != TCL_OK)) {
DestroyElement(elemPtr);
return TCL_ERROR;
}
@@ -124,21 +111,7 @@ static void DestroyElement(Element* elemPtr)
if (elemPtr->link)
Blt_Chain_DeleteLink(graphPtr->elements.displayList, elemPtr->link);
- if (elemPtr->hashPtr)
- Tcl_DeleteHashEntry(elemPtr->hashPtr);
-
- if (elemPtr->obj.name)
- free((void*)(elemPtr->obj.name));
-
- Tk_FreeConfigOptions((char*)elemPtr->ops, elemPtr->optionTable,
- graphPtr->tkwin);
-
- (*elemPtr->procsPtr->destroyProc) (graphPtr, elemPtr);
-
- if (elemPtr->ops)
- free(elemPtr->ops);
-
- free(elemPtr);
+ delete elemPtr;
}
// Configure
@@ -156,7 +129,7 @@ static int CgetOp(Graph* graphPtr, Tcl_Interp* interp,
return TCL_ERROR;
Tcl_Obj* objPtr = Tk_GetOptionValue(interp, (char*)elemPtr,
- elemPtr->optionTable,
+ elemPtr->optionTable(),
objv[4], graphPtr->tkwin);
if (objPtr == NULL)
return TCL_ERROR;
@@ -174,7 +147,7 @@ static int ConfigureOp(Graph* graphPtr, Tcl_Interp* interp,
if (objc <= 5) {
Tcl_Obj* objPtr = Tk_GetOptionInfo(graphPtr->interp, (char*)elemPtr,
- elemPtr->optionTable,
+ elemPtr->optionTable(),
(objc == 5) ? objv[4] : NULL,
graphPtr->tkwin);
if (objPtr == NULL)
@@ -198,7 +171,7 @@ static int ElementObjConfigure(Tcl_Interp* interp, Graph* graphPtr,
for (error=0; error<=1; error++) {
if (!error) {
- if (Tk_SetOptions(interp, (char*)elemPtr->ops, elemPtr->optionTable,
+ if (Tk_SetOptions(interp, (char*)elemPtr->ops(), elemPtr->optionTable(),
objc, objv, graphPtr->tkwin, &savedOptions, &mask)
!= TCL_OK)
continue;
@@ -212,7 +185,7 @@ static int ElementObjConfigure(Tcl_Interp* interp, Graph* graphPtr,
elemPtr->flags |= mask;
elemPtr->flags |= MAP_ITEM;
graphPtr->flags |= RESET_WORLD | CACHE_DIRTY;
- if ((*elemPtr->procsPtr->configProc)(graphPtr, elemPtr) != TCL_OK)
+ if (elemPtr->configure() != TCL_OK)
return TCL_ERROR;
Blt_EventuallyRedrawGraph(graphPtr);
@@ -269,10 +242,10 @@ static int ActivateOp(Graph* graphPtr, Tcl_Interp* interp,
}
}
- if (elemPtr->activeIndices)
- free(elemPtr->activeIndices);
- elemPtr->nActiveIndices = nIndices;
- elemPtr->activeIndices = indices;
+ if (elemPtr->activeIndices_)
+ free(elemPtr->activeIndices_);
+ elemPtr->nActiveIndices_ = nIndices;
+ elemPtr->activeIndices_ = indices;
elemPtr->flags |= ACTIVE | ACTIVE_PENDING;
Blt_EventuallyRedrawGraph(graphPtr);
@@ -329,9 +302,9 @@ static int ClosestOp(Graph* graphPtr, Tcl_Interp* interp,
if (Blt_GetElement(interp, graphPtr, objv[ii], &elemPtr) != TCL_OK)
return TCL_ERROR;
- if (elemPtr && !elemPtr->hide &&
+ if (elemPtr && !elemPtr->hide_ &&
!(elemPtr->flags & (MAP_ITEM|DELETE_PENDING)))
- (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr);
+ elemPtr->closest();
}
}
else {
@@ -343,9 +316,9 @@ static int ClosestOp(Graph* graphPtr, Tcl_Interp* interp,
for (Blt_ChainLink link=Blt_Chain_LastLink(graphPtr->elements.displayList);
link != NULL; link = Blt_Chain_PrevLink(link)) {
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- if (elemPtr && !elemPtr->hide &&
+ if (elemPtr && !elemPtr->hide_ &&
!(elemPtr->flags & (MAP_ITEM|DELETE_PENDING)))
- (*elemPtr->procsPtr->closestProc) (graphPtr, elemPtr);
+ elemPtr->closest();
}
}
@@ -385,11 +358,11 @@ static int DeactivateOp(Graph* graphPtr, Tcl_Interp* interp,
if (Blt_GetElement(interp, graphPtr, objv[ii], &elemPtr) != TCL_OK)
return TCL_ERROR;
- if (elemPtr->activeIndices) {
- free(elemPtr->activeIndices);
- elemPtr->activeIndices = NULL;
+ if (elemPtr->activeIndices_) {
+ free(elemPtr->activeIndices_);
+ elemPtr->activeIndices_ = NULL;
}
- elemPtr->nActiveIndices = 0;
+ elemPtr->nActiveIndices_ = 0;
elemPtr->flags &= ~(ACTIVE | ACTIVE_PENDING);
}
@@ -656,7 +629,7 @@ static void FreeElement(char* data)
static int GetIndex(Tcl_Interp* interp, Element* elemPtr,
Tcl_Obj *objPtr, int *indexPtr)
{
- ElementOptions* ops = (ElementOptions*)elemPtr->ops;
+ ElementOptions* ops = (ElementOptions*)elemPtr->ops();
char *string = Tcl_GetString(objPtr);
if ((*string == 'e') && (strcmp("end", string) == 0))
@@ -711,7 +684,7 @@ void Blt_ConfigureElements(Graph* graphPtr)
for (Blt_ChainLink link =Blt_Chain_FirstLink(graphPtr->elements.displayList);
link != NULL; link = Blt_Chain_NextLink(link)) {
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- (*elemPtr->procsPtr->configProc) (graphPtr, elemPtr);
+ elemPtr->configure();
}
}
@@ -727,7 +700,7 @@ void Blt_MapElements(Graph* graphPtr)
continue;
if ((graphPtr->flags & MAP_ALL) || (elemPtr->flags & MAP_ITEM)) {
- (*elemPtr->procsPtr->mapProc) (graphPtr, elemPtr);
+ elemPtr->map();
elemPtr->flags &= ~MAP_ITEM;
}
}
@@ -741,9 +714,8 @@ void Blt_DrawElements(Graph* graphPtr, Drawable drawable)
for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
link != NULL; link = Blt_Chain_PrevLink(link)) {
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) {
- (*elemPtr->procsPtr->drawNormalProc)(graphPtr, drawable, elemPtr);
- }
+ if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide_)
+ elemPtr->drawNormal(drawable);
}
}
@@ -754,11 +726,9 @@ void Blt_DrawActiveElements(Graph* graphPtr, Drawable drawable)
for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
link != NULL; link = Blt_Chain_PrevLink(link)) {
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- if (!(elemPtr->flags & DELETE_PENDING) &&
- (elemPtr->flags & ACTIVE) &&
- !elemPtr->hide) {
- (*elemPtr->procsPtr->drawActiveProc)(graphPtr, drawable, elemPtr);
- }
+ if (!(elemPtr->flags & DELETE_PENDING) && (elemPtr->flags & ACTIVE) &&
+ !elemPtr->hide_)
+ elemPtr->drawActive(drawable);
}
}
@@ -769,12 +739,12 @@ void Blt_ElementsToPostScript(Graph* graphPtr, Blt_Ps ps)
for (link = Blt_Chain_LastLink(graphPtr->elements.displayList);
link != NULL; link = Blt_Chain_PrevLink(link)) {
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
- if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide) {
+ if (!(elemPtr->flags & DELETE_PENDING) && !elemPtr->hide_) {
continue;
}
/* Comment the PostScript to indicate the start of the element */
Blt_Ps_Format(ps, "\n%% Element \"%s\"\n\n", elemPtr->obj.name);
- (*elemPtr->procsPtr->printNormalProc) (graphPtr, ps, elemPtr);
+ elemPtr->printNormal(ps);
}
}
@@ -787,10 +757,10 @@ void Blt_ActiveElementsToPostScript(Graph* graphPtr, Blt_Ps ps)
Element* elemPtr = (Element*)Blt_Chain_GetValue(link);
if (!(elemPtr->flags & DELETE_PENDING) &&
(elemPtr->flags & ACTIVE) &&
- !elemPtr->hide) {
+ !elemPtr->hide_) {
Blt_Ps_Format(ps, "\n%% Active Element \"%s\"\n\n",
elemPtr->obj.name);
- (*elemPtr->procsPtr->printActiveProc)(graphPtr, ps, elemPtr);
+ elemPtr->printActive(ps);
}
}
}
diff --git a/src/bltGrPen.C b/src/bltGrPen.C
index c44a496..909cbc1 100644
--- a/src/bltGrPen.C
+++ b/src/bltGrPen.C
@@ -29,19 +29,6 @@
#include "bltGrPen.h"
-Pen::Pen()
-{
- graphPtr_ =NULL;
- classId_ = CID_NONE;
- name_ =NULL;
- optionTable_ =NULL;
- ops_ =NULL;
- manageOptions_ =0;
- flags =0;
- refCount =0;
- hashPtr_ =NULL;
-}
-
Pen::Pen(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
{
graphPtr_ = graphPtr;
diff --git a/src/bltGrPenBar.C b/src/bltGrPenBar.C
index 860d8cf..427bed8 100644
--- a/src/bltGrPenBar.C
+++ b/src/bltGrPenBar.C
@@ -74,7 +74,6 @@ static Tk_OptionSpec barPenOptionSpecs[] = {
BarPen::BarPen() : Pen()
{
- classId_ = CID_ELEM_BAR;
fillGC_ =NULL;
outlineGC_ =NULL;
@@ -86,7 +85,7 @@ BarPen::BarPen(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
{
classId_ = CID_ELEM_BAR;
optionTable_ = Tk_CreateOptionTable(graphPtr_->interp, barPenOptionSpecs);
- ops_ = (BarPenOptions*)calloc(1, sizeof(BarPenOptions));
+ ops_ = calloc(1, sizeof(BarPenOptions));
manageOptions_ =1;
fillGC_ =NULL;
@@ -97,14 +96,19 @@ BarPen::BarPen(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
Blt_Ts_InitStyle(ops->valueStyle);
}
-void BarPen::init(Graph* graphPtr, const char* penName, BarPenOptions* ops)
+BarPen::BarPen(Graph* graphPtr, const char* name, void* ops)
+ : Pen(graphPtr, name, NULL)
{
- graphPtr_ = graphPtr;
- name_ = dupstr(penName);
+ classId_ = CID_ELEM_BAR;
optionTable_ = Tk_CreateOptionTable(graphPtr_->interp, barPenOptionSpecs);
ops_ = ops;
manageOptions_ =0;
+ fillGC_ =NULL;
+ outlineGC_ =NULL;
+ errorBarGC_ =NULL;
+
+ BarPenOptions* ops = (BarPenOptions*)ops_;
Blt_Ts_InitStyle(ops->valueStyle);
}
diff --git a/src/bltGrPenBar.h b/src/bltGrPenBar.h
index 2e11fe2..5e20142 100644
--- a/src/bltGrPenBar.h
+++ b/src/bltGrPenBar.h
@@ -60,11 +60,10 @@ class BarPen : public Pen {
GC errorBarGC_;
public:
- BarPen();
BarPen(Graph*, const char*, Tcl_HashEntry*);
+ BarPen(Graph*, const char*, void*);
virtual ~BarPen();
- void init(Graph*, const char*, BarPenOptions*);
int configure();
};
diff --git a/src/bltGrPenLine.C b/src/bltGrPenLine.C
index 9983ac0..2f5689c 100644
--- a/src/bltGrPenLine.C
+++ b/src/bltGrPenLine.C
@@ -226,7 +226,7 @@ LinePen::LinePen(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
{
classId_ = CID_ELEM_LINE;
optionTable_ = Tk_CreateOptionTable(graphPtr_->interp, linePenOptionSpecs);
- ops_ = (LinePenOptions*)calloc(1, sizeof(LinePenOptions));
+ ops_ = calloc(1, sizeof(LinePenOptions));
manageOptions_ =1;
traceGC_ =NULL;
@@ -239,14 +239,18 @@ LinePen::LinePen(Graph* graphPtr, const char* name, Tcl_HashEntry* hPtr)
ops->symbol.type = SYMBOL_NONE;
}
-void LinePen::init(Graph* graphPtr, const char* penName, LinePenOptions* ops)
+LinePen::LinePen(Graph* graphPtr, const char* penName, void* ops)
+ : Pen(graphPtr, name, NULL);
{
- graphPtr_ = graphPtr;
- name_ = dupstr(penName);
+ classId_ = CID_ELEM_LINE;
optionTable_ = Tk_CreateOptionTable(graphPtr_->interp, linePenOptionSpecs);
ops_ = ops;
manageOptions_ =0;
+ traceGC_ =NULL;
+ errorBarGC_ =NULL;
+
+ LinePenOptions* ops = (LinePenOptions*)ops_;
Blt_Ts_InitStyle(ops->valueStyle);
ops->symbol.bitmap = None;
ops->symbol.mask = None;
diff --git a/src/bltGrPenLine.h b/src/bltGrPenLine.h
index ff80664..1dbf2a5 100644
--- a/src/bltGrPenLine.h
+++ b/src/bltGrPenLine.h
@@ -79,11 +79,10 @@ class LinePen : public Pen {
GC errorBarGC_;
public:
- LinePen();
LinePen(Graph*, const char*, Tcl_HashEntry*);
+ LinePen(Graph*, const char*, void*);
virtual ~LinePen();
- void init(Graph*, const char*, LinePenOptions*);
int configure();
};
diff --git a/src/bltGraph.h b/src/bltGraph.h
index 4951a89..c19a8d3 100644
--- a/src/bltGraph.h
+++ b/src/bltGraph.h
@@ -49,7 +49,7 @@
typedef struct _Graph Graph;
typedef struct _Legend Legend;
typedef struct _Crosshairs Crosshairs;
-typedef struct _Element Element;
+class Element;
typedef enum {
CID_NONE, CID_AXIS_X, CID_AXIS_Y, CID_ELEM_BAR, CID_ELEM_LINE,
@@ -388,11 +388,6 @@ struct _Graph {
extern int Blt_PointInPolygon(Point2d *samplePtr, Point2d *screenPts,
int nScreenPts);
-// Elements
-extern void Blt_DestroyBarSets(Graph* graphPtr);
-extern void Blt_ResetBarGroups(Graph* graphPtr);
-extern void Blt_InitBarSetTable(Graph* graphPtr);
-
// Axis
extern int Blt_AxisOp(Graph* graphPtr, Tcl_Interp* interp,
int objc, Tcl_Obj* const objv[]);
@@ -449,7 +444,6 @@ extern Point2d Blt_Map2D(Graph* graphPtr, double x, double y,
extern Graph *Blt_GetGraphFromWindowData(Tk_Window tkwin);
extern int Blt_PolyRectClip(Region2d *extsPtr, Point2d *inputPts,
int nInputPts, Point2d *outputPts);
-extern void Blt_ComputeBarStacks(Graph* graphPtr);
extern void Blt_ReconfigureGraph(Graph* graphPtr);
extern void Blt_DrawGraph(Graph* graphPtr, Drawable drawable);
extern void Blt_Draw2DSegments(Display *display, Drawable drawable, GC gc,