tioga 1.6 → 1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Tioga_README +35 -10
  2. data/split/Dvector/dvector.c +264 -22
  3. data/split/Dvector/lib/Dvector_extras.rb +30 -2
  4. data/split/Flate/extconf.rb +1 -1
  5. data/split/Function/function.c +112 -2
  6. data/split/Tioga/figures.c +76 -77
  7. data/split/Tioga/figures.h +375 -490
  8. data/split/Tioga/generic.c +254 -0
  9. data/split/Tioga/generic.h +236 -0
  10. data/split/Tioga/init.c +434 -320
  11. data/split/Tioga/lib/Creating_Paths.rb +11 -1
  12. data/split/Tioga/lib/FigMkr.rb +263 -65
  13. data/split/Tioga/lib/Legends.rb +4 -2
  14. data/split/Tioga/lib/Markers.rb +3 -2
  15. data/split/Tioga/lib/Special_Paths.rb +22 -23
  16. data/split/Tioga/lib/TeX_Text.rb +79 -1
  17. data/split/Tioga/lib/TexPreamble.rb +14 -0
  18. data/split/Tioga/lib/Utils.rb +5 -1
  19. data/split/Tioga/pdfs.h +7 -45
  20. data/split/Tioga/{axes.c → shared/axes.c} +210 -197
  21. data/split/Tioga/{makers.c → shared/makers.c} +442 -211
  22. data/split/Tioga/{pdf_font_dicts.c → shared/pdf_font_dicts.c} +0 -0
  23. data/split/Tioga/shared/pdfcolor.c +628 -0
  24. data/split/Tioga/shared/pdfcoords.c +443 -0
  25. data/split/Tioga/{pdffile.c → shared/pdffile.c} +56 -52
  26. data/split/Tioga/{pdfimage.c → shared/pdfimage.c} +103 -211
  27. data/split/Tioga/shared/pdfpath.c +766 -0
  28. data/split/Tioga/{pdftext.c → shared/pdftext.c} +121 -99
  29. data/split/Tioga/shared/texout.c +524 -0
  30. data/split/Tioga/wrappers.c +489 -0
  31. data/split/Tioga/wrappers.h +259 -0
  32. data/split/extconf.rb +4 -0
  33. data/split/mkmf2.rb +12 -1
  34. data/tests/benchmark_dvector_reads.rb +112 -0
  35. data/tests/tc_Dvector.rb +35 -3
  36. data/tests/tc_Function.rb +32 -0
  37. metadata +65 -52
  38. data/split/Tioga/pdfcolor.c +0 -486
  39. data/split/Tioga/pdfcoords.c +0 -523
  40. data/split/Tioga/pdfpath.c +0 -913
  41. data/split/Tioga/texout.c +0 -380
@@ -0,0 +1,628 @@
1
+ /* pdfcolor.c */
2
+ /*
3
+ Copyright (C) 2005 Bill Paxton
4
+
5
+ This file is part of Tioga.
6
+
7
+ Tioga is free software; you can redistribute it and/or modify
8
+ it under the terms of the GNU General Library Public License as published
9
+ by the Free Software Foundation; either version 2 of the License, or
10
+ (at your option) any later version.
11
+
12
+ Tioga is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU Library General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Library General Public License
18
+ along with Tioga; if not, write to the Free Software
19
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+ */
21
+
22
+ #include "figures.h"
23
+ #include "pdfs.h"
24
+
25
+ /* functions */
26
+
27
+ void Free_Functions()
28
+ {
29
+ Function_Info *fo;
30
+ while (functions_list != NULL) {
31
+ fo = functions_list;
32
+ functions_list = fo->next;
33
+ if (fo->lookup != NULL) free(fo->lookup);
34
+ free(fo);
35
+ }
36
+ }
37
+
38
+ static void Write_Sampled_Function(Function_Info *fo, int *ierr)
39
+ {
40
+ fprintf(OF, "%i 0 obj << /FunctionType 0\n", fo->obj_num);
41
+ fprintf(OF, "\t/Domain [0 1]\n");
42
+ fprintf(OF, "\t/Range [0 1 0 1 0 1]\n");
43
+ fprintf(OF, "\t/Size [%i]\n", fo->hival + 1);
44
+ fprintf(OF, "\t/BitsPerSample 8\n");
45
+ fprintf(OF, "\t/Order 1\n");
46
+ fprintf(OF, "\t/Length %i\n\t>>\nstream\n", fo->lookup_len);
47
+ if (fwrite(fo->lookup, 1, fo->lookup_len, OF) < fo->lookup_len) {
48
+ RAISE_ERROR("Error writing function sample data", ierr); return; }
49
+ fprintf(OF, "\nendstream\nendobj\n");
50
+ }
51
+
52
+ void Write_Functions(int *ierr)
53
+ {
54
+ Function_Info *fo;
55
+ for (fo = functions_list; fo != NULL; fo = fo->next) {
56
+ Record_Object_Offset(fo->obj_num);
57
+ Write_Sampled_Function(fo, ierr);
58
+ }
59
+ }
60
+
61
+ static int create_function(int hival, int lookup_len, unsigned char *lookup)
62
+ {
63
+ Function_Info *fo = (Function_Info *)calloc(1,sizeof(Function_Info));
64
+ fo->next = functions_list;
65
+ functions_list = fo;
66
+ fo->lookup = ALLOC_N_unsigned_char(lookup_len);
67
+ memcpy(fo->lookup, lookup, lookup_len);
68
+ fo->lookup_len = lookup_len;
69
+ fo->hival = hival;
70
+ fo->obj_num = next_available_object_number++;
71
+ return fo->obj_num;
72
+ }
73
+
74
+ /* Opacity */
75
+
76
+ void Free_Stroke_Opacities(void)
77
+ {
78
+ Stroke_Opacity_State *p;
79
+ while (stroke_opacities != NULL) {
80
+ p = stroke_opacities; stroke_opacities = p->next; free(p);
81
+ }
82
+ }
83
+
84
+ static int Get_Stroke_Opacity_XGS(double stroke_opacity)
85
+ {
86
+ Stroke_Opacity_State *p;
87
+ for (p = stroke_opacities; p != NULL; p = p->next) {
88
+ if (p->stroke_opacity == stroke_opacity) return p->gs_num;
89
+ }
90
+ p = (Stroke_Opacity_State *)calloc(1,sizeof(Stroke_Opacity_State));
91
+ p->stroke_opacity = stroke_opacity;
92
+ p->gs_num = next_available_gs_number++;
93
+ p->obj_num = next_available_object_number++;
94
+ p->next = stroke_opacities;
95
+ stroke_opacities = p;
96
+ return p->gs_num;
97
+ }
98
+
99
+ void c_stroke_opacity_set(OBJ_PTR fmkr, FM *p, double stroke_opacity, int *ierr)
100
+ { // /GSi gs for ExtGState obj with /CS set to stroke opacity val
101
+ if (constructing_path) {
102
+ RAISE_ERROR("Sorry: must not be constructing a path when change stroke opacity", ierr); return; }
103
+ if (stroke_opacity == p->stroke_opacity) return;
104
+ int gs_num = Get_Stroke_Opacity_XGS(stroke_opacity);
105
+ fprintf(TF, "/GS%i gs\n", gs_num);
106
+ p->stroke_opacity = stroke_opacity;
107
+ }
108
+
109
+ void Free_Fill_Opacities(void)
110
+ {
111
+ Fill_Opacity_State *p;
112
+ while (fill_opacities != NULL) {
113
+ p = fill_opacities; fill_opacities = p->next; free(p);
114
+ }
115
+ }
116
+
117
+ static int Get_Fill_Opacity_XGS(double fill_opacity)
118
+ {
119
+ Fill_Opacity_State *p;
120
+ for (p = fill_opacities; p != NULL; p = p->next) {
121
+ if (p->fill_opacity == fill_opacity) return p->gs_num;
122
+ }
123
+ p = (Fill_Opacity_State *)calloc(1,sizeof(Fill_Opacity_State));
124
+ p->fill_opacity = fill_opacity;
125
+ p->gs_num = next_available_gs_number++;
126
+ p->obj_num = next_available_object_number++;
127
+ p->next = fill_opacities;
128
+ fill_opacities = p;
129
+ return p->gs_num;
130
+ }
131
+
132
+ void c_fill_opacity_set(OBJ_PTR fmkr, FM *p, double fill_opacity, int *ierr)
133
+ { // /GSi gs for ExtGState obj with /cs set to fill opacity val
134
+ if (constructing_path) {
135
+ RAISE_ERROR("Sorry: must not be constructing a path when change fill opacity", ierr); return; }
136
+ if (fill_opacity == p->fill_opacity) return;
137
+ int gs_num = Get_Fill_Opacity_XGS(fill_opacity);
138
+ fprintf(TF, "/GS%i gs\n", gs_num);
139
+ p->fill_opacity = fill_opacity;
140
+ }
141
+
142
+ void Write_Stroke_Opacity_Objects(void)
143
+ {
144
+ Stroke_Opacity_State *p;
145
+ for (p = stroke_opacities; p != NULL; p = p->next) {
146
+ Record_Object_Offset(p->obj_num);
147
+ fprintf(OF, "%2i 0 obj << /Type /ExtGState /CA %g >> endobj\n", p->obj_num, p->stroke_opacity);
148
+ }
149
+ }
150
+
151
+ void Write_Fill_Opacity_Objects(void)
152
+ {
153
+ Fill_Opacity_State *p;
154
+ for (p = fill_opacities; p != NULL; p = p->next) {
155
+ Record_Object_Offset(p->obj_num);
156
+ fprintf(OF, "%2i 0 obj << /Type /ExtGState /ca %g >> endobj\n", p->obj_num, p->fill_opacity);
157
+ }
158
+ }
159
+
160
+ /* Shading */
161
+
162
+ void Free_Shadings()
163
+ {
164
+ Shading_Info *so;
165
+ while (shades_list != NULL) {
166
+ so = shades_list;
167
+ shades_list = so->next;
168
+ free(so);
169
+ }
170
+ }
171
+
172
+ void Write_Shadings(void)
173
+ {
174
+ Shading_Info *so;
175
+ for (so = shades_list; so != NULL; so = so->next) {
176
+ Record_Object_Offset(so->obj_num);
177
+ fprintf(OF, "%i 0 obj <<\n", so->obj_num);
178
+ if (so->axial) {
179
+ fprintf(OF, "\t/ShadingType 2\n\t/Coords [%0.2f %0.2f %0.2f %0.2f]\n",
180
+ so->x0, so->y0, so->x1, so->y1);
181
+ } else {
182
+ fprintf(OF, "\t/ShadingType 3\n\t/Coords [%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f]\n",
183
+ so->x0, so->y0, so->r0, so->x1, so->y1, so->r1);
184
+ }
185
+ if (so->extend_start || so->extend_end) fprintf(OF, "\t/Extend [ %s %s ]\n",
186
+ (so->extend_start)? "true" : "false", (so->extend_end)? "true" : "false");
187
+ fprintf(OF, "\t/ColorSpace /DeviceRGB\n");
188
+ fprintf(OF, "\t/Function %i 0 R\n", so->function);
189
+ fprintf(OF, ">> endobj\n");
190
+ }
191
+ }
192
+
193
+
194
+ static void c_axial_shading(FM *p, double x0, double y0, double x1, double y1,
195
+ int hival, int lookup_len, unsigned char *lookup, bool extend_start, bool extend_end)
196
+ {
197
+ Shading_Info *so = (Shading_Info *)calloc(1,sizeof(Shading_Info));
198
+ so->next = shades_list;
199
+ shades_list = so;
200
+ so->shade_num = next_available_shade_number++;
201
+ so->obj_num = next_available_object_number++;
202
+ so->function = create_function(hival, lookup_len, lookup);
203
+ so->axial = true;
204
+ so->x0 = x0;
205
+ so->y0 = y0;
206
+ so->x1 = x1;
207
+ so->y1 = y1;
208
+ so->extend_start = extend_start;
209
+ so->extend_end = extend_end;
210
+ fprintf(TF, "/Shade%i sh\n", so->shade_num);
211
+ }
212
+
213
+ void c_private_axial_shading(OBJ_PTR fmkr, FM *p, double x0, double y0, double x1, double y1,
214
+ OBJ_PTR colormap, bool extend_start, bool extend_end, int *ierr)
215
+ {
216
+ int len = Array_Len(colormap,ierr);
217
+ if (*ierr != 0) return;
218
+ if (len != 2) {
219
+ RAISE_ERROR("Sorry: colormap must be array [hivalue, lookup]", ierr); return; }
220
+ OBJ_PTR hival = Array_Entry(colormap,0,ierr);
221
+ OBJ_PTR lookup = Array_Entry(colormap,1,ierr);
222
+ int hi_value = Number_to_int(hival,ierr);
223
+ int lookup_len = String_Len(lookup,ierr);
224
+ unsigned char *lookup_ptr = (unsigned char *)(String_Ptr(lookup,ierr));
225
+ if (*ierr != 0) return;
226
+ c_axial_shading(p, convert_figure_to_output_x(p,x0), convert_figure_to_output_y(p,y0),
227
+ convert_figure_to_output_x(p,x1), convert_figure_to_output_y(p,y1),
228
+ hi_value, lookup_len, lookup_ptr, extend_start, extend_end);
229
+ }
230
+
231
+ static void c_radial_shading(FM *p, double x0, double y0, double r0, double x1, double y1, double r1,
232
+ int hival, int lookup_len, unsigned char *lookup,
233
+ double a, double b, double c, double d, double e, double f, bool extend_start, bool extend_end)
234
+ {
235
+ Shading_Info *so = (Shading_Info *)calloc(1,sizeof(Shading_Info));
236
+ so->next = shades_list;
237
+ shades_list = so;
238
+ so->shade_num = next_available_shade_number++;
239
+ so->obj_num = next_available_object_number++;
240
+ so->function = create_function(hival, lookup_len, lookup);
241
+ so->axial = false;
242
+ so->x0 = x0;
243
+ so->y0 = y0;
244
+ so->r0 = r0;
245
+ so->x1 = x1;
246
+ so->y1 = y1;
247
+ so->r1 = r1;
248
+ so->extend_start = extend_start;
249
+ so->extend_end = extend_end;
250
+ if (a != 1.0 || b != 0.0 || c != 0.0 || d != 1.0 || e != 0 || f != 0) {
251
+ fprintf(TF, "q %0.2f %0.2f %0.2f %0.2f %0.2f %0.2f cm /Shade%i sh Q\n",
252
+ a, b, c, d, e, f, so->shade_num);
253
+ } else {
254
+ fprintf(TF, "/Shade%i sh\n", so->shade_num);
255
+ }
256
+ }
257
+
258
+
259
+ void c_private_radial_shading(OBJ_PTR fmkr, FM *p,
260
+ double x0, double y0, double r0,
261
+ double x1, double y1, double r1, OBJ_PTR colormap,
262
+ double a, double b, double c, double d, bool extend_start, bool extend_end, int *ierr)
263
+ {
264
+ int len = Array_Len(colormap, ierr);
265
+ if (*ierr != 0) return;
266
+ if (len != 2) {
267
+ RAISE_ERROR("Sorry: colormap must be array [hivalue, lookup]", ierr); return; }
268
+ OBJ_PTR hival = Array_Entry(colormap, 0, ierr);
269
+ OBJ_PTR lookup = Array_Entry(colormap, 1, ierr);
270
+ int hi_value = Number_to_int(hival,ierr);
271
+ int lookup_len = String_Len(lookup,ierr);
272
+ unsigned char *lookup_ptr = (unsigned char *)(String_Ptr(lookup,ierr));
273
+ if (*ierr != 0) return;
274
+ c_radial_shading(p, x0, y0, r0, x1, y1, r1,
275
+ hi_value, lookup_len, lookup_ptr,
276
+ convert_figure_to_output_dx(p,a), convert_figure_to_output_dy(p,b),
277
+ convert_figure_to_output_dx(p,c), convert_figure_to_output_dy(p,d),
278
+ convert_figure_to_output_x(p,0.0), convert_figure_to_output_y(p,0.0),
279
+ extend_start, extend_end);
280
+ }
281
+
282
+ /* Colormaps
283
+ */
284
+
285
+ static double clr_value(double n1, double n2, double hue) // from plplot plctrl.c
286
+ {
287
+ double val;
288
+ while (hue >= 360.) hue -= 360.;
289
+ while (hue < 0.) hue += 360.;
290
+ if (hue < 60.) val = n1 + (n2 - n1) * hue / 60.;
291
+ else if (hue < 180.) val = n2;
292
+ else if (hue < 240.) val = n1 + (n2 - n1) * (240. - hue) / 60.;
293
+ else val = n1;
294
+ return (val);
295
+ }
296
+
297
+ static void convert_hls_to_rgb(double h, double l, double s, double *p_r, double *p_g, double *p_b) // from plplot plctrl.c
298
+ {
299
+ double m1, m2;
300
+ if (l <= .5) m2 = l * (s + 1.);
301
+ else m2 = l + s - l * s;
302
+ m1 = 2 * l - m2;
303
+ *p_r = clr_value(m1, m2, h + 120.);
304
+ *p_g = clr_value(m1, m2, h);
305
+ *p_b = clr_value(m1, m2, h - 120.);
306
+ }
307
+
308
+ static void convert_rgb_to_hls(double r, double g, double b, double *p_h, double *p_l, double *p_s) // from plplot plctrl.c
309
+ {
310
+ double h, l, s, d, rc, gc, bc, rgb_min, rgb_max;
311
+ rgb_min = MIN( r, MIN( g, b ));
312
+ rgb_max = MAX( r, MAX( g, b ));
313
+ l = (rgb_min+rgb_max) / 2.0;
314
+ if (rgb_min == rgb_max) s = h = 0;
315
+ else {
316
+ d = rgb_max - rgb_min;
317
+ if (l < 0.5) s = 0.5 * d / l;
318
+ else s = 0.5* d / (1.-l);
319
+ rc = (rgb_max-r) / d;
320
+ gc = (rgb_max-g) / d;
321
+ bc = (rgb_max-b) / d;
322
+ if (r == rgb_max) h = bc-gc;
323
+ else if (g == rgb_max) h = rc-bc+2;
324
+ else h = gc-rc-2;
325
+ h = h*60;
326
+ if (h < 0) h = h+360;
327
+ else if (h >= 360) h = h-360;
328
+ }
329
+ *p_h = h;
330
+ *p_l = l;
331
+ *p_s = s;
332
+ }
333
+
334
+ static double linear_interpolate(int num_pts, double *xs, double *ys, double x)
335
+ {
336
+ int i;
337
+ if (num_pts == 1) return ys[0];
338
+ for (i = 0; i < num_pts; i++) {
339
+ if (xs[i] <= x && x < xs[i+1]) {
340
+ return ys[i] + (ys[i+1]-ys[i])*(x-xs[i])/(xs[i+1]-xs[i]);
341
+ }
342
+ }
343
+ return ys[num_pts-1];
344
+ }
345
+
346
+ static OBJ_PTR c_create_colormap(FM *p, bool rgb_flag, int length,
347
+ int num_pts, double *ps, double *c1s, double *c2s, double *c3s, int *ierr)
348
+ {
349
+ int i;
350
+ if (ps[0] != 0.0 || ps[num_pts-1] != 1.0) {
351
+ RAISE_ERROR("Sorry: first control point for create colormap must be at 0.0 and last must be at 1.0", ierr); RETURN_NIL; }
352
+ for (i = 1; i < num_pts; i++) {
353
+ if (ps[i-1] > ps[i]) {
354
+ RAISE_ERROR("Sorry: control points for create colormap must be increasing from 0 to 1", ierr); RETURN_NIL; }
355
+ }
356
+ int j, buff_len = length * 3, hival = length-1;
357
+ unsigned char *buff;
358
+ buff = ALLOC_N_unsigned_char(buff_len);
359
+ for (j = 0, i = 0; j < length; j++) {
360
+ double x = j; x /= (length-1);
361
+ double c1, c2, c3, r, g, b;
362
+ c1 = linear_interpolate(num_pts, ps, c1s, x);
363
+ c2 = linear_interpolate(num_pts, ps, c2s, x);
364
+ c3 = linear_interpolate(num_pts, ps, c3s, x);
365
+ if (rgb_flag) { r = c1; g = c2; b = c3; }
366
+ else convert_hls_to_rgb(c1, c2, c3, &r, &g, &b);
367
+ buff[i++] = ROUND(hival * r);
368
+ buff[i++] = ROUND(hival * g);
369
+ buff[i++] = ROUND(hival * b);
370
+ }
371
+ OBJ_PTR lookup = String_New((char *)buff, buff_len);
372
+ free(buff);
373
+ OBJ_PTR result = Array_New(2);
374
+ Array_Store(result, 0, Integer_New(hival), ierr);
375
+ Array_Store(result, 1, lookup, ierr);
376
+ if (*ierr != 0) RETURN_NIL;
377
+ return result;
378
+ }
379
+
380
+ OBJ_PTR c_private_create_colormap(OBJ_PTR fmkr, FM *p, bool rgb, int length,
381
+ OBJ_PTR Ps, OBJ_PTR C1s, OBJ_PTR C2s, OBJ_PTR C3s, int *ierr)
382
+ {
383
+ /*
384
+ create mappings from 'position' (0 to 1) to color (in HLS or RGB color spaces)
385
+ the length parameter determines the number of entries in the color map (any integer between 2 and 256).
386
+ for rgb, the colors are given as (red, green, blue) intensities from 0.0 to 1.0
387
+ for hls, the colors are given as (hue, lightness, saturation)
388
+ lightness and saturation given as values from 0.0 to 1.0
389
+ hue given as degrees (0 to 360) around the color wheel from red->green->blue->red
390
+ Ps are the locations in (0 to 1) for the control points -- in increasing order
391
+ must have Ps[0] == 0.0 and Ps[num_ps-1] == 1.0
392
+ */
393
+ long p_len, c1_len, c2_len, c3_len;
394
+ double *p_ptr = Vector_Data_for_Read(Ps, &p_len, ierr);
395
+ if (*ierr != 0) return;
396
+ double *c1_ptr = Vector_Data_for_Read(C1s, &c1_len, ierr);
397
+ if (*ierr != 0) return;
398
+ double *c2_ptr = Vector_Data_for_Read(C2s, &c2_len, ierr);
399
+ if (*ierr != 0) return;
400
+ double *c3_ptr = Vector_Data_for_Read(C3s, &c3_len, ierr);
401
+ if (*ierr != 0) return;
402
+ if (p_len < 2 || p_len != c1_len || p_len != c2_len || p_len != c3_len) {
403
+ RAISE_ERROR("Sorry: vectors for create colormap must all be os same length (with at least 2 entries)", ierr);
404
+ RETURN_NIL;
405
+ }
406
+ return c_create_colormap(p, rgb, length, p_len, p_ptr, c1_ptr, c2_ptr, c3_ptr, ierr);
407
+ }
408
+
409
+ OBJ_PTR c_get_color_from_colormap(OBJ_PTR fmkr, FM *p, OBJ_PTR color_map, double x, int *ierr)
410
+ { /* x is from 0 to 1. this returns a vector for the RGB color from the given colormap */
411
+ unsigned char *buff = (unsigned char *)(String_Ptr(color_map,ierr)), r, g, b, i;
412
+ int len = String_Len(color_map,ierr);
413
+ if (*ierr != 0) RETURN_NIL;
414
+ if (len % 3 != 0) {
415
+ RAISE_ERROR("Sorry: color_map length must be a multiple of 3 (for R G B components)", ierr);
416
+ RETURN_NIL;
417
+ }
418
+ i = 3 * ROUND(x * ((len/3)-1));
419
+ r = buff[i]; g = buff[i+1]; b = buff[i+2];
420
+ OBJ_PTR result = Array_New(3);
421
+ Array_Store(result, 0, Float_New(r/255.0), ierr);
422
+ Array_Store(result, 1, Float_New(g/255.0), ierr);
423
+ Array_Store(result, 2, Float_New(b/255.0), ierr);
424
+ if (*ierr != 0) RETURN_NIL;
425
+ return result;
426
+ }
427
+
428
+ OBJ_PTR c_convert_to_colormap(OBJ_PTR fmkr, FM* p, OBJ_PTR Rs, OBJ_PTR Gs, OBJ_PTR Bs, int *ierr)
429
+ {
430
+ /* this creates an arbitrary mapping from positions to colors given as (r,g,b) triples */
431
+ /* the colormap size is set to the length of the vectors */
432
+ /* the Rs, Gs, and Bs are VALUEs from 0 to 1 representing the intensity of the color component */
433
+ long r_len, g_len, b_len;
434
+ double *r_ptr = Vector_Data_for_Read(Rs, &r_len, ierr);
435
+ if (*ierr != 0) return;
436
+ double *g_ptr = Vector_Data_for_Read(Gs, &g_len, ierr);
437
+ if (*ierr != 0) return;
438
+ double *b_ptr = Vector_Data_for_Read(Bs, &b_len, ierr);
439
+ if (*ierr != 0) return;
440
+ if (r_len <= 0 || r_len != g_len || b_len != g_len) {
441
+ RAISE_ERROR("Sorry: vectors for convert_to_colormap must all be of same length", ierr);
442
+ RETURN_NIL;
443
+ }
444
+ int i, j, buff_len = r_len * 3;
445
+ unsigned char *buff;
446
+ buff = ALLOC_N_unsigned_char(buff_len);
447
+ for (i = 0, j = 0; j < r_len; j++) {
448
+ buff[i++] = ROUND(r_ptr[j]*255);
449
+ buff[i++] = ROUND(g_ptr[j]*255);
450
+ buff[i++] = ROUND(b_ptr[j]*255);
451
+ }
452
+ OBJ_PTR lookup = String_New((char *)buff, buff_len);
453
+ free(buff);
454
+ OBJ_PTR result = Array_New(2);
455
+ Array_Store(result, 0, Integer_New(r_len-1), ierr);
456
+ Array_Store(result, 1, lookup, ierr);
457
+ if (*ierr != 0) RETURN_NIL;
458
+ return result;
459
+ }
460
+
461
+ static void Unpack_HLS(OBJ_PTR hls, double *hp, double *lp, double *sp, int *ierr)
462
+ {
463
+ int len = Array_Len(hls,ierr);
464
+ if (*ierr != 0) return;
465
+ if (len != 3) {
466
+ RAISE_ERROR("Sorry: invalid hls array: must have 3 entries", ierr); return; }
467
+ OBJ_PTR entry = Array_Entry(hls, 0, ierr); if (*ierr != 0) return;
468
+ double h = Number_to_double(entry, ierr); if (*ierr != 0) return;
469
+ entry = Array_Entry(hls, 1, ierr); if (*ierr != 0) return;
470
+ double l = Number_to_double(entry, ierr); if (*ierr != 0) return;
471
+ entry = Array_Entry(hls, 2, ierr); if (*ierr != 0) return;
472
+ double s = Number_to_double(entry, ierr); if (*ierr != 0) return;
473
+ if (l < 0.0 || l > 1.0) { RAISE_ERROR_g("Sorry: invalid lightness (%g) for hls: must be between 0 and 1", l, ierr); return; }
474
+ if (s < 0.0 || s > 1.0) { RAISE_ERROR_g("Sorry: invalid saturation (%g) for hls: must be between 0 and 1", s, ierr); return; }
475
+ *hp = h; *lp = l; *sp = s;
476
+ }
477
+
478
+ OBJ_PTR c_hls_to_rgb(OBJ_PTR fmkr, FM *p, OBJ_PTR hls_vec, int *ierr)
479
+ {
480
+ double h, l, s, r, g, b;
481
+ Unpack_HLS(hls_vec, &h, &l, &s, ierr);
482
+ if (*ierr != 0) RETURN_NIL;
483
+ convert_hls_to_rgb(h, l, s, &r, &g, &b);
484
+ OBJ_PTR result = Array_New(3);
485
+ Array_Store(result, 0, Float_New(r), ierr);
486
+ Array_Store(result, 1, Float_New(g), ierr);
487
+ Array_Store(result, 2, Float_New(b), ierr);
488
+ return result;
489
+ }
490
+
491
+ OBJ_PTR c_rgb_to_hls(OBJ_PTR fmkr, FM *p, OBJ_PTR rgb_vec, int *ierr)
492
+ {
493
+ /* hue is given as an angle from 0 to 360 around the color wheel.
494
+ 0, 60, 120, 180, 240, and 300 are respectively red, yellow, green, cyan, blue, and magenta. */
495
+ /* lightness and saturation are given as numbers from 0 to 1 */
496
+ double h, l, s, r, g, b;
497
+ Unpack_RGB(rgb_vec, &r, &g, &b, ierr);
498
+ if (*ierr != 0) RETURN_NIL;
499
+ convert_rgb_to_hls(r, g, b, &h, &l, &s);
500
+ OBJ_PTR result = Array_New(3);
501
+ Array_Store(result, 0, Float_New(h), ierr);
502
+ Array_Store(result, 1, Float_New(l), ierr);
503
+ Array_Store(result, 2, Float_New(s), ierr);
504
+ return result;
505
+ }
506
+
507
+
508
+ void c_title_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
509
+ {
510
+ double r, g, b;
511
+ Unpack_RGB(val, &r, &g, &b, ierr);
512
+ if (*ierr != 0) return;
513
+ p->title_color_R = r;
514
+ p->title_color_G = g;
515
+ p->title_color_B = b;
516
+ }
517
+
518
+
519
+ OBJ_PTR c_title_color_get(OBJ_PTR fmkr, FM *p, int *ierr) // value is array of [r, g, b] intensities from 0 to 1
520
+ { // r g b RG
521
+ double r, g, b;
522
+ r = p->title_color_R;
523
+ g = p->title_color_G;
524
+ b = p->title_color_B;
525
+ OBJ_PTR result = Array_New(3);
526
+ Array_Store(result, 0, Float_New(r), ierr);
527
+ Array_Store(result, 1, Float_New(g), ierr);
528
+ Array_Store(result, 2, Float_New(b), ierr);
529
+ return result;
530
+ }
531
+
532
+
533
+ void c_xlabel_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
534
+ {
535
+ double r, g, b;
536
+ Unpack_RGB(val, &r, &g, &b, ierr);
537
+ if (*ierr != 0) return;
538
+ p->xlabel_color_R = r;
539
+ p->xlabel_color_G = g;
540
+ p->xlabel_color_B = b;
541
+ }
542
+
543
+
544
+ OBJ_PTR c_xlabel_color_get(OBJ_PTR fmkr, FM *p, int *ierr) // value is array of [r, g, b] intensities from 0 to 1
545
+ { // r g b RG
546
+ double r, g, b;
547
+ r = p->xlabel_color_R;
548
+ g = p->xlabel_color_G;
549
+ b = p->xlabel_color_B;
550
+ OBJ_PTR result = Array_New(3);
551
+ Array_Store(result, 0, Float_New(r), ierr);
552
+ Array_Store(result, 1, Float_New(g), ierr);
553
+ Array_Store(result, 2, Float_New(b), ierr);
554
+ return result;
555
+ }
556
+
557
+
558
+ void c_ylabel_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
559
+ {
560
+ double r, g, b;
561
+ Unpack_RGB(val, &r, &g, &b, ierr);
562
+ if (*ierr != 0) return;
563
+ p->ylabel_color_R = r;
564
+ p->ylabel_color_G = g;
565
+ p->ylabel_color_B = b;
566
+ }
567
+
568
+
569
+ OBJ_PTR c_ylabel_color_get(OBJ_PTR fmkr, FM *p, int *ierr) // value is array of [r, g, b] intensities from 0 to 1
570
+ { // r g b RG
571
+ double r, g, b;
572
+ r = p->ylabel_color_R;
573
+ g = p->ylabel_color_G;
574
+ b = p->ylabel_color_B;
575
+ OBJ_PTR result = Array_New(3);
576
+ Array_Store(result, 0, Float_New(r), ierr);
577
+ Array_Store(result, 1, Float_New(g), ierr);
578
+ Array_Store(result, 2, Float_New(b), ierr);
579
+ return result;
580
+ }
581
+
582
+
583
+ void c_xaxis_stroke_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
584
+ {
585
+ double r, g, b;
586
+ Unpack_RGB(val, &r, &g, &b, ierr);
587
+ if (*ierr != 0) return;
588
+ p->xaxis_stroke_color_R = r;
589
+ p->xaxis_stroke_color_G = g;
590
+ p->xaxis_stroke_color_B = b;
591
+ }
592
+
593
+ OBJ_PTR c_xaxis_stroke_color_get(OBJ_PTR fmkr, FM *p, int *ierr) // value is array of [r, g, b] intensities from 0 to 1
594
+ { // r g b RG
595
+ double r, g, b;
596
+ r = p->xaxis_stroke_color_R;
597
+ g = p->xaxis_stroke_color_G;
598
+ b = p->xaxis_stroke_color_B;
599
+ OBJ_PTR result = Array_New(3);
600
+ Array_Store(result, 0, Float_New(r), ierr);
601
+ Array_Store(result, 1, Float_New(g), ierr);
602
+ Array_Store(result, 2, Float_New(b), ierr);
603
+ return result;
604
+ }
605
+
606
+ void c_yaxis_stroke_color_set(OBJ_PTR fmkr, FM *p, OBJ_PTR val, int *ierr)
607
+ {
608
+ double r, g, b;
609
+ Unpack_RGB(val, &r, &g, &b, ierr);
610
+ if (*ierr != 0) return;
611
+ p->yaxis_stroke_color_R = r;
612
+ p->yaxis_stroke_color_G = g;
613
+ p->yaxis_stroke_color_B = b;
614
+ }
615
+
616
+
617
+ OBJ_PTR c_yaxis_stroke_color_get(OBJ_PTR fmkr, FM *p, int *ierr) // value is array of [r, g, b] intensities from 0 to 1
618
+ { // r g b RG
619
+ double r, g, b;
620
+ r = p->yaxis_stroke_color_R;
621
+ g = p->yaxis_stroke_color_G;
622
+ b = p->yaxis_stroke_color_B;
623
+ OBJ_PTR result = Array_New(3);
624
+ Array_Store(result, 0, Float_New(r), ierr);
625
+ Array_Store(result, 1, Float_New(g), ierr);
626
+ Array_Store(result, 2, Float_New(b), ierr);
627
+ return result;
628
+ }