tioga 1.7 → 1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Tioga_README +45 -29
- data/split/Dvector/dvector.c +1 -1
- data/split/Tioga/{shared/axes.c → axes.c} +360 -36
- data/split/Tioga/figures.c +2 -1
- data/split/Tioga/figures.h +6 -2
- data/split/Tioga/generic.h +0 -1
- data/split/Tioga/lib/FigMkr.rb +3 -1
- data/split/Tioga/lib/X_and_Y_Axes.rb +74 -4
- data/split/Tioga/makers.c +1303 -0
- data/split/Tioga/{shared/pdf_font_dicts.c → pdf_font_dicts.c} +0 -0
- data/split/Tioga/{shared/pdfcolor.c → pdfcolor.c} +304 -145
- data/split/Tioga/pdfcoords.c +534 -0
- data/split/Tioga/{shared/pdffile.c → pdffile.c} +161 -56
- data/split/Tioga/{shared/pdfimage.c → pdfimage.c} +171 -74
- data/split/Tioga/{shared/pdfpath.c → pdfpath.c} +0 -0
- data/split/Tioga/{shared/pdftext.c → pdftext.c} +245 -138
- data/split/Tioga/{shared/texout.c → texout.c} +18 -9
- data/split/Tioga/wrappers.c +23 -7
- data/split/Tioga/wrappers.h +5 -3
- data/split/extconf.rb +1 -1
- metadata +25 -25
- data/split/Tioga/shared/makers.c +0 -1220
- data/split/Tioga/shared/pdfcoords.c +0 -443
data/Tioga_README
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
This is the README for the Tioga kernel, version 1.
|
1
|
+
This is the README for the Tioga kernel, version 1.8, April 4, 2008.
|
2
2
|
|
3
|
-
Copyright (C) 2005, 2006, 2007 Bill Paxton
|
3
|
+
Copyright (C) 2005, 2006, 2007, 2008 Bill Paxton
|
4
|
+
Copyright (C) 2007, 2008 Vincent Fourmond, Taro Sato
|
4
5
|
|
5
6
|
This file is part of Tioga.
|
6
7
|
|
@@ -14,36 +15,21 @@ This is the README for the Tioga kernel, version 1.6, March 17, 2007.
|
|
14
15
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
16
|
GNU Library General Public License for more details.
|
16
17
|
|
17
|
-
You should have received a copy of the GNU Library General Public
|
18
|
+
You should have received a copy of the GNU Library General Public License
|
18
19
|
along with Tioga; if not, write to the Free Software
|
19
20
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
21
|
|
21
22
|
<< What's new >>
|
22
23
|
|
23
|
-
Version 1.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
It saw a very significant improvement in that you can now query
|
32
|
-
the exact size of a text typeset by LaTeX, with the function text_size. Please
|
33
|
-
have a look at its documentation, and at the Text_size and
|
34
|
-
Text_size_with_rotation samples in samples/figures/figures.rb.
|
35
|
-
|
36
|
-
The code base was quite moved around so as to facilitate work on a
|
37
|
-
Python version that would share as much code as possible with the Ruby one;
|
38
|
-
this should not bring user-visible changes (apart, maybe, from compilation
|
39
|
-
problems, but we hope not).
|
24
|
+
Version 1.8 is essentially a cleanup/bug fix release. Tioga now compiles
|
25
|
+
with hardly any warnings, thanks to the work by Taro Sato. show_axis can now
|
26
|
+
take a hash instead of a simple location, and can draw axes basically
|
27
|
+
anywhere. See the axes_fun function in samples/plots/plots.rb and
|
28
|
+
show_axis documentation. Few bugs were fixed, in particular the
|
29
|
+
position of ticks with ticks_inside/ticks_outside, and the
|
30
|
+
installation via Rubygems which was broken for such a long time we are
|
31
|
+
ashamed of it.
|
40
32
|
|
41
|
-
Some bug fixes, including potential stack overflows (unprotected
|
42
|
-
snprintfs), and some new methods of Function. Dvector.fancy_read has been
|
43
|
-
reimplemented in C and benchmarked: it should be around three times faster
|
44
|
-
than before.
|
45
|
-
|
46
|
-
Code should now compile cleanly with Ruby 1.9.
|
47
33
|
|
48
34
|
<< Quick Installation of Tioga >>
|
49
35
|
|
@@ -54,9 +40,10 @@ the whole thing with a 'sudo'. For Linux, you may have to become root.
|
|
54
40
|
Once you've taken care of that, just run the QUICK_INSTALL script and
|
55
41
|
keep your fingers crossed.
|
56
42
|
|
57
|
-
You now have the option to run HOME_INSTALL instead, which will
|
58
|
-
your home directory (no root privileges
|
59
|
-
|
43
|
+
You now have the option to run HOME_INSTALL instead, which will
|
44
|
+
install the files to your home directory (no root privileges
|
45
|
+
needed). You just need to set your RUBYLIB environment variable as
|
46
|
+
reminded at the end of the file.
|
60
47
|
|
61
48
|
Please check that there are 0 failures and 0 errors at the end of the test.
|
62
49
|
Then, in your favorite PDF previewer, open the newly created 'tests/Icon_Test.pdf'
|
@@ -191,6 +178,35 @@ Bill Paxton
|
|
191
178
|
Here are the old release messages:
|
192
179
|
|
193
180
|
|
181
|
+
--------------------------
|
182
|
+
|
183
|
+
Version 1.7 adds an option in legends for markers without any line;
|
184
|
+
just call save_legend_info with 'line_type' => 'None' in addition to
|
185
|
+
the marker information. It is also now possible to give a 'legend' argument
|
186
|
+
to show_marker. The value of the arg can be either a legend dictionary
|
187
|
+
or simply the legend text in which case defaults will be supplied for
|
188
|
+
the rest. There is an example of this in samples/plots.rb
|
189
|
+
in the Legend_Outside figure.
|
190
|
+
|
191
|
+
It saw a very significant improvement in that you can now query
|
192
|
+
the exact size of a text typeset by LaTeX, with the function text_size. Please
|
193
|
+
have a look at its documentation, and at the Text_size and
|
194
|
+
Text_size_with_rotation samples in samples/figures/figures.rb.
|
195
|
+
|
196
|
+
The code base was quite moved around so as to facilitate work on a
|
197
|
+
Python version that would share as much code as possible with the Ruby one;
|
198
|
+
this should not bring user-visible changes (apart, maybe, from compilation
|
199
|
+
problems, but we hope not).
|
200
|
+
|
201
|
+
Some bug fixes, including potential stack overflows (unprotected
|
202
|
+
snprintfs), and some new methods of Function. Dvector.fancy_read has been
|
203
|
+
reimplemented in C and benchmarked: it should be around three times faster
|
204
|
+
than before.
|
205
|
+
|
206
|
+
Code should now compile cleanly with Ruby 1.9.
|
207
|
+
|
208
|
+
|
209
|
+
|
194
210
|
|
195
211
|
--------------------------
|
196
212
|
|
data/split/Dvector/dvector.c
CHANGED
@@ -4601,7 +4601,7 @@ VALUE Read_Rows_of_Dvectors(char *filename, VALUE destinations, int first_row_of
|
|
4601
4601
|
if (!is_okay_number(v)) {
|
4602
4602
|
fclose(file);
|
4603
4603
|
free(buff);
|
4604
|
-
rb_raise(rb_eArgError, "ERROR: bad value %g in line i
|
4604
|
+
rb_raise(rb_eArgError, "ERROR: bad value %g in line %i of file %s", v, i, filename);
|
4605
4605
|
}
|
4606
4606
|
if (col < d->capa) { row_data[col] = v; d->len = col+1; }
|
4607
4607
|
else {
|
@@ -1,6 +1,8 @@
|
|
1
|
+
/* -*- c-basic-offset: 3; -*- */
|
1
2
|
/* axes.c */
|
2
3
|
/*
|
3
4
|
Copyright (C) 2005 Bill Paxton
|
5
|
+
Copyright (C) 2008 Vincent Fourmond
|
4
6
|
|
5
7
|
This file is part of Tioga.
|
6
8
|
|
@@ -21,6 +23,20 @@
|
|
21
23
|
#include "figures.h"
|
22
24
|
#include "pdfs.h"
|
23
25
|
|
26
|
+
/*
|
27
|
+
Here is my (Vincent) big TODO-list for the axes stuff:
|
28
|
+
* provide a way to reliably get the location from major/minor
|
29
|
+
ticks for a given axis, so users can build lines/grids that build on
|
30
|
+
top of that (or rather under it ;-)...)
|
31
|
+
-> this is partly done, as you can now get the major ticks position.
|
32
|
+
* let the users choose between the current way to pick up ticks position
|
33
|
+
and another, such as the one I'm using in SciYAG, which seems to give
|
34
|
+
results that are more according to my expectations.
|
35
|
+
|
36
|
+
* BUG fix: apparently, two calls to the axes stuff do no return the
|
37
|
+
same thing, so I'll need to have a careful look at that
|
38
|
+
*/
|
39
|
+
|
24
40
|
typedef struct {
|
25
41
|
int type;
|
26
42
|
int other_axis_type;
|
@@ -172,7 +188,14 @@ static void Get_yaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
172
188
|
|
173
189
|
/*======================================================================*/
|
174
190
|
|
175
|
-
|
191
|
+
/*
|
192
|
+
Internal values for axis locations.
|
193
|
+
*/
|
194
|
+
#define AXIS_FREE_LOCATION 1000
|
195
|
+
|
196
|
+
/* Prepares the various coordinates according to the axis location */
|
197
|
+
static void prepare_axis_coordinates(OBJ_PTR fmkr, FM *p,
|
198
|
+
int location, PlotAxis *s, int *ierr)
|
176
199
|
{
|
177
200
|
switch (location) {
|
178
201
|
case LEFT:
|
@@ -253,7 +276,16 @@ static void draw_axis_line(OBJ_PTR fmkr, FM *p, int location, PlotAxis *s, int *
|
|
253
276
|
s->other_axis_reversed = p->yaxis_reversed;
|
254
277
|
s->top_or_right = false;
|
255
278
|
break;
|
256
|
-
|
279
|
+
case AXIS_FREE_LOCATION:
|
280
|
+
/* Nothing to be done here. */
|
281
|
+
break;
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
static void draw_axis_line(OBJ_PTR fmkr, FM *p, int location,
|
286
|
+
PlotAxis *s, int *ierr)
|
287
|
+
{
|
288
|
+
prepare_axis_coordinates(fmkr, p, location, s, ierr);
|
257
289
|
c_line_width_set(fmkr, p, s->line_width, ierr);
|
258
290
|
figure_join_and_stroke(fmkr, p, s->x0, s->y0, s->x1, s->y1, ierr);
|
259
291
|
}
|
@@ -302,6 +334,7 @@ static char *Create_Label(double val, int scale, int prec,
|
|
302
334
|
return string;
|
303
335
|
}
|
304
336
|
|
337
|
+
/* vincent: I wonder what this function is doing here ;-)... */
|
305
338
|
char *Get_String(OBJ_PTR ary, int index, int *ierr) {
|
306
339
|
OBJ_PTR s = Array_Entry(ary,index,ierr);
|
307
340
|
if (*ierr != 0) return NULL;
|
@@ -536,9 +569,11 @@ static void Pick_Major_Tick_Interval(OBJ_PTR fmkr, FM *p,
|
|
536
569
|
}
|
537
570
|
}
|
538
571
|
|
539
|
-
|
572
|
+
/* This functions fills the majors attribute of the PlotAxis object
|
573
|
+
with the position of major ticks
|
574
|
+
*/
|
575
|
+
static void compute_major_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
540
576
|
{
|
541
|
-
s->num_minors = s->number_of_minor_intervals;
|
542
577
|
if (s->locations_for_major_ticks != OBJ_NIL) {
|
543
578
|
long len;
|
544
579
|
s->majors = Vector_Data_for_Read(s->locations_for_major_ticks, &len, ierr);
|
@@ -559,12 +594,22 @@ static void draw_major_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
559
594
|
if (*ierr != 0) return;
|
560
595
|
s->free_majors = true;
|
561
596
|
}
|
597
|
+
}
|
598
|
+
|
599
|
+
static void draw_major_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
600
|
+
{
|
601
|
+
s->num_minors = s->number_of_minor_intervals;
|
602
|
+
|
603
|
+
/* Get the major ticks position in s->majors */
|
604
|
+
compute_major_ticks(fmkr, p, s, ierr);
|
605
|
+
if(*ierr != 0) return;
|
606
|
+
|
562
607
|
int i;
|
563
608
|
double inside=0.0, outside=0.0, length;
|
564
609
|
bool did_line = false;
|
565
610
|
length = s->major_tick_length * ((s->vertical)? p->default_text_height_dx : p->default_text_height_dy);
|
566
611
|
if (s->ticks_inside) inside = length;
|
567
|
-
if (s->ticks_outside) outside = length;
|
612
|
+
if (s->ticks_outside) outside = -length;
|
568
613
|
if (s->top_or_right) { inside = -inside; outside = -outside; }
|
569
614
|
if (s->line_width != s->major_tick_width) {
|
570
615
|
c_line_width_set(fmkr, p, s->line_width = s->major_tick_width, ierr);
|
@@ -607,7 +652,7 @@ static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
607
652
|
if (s->log_vals && nsub > 9) nsub = 9;
|
608
653
|
length = s->minor_tick_length * ((s->vertical)? p->default_text_height_dx : p->default_text_height_dy);
|
609
654
|
if (s->ticks_inside) inside = length;
|
610
|
-
if (s->ticks_outside) outside = length;
|
655
|
+
if (s->ticks_outside) outside = -length;
|
611
656
|
if (s->top_or_right) { inside = -inside; outside = -outside; }
|
612
657
|
if (s->line_width != s->minor_tick_width) {
|
613
658
|
c_line_width_set(fmkr, p, s->line_width = s->minor_tick_width, ierr);
|
@@ -635,10 +680,12 @@ static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
635
680
|
double subloc = loc + ((!s->log_vals) ? (j * subinterval) : log_subintervals[j-1]);
|
636
681
|
if (subloc >= next_loc) break;
|
637
682
|
if (subloc <= s->axis_min || subloc >= s->axis_max) continue;
|
638
|
-
if (s->vertical)
|
683
|
+
if (s->vertical) {
|
639
684
|
figure_join(fmkr, p, s->x0+inside, subloc, s->x0+outside, subloc, ierr);
|
640
|
-
|
685
|
+
}
|
686
|
+
else {
|
641
687
|
figure_join(fmkr, p, subloc, s->y0+inside, subloc, s->y0+outside, ierr);
|
688
|
+
}
|
642
689
|
did_line = true;
|
643
690
|
if (*ierr != 0) return;
|
644
691
|
}
|
@@ -649,10 +696,41 @@ static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
|
|
649
696
|
|
650
697
|
static void show_numeric_label(OBJ_PTR fmkr, FM *p, PlotAxis *s,
|
651
698
|
char *text, int location, double position, double shift, int *ierr)
|
652
|
-
{
|
653
|
-
|
654
|
-
|
655
|
-
|
699
|
+
{
|
700
|
+
if(location == AXIS_FREE_LOCATION) {
|
701
|
+
/* We convert the tick position into frame position */
|
702
|
+
double x,y, ft_ht = p->default_text_scale *
|
703
|
+
s->numeric_label_scale * p->default_font_size;
|
704
|
+
double angle;
|
705
|
+
/* Defaults to angle = +90, left side of the axis */
|
706
|
+
if(s->vertical) {
|
707
|
+
y = position;
|
708
|
+
x = s->x0 + convert_output_to_figure_dx(p,(s->reversed ? 1.0 : -1.0) *
|
709
|
+
ft_ht * ENLARGE * shift);
|
710
|
+
|
711
|
+
|
712
|
+
angle = 90;
|
713
|
+
}
|
714
|
+
else {
|
715
|
+
angle = 0;
|
716
|
+
x = position;
|
717
|
+
y = s->y0 + convert_output_to_figure_dy(p,(s->reversed ? 1.0 : -1.0) *
|
718
|
+
ft_ht * ENLARGE * shift);
|
719
|
+
}
|
720
|
+
|
721
|
+
c_show_rotated_label(fmkr, p, text, x, y,
|
722
|
+
s->numeric_label_scale,
|
723
|
+
s->numeric_label_angle + angle,
|
724
|
+
s->numeric_label_justification,
|
725
|
+
s->numeric_label_alignment, OBJ_NIL, ierr);
|
726
|
+
|
727
|
+
}
|
728
|
+
else {
|
729
|
+
// position is in figure coords and must be converted to frame coords
|
730
|
+
double pos = ((!s->reversed)? (position - s->axis_min) : (s->axis_max - position)) / s->length;
|
731
|
+
c_show_rotated_text(fmkr, p, text, location, shift, pos,
|
732
|
+
s->numeric_label_scale, s->numeric_label_angle, s->numeric_label_justification, s->numeric_label_alignment, OBJ_NIL, ierr);
|
733
|
+
}
|
656
734
|
}
|
657
735
|
|
658
736
|
static void draw_numeric_labels(OBJ_PTR fmkr, FM *p, int location, PlotAxis *s, int *ierr)
|
@@ -669,6 +747,20 @@ static void draw_numeric_labels(OBJ_PTR fmkr, FM *p, int location, PlotAxis *s,
|
|
669
747
|
}
|
670
748
|
}
|
671
749
|
|
750
|
+
/* Frees all temporarily allocated memory */
|
751
|
+
static void free_allocated_memory(PlotAxis *s)
|
752
|
+
{
|
753
|
+
int i;
|
754
|
+
if (s->free_majors) free(s->majors);
|
755
|
+
if (s->labels != NULL) {
|
756
|
+
if (s->free_strings_for_labels) {
|
757
|
+
for (i = 0; i < s->nmajors; i++)
|
758
|
+
if (s->labels[i] != NULL) free(s->labels[i]);
|
759
|
+
}
|
760
|
+
free(s->labels);
|
761
|
+
}
|
762
|
+
}
|
763
|
+
|
672
764
|
static void c_show_side(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr) {
|
673
765
|
int i;
|
674
766
|
if (s->type == AXIS_HIDDEN) return;
|
@@ -694,32 +786,9 @@ static void c_show_side(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr) {
|
|
694
786
|
if (*ierr != 0) return;
|
695
787
|
done:
|
696
788
|
End_Axis_Standard_State(); // grestore
|
697
|
-
|
698
|
-
if (s->labels != NULL) {
|
699
|
-
if (s->free_strings_for_labels) {
|
700
|
-
for (i = 0; i < s->nmajors; i++)
|
701
|
-
if (s->labels[i] != NULL) free(s->labels[i]);
|
702
|
-
}
|
703
|
-
free(s->labels);
|
704
|
-
}
|
789
|
+
free_allocated_memory(s);
|
705
790
|
}
|
706
791
|
|
707
|
-
|
708
|
-
void c_show_axis(OBJ_PTR fmkr, FM *p, int location, int *ierr)
|
709
|
-
{
|
710
|
-
PlotAxis axis;
|
711
|
-
if (location == LEFT || location == RIGHT || location == AT_X_ORIGIN) {
|
712
|
-
if (!p->yaxis_visible) return;
|
713
|
-
Get_yaxis_Specs(fmkr, p, &axis, ierr);
|
714
|
-
} else if (location == TOP || location == BOTTOM || location == AT_Y_ORIGIN) {
|
715
|
-
if (!p->xaxis_visible) return;
|
716
|
-
Get_xaxis_Specs(fmkr, p, &axis, ierr);
|
717
|
-
} else RAISE_ERROR_i(
|
718
|
-
"Sorry: invalid 'loc' for axis: must be one of LEFT, RIGHT, TOP, BOTTOM, AT_X_ORIGIN, or AT_Y_ORIGIN: is (%i)", location, ierr);
|
719
|
-
if (*ierr != 0) return;
|
720
|
-
axis.location = location;
|
721
|
-
c_show_side(fmkr, p, &axis, ierr);
|
722
|
-
}
|
723
792
|
|
724
793
|
void c_show_edge(OBJ_PTR fmkr, FM *p, int location, int *ierr)
|
725
794
|
{
|
@@ -796,3 +865,258 @@ void c_no_bottom_edge(OBJ_PTR fmkr, FM *p, int *ierr)
|
|
796
865
|
p->bottom_edge_visible = false;
|
797
866
|
}
|
798
867
|
|
868
|
+
|
869
|
+
/* Prepares the PlotAxis object for a standard use.
|
870
|
+
Returns 1 if the corresponding axis is marked as
|
871
|
+
visible and 0 if not.
|
872
|
+
|
873
|
+
This function will be used later to get the exact same PlotAxis
|
874
|
+
object so as to get information about the ticks, for instance.
|
875
|
+
*/
|
876
|
+
static int prepare_standard_PlotAxis(OBJ_PTR fmkr, FM *p,
|
877
|
+
int location, PlotAxis * axis,
|
878
|
+
int *ierr)
|
879
|
+
{
|
880
|
+
axis->location = location;
|
881
|
+
if (location == LEFT || location == RIGHT || location == AT_X_ORIGIN) {
|
882
|
+
Get_yaxis_Specs(fmkr, p, axis, ierr);
|
883
|
+
if (!p->yaxis_visible) return 0;
|
884
|
+
}
|
885
|
+
else if (location == TOP || location == BOTTOM || location == AT_Y_ORIGIN) {
|
886
|
+
Get_xaxis_Specs(fmkr, p, axis, ierr);
|
887
|
+
if (!p->xaxis_visible) return 0;
|
888
|
+
}
|
889
|
+
else
|
890
|
+
RAISE_ERROR_i("Sorry: invalid 'loc' for axis: must be one of LEFT,"
|
891
|
+
"RIGHT, TOP, BOTTOM, AT_X_ORIGIN, or AT_Y_ORIGIN: is (%i)",
|
892
|
+
location, ierr);
|
893
|
+
if (*ierr != 0)
|
894
|
+
return 0;
|
895
|
+
return 1;
|
896
|
+
}
|
897
|
+
|
898
|
+
|
899
|
+
void c_show_axis(OBJ_PTR fmkr, FM *p, int location, int *ierr)
|
900
|
+
{
|
901
|
+
PlotAxis axis;
|
902
|
+
if(prepare_standard_PlotAxis(fmkr, p, location, &axis, ierr)) {
|
903
|
+
c_show_side(fmkr, p, &axis, ierr);
|
904
|
+
}
|
905
|
+
}
|
906
|
+
|
907
|
+
/* This function prepares a PlotAxis object based on the information
|
908
|
+
given in the dict argument.
|
909
|
+
*/
|
910
|
+
static int prepare_dict_PlotAxis(OBJ_PTR fmkr, FM *p,
|
911
|
+
OBJ_PTR axis_spec, PlotAxis * axis,
|
912
|
+
int *ierr)
|
913
|
+
{
|
914
|
+
/* First, we get default from the location or from style.
|
915
|
+
Too many things need to be checked if we don't get default values
|
916
|
+
from a given point
|
917
|
+
*/
|
918
|
+
if(Hash_Has_Key(axis_spec, "location")) {
|
919
|
+
int location = Number_to_int(Hash_Get_Obj(axis_spec, "location"), ierr);
|
920
|
+
if (location == LEFT || location == RIGHT || location == AT_X_ORIGIN) {
|
921
|
+
Get_yaxis_Specs(fmkr, p, axis, ierr);
|
922
|
+
}
|
923
|
+
else if (location == TOP || location == BOTTOM ||
|
924
|
+
location == AT_Y_ORIGIN) {
|
925
|
+
Get_xaxis_Specs(fmkr, p, axis, ierr);
|
926
|
+
}
|
927
|
+
axis->location = location;
|
928
|
+
}
|
929
|
+
else {
|
930
|
+
if(Hash_Has_Key(axis_spec, "from") && Hash_Has_Key(axis_spec, "to")) {
|
931
|
+
long dummy;
|
932
|
+
double *from = Vector_Data_for_Read(Hash_Get_Obj(axis_spec, "from"),
|
933
|
+
&dummy, ierr);
|
934
|
+
double *to = Vector_Data_for_Read(Hash_Get_Obj(axis_spec, "to"),
|
935
|
+
&dummy, ierr);
|
936
|
+
axis->x0 = from[0];
|
937
|
+
axis->x1 = to[0];
|
938
|
+
axis->y0 = from[1];
|
939
|
+
axis->y1 = to[1];
|
940
|
+
|
941
|
+
/* We now determine various parameters attached to the axis:
|
942
|
+
* its length
|
943
|
+
* its min/max boundaries
|
944
|
+
* whether it is reversed
|
945
|
+
*/
|
946
|
+
if(axis->y0 != axis->y1) {
|
947
|
+
Get_yaxis_Specs(fmkr, p, axis, ierr);
|
948
|
+
if(axis->x0 != axis->x1) {
|
949
|
+
RAISE_ERROR("show_axis: sorry, axes must be horizontal or "
|
950
|
+
"vertical", ierr);
|
951
|
+
}
|
952
|
+
else {
|
953
|
+
if(axis->y0 > axis->y1) {
|
954
|
+
axis->reversed = true;
|
955
|
+
axis->axis_min = axis->y1;
|
956
|
+
axis->axis_max = axis->y0;
|
957
|
+
axis->length = axis->y0 - axis->y1;
|
958
|
+
}
|
959
|
+
else {
|
960
|
+
axis->reversed = false;
|
961
|
+
axis->axis_min = axis->y0;
|
962
|
+
axis->axis_max = axis->y1;
|
963
|
+
axis->length = axis->y1 - axis->y0;
|
964
|
+
}
|
965
|
+
axis->vertical = true;
|
966
|
+
axis->location = AXIS_FREE_LOCATION;
|
967
|
+
}
|
968
|
+
}
|
969
|
+
else {
|
970
|
+
Get_xaxis_Specs(fmkr, p, axis, ierr);
|
971
|
+
if(axis->x0 > axis->x1) {
|
972
|
+
axis->reversed = true;
|
973
|
+
axis->axis_min = axis->x1;
|
974
|
+
axis->axis_max = axis->x0;
|
975
|
+
axis->length = axis->x0 - axis->x1;
|
976
|
+
}
|
977
|
+
else {
|
978
|
+
axis->reversed = false;
|
979
|
+
axis->axis_min = axis->x0;
|
980
|
+
axis->axis_max = axis->x1;
|
981
|
+
axis->length = axis->x1 - axis->x0;
|
982
|
+
}
|
983
|
+
axis->vertical = false;
|
984
|
+
axis->location = AXIS_FREE_LOCATION;
|
985
|
+
}
|
986
|
+
}
|
987
|
+
else {
|
988
|
+
RAISE_ERROR("show_axis: there must be 'location' or 'to' and 'from'", ierr);
|
989
|
+
}
|
990
|
+
}
|
991
|
+
|
992
|
+
/* Some generic overrides */
|
993
|
+
if(Hash_Has_Key(axis_spec, "type"))
|
994
|
+
axis->type = Number_to_int(Hash_Get_Obj(axis_spec, "type"), ierr);
|
995
|
+
|
996
|
+
if(Hash_Has_Key(axis_spec, "ticks_inside")) {
|
997
|
+
OBJ_PTR val = Hash_Get_Obj(axis_spec, "ticks_inside");
|
998
|
+
if(val == OBJ_NIL || val == OBJ_FALSE)
|
999
|
+
axis->ticks_inside = false;
|
1000
|
+
else
|
1001
|
+
axis->ticks_inside = true;
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
if(Hash_Has_Key(axis_spec, "ticks_outside")) {
|
1005
|
+
OBJ_PTR val = Hash_Get_Obj(axis_spec, "ticks_outside");
|
1006
|
+
if(val == OBJ_NIL || val == OBJ_FALSE)
|
1007
|
+
axis->ticks_outside = false;
|
1008
|
+
else
|
1009
|
+
axis->ticks_outside = true;
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
if(Hash_Has_Key(axis_spec, "major_ticks"))
|
1013
|
+
axis->locations_for_major_ticks = Hash_Get_Obj(axis_spec, "major_ticks");
|
1014
|
+
if(Hash_Has_Key(axis_spec, "minor_ticks"))
|
1015
|
+
axis->locations_for_minor_ticks = Hash_Get_Obj(axis_spec, "minor_ticks");
|
1016
|
+
if(Hash_Has_Key(axis_spec, "labels"))
|
1017
|
+
axis->tick_labels = Hash_Get_Obj(axis_spec, "labels");
|
1018
|
+
|
1019
|
+
|
1020
|
+
/* Various tick label attributes */
|
1021
|
+
if(Hash_Has_Key(axis_spec, "shift"))
|
1022
|
+
axis->numeric_label_shift = Hash_Get_Double(axis_spec, "shift");
|
1023
|
+
if(Hash_Has_Key(axis_spec, "scale"))
|
1024
|
+
axis->numeric_label_scale = Hash_Get_Double(axis_spec, "scale");
|
1025
|
+
if(Hash_Has_Key(axis_spec, "angle"))
|
1026
|
+
axis->numeric_label_angle = Hash_Get_Double(axis_spec, "angle");
|
1027
|
+
|
1028
|
+
/* Ticks attributes */
|
1029
|
+
if(Hash_Has_Key(axis_spec, "major_tick_width"))
|
1030
|
+
axis->major_tick_width = Hash_Get_Double(axis_spec, "major_tick_width");
|
1031
|
+
if(Hash_Has_Key(axis_spec, "minor_tick_width"))
|
1032
|
+
axis->minor_tick_width = Hash_Get_Double(axis_spec, "minor_tick_width");
|
1033
|
+
if(Hash_Has_Key(axis_spec, "major_tick_length"))
|
1034
|
+
axis->major_tick_length = Hash_Get_Double(axis_spec, "major_tick_length");
|
1035
|
+
if(Hash_Has_Key(axis_spec, "minor_tick_length"))
|
1036
|
+
axis->minor_tick_length = Hash_Get_Double(axis_spec, "minor_tick_length");
|
1037
|
+
|
1038
|
+
return 1;
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
|
1042
|
+
/* This function does nearly the same job as c_show_axis, but takes
|
1043
|
+
a full hash instead of getting information from the FigureMaker object,
|
1044
|
+
it retrieves them from the axis_spec hash. Following keys are
|
1045
|
+
understood:
|
1046
|
+
- location: position, as in show_axis. Can be omitted, if you
|
1047
|
+
provide the position yourself
|
1048
|
+
|
1049
|
+
This function bypasses the axis_visible checks. Use with caution !
|
1050
|
+
*/
|
1051
|
+
void c_show_axis_generic(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec, int *ierr)
|
1052
|
+
{
|
1053
|
+
PlotAxis axis;
|
1054
|
+
if(prepare_dict_PlotAxis(fmkr, p, axis_spec, &axis, ierr)) {
|
1055
|
+
c_show_side(fmkr, p, &axis, ierr);
|
1056
|
+
}
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
|
1060
|
+
/*
|
1061
|
+
This function takes an axis specification (either integer or
|
1062
|
+
hash) and returns a hash containing the following keys:
|
1063
|
+
* 'major' : position of all major ticks
|
1064
|
+
* 'labels' : the names of all labels
|
1065
|
+
* 'vertical' : if the axis is vertical or horizontal
|
1066
|
+
* 'line_width' : the line width
|
1067
|
+
* 'major_tick_width', 'major_tick_length' : the major tick width and length
|
1068
|
+
* 'minor_tick_width', 'minor_tick_length' : the minor tick width and length
|
1069
|
+
* 'scale', 'shift' and 'angle': the scale, shift and angle of numeric
|
1070
|
+
labels
|
1071
|
+
* 'x0', 'y0', 'x1', 'y1': the position of the axis in figure coordinates
|
1072
|
+
|
1073
|
+
*/
|
1074
|
+
OBJ_PTR c_axis_get_information(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec,
|
1075
|
+
int *ierr)
|
1076
|
+
{
|
1077
|
+
PlotAxis axis;
|
1078
|
+
OBJ_PTR hash = Hash_New(), ar;
|
1079
|
+
int i;
|
1080
|
+
if(Is_Kind_of_Integer(axis_spec))
|
1081
|
+
prepare_standard_PlotAxis(fmkr, p, Number_to_int(axis_spec, ierr),
|
1082
|
+
&axis, ierr);
|
1083
|
+
else
|
1084
|
+
prepare_dict_PlotAxis(fmkr, p, axis_spec, &axis, ierr);
|
1085
|
+
|
1086
|
+
/* First, major ticks positions */
|
1087
|
+
prepare_axis_coordinates(fmkr, p, axis.location, &axis, ierr);
|
1088
|
+
compute_major_ticks(fmkr, p, &axis, ierr);
|
1089
|
+
Hash_Set_Obj(hash, "major", Vector_New(axis.nmajors, axis.majors));
|
1090
|
+
|
1091
|
+
/* Then, labels */
|
1092
|
+
ar = Array_New(axis.nmajors);
|
1093
|
+
axis.labels = Get_Labels(fmkr, p, &axis, ierr);
|
1094
|
+
for (i=0; i < axis.nmajors; i++) {
|
1095
|
+
if (axis.labels[i])
|
1096
|
+
Array_Store(ar, i, String_From_Cstring(axis.labels[i]), ierr);
|
1097
|
+
else
|
1098
|
+
Array_Store(ar, i, OBJ_NIL, ierr);
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
Hash_Set_Obj(hash, "labels", ar);
|
1102
|
+
|
1103
|
+
Hash_Set_Obj(hash, "vertical", axis.vertical ? OBJ_TRUE : OBJ_FALSE);
|
1104
|
+
|
1105
|
+
Hash_Set_Double(hash, "line_width", axis.line_width);
|
1106
|
+
Hash_Set_Double(hash, "major_tick_width", axis.major_tick_width);
|
1107
|
+
Hash_Set_Double(hash, "minor_tick_width", axis.major_tick_width);
|
1108
|
+
Hash_Set_Double(hash, "major_tick_length", axis.major_tick_length);
|
1109
|
+
Hash_Set_Double(hash, "minor_tick_length", axis.major_tick_length);
|
1110
|
+
Hash_Set_Double(hash, "shift", axis.numeric_label_shift);
|
1111
|
+
Hash_Set_Double(hash, "scale", axis.numeric_label_scale);
|
1112
|
+
Hash_Set_Double(hash, "angle", axis.numeric_label_angle);
|
1113
|
+
|
1114
|
+
/* Positions of the axis */
|
1115
|
+
Hash_Set_Double(hash, "x0", axis.x0);
|
1116
|
+
Hash_Set_Double(hash, "x1", axis.x1);
|
1117
|
+
Hash_Set_Double(hash, "y0", axis.y0);
|
1118
|
+
Hash_Set_Double(hash, "y1", axis.y1);
|
1119
|
+
|
1120
|
+
free_allocated_memory(&axis);
|
1121
|
+
return hash;
|
1122
|
+
}
|