tioga 1.8 → 1.9

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.
Files changed (53) hide show
  1. data/Tioga_README +46 -11
  2. data/split/Dtable/dtable.c +2 -2
  3. data/split/Dtable/dvector.h +8 -0
  4. data/split/Dtable/namespace.h +16 -8
  5. data/split/Dtable/symbols.h +1 -1
  6. data/split/Dvector/dvector.c +77 -2
  7. data/split/Dvector/dvector_intern.h +2 -0
  8. data/split/Dvector/include/dvector.h +8 -0
  9. data/split/Dvector/lib/Dvector_extras.rb +12 -0
  10. data/split/Dvector/namespace.h +16 -8
  11. data/split/Dvector/symbols.h +1 -1
  12. data/split/Flate/namespace.h +16 -8
  13. data/split/Flate/symbols.h +1 -1
  14. data/split/Function/dvector.h +8 -0
  15. data/split/Function/function.c +2 -1
  16. data/split/Function/namespace.h +16 -8
  17. data/split/Function/symbols.h +1 -1
  18. data/split/Tioga/axes.c +217 -75
  19. data/split/Tioga/dvector.h +8 -0
  20. data/split/Tioga/figures.c +19 -2
  21. data/split/Tioga/figures.h +7 -6
  22. data/split/Tioga/generic.c +14 -1
  23. data/split/Tioga/generic.h +13 -0
  24. data/split/Tioga/init.c +5 -9
  25. data/split/Tioga/lib/Colormaps.rb +33 -2
  26. data/split/Tioga/lib/Doc.rb +30 -0
  27. data/split/Tioga/lib/Executive.rb +4 -2
  28. data/split/Tioga/lib/FigMkr.rb +219 -53
  29. data/split/Tioga/lib/Figures_and_Plots.rb +7 -0
  30. data/split/Tioga/lib/Images.rb +10 -2
  31. data/split/Tioga/lib/Legends.rb +7 -3
  32. data/split/Tioga/lib/Markers.rb +7 -0
  33. data/split/Tioga/lib/TexPreamble.rb +56 -56
  34. data/split/Tioga/lib/Utils.rb +7 -0
  35. data/split/Tioga/lib/maker.rb +1 -0
  36. data/split/Tioga/lib/tioga_ui_cmds.rb +6 -5
  37. data/split/Tioga/namespace.h +16 -8
  38. data/split/Tioga/pdfcolor.c +63 -7
  39. data/split/Tioga/pdfcoords.c +0 -16
  40. data/split/Tioga/pdfimage.c +16 -2
  41. data/split/Tioga/pdfs.h +1 -0
  42. data/split/Tioga/pdftext.c +223 -82
  43. data/split/Tioga/symbols.h +1 -1
  44. data/split/Tioga/texout.c +1 -1
  45. data/split/Tioga/wrappers.c +21 -10
  46. data/split/Tioga/wrappers.h +5 -0
  47. data/split/extconf.rb +27 -15
  48. data/split/namespace.h +16 -8
  49. data/split/scripts/tioga +0 -0
  50. data/split/symbols.h +1 -1
  51. data/tests/Icon_Test.pdf +0 -0
  52. data/tests/tc_Dvector.rb +24 -0
  53. metadata +38 -37
@@ -22,7 +22,7 @@ PRIVATE void * rb_import_symbol_no_raise(VALUE module,
22
22
 
23
23
  #define DECLARE_SYMBOL(ret_type,name,args) \
24
24
  typedef ret_type (*rb_export_##name##_type) args;\
25
- INTERN rb_export_##name##_type name
25
+ INTERN INTERN_EXTERN rb_export_##name##_type name
26
26
 
27
27
  #define IMPLEMENT_SYMBOL(name)\
28
28
  INTERN rb_export_##name##_type name = 0;
@@ -31,6 +31,13 @@
31
31
 
32
32
  /* functions for handling Dvectors: */
33
33
 
34
+ DECLARE_SYMBOL(bool, isa_Dvector, (VALUE obj));
35
+ /* returns true if the obj is a Dvector */
36
+ DECLARE_SYMBOL(long, len_Dvector, (VALUE dvector));
37
+ /* returns length of the dvector */
38
+ DECLARE_SYMBOL(double, access_Dvector, (VALUE dvector, long idx));
39
+ /* returns the value of entry idx in dvector */
40
+
34
41
  DECLARE_SYMBOL(double *, Dvector_Data_for_Read, (VALUE dvector, long *len_ptr));
35
42
  /* returns pointer to the dvector's data (which may be shared) */
36
43
  DECLARE_SYMBOL(double *, Dvector_Data_Copy, (VALUE dvector, long *len_ptr));
@@ -46,6 +53,7 @@ DECLARE_SYMBOL(void, Dvector_Store_Double, (VALUE ary, long idx, double val));
46
53
  /* pushes one element onto the vector */
47
54
  DECLARE_SYMBOL(void, Dvector_Push_Double, (VALUE ary, double val));
48
55
 
56
+
49
57
  /* functions for interpolation */
50
58
  DECLARE_SYMBOL(double, c_dvector_spline_interpolate,
51
59
  (double x, int n_pts_data, double *Xs, double *Ys,
@@ -898,6 +898,8 @@ static VALUE function_primitive(VALUE self)
898
898
  /*
899
899
  Computes the derivative of the Function and returns it as a new Function.
900
900
  The newly created function shares the X vector with the previous one.
901
+
902
+ WARNING: this is a very naive 3-points algorithm.
901
903
  */
902
904
  static VALUE function_derivative(VALUE self)
903
905
  {
@@ -906,7 +908,6 @@ static VALUE function_derivative(VALUE self)
906
908
  const double *y = Dvector_Data_for_Read(get_y_vector(self),NULL);
907
909
  VALUE derivative = Dvector_Create();
908
910
  long i = 0;
909
- double val = 0;
910
911
  /* First value */
911
912
  Dvector_Push_Double(derivative, (y[i+1] - y[i]) /(x[i+1] - x[i]));
912
913
  i++;
@@ -21,27 +21,35 @@
21
21
  #ifndef _NAMESPACE_H
22
22
  #define _NAMESPACE_H
23
23
 
24
- /* This header file provides two OS-specific macros for the definition of
25
- extern symbols:
24
+ /* This header file provides three OS-specific macros for the definition of
25
+ extern (or NOT extern) symbols:
26
26
 
27
27
  * PUBLIC, which has to be used to mark objects that will be used
28
- outside the module
28
+ outside the module
29
29
 
30
- * PRIVATE, for symbols which are "extern" but intern to the module
30
+ * INTERN, for symbols which are shared among compilation units within a
31
+ module, but are NOT exported to other modules.
32
+
33
+ * PRIVATE, for symbols which are visible only within the containing
34
+ compilation unit (i.e. C source file) and, of course, are not exported to
35
+ other modules.
31
36
 
32
37
  Please don't add "extern" after the PRIVATE or PUBLIC declaration
33
38
  as this would break compilation on Darwin.
34
39
  */
35
40
 
36
- #ifdef __APPLE__
41
+ #if __GNUC__ >= 4 /* we have the visibility attribute */
42
+ # define INTERN __attribute__ ((visibility ("hidden")))
43
+ # define PUBLIC __attribute__ ((visibility ("default")))
44
+ # define INTERN_EXTERN extern
45
+ #elif defined __APPLE__
37
46
  # define INTERN __private_extern__
38
47
  # define PUBLIC
39
- #elif __GNUC__ >= 4 /* we have the visibility attribute */
40
- # define INTERN __attribute__ ((visibility ("hidden")))
41
- # define PUBLIC __attribute__ ((visibility ("default")))
48
+ # define INTERN_EXTERN
42
49
  #else /* not really good */
43
50
  # define INTERN
44
51
  # define PUBLIC
52
+ # define INTERN_EXTERN
45
53
  #endif /* __APPLE__ and __GNU_C_ >= 4*/
46
54
 
47
55
  /* In any case, PRIVATE is static */
@@ -22,7 +22,7 @@ PRIVATE void * rb_import_symbol_no_raise(VALUE module,
22
22
 
23
23
  #define DECLARE_SYMBOL(ret_type,name,args) \
24
24
  typedef ret_type (*rb_export_##name##_type) args;\
25
- INTERN rb_export_##name##_type name
25
+ INTERN INTERN_EXTERN rb_export_##name##_type name
26
26
 
27
27
  #define IMPLEMENT_SYMBOL(name)\
28
28
  INTERN rb_export_##name##_type name = 0;
data/split/Tioga/axes.c CHANGED
@@ -81,6 +81,9 @@ typedef struct {
81
81
  int num_minors; // number of minor intervals
82
82
  double interval; // tick interval
83
83
  int location;
84
+ bool vincent_or_bill; /* True if we use Vincent's algorithm
85
+ for picking major ticks
86
+ */
84
87
  } PlotAxis;
85
88
 
86
89
  static void figure_moveto(OBJ_PTR fmkr, FM *p, double x, double y, int *ierr) // figure coords
@@ -147,6 +150,8 @@ static void Get_xaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
147
150
  s->numeric_label_justification = p->xaxis_numeric_label_justification;
148
151
  s->numeric_label_frequency = p->xaxis_numeric_label_frequency;
149
152
  s->numeric_label_phase = p->xaxis_numeric_label_phase;
153
+
154
+ s->vincent_or_bill = p->vincent_or_bill;
150
155
  }
151
156
 
152
157
  static void Get_yaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
@@ -184,6 +189,8 @@ static void Get_yaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
184
189
  s->numeric_label_justification = p->yaxis_numeric_label_justification;
185
190
  s->numeric_label_frequency = p->yaxis_numeric_label_frequency;
186
191
  s->numeric_label_phase = p->yaxis_numeric_label_phase;
192
+
193
+ s->vincent_or_bill = p->vincent_or_bill;
187
194
  }
188
195
 
189
196
  /*======================================================================*/
@@ -474,6 +481,42 @@ static char **Get_Labels(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
474
481
  return labels;
475
482
  }
476
483
 
484
+ static int Pick_Number_of_Minor_Intervals(double length, int *ierr)
485
+ {
486
+ double t1, fuzz, newlen;
487
+ int np, num_subintervals, inewlen;
488
+ if (length < 10.0 && length > 1.0) {
489
+ newlen = length;
490
+ } else {
491
+ t1 = (double) log10(length);
492
+ np = (int) floor(t1);
493
+ t1 -= np;
494
+ newlen = pow(10.0, t1);
495
+ }
496
+ inewlen = (int) floor(newlen + 0.5);
497
+ fuzz = newlen - inewlen;
498
+ fuzz = abs(fuzz);
499
+ num_subintervals = 4;
500
+ if (fuzz < 1e-2) {
501
+ switch (inewlen) {
502
+ case 0: case 1: case 2: num_subintervals = 4; break;
503
+ case 4: break;
504
+ case 8: case 10: num_subintervals = 2; break;
505
+ case 3: case 6: case 9: num_subintervals = 3; break;
506
+ default: num_subintervals = 5;
507
+ }
508
+ } else {
509
+ if (newlen > 5.0) num_subintervals = 4;
510
+ else if (newlen > 3.0) num_subintervals = 5;
511
+ else if (newlen > 1.5) num_subintervals = 5;
512
+ }
513
+ return num_subintervals;
514
+ }
515
+
516
+ /* Refactoring of the axis location picking code */
517
+
518
+ /* First, Bill's point of view */
519
+
477
520
  static double *Pick_Locations_for_Major_Ticks(double interval,
478
521
  double axis_min, double axis_max, int *num_locations, int *ierr)
479
522
  {
@@ -503,34 +546,6 @@ static double *Pick_Locations_for_Major_Ticks(double interval,
503
546
  return majors;
504
547
  }
505
548
 
506
- static int Pick_Number_of_Minor_Intervals(double length, int *ierr)
507
- {
508
- double t1, fuzz, newlen;
509
- int np, num_subintervals, inewlen;
510
- t1 = (double) log10(length);
511
- np = (int) floor(t1);
512
- t1 -= np;
513
- newlen = pow(10.0, t1);
514
- inewlen = (int) floor(newlen + 0.5);
515
- fuzz = newlen - inewlen;
516
- fuzz = abs(fuzz);
517
- num_subintervals = 4;
518
- if (fuzz < 1e-2) {
519
- switch (inewlen) {
520
- case 0: case 1: case 2: num_subintervals = 4; break;
521
- case 4: break;
522
- case 8: case 10: num_subintervals = 2; break;
523
- case 3: case 6: case 9: num_subintervals = 3; break;
524
- default: num_subintervals = 5;
525
- }
526
- } else {
527
- if (newlen > 5.0) num_subintervals = 4;
528
- else if (newlen > 3.0) num_subintervals = 5;
529
- else if (newlen > 1.5) num_subintervals = 5;
530
- }
531
- return num_subintervals;
532
- }
533
-
534
549
  static void Pick_Major_Tick_Interval(OBJ_PTR fmkr, FM *p,
535
550
  double tick_min, double tick_gap, double length, bool log_vals, double *tick, int *ierr)
536
551
  {
@@ -569,6 +584,76 @@ static void Pick_Major_Tick_Interval(OBJ_PTR fmkr, FM *p,
569
584
  }
570
585
  }
571
586
 
587
+ static double * pick_major_ticks_positions_Bill(OBJ_PTR fmkr, FM *p,
588
+ double axis_min,
589
+ double axis_max,
590
+ int *num_locations,
591
+ double tick_min,
592
+ double tick_gap,
593
+ double length,
594
+ bool log_vals,
595
+ double *tick,
596
+ int *ierr)
597
+ {
598
+ /* This code is using Bill's initial implementation */
599
+ Pick_Major_Tick_Interval(fmkr, p, tick_min, tick_gap,
600
+ length, log_vals, tick, ierr);
601
+ /* printf("Tick gap: %f, length: %f, tick_min: %f, tick interval: %f\n", */
602
+ /* tick_gap, length, tick_min, *tick); */
603
+ if (*ierr != 0)
604
+ return NULL;
605
+ return Pick_Locations_for_Major_Ticks(*tick, axis_min, axis_max,
606
+ num_locations, ierr);
607
+ }
608
+
609
+ /* Then, Vincent's point of view ;-) ... */
610
+
611
+ static double natural_distances[] = { 1.0, 2.0, /*2.5,*/ 5.0, 10.0 };
612
+ const int nb_natural_distances = sizeof(natural_distances)/sizeof(double);
613
+
614
+ static double * pick_major_ticks_positions_Vincent(OBJ_PTR fmkr, FM *p,
615
+ double axis_min,
616
+ double axis_max,
617
+ int *num_locations,
618
+ double tick_min,
619
+ double tick_gap,
620
+ double length,
621
+ bool log_vals,
622
+ double *tick,
623
+ int *ierr)
624
+ {
625
+ /* I like Bill's way of handling log scale */
626
+ if(log_vals)
627
+ return pick_major_ticks_positions_Bill(fmkr,p,
628
+ axis_min, axis_max,
629
+ num_locations, tick_min,
630
+ tick_gap, length, log_vals,
631
+ tick, ierr);
632
+ /* The factor by which you need to divide to get
633
+ the tick_min within [1,10[ */
634
+ double factor = pow(10, floor(log10(tick_min)));
635
+ double norm_tick_min = tick_min/factor;
636
+ int i;
637
+
638
+ /* We get the one just above tick_min */
639
+ for(i = 0; i < nb_natural_distances; i++)
640
+ if(natural_distances[i] >= norm_tick_min)
641
+ break;
642
+
643
+ *tick = natural_distances[i] * factor;
644
+ double first_tick = ceil(axis_min /(*tick)) * (*tick);
645
+ double last_tick = floor(axis_max /(*tick)) * (*tick);
646
+
647
+ *num_locations = (int)((last_tick - first_tick)/(*tick) + 1);
648
+
649
+ double *majors = ALLOC_N_double(*num_locations);
650
+ for (i = 0; i < *num_locations; i++)
651
+ majors[i] = first_tick + (*tick) * i;
652
+
653
+ return majors;
654
+ }
655
+
656
+
572
657
  /* This functions fills the majors attribute of the PlotAxis object
573
658
  with the position of major ticks
574
659
  */
@@ -588,10 +673,22 @@ static void compute_major_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
588
673
  double height = ((s->vertical)? p->default_text_height_dy : p->default_text_height_dx);
589
674
  double tick_min = s->min_between_major_ticks * height;
590
675
  double tick_gap = 10.0 * height;
591
- Pick_Major_Tick_Interval(fmkr, p, tick_min, tick_gap, s->length, s->log_vals, &s->interval, ierr);
592
- if (*ierr != 0) return;
593
- s->majors = Pick_Locations_for_Major_Ticks(s->interval, s->axis_min, s->axis_max, &s->nmajors, ierr);
594
- if (*ierr != 0) return;
676
+
677
+ s->majors = (s->vincent_or_bill ?
678
+ pick_major_ticks_positions_Vincent(fmkr, p,
679
+ s->axis_min,
680
+ s->axis_max, &s->nmajors,
681
+ tick_min, tick_gap,
682
+ s->length, s->log_vals,
683
+ &s->interval, ierr) :
684
+ pick_major_ticks_positions_Bill(fmkr, p, s->axis_min,
685
+ s->axis_max, &s->nmajors,
686
+ tick_min, tick_gap,
687
+ s->length, s->log_vals,
688
+ &s->interval, ierr));
689
+
690
+ if(*ierr || ! s->majors)
691
+ return;
595
692
  s->free_majors = true;
596
693
  }
597
694
  }
@@ -626,51 +723,53 @@ static void draw_major_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
626
723
  if (did_line) axis_stroke(fmkr,p, ierr);
627
724
  }
628
725
 
629
- static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
726
+ static double log_subintervals[8] = {
727
+ 0.301030, 0.477121, 0.602060, 0.698970,
728
+ 0.778151, 0.845098, 0.903090, 0.954243 };
729
+
730
+
731
+ /* A function that returns a double array *TO BE FREED* containing
732
+ the position of the minor ticks for the given axis.
733
+
734
+ The number of ticks is stored in the cnt (long) parameter.
735
+
736
+ Returns NULL in case of problems
737
+ */
738
+ static double * get_minor_ticks_location(OBJ_PTR fmkr, FM *p,
739
+ PlotAxis *s, long * cnt)
630
740
  {
741
+ double * target = NULL;
742
+ int ierr = 0;
743
+ *cnt = 0;
744
+
745
+ /* First, pick up the number of ticks to be used */
631
746
  if (s->number_of_minor_intervals <= 0) {
632
747
  if (s->log_vals) {
633
748
  double interval = s->majors[1] - s->majors[0];
634
749
  s->number_of_minor_intervals = (abs(interval) != 1.0 || s->nmajors > 10)? 1 : 9;
635
750
  } else {
636
- s->number_of_minor_intervals = Pick_Number_of_Minor_Intervals(s->interval, ierr);
637
- if (*ierr != 0) return;
751
+ s->number_of_minor_intervals = Pick_Number_of_Minor_Intervals(s->interval, &ierr);
752
+ if (ierr != 0) return NULL;
638
753
  }
639
754
  }
640
755
  int i, j, nsub = s->number_of_minor_intervals;
641
- double inside=0.0, outside=0.0, length;
642
- bool did_line = false;
643
- double log_subintervals[8];
644
- log_subintervals[0] = 0.301030;
645
- log_subintervals[1] = 0.477121;
646
- log_subintervals[2] = 0.602060;
647
- log_subintervals[3] = 0.698970;
648
- log_subintervals[4] = 0.778151;
649
- log_subintervals[5] = 0.845098;
650
- log_subintervals[6] = 0.903090;
651
- log_subintervals[7] = 0.954243;
756
+
652
757
  if (s->log_vals && nsub > 9) nsub = 9;
653
- length = s->minor_tick_length * ((s->vertical)? p->default_text_height_dx : p->default_text_height_dy);
654
- if (s->ticks_inside) inside = length;
655
- if (s->ticks_outside) outside = -length;
656
- if (s->top_or_right) { inside = -inside; outside = -outside; }
657
- if (s->line_width != s->minor_tick_width) {
658
- c_line_width_set(fmkr, p, s->line_width = s->minor_tick_width, ierr);
659
- if (*ierr != 0) return;
660
- }
758
+
759
+ /* First case: user-supplied position of minor ticks */
661
760
  if (s->locations_for_minor_ticks != OBJ_NIL) {
662
- long cnt;
663
- double *locs = Vector_Data_for_Read(s->locations_for_minor_ticks, &cnt, ierr);
664
- if (*ierr != 0) return;
665
- for (i=0; i < cnt; i++) {
666
- if (s->vertical)
667
- figure_join(fmkr, p, s->x0+inside, locs[i], s->x0+outside, locs[i], ierr);
668
- else
669
- figure_join(fmkr, p, locs[i], s->y0+inside, locs[i], s->y0+outside, ierr);
670
- did_line = true;
671
- if (*ierr != 0) return;
672
- }
761
+ double *locs = Vector_Data_for_Read(s->locations_for_minor_ticks,
762
+ cnt, &ierr);
763
+ if (ierr != 0)
764
+ return NULL;
765
+ target = ALLOC_N_double(*cnt);
766
+ long i;
767
+ for(i = 0; i < *cnt; i++)
768
+ target[i] = locs[i];
769
+ return target;
673
770
  } else {
771
+ /* We allocate sligthly more space than should be necessary: */
772
+ target = ALLOC_N_double(nsub * (s->nmajors + 1));
674
773
  for (i=0; i <= s->nmajors; i++) {
675
774
  double loc = (i==0)? s->majors[0] - s->interval : s->majors[i-1];
676
775
  double next_loc = (i==s->nmajors)? loc + s->interval : s->majors[i];
@@ -680,18 +779,53 @@ static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
680
779
  double subloc = loc + ((!s->log_vals) ? (j * subinterval) : log_subintervals[j-1]);
681
780
  if (subloc >= next_loc) break;
682
781
  if (subloc <= s->axis_min || subloc >= s->axis_max) continue;
683
- if (s->vertical) {
684
- figure_join(fmkr, p, s->x0+inside, subloc, s->x0+outside, subloc, ierr);
685
- }
686
- else {
687
- figure_join(fmkr, p, subloc, s->y0+inside, subloc, s->y0+outside, ierr);
688
- }
689
- did_line = true;
690
- if (*ierr != 0) return;
782
+
783
+ /* We add one */
784
+ target[*cnt] = subloc;
785
+ (*cnt)++;
691
786
  }
692
787
  }
788
+ return target;
693
789
  }
694
- if (did_line) axis_stroke(fmkr,p, ierr);
790
+ }
791
+
792
+
793
+ static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
794
+ {
795
+ long number;
796
+ double * locs = get_minor_ticks_location(fmkr, p, s, &number);
797
+ if(! locs) {
798
+ *ierr = 1;
799
+ return ;
800
+ }
801
+ long i;
802
+ double inside=0.0, outside=0.0, length;
803
+ bool did_line = false;
804
+
805
+ /* Initialization of the various lengths */
806
+ length = s->minor_tick_length * ((s->vertical)? p->default_text_height_dx : p->default_text_height_dy);
807
+ if (s->ticks_inside) inside = length;
808
+ if (s->ticks_outside) outside = -length;
809
+ if (s->top_or_right) { inside = -inside; outside = -outside; }
810
+ if (s->line_width != s->minor_tick_width) {
811
+ c_line_width_set(fmkr, p, s->line_width = s->minor_tick_width, ierr);
812
+ if (*ierr != 0) return;
813
+ }
814
+
815
+ /* Now, we stroke the ticks */
816
+ for(i = 0; i < number; i++) {
817
+ if (s->vertical)
818
+ figure_join(fmkr, p, s->x0+inside, locs[i],
819
+ s->x0+outside, locs[i], ierr);
820
+ else
821
+ figure_join(fmkr, p, locs[i], s->y0+inside, locs[i],
822
+ s->y0+outside, ierr);
823
+ did_line = true;
824
+ }
825
+ /* And we free the array returned by get_minor_ticks_location */
826
+ free(locs);
827
+ if (did_line)
828
+ axis_stroke(fmkr,p, ierr);
695
829
  }
696
830
 
697
831
  static void show_numeric_label(OBJ_PTR fmkr, FM *p, PlotAxis *s,
@@ -762,7 +896,6 @@ static void free_allocated_memory(PlotAxis *s)
762
896
  }
763
897
 
764
898
  static void c_show_side(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr) {
765
- int i;
766
899
  if (s->type == AXIS_HIDDEN) return;
767
900
  Start_Axis_Standard_State(fmkr, p,
768
901
  s->stroke_color_R, s->stroke_color_G, s->stroke_color_B,
@@ -1088,6 +1221,15 @@ OBJ_PTR c_axis_get_information(OBJ_PTR fmkr, FM *p, OBJ_PTR axis_spec,
1088
1221
  compute_major_ticks(fmkr, p, &axis, ierr);
1089
1222
  Hash_Set_Obj(hash, "major", Vector_New(axis.nmajors, axis.majors));
1090
1223
 
1224
+ /* Then, minor ticks positions */
1225
+ double * minor;
1226
+ long count;
1227
+ minor = get_minor_ticks_location(fmkr, p, &axis, &count);
1228
+ if(minor) {
1229
+ Hash_Set_Obj(hash, "minor", Vector_New(count, minor));
1230
+ free(minor);
1231
+ }
1232
+
1091
1233
  /* Then, labels */
1092
1234
  ar = Array_New(axis.nmajors);
1093
1235
  axis.labels = Get_Labels(fmkr, p, &axis, ierr);