/*
* Grace - GRaphing, Advanced Computation and Exploration of data
*
* Home page: http://plasma-gate.weizmann.ac.il/Grace/
*
* Copyright (c) 1991-1995 Paul J Turner, Portland, OR
* Copyright (c) 1996-2007 Grace Development Team
*
* Maintained by Evgeny Stambulchik
*
*
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Draw axis bars, axis labels, ticks and tick labels
*/
#include <config.h>
#include <cmath.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "globals.h"
#include "utils.h"
#include "graphs.h"
#include "graphutils.h"
#include "draw.h"
#include "parser.h"
#include "protos.h"
int is_xaxis(int axis)
{
return ((axis % 2 == 0));
}
int is_yaxis(int axis)
{
return ((axis % 2 == 1));
}
int is_log_axis(int gno, int axis)
{
if ((is_xaxis(axis) && islogx(gno)) ||
(is_yaxis(axis) && islogy(gno))) {
return TRUE;
} else {
return FALSE;
}
}
int is_logit_axis(int gno, int axis)
{
if ((is_xaxis(axis) && islogitx(gno)) ||
(is_yaxis(axis) && islogity(gno))) {
return TRUE;
} else {
return FALSE;
}
}
void drawgrid(int gno)
{
int caxis;
tickmarks *t;
tickprops tprops;
int ttype;
world w;
view v;
double wtpos;
WPoint wp_grid_start = {0.0, 0.0}, wp_grid_stop = {0.0, 0.0};
VPoint vp_grid_start, vp_grid_stop;
VPoint vpc, vp1, vp2;
double phi_start, phi_stop, rho;
double wc_start, wc_stop; /* world coordinates */
int ittype_loop, itick;
setclipping(TRUE);
/* TODO: add Pen to ticks and remove the following */
setpattern(1);
get_graph_viewport(gno, &v);
get_graph_world(gno, &w);
/* graph center; for polar plots */
vpc.x = (v.xv1 + v.xv2)/2.0;
vpc.y = (v.yv1 + v.yv2)/2.0;
for (caxis = 0; caxis < MAXAXES; caxis++) {
t = get_graph_tickmarks(gno, caxis);
if (!t || t->active != TRUE) {
continue;
}
if (is_xaxis(caxis)) { /* an X-axis */
wc_start = w.xg1;
wc_stop = w.xg2;
wp_grid_start.y = w.yg1;
wp_grid_stop.y = w.yg2;
} else { /* a Y-axis */
wc_start = w.yg1;
wc_stop = w.yg2;
wp_grid_start.x = w.xg1;
wp_grid_stop.x = w.xg2;
}
for (ittype_loop = 0; ittype_loop < 2; ittype_loop++) {
if (ittype_loop == 0) { /* minor ticks */
ttype = TICK_TYPE_MINOR;
tprops = t->mprops;
} else { /* major ticks */
ttype = TICK_TYPE_MAJOR;
tprops = t->props;
}
if (tprops.gridflag == 0) {
continue;
}
setcolor(tprops.color);
setlinewidth(tprops.linew);
setlinestyle(tprops.lines);
for (itick = 0; itick < t->nticks; itick++) {
if (t->tloc[itick].type != ttype) {
continue;
}
wtpos = t->tloc[itick].wtpos;
if ((wtpos < wc_start) || (wtpos > wc_stop)) {
continue;
}
if (is_xaxis(caxis)) { /* an X-axis */
wp_grid_start.x = wtpos;
wp_grid_stop.x = wtpos;
} else { /* a Y-axis */
wp_grid_start.y = wtpos;
wp_grid_stop.y = wtpos;
}
vp_grid_start = Wpoint2Vpoint(wp_grid_start);
vp_grid_stop = Wpoint2Vpoint(wp_grid_stop);
if (!is_xaxis(caxis) && get_graph_type(gno) == GRAPH_POLAR) {
xy2polar(vp_grid_start.x - vpc.x, vp_grid_start.y - vpc.y,
&phi_start, &rho);
xy2polar(vp_grid_stop.x - vpc.x, vp_grid_stop.y - vpc.y,
&phi_stop, &rho);
vp1.x = vpc.x - rho;
vp1.y = vpc.y + rho;
vp2.x = vpc.x + rho;
vp2.y = vpc.y - rho;
if (is_graph_xinvert(gno) == TRUE) {
fswap(&phi_start, &phi_stop);
}
if (phi_stop < phi_start) {
phi_stop += 2*M_PI;
}
DrawArc(vp1, vp2, (int) rint(180.0/M_PI*phi_start),
(int) rint(180.0/M_PI*phi_stop));
} else {
DrawLine(vp_grid_start, vp_grid_stop);
}
}
}
}
}
void drawaxes(int gno)
{
int caxis;
tickmarks *t;
tickprops tprops;
world w;
view v, bb;
double vbase1, vbase2, vbase1_start, vbase1_stop, vbase2_start, vbase2_stop;
double vbase_tlabel, vbase_tlabel1, vbase_tlabel2;
double tsize, tlsize, wtpos, vtpos;
double tl_offset, tl_trans;
WPoint wp1_start, wp1_stop, wp2_start, wp2_stop;
VPoint vp1_start, vp1_stop, vp2_start, vp2_stop;
VPoint vp_tick1_start, vp_tick1_stop, vp_tick2_start, vp_tick2_stop;
VPoint vp_tlabel, vp_label, vp_label_offset1, vp_label_offset2;
VPoint vpc, vp1, vp2;
double phi_start, phi_stop, rho;
VVector ort_para, ort_perp;
double wc_start, wc_stop, wc_start_labels, wc_stop_labels; /* world
coordinates */
int ittype_loop, itick, itcur;
int ttype;
char tlabel[MAX_STRING_LENGTH];
int tlabel1_just, tlabel2_just, label1_just, label2_just;
int langle;
int tick_dir_sign;
double (*coord_conv) ();
setclipping(FALSE);
/* TODO: add Pen to ticks and remove the following */
setpattern(1);
get_graph_viewport(gno, &v);
get_graph_world(gno, &w);
/* graph center; for polar plots */
vpc.x = (v.xv1 + v.xv2)/2.0;
vpc.y = (v.yv1 + v.yv2)/2.0;
for (caxis = 0; caxis < MAXAXES; caxis++) {
t = get_graph_tickmarks(gno, caxis);
if (!t || t->active != TRUE) {
continue;
}
if (t->zero == FALSE) {
tick_dir_sign = +1;
} else {
tick_dir_sign = -1;
}
if (is_xaxis(caxis)) { /* an X-axis */
ort_para.x = 1.0;
ort_para.y = 0.0;
ort_perp.x = 0.0;
ort_perp.y = 1.0;
coord_conv = xy_xconv;
wc_start = w.xg1;
wc_stop = w.xg2;
wp1_start.x = w.xg1;
wp1_stop.x = w.xg2;
wp2_start.x = w.xg1;
wp2_stop.x = w.xg2;
if (t->zero == TRUE) {
if (w.yg1 <= 0.0 && w.yg2 >= 0.0) {
wp1_start.y = 0.0;
wp1_stop.y = 0.0;
wp2_start.y = 0.0;
wp2_stop.y = 0.0;
} else {
continue;
}
} else {
wp1_start.y = w.yg1;
wp1_stop.y = w.yg1;
wp2_start.y = w.yg2;
wp2_stop.y = w.yg2;
}
vp1_start = Wpoint2Vpoint(wp1_start);
vp1_stop = Wpoint2Vpoint(wp1_stop);
vp2_start = Wpoint2Vpoint(wp2_start);
vp2_stop = Wpoint2Vpoint(wp2_stop);
if (is_graph_yinvert(gno) == TRUE) {
vpswap(&vp1_start, &vp2_start);
vpswap(&vp1_stop, &vp2_stop);
}
/* TODO axis offset for polar plots */
if (get_graph_type(gno) != GRAPH_POLAR) {
vp1_start.y -= t->offsx;
vp1_stop.y -= t->offsx;
vp2_start.y += t->offsy;
vp2_stop.y += t->offsy;
}
vbase1 = vp1_start.y;
vbase2 = vp2_start.y;
tlabel1_just = JUST_CENTER|JUST_TOP;
tlabel2_just = JUST_CENTER|JUST_BOTTOM;
switch (t->label_layout) {
case LAYOUT_PARALLEL:
langle = 0;
break;
case LAYOUT_PERPENDICULAR:
langle = 90;
break;
default:
errmsg("Internal error in drawaxes()");
return;
}
} else { /* a Y-axis */
ort_para.x = 0.0;
ort_para.y = 1.0;
ort_perp.x = 1.0;
ort_perp.y = 0.0;
coord_conv = xy_yconv;
wc_start = w.yg1;
wc_stop = w.yg2;
wp1_start.y = w.yg1;
wp1_stop.y = w.yg2;
wp2_start.y = w.yg1;
wp2_stop.y = w.yg2;
if (t->zero == TRUE) {
if (w.xg1 <= 0.0 && w.xg2 >= 0.0) {
wp1_start.x = 0.0;
wp1_stop.x = 0.0;
wp2_start.x = 0.0;
wp2_stop.x = 0.0;
} else {
continue;
}
} else {
wp1_start.x = w.xg1;
wp1_stop.x = w.xg1;
wp2_start.x = w.xg2;
wp2_stop.x = w.xg2;
}
vp1_start = Wpoint2Vpoint(wp1_start);
vp1_stop = Wpoint2Vpoint(wp1_stop);
vp2_start = Wpoint2Vpoint(wp2_start);
vp2_stop = Wpoint2Vpoint(wp2_stop);
if (is_graph_xinvert(gno) == TRUE) {
vpswap(&vp1_start, &vp2_start);
vpswap(&vp1_stop, &vp2_stop);
}
if (get_graph_type(gno) != GRAPH_POLAR) {
vp1_start.x -= t->offsx;
vp1_stop.x -= t->offsx;
vp2_start.x += t->offsy;
vp2_stop.x += t->offsy;
}
vbase1 = vp1_start.x;
vbase2 = vp2_start.x;
tlabel1_just = JUST_RIGHT|JUST_MIDDLE;
tlabel2_just = JUST_LEFT|JUST_MIDDLE;
switch (t->label_layout) {
case LAYOUT_PARALLEL:
langle = 90;
break;
case LAYOUT_PERPENDICULAR:
langle = 0;
break;
default:
errmsg("Internal error in drawaxes()");
return;
}
}
/* Begin axis bar stuff */
if (t->t_drawbar) {
setcolor(t->t_drawbarcolor);
setlinewidth(t->t_drawbarlinew);
setlinestyle(t->t_drawbarlines);
if (t->t_op == PLACEMENT_NORMAL || t->t_op == PLACEMENT_BOTH) {
if (is_xaxis(caxis) && get_graph_type(gno) == GRAPH_POLAR) {
xy2polar(vp1_start.x - vpc.x, vp1_start.y - vpc.y,
&phi_start, &rho);
xy2polar(vp1_stop.x - vpc.x, vp1_stop.y - vpc.y,
&phi_stop, &rho);
vp1.x = vpc.x - rho;
vp1.y = vpc.y + rho;
vp2.x = vpc.x + rho;
vp2.y = vpc.y - rho;
if (is_graph_xinvert(gno) == TRUE) {
fswap(&phi_start, &phi_stop);
}
if (phi_stop < phi_start) {
phi_stop += 2*M_PI;
}
DrawArc(vp1, vp2, (int) rint(180.0/M_PI*phi_start),
(int) rint(180.0/M_PI*phi_stop));
} else {
DrawLine(vp1_start, vp1_stop);
}
}
if (t->t_op == PLACEMENT_OPPOSITE || t->t_op == PLACEMENT_BOTH) {
if (is_xaxis(caxis) && get_graph_type(gno) == GRAPH_POLAR) {
xy2polar(vp2_start.x - vpc.x, vp2_start.y - vpc.y,
&phi_start, &rho);
xy2polar(vp2_stop.x - vpc.x, vp2_stop.y - vpc.y,
&phi_stop, &rho);
vp1.x = vpc.x - rho;
vp1.y = vpc.y + rho;
vp2.x = vpc.x + rho;
vp2.y = vpc.y - rho;
if (is_graph_xinvert(gno) == TRUE) {
fswap(&phi_start, &phi_stop);
}
if (phi_stop < phi_start) {
phi_stop += 2*M_PI;
}
DrawArc(vp1, vp2, (int) rint(180.0/M_PI*phi_start),
(int) rint(180.0/M_PI*phi_stop));
} else {
DrawLine(vp2_start, vp2_stop);
}
}
}
/* End axis bar stuff*/
/* TODO ticks, labels and axis labels for polar plots */
if (get_graph_type(gno) == GRAPH_POLAR) {
continue;
}
activate_bbox(BBOX_TYPE_TEMP, TRUE);
reset_bbox(BBOX_TYPE_TEMP);
/* Begin axis tick stuff */
if (t->t_flag) {
for (ittype_loop = 0; ittype_loop < 2; ittype_loop++) {
if (ittype_loop == 0) { /* minor ticks */
ttype = TICK_TYPE_MINOR;
tprops = t->mprops;
} else { /* major ticks */
ttype = TICK_TYPE_MAJOR;
tprops = t->props;
}
tsize = 0.02 * tprops.size;
switch (t->t_inout) {
case TICKS_IN:
vbase1_start = vbase1;
vbase1_stop = vbase1 + tick_dir_sign*tsize;
vbase2_start = vbase2;
vbase2_stop = vbase2 - tick_dir_sign*tsize;
break;
case TICKS_OUT:
vbase1_start = vbase1;
vbase1_stop = vbase1 - tick_dir_sign*tsize;
vbase2_start = vbase2;
vbase2_stop = vbase2 + tick_dir_sign*tsize;
break;
case TICKS_BOTH:
vbase1_start = vbase1 - tsize;
vbase1_stop = vbase1 + tsize;
vbase2_start = vbase2 + tsize;
vbase2_stop = vbase2 - tsize;
break;
default:
errmsg("Internal error in drawaxes()");
return;
}
setcolor(tprops.color);
setlinewidth(tprops.linew);
setlinestyle(tprops.lines);
itcur = 0;
for (itick = 0; itick < t->nticks; itick++) {
if (t->tloc[itick].type != ttype) {
continue;
}
wtpos = t->tloc[itick].wtpos;
if ((wtpos < wc_start) || (wtpos > wc_stop)) {
continue;
}
vtpos = coord_conv(wtpos);
if (t->t_op == PLACEMENT_NORMAL ||
t->t_op == PLACEMENT_BOTH) {
vp_tick1_start.x = vtpos*ort_para.x + vbase1_start*ort_perp.x;
vp_tick1_start.y = vtpos*ort_para.y + vbase1_start*ort_perp.y;
vp_tick1_stop.x = vtpos*ort_para.x + vbase1_stop*ort_perp.x;
vp_tick1_stop.y = vtpos*ort_para.y + vbase1_stop*ort_perp.y;
DrawLine(vp_tick1_start, vp_tick1_stop);
}
if (t->t_op == PLACEMENT_OPPOSITE ||
t->t_op == PLACEMENT_BOTH) {
vp_tick2_start.x = vtpos*ort_para.x + vbase2_start*ort_perp.x;
vp_tick2_start.y = vtpos*ort_para.y + vbase2_start*ort_perp.y;
vp_tick2_stop.x = vtpos*ort_para.x + vbase2_stop*ort_perp.x;
vp_tick2_stop.y = vtpos*ort_para.y + vbase2_stop*ort_perp.y;
DrawLine(vp_tick2_start, vp_tick2_stop);
}
itcur++;
}
}
}
/* End axis ticks stuff */
/* Make sure we don't end up with an empty BBox if no ticks have
been drawn */
vp1.x = v.xv1;
vp1.y = v.yv1;
vp2.x = v.xv2;
vp2.y = v.yv2;
update_bbox(BBOX_TYPE_TEMP, vp1);
update_bbox(BBOX_TYPE_TEMP, vp2);
/* Begin tick label stuff */
if(t->tl_gaptype==TYPE_AUTO) {
/* hard coded offsets for autoplacement of tick labels */
tl_trans=0.0; /* parallel */
tl_offset=0.01; /* perpendicular */
} else{
tl_trans = t->tl_gap.x;
tl_offset = t->tl_gap.y;
}
if (t->tl_flag) {
if (t->tl_starttype == TYPE_SPEC) {
wc_start_labels = t->tl_start;
} else {
wc_start_labels = wc_start;
}
if (t->tl_stoptype == TYPE_SPEC) {
wc_stop_labels = t->tl_stop;
} else {
wc_stop_labels = wc_stop;
}
tlsize = 0.02 * t->tl_charsize;
tsize = 0.02 * t->props.size;
switch (t->t_inout) {
case TICKS_IN:
vbase_tlabel1 = vbase1 - (1 - tick_dir_sign)/2*tsize - tl_offset;
vbase_tlabel2 = vbase2 + (1 - tick_dir_sign)/2*tsize + tl_offset;
break;
case TICKS_OUT:
vbase_tlabel1 = vbase1 - (1 + tick_dir_sign)/2*tsize - tl_offset;
vbase_tlabel2 = vbase2 + (1 + tick_dir_sign)/2*tsize + tl_offset;
break;
case TICKS_BOTH:
vbase_tlabel1 = vbase1 - tsize - tl_offset;
vbase_tlabel2 = vbase2 + tsize + tl_offset;
break;
default:
errmsg("Internal error in drawaxes()");
return;
}
setfont(t->tl_font);
setcharsize(t->tl_charsize);
itcur = 0;
for (itick = 0; itick < t->nticks; itick++) {
if (t->tloc[itick].type != TICK_TYPE_MAJOR) {
continue;
}
wtpos = t->tloc[itick].wtpos;
if ((wtpos < wc_start_labels) || (wtpos > wc_stop_labels)) {
continue;
}
if (t->tl_prestr[0]) {
strcpy(tlabel, t->tl_prestr);
} else {
tlabel[0] = '\0';
}
if (t->tloc[itick].label != NULL) {
strcat(tlabel, t->tloc[itick].label);
}
if (t->tl_appstr[0]) {
strcat(tlabel, t->tl_appstr);
}
vtpos = coord_conv(wtpos);
if (itcur % (t->tl_skip + 1) == 0) {
/* Set color before each tick label, since pre/app
strings may change it */
setcolor(t->tl_color);
/* Tick labels on normal side */
if (t->tl_op == PLACEMENT_NORMAL ||
t->tl_op == PLACEMENT_BOTH) {
vbase_tlabel = vbase_tlabel1 - (tl_offset + tlsize)*
(itcur % (t->tl_staggered + 1));
vp_tlabel.x = (vtpos + tl_trans)*ort_para.x +
vbase_tlabel*ort_perp.x;
vp_tlabel.y = (vtpos + tl_trans)*ort_para.y +
vbase_tlabel*ort_perp.y;
WriteString(vp_tlabel, t->tl_angle, tlabel1_just, tlabel);
}
/* Tick labels on opposite side */
if (t->tl_op == PLACEMENT_OPPOSITE ||
t->tl_op == PLACEMENT_BOTH) {
vbase_tlabel = vbase_tlabel2 + (tl_offset + tlsize)*
(itcur % (t->tl_staggered + 1));
vp_tlabel.x = (vtpos + tl_trans)*ort_para.x +
vbase_tlabel*ort_perp.x;
vp_tlabel.y = (vtpos + tl_trans)*ort_para.y +
vbase_tlabel*ort_perp.y;
WriteString(vp_tlabel, t->tl_angle, tlabel2_just, tlabel);
}
}
itcur++;
}
}
/* End tick label stuff */
bb = get_bbox(BBOX_TYPE_TEMP);
/* Begin axis label stuff */
if (t->label_place == TYPE_SPEC) {
vp_label_offset1.x = t->label.x;
vp_label_offset1.y = t->label.y;
vp_label_offset2.x = t->label.x;
vp_label_offset2.y = t->label.y;
/* These settings are for backward compatibility */
label1_just = JUST_CENTER|JUST_MIDDLE;
label2_just = JUST_CENTER|JUST_MIDDLE;
} else {
/* parallel is trivial ;-) */
vp_label_offset1.x = 0.00;
vp_label_offset2.x = 0.00;
/* perpendicular */
if (is_xaxis(caxis)) {
vp_label_offset1.y = vbase1 - bb.yv1;
vp_label_offset2.y = bb.yv2 - vbase2;
} else {
vp_label_offset1.y = vbase1 - bb.xv1;
vp_label_offset2.y = bb.xv2 - vbase2;
}
vp_label_offset1.y += tl_offset;
vp_label_offset2.y += tl_offset;
label1_just = tlabel1_just;
label2_just = tlabel2_just;
}
if (t->label.s && t->label.s[0]) {
setcharsize(t->label.charsize);
setfont(t->label.font);
setcolor(t->label.color);
/* Axis label on normal side */
if (t->label_op == PLACEMENT_NORMAL ||
t->label_op == PLACEMENT_BOTH) {
vp_label.x = (vp1_start.x + vp1_stop.x)/2
+ vp_label_offset1.x*ort_para.x
- vp_label_offset1.y*ort_perp.x;
vp_label.y = (vp1_start.y + vp1_stop.y)/2
+ vp_label_offset1.x*ort_para.y
- vp_label_offset1.y*ort_perp.y;
WriteString(vp_label, langle, label1_just, t->label.s);
}
/* Axis label on opposite side */
if (t->label_op == PLACEMENT_OPPOSITE ||
t->label_op == PLACEMENT_BOTH) {
vp_label.x = (vp2_start.x + vp2_stop.x)/2
+ vp_label_offset2.x*ort_para.x
+ vp_label_offset2.y*ort_perp.x ;
vp_label.y = (vp2_start.y + vp2_stop.y)/2
+ vp_label_offset2.x*ort_para.y
+ vp_label_offset2.y*ort_perp.y ;
WriteString(vp_label, langle, label2_just, t->label.s);
}
}
/* End axis label stuff */
}
}
void calculate_tickgrid(int gno)
{
int caxis;
int itick, imtick, itmaj;
int nmajor;
double swc_start, swc_stop, stmajor;
int scale;
double wtmaj;
world w;
tickmarks *t;
int res, len;
grarr *tvar;
double *tt;
reenter:
get_graph_world(gno, &w);
for (caxis = 0; caxis < MAXAXES; caxis++) {
t = get_graph_tickmarks(gno, caxis);
if (!t || t->active != TRUE) {
continue;
}
if (t->t_spec == TICKS_SPEC_NONE) {
if (is_xaxis(caxis)) {
scale = get_graph_xscale(gno);
if (scale == SCALE_LOG) {
swc_start = fscale(w.xg1, scale);
swc_stop = fscale(w.xg2, scale);
} else {
swc_start = w.xg1;
swc_stop = w.xg2;
}
} else {
scale = get_graph_yscale(gno);
if (scale == SCALE_LOG) {
swc_start = fscale(w.yg1, scale);
swc_stop = fscale(w.yg2, scale);
} else {
swc_start = w.yg1;
swc_stop = w.yg2;
}
}
if (scale == SCALE_LOG) {
stmajor = fscale(t->tmajor, scale);
} else {
stmajor = t->tmajor;
}
if (stmajor <= 0.0) {
errmsg("Invalid major tick spacing, autoticking");
autotick_axis(gno, caxis);
goto reenter;
}
if (t->t_round == TRUE) {
swc_start = floor(swc_start/stmajor)*stmajor;
}
nmajor = (int) ceil((swc_stop - swc_start) / stmajor + 1);
t->nticks = (nmajor - 1)*(t->nminor + 1) + 1;
if (t->nticks > MAX_TICKS) {
errmsg("Too many ticks ( > MAX_TICKS ), autoticking");
autotick_axis(gno, caxis);
goto reenter;
}
/*
* if (t->nticks > MAX_TICKS) {
* t->nticks = MAX_TICKS;
* }
*/
itick = 0;
itmaj = 0;
while (itick < t->nticks) {
if (scale == SCALE_LOG) {
wtmaj = ifscale(swc_start + itmaj*stmajor, scale);
} else {
wtmaj = swc_start + itmaj*stmajor;
if (t->t_round == TRUE && fabs(wtmaj) < 1.0e-6*stmajor) {
wtmaj = 0.0;
}
}
t->tloc[itick].wtpos = wtmaj;
t->tloc[itick].type = TICK_TYPE_MAJOR;
itick++;
for (imtick = 0; imtick < t->nminor && itick < t->nticks; imtick++) {
if (scale == SCALE_LOG) {
t->tloc[itick].wtpos = wtmaj * (imtick + 2);
} else {
t->tloc[itick].wtpos = wtmaj + (imtick + 1)*stmajor/(t->nminor + 1);
}
t->tloc[itick].type = TICK_TYPE_MINOR;
XCFREE(t->tloc[itick].label);
itick++;
}
itmaj++;
}
}
if (t->t_spec != TICKS_SPEC_BOTH) {
nmajor = 0;
for (itick = 0; itick < t->nticks; itick++) {
if (t->tloc[itick].type == TICK_TYPE_MAJOR) {
nmajor++;
}
}
if (t->tl_formula && t->tl_formula[0] != '\0') {
tvar = get_parser_arr_by_name("$t");
if (tvar == NULL) {
tvar = define_parser_arr("$t");
if (tvar == NULL) {
errmsg("Internal error");
return;
}
}
if (tvar->length != 0) {
xfree(tvar->data);
tvar->length = 0;
}
tvar->data = xmalloc(nmajor*SIZEOF_DOUBLE);
if (tvar->data == NULL) {
return;
}
tvar->length = nmajor;
itmaj = 0;
for (itick = 0; itick < t->nticks; itick++) {
if (t->tloc[itick].type == TICK_TYPE_MAJOR) {
tvar->data[itmaj] = t->tloc[itick].wtpos;
itmaj++;
}
}
res = v_scanner(t->tl_formula, &len, &tt);
XCFREE(tvar->data);
tvar->length = 0;
if (res != RETURN_SUCCESS || len != nmajor) {
errmsg("Error in tick transformation formula");
return;
}
itmaj = 0;
for (itick = 0; itick < t->nticks; itick++) {
if (t->tloc[itick].type == TICK_TYPE_MAJOR) {
t->tloc[itick].label = copy_string(t->tloc[itick].label,
create_fstring(t->tl_format, t->tl_prec,
tt[itmaj], LFORMAT_TYPE_EXTENDED));
itmaj++;
}
}
xfree(tt);
} else {
for (itick = 0; itick < t->nticks; itick++) {
if (t->tloc[itick].type == TICK_TYPE_MAJOR) {
t->tloc[itick].label = copy_string(t->tloc[itick].label,
create_fstring(t->tl_format, t->tl_prec,
t->tloc[itick].wtpos, LFORMAT_TYPE_EXTENDED));
}
}
}
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1