tioga 1.4

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 (116) hide show
  1. data/Tioga_README +372 -0
  2. data/lgpl.txt +504 -0
  3. data/split/Dtable/defs.h +33 -0
  4. data/split/Dtable/dtable.c +1928 -0
  5. data/split/Dtable/dtable_intern.h +144 -0
  6. data/split/Dtable/dvector.h +61 -0
  7. data/split/Dtable/extconf.rb +4 -0
  8. data/split/Dtable/include/dtable.h +35 -0
  9. data/split/Dtable/lib/Dtable_extras.rb +90 -0
  10. data/split/Dtable/namespace.h +47 -0
  11. data/split/Dtable/safe_double.h +104 -0
  12. data/split/Dtable/symbols.c +92 -0
  13. data/split/Dtable/symbols.h +52 -0
  14. data/split/Dvector/defs.h +33 -0
  15. data/split/Dvector/dvector.c +5486 -0
  16. data/split/Dvector/dvector_intern.h +142 -0
  17. data/split/Dvector/extconf.rb +4 -0
  18. data/split/Dvector/include/dvector.h +61 -0
  19. data/split/Dvector/lib/Dvector_extras.rb +328 -0
  20. data/split/Dvector/lib/Numeric_extras.rb +134 -0
  21. data/split/Dvector/namespace.h +47 -0
  22. data/split/Dvector/safe_double.h +104 -0
  23. data/split/Dvector/symbols.c +92 -0
  24. data/split/Dvector/symbols.h +52 -0
  25. data/split/Flate/defs.h +33 -0
  26. data/split/Flate/extconf.rb +19 -0
  27. data/split/Flate/flate.c +156 -0
  28. data/split/Flate/flate_intern.h +97 -0
  29. data/split/Flate/include/flate.h +98 -0
  30. data/split/Flate/namespace.h +47 -0
  31. data/split/Flate/safe_double.h +104 -0
  32. data/split/Flate/symbols.c +92 -0
  33. data/split/Flate/symbols.h +52 -0
  34. data/split/Function/defs.h +33 -0
  35. data/split/Function/dvector.h +61 -0
  36. data/split/Function/extconf.rb +4 -0
  37. data/split/Function/function.c +988 -0
  38. data/split/Function/joint_qsort.c +258 -0
  39. data/split/Function/lib/Function_extras.rb +44 -0
  40. data/split/Function/namespace.h +47 -0
  41. data/split/Function/safe_double.h +104 -0
  42. data/split/Function/symbols.c +92 -0
  43. data/split/Function/symbols.h +52 -0
  44. data/split/Tioga/axes.c +774 -0
  45. data/split/Tioga/defs.h +33 -0
  46. data/split/Tioga/dtable.h +35 -0
  47. data/split/Tioga/dvector.h +61 -0
  48. data/split/Tioga/extconf.rb +4 -0
  49. data/split/Tioga/figures.c +672 -0
  50. data/split/Tioga/figures.h +855 -0
  51. data/split/Tioga/flate.h +98 -0
  52. data/split/Tioga/init.c +524 -0
  53. data/split/Tioga/lib/Arcs_and_Circles.rb +64 -0
  54. data/split/Tioga/lib/ColorConstants.rb +274 -0
  55. data/split/Tioga/lib/Colorbars.rb +10 -0
  56. data/split/Tioga/lib/Colormaps.rb +105 -0
  57. data/split/Tioga/lib/Coordinate_Conversions.rb +194 -0
  58. data/split/Tioga/lib/Creating_Paths.rb +94 -0
  59. data/split/Tioga/lib/Doc.rb +91 -0
  60. data/split/Tioga/lib/Executive.rb +515 -0
  61. data/split/Tioga/lib/FigMkr.rb +2224 -0
  62. data/split/Tioga/lib/FigureConstants.rb +125 -0
  63. data/split/Tioga/lib/Figures_and_Plots.rb +268 -0
  64. data/split/Tioga/lib/Images.rb +278 -0
  65. data/split/Tioga/lib/Legends.rb +190 -0
  66. data/split/Tioga/lib/MarkerConstants.rb +122 -0
  67. data/split/Tioga/lib/Markers.rb +129 -0
  68. data/split/Tioga/lib/Page_Frame_Bounds.rb +567 -0
  69. data/split/Tioga/lib/Rectangles.rb +94 -0
  70. data/split/Tioga/lib/Shading.rb +100 -0
  71. data/split/Tioga/lib/Special_Paths.rb +307 -0
  72. data/split/Tioga/lib/Strokes.rb +129 -0
  73. data/split/Tioga/lib/TeX_Text.rb +454 -0
  74. data/split/Tioga/lib/TexPreamble.rb +358 -0
  75. data/split/Tioga/lib/Titles_and_Labels.rb +306 -0
  76. data/split/Tioga/lib/Transparency.rb +89 -0
  77. data/split/Tioga/lib/Using_Paths.rb +164 -0
  78. data/split/Tioga/lib/Utils.rb +74 -0
  79. data/split/Tioga/lib/X_and_Y_Axes.rb +749 -0
  80. data/split/Tioga/lib/irb_tioga.rb +122 -0
  81. data/split/Tioga/lib/tioga.rb +1 -0
  82. data/split/Tioga/lib/tioga_ui.rb +5 -0
  83. data/split/Tioga/lib/tioga_ui_cmds.rb +793 -0
  84. data/split/Tioga/makers.c +989 -0
  85. data/split/Tioga/mk_tioga_sty.rb +53 -0
  86. data/split/Tioga/namespace.h +47 -0
  87. data/split/Tioga/pdf_font_dicts.c +18253 -0
  88. data/split/Tioga/pdfcolor.c +486 -0
  89. data/split/Tioga/pdfcoords.c +505 -0
  90. data/split/Tioga/pdffile.c +342 -0
  91. data/split/Tioga/pdfimage.c +536 -0
  92. data/split/Tioga/pdfpath.c +914 -0
  93. data/split/Tioga/pdfs.h +229 -0
  94. data/split/Tioga/pdftext.c +443 -0
  95. data/split/Tioga/safe_double.h +104 -0
  96. data/split/Tioga/symbols.c +92 -0
  97. data/split/Tioga/symbols.h +52 -0
  98. data/split/Tioga/texout.c +380 -0
  99. data/split/defs.h +33 -0
  100. data/split/extconf.rb +107 -0
  101. data/split/mkmf2.rb +1612 -0
  102. data/split/namespace.h +47 -0
  103. data/split/safe_double.h +104 -0
  104. data/split/scripts/tioga +4 -0
  105. data/split/symbols.c +92 -0
  106. data/split/symbols.h +52 -0
  107. data/tests/dtable_test.data +6 -0
  108. data/tests/dvector_read_test.data +1 -0
  109. data/tests/dvector_test.data +101 -0
  110. data/tests/tc_Dtable.rb +221 -0
  111. data/tests/tc_Dvector.rb +791 -0
  112. data/tests/tc_FMkr.rb +162 -0
  113. data/tests/tc_Flate.rb +45 -0
  114. data/tests/tc_Function.rb +111 -0
  115. data/tests/ts_Tioga.rb +38 -0
  116. metadata +163 -0
@@ -0,0 +1,229 @@
1
+ /* pdfs.h */
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
+ #ifndef __pdfs_H__
23
+ #define __pdfs_H__
24
+
25
+ #include <namespace.h>
26
+
27
+ #include "flate.h"
28
+
29
+ extern VALUE rb_Integer_class, rb_Numeric_class;
30
+ extern ID save_dir_ID, model_number_ID, add_model_number_ID, quiet_mode_ID;
31
+ extern ID tex_preview_documentclass_ID, tex_preview_preamble_ID, tex_preview_pagestyle_ID;
32
+ extern ID tex_preview_left_margin_ID, tex_preview_right_margin_ID, tex_preview_top_margin_ID;
33
+ extern ID tex_preview_bottom_margin_ID, tex_preview_left_fudge_ID, tex_preview_top_fudge_ID;
34
+ extern ID do_cmd_ID, data_dir_ID, initialized_ID, tex_xoffset_ID, tex_yoffset_ID;
35
+
36
+ extern long int *obj_offsets, capacity_obj_offsets, stream_start, stream_end, length_offset, xref_offset;
37
+ extern int num_objects, next_available_object_number, next_available_gs_number, next_available_xo_number;
38
+ extern int next_available_shade_number, next_available_font_number;
39
+ extern void Record_Object_Offset(int obj_number);
40
+ extern char *predefined_Fonts[];
41
+ extern int num_pdf_standard_fonts, num_predefined_fonts;
42
+
43
+ typedef struct stroke_opacity_state {
44
+ struct stroke_opacity_state *next;
45
+ int gs_num;
46
+ int obj_num;
47
+ double stroke_opacity;
48
+ } Stroke_Opacity_State;
49
+ extern Stroke_Opacity_State *stroke_opacities;
50
+
51
+ typedef struct fill_opacity_state {
52
+ struct fill_opacity_state *next;
53
+ int gs_num;
54
+ int obj_num;
55
+ double fill_opacity;
56
+ } Fill_Opacity_State;
57
+ extern Fill_Opacity_State *fill_opacities;
58
+
59
+ typedef struct xobj_info {
60
+ struct xobj_info *next;
61
+ int xo_num;
62
+ int obj_num;
63
+ int xobj_subtype;
64
+ } XObject_Info;
65
+ extern XObject_Info *xobj_list;
66
+
67
+ typedef struct jpg_info {
68
+ // start must match start of xobj_info
69
+ struct xobj_info *next;
70
+ int xo_num;
71
+ int obj_num;
72
+ int xobj_subtype;
73
+ // remainder is for this subtype of xobj
74
+ int width, height;
75
+ int mask_obj_num;
76
+ char *filename;
77
+ } JPG_Info;
78
+
79
+ typedef struct sampled_info {
80
+ // start must match start of xobj_info
81
+ struct xobj_info *next;
82
+ int xo_num;
83
+ int obj_num;
84
+ int xobj_subtype;
85
+ // remainder is for this subtype of xobj
86
+ int width, height;
87
+ int length; // number of bytes of image data
88
+ unsigned char *image_data;
89
+ bool interpolate;
90
+ bool reversed; // only applies to mono images
91
+ int mask_obj_num;
92
+ int image_type;
93
+ int value_mask_min;
94
+ int value_mask_max;
95
+ int hival;
96
+ int lookup_len;
97
+ unsigned char *lookup;
98
+ } Sampled_Info;
99
+
100
+ #define JPG_SUBTYPE 1
101
+ #define SAMPLED_SUBTYPE 2
102
+
103
+ #define RGB_IMAGE 0
104
+ #define CMYK_IMAGE 4
105
+ #define GRAY_IMAGE 1
106
+ #define MONO_IMAGE 2
107
+ #define COLORMAP_IMAGE 3
108
+
109
+ typedef struct function_info {
110
+ struct function_info *next;
111
+ int obj_num;
112
+ int hival;
113
+ int lookup_len;
114
+ unsigned char *lookup;
115
+ } Function_Info;
116
+ extern Function_Info *functions_list;
117
+
118
+ typedef struct shading_info {
119
+ struct shading_info *next;
120
+ int shade_num;
121
+ int obj_num;
122
+ bool axial;
123
+ double x0;
124
+ double y0;
125
+ double x1;
126
+ double y1;
127
+ double r0;
128
+ double r1;
129
+ int function;
130
+ bool extend_start;
131
+ bool extend_end;
132
+ } Shading_Info;
133
+ extern Shading_Info *shades_list;
134
+
135
+ typedef struct {
136
+ int font_num; // for making font resource name such as /F7
137
+ char *font_name;
138
+ int firstChar, lastChar; // firstChar typically is 0 and lastChar 255
139
+ int char_width[256], char_llx[256], char_lly[256], char_urx[256], char_ury[256];
140
+ int widths_obj_num;
141
+ /* FontDescriptor */
142
+ int flags; // describe the font
143
+ int fnt_llx, fnt_lly, fnt_urx, fnt_ury; // FontBBox
144
+ int italicAngle, ascent, descent, capHeight, stemV;
145
+ } Font_Afm_Info;
146
+
147
+ extern Font_Afm_Info afm_array[];
148
+
149
+ typedef struct font_dictionary {
150
+ struct font_dictionary *next;
151
+ int font_num; // for making font resource name such as /F7
152
+ int obj_num;
153
+ bool in_use;
154
+ int widths_obj_num;
155
+ int descriptor_obj_num;
156
+ Font_Afm_Info *afm;
157
+ } Font_Dictionary;
158
+ extern Font_Dictionary *font_dictionaries;
159
+
160
+ typedef struct old_font_dictionary {
161
+ struct old_font_dictionary *next;
162
+ int font_num; // for making font resource name such as /F7
163
+ int obj_num;
164
+ bool in_use;
165
+ char *font_name;
166
+ int firstChar, lastChar; // firstChar typically is 0 and lastChar 255
167
+ int char_width[256], char_llx[256], char_lly[256], char_urx[256], char_ury[256];
168
+ int widths_obj_num;
169
+ /* FontDescriptor */
170
+ int descriptor_obj_num;
171
+ int flags; // describe the font
172
+ int fnt_llx, fnt_lly, fnt_urx, fnt_ury; // FontBBox
173
+ int italicAngle, ascent, descent, capHeight, stemV;
174
+ } Old_Font_Dictionary;
175
+ extern Old_Font_Dictionary *old_font_dictionaries;
176
+
177
+ #define FixedPitchFlag 1
178
+ #define SerifFlag 2
179
+ #define SymbolicFlag 4
180
+ #define ScriptFlag 8
181
+ #define NonsymbolicFlag (1<<5)
182
+ #define ItalicFlag (1<<6)
183
+ #define AllCapFlag (1<<16)
184
+ #define SmallCapFlag (1<<17)
185
+ #define ForceBoldFlag (1<<18)
186
+
187
+ #define RADIANS_TO_DEGREES (180.0 / PI)
188
+
189
+ extern bool Used_Any_Fonts(void);
190
+ extern void Clear_Fonts_In_Use_Flags(void);
191
+ extern void Write_Font_Dictionaries(void);
192
+ extern void Write_Font_Descriptors(void);
193
+ extern void Write_Font_Widths(void);
194
+ extern void Write_Functions(void);
195
+ extern void Write_Stroke_Opacity_Objects(void);
196
+ extern void Write_Fill_Opacity_Objects(void);
197
+ extern void Write_Shadings(void);
198
+ extern void Write_JPG(JPG_Info *xo);
199
+ extern void Write_Sampled(Sampled_Info *xo);
200
+ extern void Free_Stroke_Opacities(void);
201
+ extern void Free_Shadings();
202
+ extern void Free_Functions();
203
+ extern void Free_JPG(JPG_Info *xo);
204
+ extern void Free_Sampled(Sampled_Info *xo);
205
+ extern void Free_Fill_Opacities(void);
206
+
207
+ extern void c_append_rect(FM *p, double x, double y, double width, double height);
208
+ extern void c_clip(FM *p);
209
+
210
+ extern bool have_current_point, constructing_path, writing_file;
211
+ extern double bbox_llx, bbox_lly, bbox_urx, bbox_ury;
212
+
213
+ extern FILE *OF; // for the PDF file
214
+ extern FILE *TF; // for the temp file holding the uncompressed stream
215
+
216
+ extern void Unpack_RGB(VALUE rgb, double *rp, double *gp, double *bp);
217
+
218
+ extern void Start_Axis_Standard_State(FM *p, VALUE color, double line_width);
219
+ extern void End_Axis_Standard_State(void);
220
+
221
+ extern void Write_gsave(void);
222
+ extern void Write_grestore(void);
223
+
224
+ PRIVATE void c_private_set_default_font_size(FM *p, double size);
225
+
226
+ void Init_Font_Dictionary(void);
227
+
228
+ #endif /* __pdfs_H__ */
229
+
@@ -0,0 +1,443 @@
1
+ /* pdftext.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
+ void Init_Font_Dictionary(void) {
26
+ int i, num_fonts = num_pdf_standard_fonts;
27
+ Font_Dictionary *font_info;
28
+ for (i = 0; i < num_fonts; i++) {
29
+ font_info = ALLOC(Font_Dictionary);
30
+ font_info->afm = &afm_array[i];
31
+ font_info->font_num = font_info->afm->font_num;
32
+ font_info->in_use = false;
33
+ font_info->next = font_dictionaries;
34
+ font_dictionaries = font_info;
35
+ }
36
+ }
37
+
38
+ static void Write_Font_Dictionary(FILE *file, Old_Font_Dictionary *fi) {
39
+ int i;
40
+ fprintf(file, "{\n");
41
+ fprintf(file, "\t%i, // font_num\n", fi->font_num);
42
+ fprintf(file, "\t\"%s\", // font_name\n", fi->font_name);
43
+ fprintf(file, "\t%4i, // firstChar\n", fi->firstChar);
44
+ fprintf(file, "\t%4i, // lastChar\n", fi->lastChar);
45
+
46
+ fprintf(file, "\t{ // char_width\n");
47
+ for (i=0; i<255; i++) fprintf(file, "\t\t%4i, // %i\n", fi->char_width[i], i);
48
+ fprintf(file, "\t\t%4i }, // char_width\n", fi->char_width[255]);
49
+
50
+ fprintf(file, "\t{ // char_llx\n");
51
+ for (i=0; i<255; i++) fprintf(file, "\t\t%4i, // %i\n", fi->char_llx[i], i);
52
+ fprintf(file, "\t\t%4i }, // char_llx\n", fi->char_llx[255]);
53
+
54
+ fprintf(file, "\t{ // char_lly\n");
55
+ for (i=0; i<255; i++) fprintf(file, "\t\t%4i, // %i\n", fi->char_lly[i], i);
56
+ fprintf(file, "\t\t4%i }, // char_lly\n", fi->char_lly[255]);
57
+
58
+ fprintf(file, "\t{ // char_urx\n");
59
+ for (i=0; i<255; i++) fprintf(file, "\t\t%4i, // %i\n", fi->char_urx[i], i);
60
+ fprintf(file, "\t\t%4i }, // char_urx\n", fi->char_urx[255]);
61
+
62
+ fprintf(file, "\t{ // char_ury\n");
63
+ for (i=0; i<255; i++) fprintf(file, "\t\t%4i, // %i\n", fi->char_ury[i], i);
64
+ fprintf(file, "\t\t%4i }, // char_ury\n", fi->char_ury[255]);
65
+
66
+ fprintf(file, "\t%i, // flags\n", fi->flags);
67
+ fprintf(file, "\t%i, // fnt_llx\n", fi->fnt_llx);
68
+ fprintf(file, "\t%i, // fnt_lly\n", fi->fnt_lly);
69
+ fprintf(file, "\t%i, // fnt_urx\n", fi->fnt_urx);
70
+ fprintf(file, "\t%i, // fnt_ury\n", fi->fnt_ury);
71
+ fprintf(file, "\t%i, // italicAngle\n", fi->italicAngle);
72
+ fprintf(file, "\t%i, // ascent\n", fi->ascent);
73
+ fprintf(file, "\t%i, // descent\n", fi->descent);
74
+ fprintf(file, "\t%i, // capHeight\n", fi->capHeight);
75
+ fprintf(file, "\t%i // stemV\n", fi->stemV);
76
+
77
+ fprintf(file, "} // %s\n", fi->font_name);
78
+ }
79
+
80
+ static void WriteFontDictsToFile(void) {
81
+ Old_Font_Dictionary *font_info;
82
+ FILE *file;
83
+ file = fopen("pdf_font_dicts.c", "w");
84
+ fprintf(file, "Font_Dict_Array font_dictionaries[] = { // afm info for PDF fonts \n");
85
+ for (font_info = old_font_dictionaries; font_info != NULL; font_info = font_info->next) {
86
+ Write_Font_Dictionary(file, font_info);
87
+ if (font_info->next != NULL) fprintf(file, ",\n");
88
+ }
89
+ fprintf(file, "}; // end of font_dictionaries declaration \n");
90
+ fclose(file);
91
+ }
92
+
93
+ static void Record_Font_In_Use(Font_Dictionary *font_info, int font_number)
94
+ {
95
+ if (font_info->in_use) return;
96
+ font_info->afm->font_num = font_number;
97
+ font_info->obj_num = next_available_object_number++;
98
+ font_info->in_use = true;
99
+ if (font_number > num_pdf_standard_fonts) {
100
+ font_info->widths_obj_num = next_available_object_number++;
101
+ font_info->descriptor_obj_num = next_available_object_number++;
102
+ }
103
+ }
104
+
105
+ #define DEBUG 0
106
+ #define MAXSTR 100
107
+ static Font_Dictionary *GetFontDict(char *font_name, int font_number) {
108
+ Font_Dictionary *font_info;
109
+ for (font_info = font_dictionaries; font_info != NULL; font_info = font_info->next) {
110
+ if (strcmp(font_name, font_info->afm->font_name) == 0) {
111
+ Record_Font_In_Use(font_info, font_number);
112
+ return font_info;
113
+ }
114
+ }
115
+ rb_raise(rb_eArgError, "Sorry: invalid font name (%s)", font_name);
116
+ return NULL;
117
+ }
118
+
119
+ static Font_Dictionary *GetFontInfo(int font_number)
120
+ {
121
+ Font_Dictionary *f;
122
+ for (f = font_dictionaries; f != NULL; f = f->next) {
123
+ if (f->font_num == font_number) { Record_Font_In_Use(f, font_number); return f; }
124
+ }
125
+ if (font_number > 0 && font_number <= num_predefined_fonts)
126
+ return GetFontDict(predefined_Fonts[font_number], font_number);
127
+ return NULL;
128
+ }
129
+
130
+ static int c_register_font(char *font_name)
131
+ {
132
+ Font_Dictionary *f;
133
+ int i;
134
+ for (f = font_dictionaries; f != NULL; f = f->next) {
135
+ if (strcmp(f->afm->font_name, font_name)==0) return f->afm->font_num;
136
+ }
137
+ for (i = 1; i <= num_predefined_fonts; i++) {
138
+ if (strcmp(predefined_Fonts[i], font_name)==0) {
139
+ f = GetFontDict(font_name, i);
140
+ if (f == NULL) rb_raise(rb_eArgError, "Error in reading font metrics for %s", font_name);
141
+ return i;
142
+ }
143
+ }
144
+ f = GetFontDict(font_name, next_available_font_number);
145
+ if (f == NULL) rb_raise(rb_eArgError, "Error in reading font metrics for %s", font_name);
146
+ return next_available_font_number++;
147
+ }
148
+
149
+ VALUE FM_register_font(VALUE fmkr, VALUE font_name)
150
+ {
151
+ font_name = rb_String(font_name);
152
+ int font_num = c_register_font(RSTRING(font_name)->ptr);
153
+ return INT2FIX(font_num);
154
+ }
155
+
156
+ bool Used_Any_Fonts(void)
157
+ {
158
+ Font_Dictionary *f;
159
+ for (f = font_dictionaries; f != NULL; f = f->next) {
160
+ if (f->in_use) return true;
161
+ }
162
+ return false;
163
+ }
164
+
165
+ void Clear_Fonts_In_Use_Flags(void)
166
+ {
167
+ Font_Dictionary *f;
168
+ for (f = font_dictionaries; f != NULL; f = f->next) {
169
+ f->in_use = false;
170
+ }
171
+ }
172
+
173
+ void Write_Font_Descriptors(void)
174
+ {
175
+ Font_Dictionary *f;
176
+ for (f = font_dictionaries; f != NULL; f = f->next) {
177
+ if (!f->in_use || f->font_num <= num_pdf_standard_fonts) continue;
178
+ Record_Object_Offset(f->descriptor_obj_num);
179
+ fprintf(OF, "%i 0 obj << /Type /FontDescriptor /FontName /%s\n", f->descriptor_obj_num, f->afm->font_name);
180
+ fprintf(OF, " /Flags %i /FontBBox [ %i %i %i %i ]\n",
181
+ f->afm->flags, f->afm->fnt_llx, f->afm->fnt_lly, f->afm->fnt_urx, f->afm->fnt_ury);
182
+ fprintf(OF, " /ItalicAngle %i /Ascent %i /Descent %i /CapHeight %i /StemV %i\n",
183
+ f->afm->italicAngle, f->afm->ascent, f->afm->descent, f->afm->capHeight, f->afm->stemV);
184
+ fprintf(OF, ">> endobj\n");
185
+ }
186
+ }
187
+
188
+ void Write_Font_Widths(void)
189
+ {
190
+ Font_Dictionary *f;
191
+ int i, cnt = 0;
192
+ for (f = font_dictionaries; f != NULL; f = f->next) {
193
+ if (!f->in_use || f->font_num <= num_pdf_standard_fonts) continue;
194
+ Record_Object_Offset(f->widths_obj_num);
195
+ fprintf(OF, "%i 0 obj [\n ", f->widths_obj_num);
196
+ for (i = f->afm->firstChar; i <= f->afm->lastChar; i++) {
197
+ fprintf(OF, "%i ", f->afm->char_width[i]);
198
+ if (++cnt % 16 == 0) fprintf(OF, "\n ");
199
+ }
200
+ fprintf(OF, "\n] endobj\n");
201
+ }
202
+ }
203
+
204
+ void Write_Font_Dictionaries(void)
205
+ {
206
+ if (0) WriteFontDictsToFile(); // creates pdf_font_dicts.c
207
+ Font_Dictionary *f;
208
+ for (f = font_dictionaries; f != NULL; f = f->next) {
209
+ if (!f->in_use) continue;
210
+ Record_Object_Offset(f->obj_num);
211
+ fprintf(OF, "%i 0 obj << /Type /Font /Subtype /Type1 /BaseFont /%s", f->obj_num, f->afm->font_name);
212
+ if (strcmp(f->afm->font_name,"Symbol")!=0 && strcmp(f->afm->font_name,"ZapfDingbats")!=0)
213
+ fprintf(OF, " /Encoding /MacRomanEncoding\n");
214
+ else
215
+ fprintf(OF, "\n");
216
+ if (f->font_num > num_pdf_standard_fonts)
217
+ fprintf(OF, " /FirstChar %i /LastChar %i /Widths %i 0 R /FontDescriptor %i 0 R\n",
218
+ f->afm->firstChar, f->afm->lastChar, f->widths_obj_num, f->descriptor_obj_num);
219
+ fprintf(OF, ">> endobj\n");
220
+ }
221
+ }
222
+
223
+ static void GetStringInfo(FM *p, int font_number, unsigned char *text, double ft_ht,
224
+ double *llx_ptr, double *lly_ptr, double *urx_ptr, double *ury_ptr, double *width_ptr) {
225
+ Font_Dictionary *fontinfo = GetFontInfo(font_number);
226
+ if (fontinfo == NULL)
227
+ rb_raise(rb_eArgError, "Sorry: invalid font number (%i): must register font before use it.", font_number);
228
+ unsigned char *c_ptr = text, c;
229
+ double width = 0, llx, lly, urx, ury;
230
+ if (fontinfo == NULL || text == NULL || text[0] == '\0') {
231
+ *width_ptr = *llx_ptr = *lly_ptr = *urx_ptr = *ury_ptr = 0;
232
+ return;
233
+ }
234
+ c = *c_ptr;
235
+ llx = fontinfo->afm->char_llx[c];
236
+ lly = fontinfo->afm->char_lly[c];
237
+ ury = fontinfo->afm->char_ury[c];
238
+ while ((c = *c_ptr++) != '\0') {
239
+ width += fontinfo->afm->char_width[c];
240
+ if (fontinfo->afm->char_ury[c] > ury) ury = fontinfo->afm->char_ury[c];
241
+ if (fontinfo->afm->char_lly[c] < lly) lly = fontinfo->afm->char_lly[c];
242
+ }
243
+ urx = llx + width;
244
+ *width_ptr = width * ft_ht * 1e-3;
245
+ *llx_ptr = llx * ft_ht * 1e-3;
246
+ *lly_ptr = lly * ft_ht * 1e-3;
247
+ *urx_ptr = urx * ft_ht * 1e-3;
248
+ *ury_ptr = ury * ft_ht * 1e-3;
249
+ }
250
+
251
+ VALUE FM_marker_string_info(VALUE fmkr, VALUE font_number, VALUE string, VALUE scale)
252
+ { // [ width, llx, lly, urx, ury ] in figure coords
253
+ FM *p = Get_FM(fmkr);
254
+ font_number = rb_Integer(font_number);
255
+ string = rb_String(string);
256
+ unsigned char *text = (unsigned char *)(RSTRING(string)->ptr);
257
+ scale = rb_Float(scale);
258
+ double ft_ht = p->default_text_scale * NUM2DBL(scale) * p->default_font_size * ENLARGE;
259
+ int ft_height = ROUND(ft_ht);
260
+ ft_ht = ft_height;
261
+ double llx, lly, urx, ury, width;
262
+ int fnt = NUM2INT(font_number);
263
+ GetStringInfo(p, fnt, text, ft_ht, &llx, &lly, &urx, &ury, &width);
264
+ VALUE result = rb_ary_new2(5);
265
+ width = convert_output_to_figure_dx(p,width);
266
+ llx = convert_output_to_figure_dx(p,llx);
267
+ urx = convert_output_to_figure_dx(p,urx);
268
+ lly = convert_output_to_figure_dy(p,lly);
269
+ ury = convert_output_to_figure_dy(p,ury);
270
+ rb_ary_store(result, 0, rb_float_new(width));
271
+ rb_ary_store(result, 1, rb_float_new(llx));
272
+ rb_ary_store(result, 2, rb_float_new(lly));
273
+ rb_ary_store(result, 3, rb_float_new(urx));
274
+ rb_ary_store(result, 4, rb_float_new(ury));
275
+ return result;
276
+ }
277
+
278
+ #define TRANSFORM_VEC(dx,dy) tmp = dx; dx = (dx) * a + (dy) * c; dy = tmp * b + (dy) * d;
279
+
280
+ /* This macro checks that it's a real number we're looking at */
281
+ #define is_okay_number(x) ((x) - (x) == 0.0)
282
+
283
+ void c_rotated_string_at_points(FM *p, double rotation, int font_number, unsigned char *text, double scale,
284
+ int n, double *xs, double *ys, int alignment, int justification, double horizontal_scaling, double vertical_scaling,
285
+ double italic_angle, double ascent_angle)
286
+ {
287
+ double ft_ht = p->default_text_scale * scale * p->default_font_size * ENLARGE;
288
+ int i, ft_height = ROUND(ft_ht);
289
+ ft_ht = ft_height;
290
+ if (constructing_path) rb_raise(rb_eArgError, "Sorry: must not be constructing a path when show marker");
291
+ double llx, lly, urx, ury, width, shiftx, shifty, tmp;
292
+ double a=horizontal_scaling, b=0.0, c=0.0, d=vertical_scaling; // the initial transform
293
+ GetStringInfo(p, font_number, text, ft_ht, &llx, &lly, &urx, &ury, &width);
294
+ // translate according to justification and alignment
295
+ // note that we use the bbox to calculate shifts so 'center' means center of bbox
296
+ if (italic_angle != 0) {
297
+ double skew = sin(italic_angle / RADIANS_TO_DEGREES);
298
+ c -= skew*a; d -= skew*b;
299
+ }
300
+ if (ascent_angle != 0) {
301
+ double skew = sin(ascent_angle / RADIANS_TO_DEGREES);
302
+ a += skew*c; b += skew*d;
303
+ }
304
+ if (rotation != 0) {
305
+ double xa, xb, xc, xd; // new transform
306
+ double cs = cos(rotation / RADIANS_TO_DEGREES), sn = sin(rotation / RADIANS_TO_DEGREES);
307
+ xa = cs*a + sn*c; xb = cs*b + sn*d; xc = -sn*a + cs*c; xd = -sn*b + cs*d;
308
+ a = xa; b = xb; c = xc; d = xd;
309
+ }
310
+ switch (justification) {
311
+ case LEFT_JUSTIFIED: shiftx = 0; break;
312
+ case CENTERED: shiftx = -(urx+llx)/2; break; // CENTERED for marker means centered on BBOX
313
+ case RIGHT_JUSTIFIED:
314
+ shiftx = -width;
315
+ // the following hack compensates for Arrowhead bbox in ZaphDingbats
316
+ // needed to make tip of arrowhead fall on the reference point correctly
317
+ if (font_number == 14 && strlen((char *)text) == 1 && text[0] == 0344) {
318
+ shiftx *= 0.9;
319
+ }
320
+ break;
321
+ default: rb_raise(rb_eArgError, "Sorry: invalid setting for marker justification (%i)", justification);
322
+ }
323
+ switch (alignment) {
324
+ case ALIGNED_AT_TOP: shifty = -ury; break;
325
+ case ALIGNED_AT_MIDHEIGHT: shifty = -(ury+lly)/2; break;
326
+ case ALIGNED_AT_BASELINE: shifty = 0; break;
327
+ case ALIGNED_AT_BOTTOM: shifty = -lly; break;
328
+ default: rb_raise(rb_eArgError, "Sorry: invalid setting for marker alignment (%i)", alignment);
329
+ }
330
+ // transform the bbox
331
+ double llx2 = llx, lly2 = lly, urx2 = urx, ury2 = ury; // if we're rotated we'll need all 4 corners of bbox
332
+ TRANSFORM_VEC(llx, lly)
333
+ TRANSFORM_VEC(urx, ury)
334
+ TRANSFORM_VEC(llx2, ury2)
335
+ TRANSFORM_VEC(urx2, lly2)
336
+ TRANSFORM_VEC(shiftx, shifty)
337
+ fprintf(TF, "BT /F%i %i Tf\n", font_number, ft_height);
338
+ if (0 && horizontal_scaling != 1.0) {
339
+ fprintf(TF, "%d Tz\n", ROUND(100*ABS(horizontal_scaling)));
340
+ }
341
+ double x, y, prev_x=0, prev_y=0, dx, dy;
342
+ int idx, idy;
343
+ for (i = 0; i < n; i++) {
344
+ unsigned char *cp = text, char_code;
345
+ x = convert_figure_to_output_x(p,xs[i]) + shiftx;
346
+ y = convert_figure_to_output_y(p,ys[i]) + shifty;
347
+ if(!is_okay_number(x) || ! is_okay_number(y))
348
+ continue; /* we forget this point if at least one coordinate is not
349
+ 'real'
350
+ */
351
+ update_bbox(p,x+llx, y+lly);
352
+ update_bbox(p,x+urx, y+ury);
353
+ update_bbox(p,x+llx2, y+ury2);
354
+ update_bbox(p,x+urx2, y+lly2);
355
+ dx = x - prev_x; dy = y - prev_y;
356
+ idx = ROUND(dx); idy = ROUND(dy);
357
+ prev_x = prev_x + idx; prev_y = prev_y + idy;
358
+ if (b == 0 && c == 0 && a == 1 && d == 1) {
359
+ fprintf(TF, "%i %i Td (", idx, idy);
360
+ } else { // need high precision when doing rotations
361
+ fprintf(TF, "%0.6f %0.6f %0.6f %0.6f %0.6f %0.6f Tm (", a, b, c, d, dx, dy);
362
+ }
363
+ while ((char_code = *cp++) != '\0') {
364
+ if (char_code == '\\')
365
+ fprintf(TF, "\\\\");
366
+ else if (char_code == '(' || char_code == ')')
367
+ fprintf(TF, "\\%c", char_code);
368
+ else
369
+ fprintf(TF, "%c", char_code);
370
+ }
371
+ fprintf(TF, ") Tj\n");
372
+ }
373
+ fprintf(TF, "ET\n");
374
+ }
375
+
376
+ VALUE FM_private_show_marker(VALUE fmkr, VALUE integer_args, VALUE stroke_width, VALUE string,
377
+ VALUE x, VALUE y, VALUE x_vec, VALUE y_vec,
378
+ VALUE h_scale, VALUE v_scale, VALUE scale, VALUE it_angle, VALUE ascent_angle, VALUE angle,
379
+ VALUE fill_color, VALUE stroke_color)
380
+ {
381
+ FM *p = Get_FM(fmkr);
382
+ int int_args, c, alignment, justification, fnt_num, n, mode;
383
+ unsigned char *text = NULL, buff[2];
384
+ double *xs, *ys, xloc, yloc, prev_line_width = -1;
385
+ bool restore_fill_color = false, restore_stroke_color = false;
386
+ VALUE prev_fill_color = Qnil, prev_stroke_color = Qnil;
387
+ integer_args = rb_Integer(integer_args);
388
+ int_args = NUM2INT(integer_args);
389
+ c = int_args / 100000; int_args -= c * 100000;
390
+ fnt_num = int_args / 1000; int_args -= fnt_num * 1000;
391
+ mode = int_args / 100; int_args -= mode * 100;
392
+ alignment = int_args / 10; int_args -= alignment * 10;
393
+ justification = int_args;
394
+ if (string == Qnil) {
395
+ if (c < 0 || c > 255)
396
+ rb_raise(rb_eArgError, "Sorry: invalid character code (%i) : must be between 0 and 255", c);
397
+ text = buff; text[0] = c; text[1] = '\0';
398
+ if (stroke_width != Qnil) {
399
+ stroke_width = rb_Float(stroke_width);
400
+ double width = NUM2DBL(stroke_width);
401
+ prev_line_width = p->line_width; // restore it later
402
+ fprintf(TF, "%0.6f w\n", width * ENLARGE);
403
+ }
404
+ } else {
405
+ string = rb_String(string);
406
+ text = (unsigned char *)(RSTRING(string)->ptr);
407
+ }
408
+ fprintf(TF, "%d Tr\n", mode);
409
+ if (stroke_color != Qnil && stroke_color != p->stroke_color &&
410
+ (mode == STROKE || mode == FILL_AND_STROKE || mode == STROKE_AND_CLIP || mode == FILL_STROKE_AND_CLIP)) {
411
+ prev_stroke_color = p->stroke_color; restore_stroke_color = true;
412
+ FM_stroke_color_set(fmkr, stroke_color);
413
+ }
414
+ if (fill_color != Qnil && fill_color != p->fill_color &&
415
+ (mode == FILL || mode == FILL_AND_STROKE || mode == FILL_AND_CLIP || mode == FILL_STROKE_AND_CLIP)) {
416
+ prev_fill_color = p->fill_color; restore_fill_color = true;
417
+ FM_fill_color_set(fmkr, fill_color);
418
+ }
419
+ h_scale = rb_Float(h_scale);
420
+ v_scale = rb_Float(v_scale);
421
+ scale = rb_Float(scale);
422
+ it_angle = rb_Float(it_angle);
423
+ ascent_angle = rb_Float(ascent_angle);
424
+ angle = rb_Float(angle);
425
+ if (x == Qnil) {
426
+ long xlen, ylen;
427
+ xs = Dvector_Data_for_Read(x_vec, &xlen);
428
+ ys = Dvector_Data_for_Read(y_vec, &ylen);
429
+ if (xlen != ylen) rb_raise(rb_eArgError, "Sorry: must have same number xs and ys for showing markers");
430
+ if (xlen <= 0) return fmkr;
431
+ n = xlen;
432
+ } else {
433
+ x = rb_Float(x); xloc = NUM2DBL(x); xs = &xloc;
434
+ y = rb_Float(y); yloc = NUM2DBL(y); ys = &yloc;
435
+ n = 1;
436
+ }
437
+ c_rotated_string_at_points(p, NUM2DBL(angle), fnt_num, text, NUM2DBL(scale), n, xs, ys,
438
+ alignment, justification, NUM2DBL(h_scale), NUM2DBL(v_scale), NUM2DBL(it_angle), NUM2DBL(ascent_angle));
439
+ if (prev_line_width >= 0) c_line_width_set(p, prev_line_width);
440
+ if (restore_fill_color) FM_fill_color_set(fmkr, prev_fill_color);
441
+ if (restore_stroke_color) FM_stroke_color_set(fmkr, prev_stroke_color);
442
+ return fmkr;
443
+ }