tioga 1.4

Sign up to get free protection for your applications and to get access to all the features.
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
+ }