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.
- data/Tioga_README +372 -0
- data/lgpl.txt +504 -0
- data/split/Dtable/defs.h +33 -0
- data/split/Dtable/dtable.c +1928 -0
- data/split/Dtable/dtable_intern.h +144 -0
- data/split/Dtable/dvector.h +61 -0
- data/split/Dtable/extconf.rb +4 -0
- data/split/Dtable/include/dtable.h +35 -0
- data/split/Dtable/lib/Dtable_extras.rb +90 -0
- data/split/Dtable/namespace.h +47 -0
- data/split/Dtable/safe_double.h +104 -0
- data/split/Dtable/symbols.c +92 -0
- data/split/Dtable/symbols.h +52 -0
- data/split/Dvector/defs.h +33 -0
- data/split/Dvector/dvector.c +5486 -0
- data/split/Dvector/dvector_intern.h +142 -0
- data/split/Dvector/extconf.rb +4 -0
- data/split/Dvector/include/dvector.h +61 -0
- data/split/Dvector/lib/Dvector_extras.rb +328 -0
- data/split/Dvector/lib/Numeric_extras.rb +134 -0
- data/split/Dvector/namespace.h +47 -0
- data/split/Dvector/safe_double.h +104 -0
- data/split/Dvector/symbols.c +92 -0
- data/split/Dvector/symbols.h +52 -0
- data/split/Flate/defs.h +33 -0
- data/split/Flate/extconf.rb +19 -0
- data/split/Flate/flate.c +156 -0
- data/split/Flate/flate_intern.h +97 -0
- data/split/Flate/include/flate.h +98 -0
- data/split/Flate/namespace.h +47 -0
- data/split/Flate/safe_double.h +104 -0
- data/split/Flate/symbols.c +92 -0
- data/split/Flate/symbols.h +52 -0
- data/split/Function/defs.h +33 -0
- data/split/Function/dvector.h +61 -0
- data/split/Function/extconf.rb +4 -0
- data/split/Function/function.c +988 -0
- data/split/Function/joint_qsort.c +258 -0
- data/split/Function/lib/Function_extras.rb +44 -0
- data/split/Function/namespace.h +47 -0
- data/split/Function/safe_double.h +104 -0
- data/split/Function/symbols.c +92 -0
- data/split/Function/symbols.h +52 -0
- data/split/Tioga/axes.c +774 -0
- data/split/Tioga/defs.h +33 -0
- data/split/Tioga/dtable.h +35 -0
- data/split/Tioga/dvector.h +61 -0
- data/split/Tioga/extconf.rb +4 -0
- data/split/Tioga/figures.c +672 -0
- data/split/Tioga/figures.h +855 -0
- data/split/Tioga/flate.h +98 -0
- data/split/Tioga/init.c +524 -0
- data/split/Tioga/lib/Arcs_and_Circles.rb +64 -0
- data/split/Tioga/lib/ColorConstants.rb +274 -0
- data/split/Tioga/lib/Colorbars.rb +10 -0
- data/split/Tioga/lib/Colormaps.rb +105 -0
- data/split/Tioga/lib/Coordinate_Conversions.rb +194 -0
- data/split/Tioga/lib/Creating_Paths.rb +94 -0
- data/split/Tioga/lib/Doc.rb +91 -0
- data/split/Tioga/lib/Executive.rb +515 -0
- data/split/Tioga/lib/FigMkr.rb +2224 -0
- data/split/Tioga/lib/FigureConstants.rb +125 -0
- data/split/Tioga/lib/Figures_and_Plots.rb +268 -0
- data/split/Tioga/lib/Images.rb +278 -0
- data/split/Tioga/lib/Legends.rb +190 -0
- data/split/Tioga/lib/MarkerConstants.rb +122 -0
- data/split/Tioga/lib/Markers.rb +129 -0
- data/split/Tioga/lib/Page_Frame_Bounds.rb +567 -0
- data/split/Tioga/lib/Rectangles.rb +94 -0
- data/split/Tioga/lib/Shading.rb +100 -0
- data/split/Tioga/lib/Special_Paths.rb +307 -0
- data/split/Tioga/lib/Strokes.rb +129 -0
- data/split/Tioga/lib/TeX_Text.rb +454 -0
- data/split/Tioga/lib/TexPreamble.rb +358 -0
- data/split/Tioga/lib/Titles_and_Labels.rb +306 -0
- data/split/Tioga/lib/Transparency.rb +89 -0
- data/split/Tioga/lib/Using_Paths.rb +164 -0
- data/split/Tioga/lib/Utils.rb +74 -0
- data/split/Tioga/lib/X_and_Y_Axes.rb +749 -0
- data/split/Tioga/lib/irb_tioga.rb +122 -0
- data/split/Tioga/lib/tioga.rb +1 -0
- data/split/Tioga/lib/tioga_ui.rb +5 -0
- data/split/Tioga/lib/tioga_ui_cmds.rb +793 -0
- data/split/Tioga/makers.c +989 -0
- data/split/Tioga/mk_tioga_sty.rb +53 -0
- data/split/Tioga/namespace.h +47 -0
- data/split/Tioga/pdf_font_dicts.c +18253 -0
- data/split/Tioga/pdfcolor.c +486 -0
- data/split/Tioga/pdfcoords.c +505 -0
- data/split/Tioga/pdffile.c +342 -0
- data/split/Tioga/pdfimage.c +536 -0
- data/split/Tioga/pdfpath.c +914 -0
- data/split/Tioga/pdfs.h +229 -0
- data/split/Tioga/pdftext.c +443 -0
- data/split/Tioga/safe_double.h +104 -0
- data/split/Tioga/symbols.c +92 -0
- data/split/Tioga/symbols.h +52 -0
- data/split/Tioga/texout.c +380 -0
- data/split/defs.h +33 -0
- data/split/extconf.rb +107 -0
- data/split/mkmf2.rb +1612 -0
- data/split/namespace.h +47 -0
- data/split/safe_double.h +104 -0
- data/split/scripts/tioga +4 -0
- data/split/symbols.c +92 -0
- data/split/symbols.h +52 -0
- data/tests/dtable_test.data +6 -0
- data/tests/dvector_read_test.data +1 -0
- data/tests/dvector_test.data +101 -0
- data/tests/tc_Dtable.rb +221 -0
- data/tests/tc_Dvector.rb +791 -0
- data/tests/tc_FMkr.rb +162 -0
- data/tests/tc_Flate.rb +45 -0
- data/tests/tc_Function.rb +111 -0
- data/tests/ts_Tioga.rb +38 -0
- metadata +163 -0
data/split/Tioga/pdfs.h
ADDED
|
@@ -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
|
+
}
|