| 5148 |
ripley |
1 |
/*
|
|
|
2 |
* A PicTeX device, (C) 1996 Valerio Aimale, for
|
|
|
3 |
* R : A Computer Language for Statistical Data Analysis
|
| 87832 |
ripley |
4 |
* Copyright (C) 2001--2025 The R Core Team
|
| 5148 |
ripley |
5 |
* Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka
|
|
|
6 |
*
|
|
|
7 |
* This program is free software; you can redistribute it and/or modify
|
|
|
8 |
* it under the terms of the GNU General Public License as published by
|
|
|
9 |
* the Free Software Foundation; either version 2 of the License, or
|
|
|
10 |
* (at your option) any later version.
|
|
|
11 |
*
|
|
|
12 |
* This program 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 General Public License for more details.
|
|
|
16 |
*
|
|
|
17 |
* You should have received a copy of the GNU General Public License
|
| 42307 |
ripley |
18 |
* along with this program; if not, a copy is available at
|
| 68948 |
ripley |
19 |
* https://www.R-project.org/Licenses/
|
| 5148 |
ripley |
20 |
*/
|
|
|
21 |
|
| 5187 |
hornik |
22 |
#ifdef HAVE_CONFIG_H
|
| 44342 |
ripley |
23 |
# include <config.h>
|
| 5187 |
hornik |
24 |
#endif
|
|
|
25 |
|
| 36498 |
ripley |
26 |
#include <Defn.h>
|
|
|
27 |
|
| 60260 |
ripley |
28 |
# include <rlocale.h> /* includes wchar.h */
|
| 35776 |
ripley |
29 |
|
| 44271 |
ripley |
30 |
#define R_USE_PROTOTYPES 1
|
| 44249 |
ripley |
31 |
#include <R_ext/GraphicsEngine.h>
|
| 5148 |
ripley |
32 |
#include "Fileio.h"
|
| 32879 |
ripley |
33 |
#include "grDevices.h"
|
| 5148 |
ripley |
34 |
|
|
|
35 |
/* device-specific information per picTeX device */
|
|
|
36 |
|
| 11067 |
maechler |
37 |
#define DOTSperIN 72.27
|
|
|
38 |
#define in2dots(x) (DOTSperIN * x)
|
|
|
39 |
|
| 5148 |
ripley |
40 |
typedef struct {
|
| 9004 |
ripley |
41 |
FILE *texfp;
|
|
|
42 |
char filename[128];
|
|
|
43 |
int pageno;
|
| 87953 |
ripley |
44 |
int landscape; // unused
|
| 9004 |
ripley |
45 |
double width;
|
|
|
46 |
double height;
|
|
|
47 |
double pagewidth;
|
|
|
48 |
double pageheight;
|
|
|
49 |
double xlast;
|
|
|
50 |
double ylast;
|
|
|
51 |
double clipleft, clipright, cliptop, clipbottom;
|
|
|
52 |
double clippedx0, clippedy0, clippedx1, clippedy1;
|
|
|
53 |
int lty;
|
|
|
54 |
rcolor col;
|
| 17112 |
murrell |
55 |
rcolor fill;
|
| 9004 |
ripley |
56 |
int fontsize;
|
|
|
57 |
int fontface;
|
| 87953 |
ripley |
58 |
bool debug;
|
| 5148 |
ripley |
59 |
} picTeXDesc;
|
|
|
60 |
|
|
|
61 |
|
|
|
62 |
/* Global device information */
|
|
|
63 |
|
| 19912 |
duncan |
64 |
static const double charwidth[4][128] = {
|
| 5148 |
ripley |
65 |
{
|
| 6844 |
maechler |
66 |
0.5416690, 0.8333360, 0.7777810, 0.6111145, 0.6666690, 0.7083380, 0.7222240,
|
|
|
67 |
0.7777810, 0.7222240, 0.7777810, 0.7222240, 0.5833360, 0.5361130, 0.5361130,
|
|
|
68 |
0.8138910, 0.8138910, 0.2388900, 0.2666680, 0.5000020, 0.5000020, 0.5000020,
|
|
|
69 |
0.5000020, 0.5000020, 0.6666700, 0.4444460, 0.4805580, 0.7222240, 0.7777810,
|
|
|
70 |
0.5000020, 0.8611145, 0.9722260, 0.7777810, 0.2388900, 0.3194460, 0.5000020,
|
|
|
71 |
0.8333360, 0.5000020, 0.8333360, 0.7583360, 0.2777790, 0.3888900, 0.3888900,
|
|
|
72 |
0.5000020, 0.7777810, 0.2777790, 0.3333340, 0.2777790, 0.5000020, 0.5000020,
|
|
|
73 |
0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020,
|
|
|
74 |
0.5000020, 0.5000020, 0.2777790, 0.2777790, 0.3194460, 0.7777810, 0.4722240,
|
|
|
75 |
0.4722240, 0.6666690, 0.6666700, 0.6666700, 0.6388910, 0.7222260, 0.5972240,
|
|
|
76 |
0.5694475, 0.6666690, 0.7083380, 0.2777810, 0.4722240, 0.6944480, 0.5416690,
|
|
|
77 |
0.8750050, 0.7083380, 0.7361130, 0.6388910, 0.7361130, 0.6458360, 0.5555570,
|
|
|
78 |
0.6805570, 0.6875050, 0.6666700, 0.9444480, 0.6666700, 0.6666700, 0.6111130,
|
|
|
79 |
0.2888900, 0.5000020, 0.2888900, 0.5000020, 0.2777790, 0.2777790, 0.4805570,
|
|
|
80 |
0.5166680, 0.4444460, 0.5166680, 0.4444460, 0.3055570, 0.5000020, 0.5166680,
|
|
|
81 |
0.2388900, 0.2666680, 0.4888920, 0.2388900, 0.7944470, 0.5166680, 0.5000020,
|
|
|
82 |
0.5166680, 0.5166680, 0.3416690, 0.3833340, 0.3611120, 0.5166680, 0.4611130,
|
|
|
83 |
0.6833360, 0.4611130, 0.4611130, 0.4347230, 0.5000020, 1.0000030, 0.5000020,
|
| 5148 |
ripley |
84 |
0.5000020, 0.5000020
|
|
|
85 |
},
|
|
|
86 |
{
|
| 6844 |
maechler |
87 |
0.5805590, 0.9166720, 0.8555600, 0.6722260, 0.7333370, 0.7944490, 0.7944490,
|
|
|
88 |
0.8555600, 0.7944490, 0.8555600, 0.7944490, 0.6416700, 0.5861150, 0.5861150,
|
|
|
89 |
0.8916720, 0.8916720, 0.2555570, 0.2861130, 0.5500030, 0.5500030, 0.5500030,
|
|
|
90 |
0.5500030, 0.5500030, 0.7333370, 0.4888920, 0.5652800, 0.7944490, 0.8555600,
|
|
|
91 |
0.5500030, 0.9472275, 1.0694500, 0.8555600, 0.2555570, 0.3666690, 0.5583360,
|
|
|
92 |
0.9166720, 0.5500030, 1.0291190, 0.8305610, 0.3055570, 0.4277800, 0.4277800,
|
|
|
93 |
0.5500030, 0.8555600, 0.3055570, 0.3666690, 0.3055570, 0.5500030, 0.5500030,
|
|
|
94 |
0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030,
|
|
|
95 |
0.5500030, 0.5500030, 0.3055570, 0.3055570, 0.3666690, 0.8555600, 0.5194470,
|
|
|
96 |
0.5194470, 0.7333370, 0.7333370, 0.7333370, 0.7027820, 0.7944490, 0.6416700,
|
|
|
97 |
0.6111145, 0.7333370, 0.7944490, 0.3305570, 0.5194470, 0.7638930, 0.5805590,
|
|
|
98 |
0.9777830, 0.7944490, 0.7944490, 0.7027820, 0.7944490, 0.7027820, 0.6111145,
|
|
|
99 |
0.7333370, 0.7638930, 0.7333370, 1.0388950, 0.7333370, 0.7333370, 0.6722260,
|
|
|
100 |
0.3430580, 0.5583360, 0.3430580, 0.5500030, 0.3055570, 0.3055570, 0.5250030,
|
|
|
101 |
0.5611140, 0.4888920, 0.5611140, 0.5111140, 0.3361130, 0.5500030, 0.5611140,
|
|
|
102 |
0.2555570, 0.2861130, 0.5305590, 0.2555570, 0.8666720, 0.5611140, 0.5500030,
|
|
|
103 |
0.5611140, 0.5611140, 0.3722250, 0.4216690, 0.4041690, 0.5611140, 0.5000030,
|
|
|
104 |
0.7444490, 0.5000030, 0.5000030, 0.4763920, 0.5500030, 1.1000060, 0.5500030,
|
|
|
105 |
0.5500030, 0.550003 },
|
| 5148 |
ripley |
106 |
{
|
| 6844 |
maechler |
107 |
0.5416690, 0.8333360, 0.7777810, 0.6111145, 0.6666690, 0.7083380, 0.7222240,
|
|
|
108 |
0.7777810, 0.7222240, 0.7777810, 0.7222240, 0.5833360, 0.5361130, 0.5361130,
|
|
|
109 |
0.8138910, 0.8138910, 0.2388900, 0.2666680, 0.5000020, 0.5000020, 0.5000020,
|
|
|
110 |
0.5000020, 0.5000020, 0.7375210, 0.4444460, 0.4805580, 0.7222240, 0.7777810,
|
|
|
111 |
0.5000020, 0.8611145, 0.9722260, 0.7777810, 0.2388900, 0.3194460, 0.5000020,
|
|
|
112 |
0.8333360, 0.5000020, 0.8333360, 0.7583360, 0.2777790, 0.3888900, 0.3888900,
|
|
|
113 |
0.5000020, 0.7777810, 0.2777790, 0.3333340, 0.2777790, 0.5000020, 0.5000020,
|
|
|
114 |
0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020,
|
|
|
115 |
0.5000020, 0.5000020, 0.2777790, 0.2777790, 0.3194460, 0.7777810, 0.4722240,
|
|
|
116 |
0.4722240, 0.6666690, 0.6666700, 0.6666700, 0.6388910, 0.7222260, 0.5972240,
|
|
|
117 |
0.5694475, 0.6666690, 0.7083380, 0.2777810, 0.4722240, 0.6944480, 0.5416690,
|
|
|
118 |
0.8750050, 0.7083380, 0.7361130, 0.6388910, 0.7361130, 0.6458360, 0.5555570,
|
|
|
119 |
0.6805570, 0.6875050, 0.6666700, 0.9444480, 0.6666700, 0.6666700, 0.6111130,
|
|
|
120 |
0.2888900, 0.5000020, 0.2888900, 0.5000020, 0.2777790, 0.2777790, 0.4805570,
|
|
|
121 |
0.5166680, 0.4444460, 0.5166680, 0.4444460, 0.3055570, 0.5000020, 0.5166680,
|
|
|
122 |
0.2388900, 0.2666680, 0.4888920, 0.2388900, 0.7944470, 0.5166680, 0.5000020,
|
|
|
123 |
0.5166680, 0.5166680, 0.3416690, 0.3833340, 0.3611120, 0.5166680, 0.4611130,
|
|
|
124 |
0.6833360, 0.4611130, 0.4611130, 0.4347230, 0.5000020, 1.0000030, 0.5000020,
|
|
|
125 |
0.5000020, 0.5000020 },
|
| 5148 |
ripley |
126 |
{
|
| 6844 |
maechler |
127 |
0.5805590, 0.9166720, 0.8555600, 0.6722260, 0.7333370, 0.7944490, 0.7944490,
|
|
|
128 |
0.8555600, 0.7944490, 0.8555600, 0.7944490, 0.6416700, 0.5861150, 0.5861150,
|
|
|
129 |
0.8916720, 0.8916720, 0.2555570, 0.2861130, 0.5500030, 0.5500030, 0.5500030,
|
|
|
130 |
0.5500030, 0.5500030, 0.8002530, 0.4888920, 0.5652800, 0.7944490, 0.8555600,
|
|
|
131 |
0.5500030, 0.9472275, 1.0694500, 0.8555600, 0.2555570, 0.3666690, 0.5583360,
|
|
|
132 |
0.9166720, 0.5500030, 1.0291190, 0.8305610, 0.3055570, 0.4277800, 0.4277800,
|
|
|
133 |
0.5500030, 0.8555600, 0.3055570, 0.3666690, 0.3055570, 0.5500030, 0.5500030,
|
|
|
134 |
0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030,
|
|
|
135 |
0.5500030, 0.5500030, 0.3055570, 0.3055570, 0.3666690, 0.8555600, 0.5194470,
|
|
|
136 |
0.5194470, 0.7333370, 0.7333370, 0.7333370, 0.7027820, 0.7944490, 0.6416700,
|
|
|
137 |
0.6111145, 0.7333370, 0.7944490, 0.3305570, 0.5194470, 0.7638930, 0.5805590,
|
|
|
138 |
0.9777830, 0.7944490, 0.7944490, 0.7027820, 0.7944490, 0.7027820, 0.6111145,
|
|
|
139 |
0.7333370, 0.7638930, 0.7333370, 1.0388950, 0.7333370, 0.7333370, 0.6722260,
|
|
|
140 |
0.3430580, 0.5583360, 0.3430580, 0.5500030, 0.3055570, 0.3055570, 0.5250030,
|
|
|
141 |
0.5611140, 0.4888920, 0.5611140, 0.5111140, 0.3361130, 0.5500030, 0.5611140,
|
|
|
142 |
0.2555570, 0.2861130, 0.5305590, 0.2555570, 0.8666720, 0.5611140, 0.5500030,
|
|
|
143 |
0.5611140, 0.5611140, 0.3722250, 0.4216690, 0.4041690, 0.5611140, 0.5000030,
|
|
|
144 |
0.7444490, 0.5000030, 0.5000030, 0.4763920, 0.5500030, 1.1000060, 0.5500030,
|
| 5148 |
ripley |
145 |
0.5500030, 0.550003
|
|
|
146 |
}
|
|
|
147 |
};
|
|
|
148 |
|
| 19912 |
duncan |
149 |
static const char * const fontname[] = {
|
| 12976 |
pd |
150 |
"cmss10",
|
|
|
151 |
"cmssbx10",
|
|
|
152 |
"cmssi10",
|
|
|
153 |
"cmssxi10"
|
| 5148 |
ripley |
154 |
};
|
|
|
155 |
|
|
|
156 |
|
|
|
157 |
/* Device driver actions */
|
|
|
158 |
|
| 17112 |
murrell |
159 |
static void PicTeX_Circle(double x, double y, double r,
|
| 44500 |
ripley |
160 |
const pGEcontext gc,
|
| 44299 |
ripley |
161 |
pDevDesc dd);
|
| 17112 |
murrell |
162 |
static void PicTeX_Clip(double x0, double x1, double y0, double y1,
|
| 44299 |
ripley |
163 |
pDevDesc dd);
|
|
|
164 |
static void PicTeX_Close(pDevDesc dd);
|
| 17112 |
murrell |
165 |
static void PicTeX_Line(double x1, double y1, double x2, double y2,
|
| 44500 |
ripley |
166 |
const pGEcontext gc,
|
| 44299 |
ripley |
167 |
pDevDesc dd);
|
| 27236 |
murrell |
168 |
static void PicTeX_MetricInfo(int c,
|
| 44500 |
ripley |
169 |
const pGEcontext gc,
|
| 17112 |
murrell |
170 |
double* ascent, double* descent,
|
| 44299 |
ripley |
171 |
double* width, pDevDesc dd);
|
| 44500 |
ripley |
172 |
static void PicTeX_NewPage(const pGEcontext gc, pDevDesc dd);
|
| 17112 |
murrell |
173 |
static void PicTeX_Polygon(int n, double *x, double *y,
|
| 44500 |
ripley |
174 |
const pGEcontext gc,
|
| 44299 |
ripley |
175 |
pDevDesc dd);
|
| 27236 |
murrell |
176 |
static void PicTeX_Rect(double x0, double y0, double x1, double y1,
|
| 44500 |
ripley |
177 |
const pGEcontext gc,
|
| 44299 |
ripley |
178 |
pDevDesc dd);
|
| 17112 |
murrell |
179 |
static void PicTeX_Size(double *left, double *right,
|
| 27236 |
murrell |
180 |
double *bottom, double *top,
|
| 44299 |
ripley |
181 |
pDevDesc dd);
|
| 44271 |
ripley |
182 |
static double PicTeX_StrWidth(const char *str,
|
| 44500 |
ripley |
183 |
const pGEcontext gc,
|
| 44299 |
ripley |
184 |
pDevDesc dd);
|
| 44271 |
ripley |
185 |
static void PicTeX_Text(double x, double y, const char *str,
|
| 27236 |
murrell |
186 |
double rot, double hadj,
|
| 44500 |
ripley |
187 |
const pGEcontext gc,
|
| 44299 |
ripley |
188 |
pDevDesc dd);
|
| 78759 |
murrell |
189 |
static SEXP PicTeX_setPattern(SEXP pattern, pDevDesc dd);
|
|
|
190 |
static void PicTeX_releasePattern(SEXP ref, pDevDesc dd);
|
|
|
191 |
static SEXP PicTeX_setClipPath(SEXP path, SEXP ref, pDevDesc dd);
|
|
|
192 |
static void PicTeX_releaseClipPath(SEXP ref, pDevDesc dd);
|
|
|
193 |
static SEXP PicTeX_setMask(SEXP path, SEXP ref, pDevDesc dd);
|
|
|
194 |
static void PicTeX_releaseMask(SEXP ref, pDevDesc dd);
|
| 5148 |
ripley |
195 |
|
|
|
196 |
/* Support routines */
|
|
|
197 |
|
| 59184 |
ripley |
198 |
static void SetLinetype(int newlty, double newlwd, pDevDesc dd)
|
| 5148 |
ripley |
199 |
{
|
| 9004 |
ripley |
200 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
201 |
|
| 9004 |
ripley |
202 |
int i, templty;
|
|
|
203 |
ptd->lty = newlty;
|
|
|
204 |
if (ptd->lty) {
|
|
|
205 |
fprintf(ptd->texfp,"\\setdashpattern <");
|
|
|
206 |
for(i=0 ; i<8 && newlty&15 ; i++) {
|
| 59184 |
ripley |
207 |
int lwd = (int)newlwd * newlty;
|
|
|
208 |
fprintf(ptd->texfp,"%dpt", lwd & 15);
|
| 9004 |
ripley |
209 |
templty = newlty>>4;
|
|
|
210 |
if ((i+1)<8 && templty&15) fprintf(ptd->texfp,", ");
|
|
|
211 |
newlty = newlty>>4;
|
|
|
212 |
}
|
|
|
213 |
fprintf(ptd->texfp,">\n");
|
|
|
214 |
} else fprintf(ptd->texfp,"\\setsolid\n");
|
| 5148 |
ripley |
215 |
}
|
|
|
216 |
|
|
|
217 |
|
|
|
218 |
static void SetFont(int face, int size, picTeXDesc *ptd)
|
|
|
219 |
{
|
| 9004 |
ripley |
220 |
int lface=face, lsize= size;
|
| 27236 |
murrell |
221 |
if(lface < 1 || lface > 4 ) lface = 1;
|
| 9004 |
ripley |
222 |
if(lsize < 1 || lsize > 24) lsize = 10;
|
|
|
223 |
if(lsize != ptd->fontsize || lface != ptd->fontface) {
|
|
|
224 |
fprintf(ptd->texfp, "\\font\\picfont %s at %dpt\\picfont\n",
|
|
|
225 |
fontname[lface-1], lsize);
|
|
|
226 |
ptd->fontsize = lsize;
|
|
|
227 |
ptd->fontface = lface;
|
|
|
228 |
}
|
| 5148 |
ripley |
229 |
}
|
|
|
230 |
|
| 27236 |
murrell |
231 |
static void PicTeX_MetricInfo(int c,
|
| 44500 |
ripley |
232 |
const pGEcontext gc,
|
| 17112 |
murrell |
233 |
double* ascent, double* descent,
|
| 44299 |
ripley |
234 |
double* width, pDevDesc dd)
|
| 5148 |
ripley |
235 |
{
|
| 6994 |
pd |
236 |
/* metric information not available => return 0,0,0 */
|
|
|
237 |
*ascent = 0.0;
|
|
|
238 |
*descent = 0.0;
|
|
|
239 |
*width = 0.0;
|
| 5148 |
ripley |
240 |
}
|
| 6994 |
pd |
241 |
|
| 5148 |
ripley |
242 |
/* Initialize the device */
|
|
|
243 |
|
|
|
244 |
|
|
|
245 |
|
|
|
246 |
/* Interactive Resize */
|
|
|
247 |
|
| 17112 |
murrell |
248 |
static void PicTeX_Size(double *left, double *right,
|
|
|
249 |
double *bottom, double *top,
|
| 44299 |
ripley |
250 |
pDevDesc dd)
|
| 5148 |
ripley |
251 |
{
|
| 17112 |
murrell |
252 |
*left = dd->left; /* left */
|
|
|
253 |
*right = dd->right;/* right */
|
|
|
254 |
*bottom = dd->bottom; /* bottom */
|
|
|
255 |
*top = dd->top;/* top */
|
| 5148 |
ripley |
256 |
}
|
|
|
257 |
|
|
|
258 |
static void PicTeX_Clip(double x0, double x1, double y0, double y1,
|
| 44299 |
ripley |
259 |
pDevDesc dd)
|
| 5148 |
ripley |
260 |
{
|
| 9004 |
ripley |
261 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
262 |
|
| 9004 |
ripley |
263 |
if(ptd->debug)
|
| 5148 |
ripley |
264 |
fprintf(ptd->texfp, "%% Setting Clip Region to %.2f %.2f %.2f %.2f\n",
|
|
|
265 |
x0, y0, x1, y1);
|
| 9004 |
ripley |
266 |
ptd->clipleft = x0;
|
|
|
267 |
ptd->clipright = x1;
|
|
|
268 |
ptd->clipbottom = y0;
|
|
|
269 |
ptd->cliptop = y1;
|
| 5148 |
ripley |
270 |
}
|
|
|
271 |
|
|
|
272 |
/* Start a new page */
|
|
|
273 |
|
| 44500 |
ripley |
274 |
static void PicTeX_NewPage(const pGEcontext gc,
|
| 44299 |
ripley |
275 |
pDevDesc dd)
|
| 5148 |
ripley |
276 |
{
|
| 9004 |
ripley |
277 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
278 |
|
| 9004 |
ripley |
279 |
int face, size;
|
|
|
280 |
if (ptd->pageno) {
|
|
|
281 |
fprintf(ptd->texfp, "\\endpicture\n}\n\n\n");
|
|
|
282 |
fprintf(ptd->texfp, "\\hbox{\\beginpicture\n");
|
|
|
283 |
fprintf(ptd->texfp, "\\setcoordinatesystem units <1pt,1pt>\n");
|
|
|
284 |
fprintf(ptd->texfp,
|
|
|
285 |
"\\setplotarea x from 0 to %.2f, y from 0 to %.2f\n",
|
| 11067 |
maechler |
286 |
in2dots(ptd->width), in2dots(ptd->height));
|
| 9004 |
ripley |
287 |
fprintf(ptd->texfp,"\\setlinear\n");
|
|
|
288 |
fprintf(ptd->texfp, "\\font\\picfont cmss10\\picfont\n");
|
|
|
289 |
}
|
| 11067 |
maechler |
290 |
ptd->pageno++;
|
| 9004 |
ripley |
291 |
face = ptd->fontface;
|
|
|
292 |
size = ptd->fontsize;
|
|
|
293 |
ptd->fontface = 0;
|
|
|
294 |
ptd->fontsize = 0;
|
|
|
295 |
SetFont(face, size, ptd);
|
| 5148 |
ripley |
296 |
}
|
|
|
297 |
|
|
|
298 |
/* Close down the driver */
|
|
|
299 |
|
| 44299 |
ripley |
300 |
static void PicTeX_Close(pDevDesc dd)
|
| 5148 |
ripley |
301 |
{
|
| 12976 |
pd |
302 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
303 |
|
| 12976 |
pd |
304 |
fprintf(ptd->texfp, "\\endpicture\n}\n");
|
|
|
305 |
fclose(ptd->texfp);
|
| 5148 |
ripley |
306 |
|
| 12976 |
pd |
307 |
free(ptd);
|
| 5148 |
ripley |
308 |
}
|
|
|
309 |
|
|
|
310 |
/* Draw To */
|
|
|
311 |
|
|
|
312 |
static void PicTeX_ClipLine(double x0, double y0, double x1, double y1,
|
|
|
313 |
picTeXDesc *ptd)
|
|
|
314 |
{
|
| 9004 |
ripley |
315 |
ptd->clippedx0 = x0; ptd->clippedx1 = x1;
|
|
|
316 |
ptd->clippedy0 = y0; ptd->clippedy1 = y1;
|
| 5148 |
ripley |
317 |
|
| 9004 |
ripley |
318 |
if ((ptd->clippedx0 < ptd->clipleft &&
|
|
|
319 |
ptd->clippedx1 < ptd->clipleft) ||
|
|
|
320 |
(ptd->clippedx0 > ptd->clipright &&
|
|
|
321 |
ptd->clippedx1 > ptd->clipright) ||
|
|
|
322 |
(ptd->clippedy0 < ptd->clipbottom &&
|
|
|
323 |
ptd->clippedy1 < ptd->clipbottom) ||
|
|
|
324 |
(ptd->clippedy0 > ptd->cliptop &&
|
|
|
325 |
ptd->clippedy1 > ptd->cliptop)) {
|
|
|
326 |
ptd->clippedx0 = ptd->clippedx1;
|
|
|
327 |
ptd->clippedy0 = ptd->clippedy1;
|
|
|
328 |
return;
|
|
|
329 |
}
|
| 5148 |
ripley |
330 |
|
| 9004 |
ripley |
331 |
/*Clipping Left */
|
|
|
332 |
if (ptd->clippedx1 >= ptd->clipleft && ptd->clippedx0 < ptd->clipleft) {
|
|
|
333 |
ptd->clippedy0 = ((ptd->clippedy1-ptd->clippedy0) /
|
|
|
334 |
(ptd->clippedx1-ptd->clippedx0) *
|
|
|
335 |
(ptd->clipleft-ptd->clippedx0)) +
|
|
|
336 |
ptd->clippedy0;
|
|
|
337 |
ptd->clippedx0 = ptd->clipleft;
|
|
|
338 |
}
|
|
|
339 |
if (ptd->clippedx1 <= ptd->clipleft && ptd->clippedx0 > ptd->clipleft) {
|
|
|
340 |
ptd->clippedy1 = ((ptd->clippedy1-ptd->clippedy0) /
|
|
|
341 |
(ptd->clippedx1-ptd->clippedx0) *
|
|
|
342 |
(ptd->clipleft-ptd->clippedx0)) +
|
|
|
343 |
ptd->clippedy0;
|
|
|
344 |
ptd->clippedx1 = ptd->clipleft;
|
|
|
345 |
}
|
|
|
346 |
/* Clipping Right */
|
|
|
347 |
if (ptd->clippedx1 >= ptd->clipright &&
|
|
|
348 |
ptd->clippedx0 < ptd->clipright) {
|
|
|
349 |
ptd->clippedy1 = ((ptd->clippedy1-ptd->clippedy0) /
|
|
|
350 |
(ptd->clippedx1-ptd->clippedx0) *
|
|
|
351 |
(ptd->clipright-ptd->clippedx0)) +
|
|
|
352 |
ptd->clippedy0;
|
|
|
353 |
ptd->clippedx1 = ptd->clipright;
|
|
|
354 |
}
|
|
|
355 |
if (ptd->clippedx1 <= ptd->clipright &&
|
|
|
356 |
ptd->clippedx0 > ptd->clipright) {
|
|
|
357 |
ptd->clippedy0 = ((ptd->clippedy1-ptd->clippedy0) /
|
|
|
358 |
(ptd->clippedx1-ptd->clippedx0) *
|
|
|
359 |
(ptd->clipright-ptd->clippedx0)) +
|
|
|
360 |
ptd->clippedy0;
|
|
|
361 |
ptd->clippedx0 = ptd->clipright;
|
|
|
362 |
}
|
|
|
363 |
/*Clipping Bottom */
|
|
|
364 |
if (ptd->clippedy1 >= ptd->clipbottom &&
|
|
|
365 |
ptd->clippedy0 < ptd->clipbottom ) {
|
|
|
366 |
ptd->clippedx0 = ((ptd->clippedx1-ptd->clippedx0) /
|
|
|
367 |
(ptd->clippedy1-ptd->clippedy0) *
|
|
|
368 |
(ptd->clipbottom -ptd->clippedy0)) +
|
|
|
369 |
ptd->clippedx0;
|
|
|
370 |
ptd->clippedy0 = ptd->clipbottom ;
|
|
|
371 |
}
|
|
|
372 |
if (ptd->clippedy1 <= ptd->clipbottom &&
|
|
|
373 |
ptd->clippedy0 > ptd->clipbottom ) {
|
|
|
374 |
ptd->clippedx1 = ((ptd->clippedx1-ptd->clippedx0) /
|
|
|
375 |
(ptd->clippedy1-ptd->clippedy0) *
|
|
|
376 |
(ptd->clipbottom -ptd->clippedy0)) +
|
|
|
377 |
ptd->clippedx0;
|
|
|
378 |
ptd->clippedy1 = ptd->clipbottom ;
|
|
|
379 |
}
|
|
|
380 |
/*Clipping Top */
|
|
|
381 |
if (ptd->clippedy1 >= ptd->cliptop && ptd->clippedy0 < ptd->cliptop ) {
|
|
|
382 |
ptd->clippedx1 = ((ptd->clippedx1-ptd->clippedx0) /
|
|
|
383 |
(ptd->clippedy1-ptd->clippedy0) *
|
|
|
384 |
(ptd->cliptop -ptd->clippedy0)) +
|
|
|
385 |
ptd->clippedx0;
|
|
|
386 |
ptd->clippedy1 = ptd->cliptop ;
|
|
|
387 |
}
|
|
|
388 |
if (ptd->clippedy1 <= ptd->cliptop && ptd->clippedy0 > ptd->cliptop ) {
|
|
|
389 |
ptd->clippedx0 = ((ptd->clippedx1-ptd->clippedx0) /
|
|
|
390 |
(ptd->clippedy1-ptd->clippedy0) *
|
|
|
391 |
(ptd->cliptop -ptd->clippedy0)) +
|
|
|
392 |
ptd->clippedx0;
|
|
|
393 |
ptd->clippedy0 = ptd->cliptop ;
|
|
|
394 |
}
|
| 5148 |
ripley |
395 |
}
|
|
|
396 |
|
|
|
397 |
static void PicTeX_Line(double x1, double y1, double x2, double y2,
|
| 44500 |
ripley |
398 |
const pGEcontext gc,
|
| 44299 |
ripley |
399 |
pDevDesc dd)
|
| 5148 |
ripley |
400 |
{
|
| 12976 |
pd |
401 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
402 |
|
| 12976 |
pd |
403 |
if (x1 != x2 || y1 != y2) {
|
| 27236 |
murrell |
404 |
SetLinetype(gc->lty, gc->lwd, dd);
|
| 5148 |
ripley |
405 |
if(ptd->debug)
|
| 12976 |
pd |
406 |
fprintf(ptd->texfp,
|
|
|
407 |
"%% Drawing line from %.2f, %.2f to %.2f, %.2f\n",
|
|
|
408 |
x1, y1, x2, y2);
|
| 5148 |
ripley |
409 |
PicTeX_ClipLine(x1, y1, x2, y2, ptd);
|
|
|
410 |
if (ptd->debug)
|
| 12976 |
pd |
411 |
fprintf(ptd->texfp,
|
|
|
412 |
"%% Drawing clipped line from %.2f, %.2f to %.2f, %.2f\n",
|
|
|
413 |
ptd->clippedx0, ptd->clippedy0,
|
|
|
414 |
ptd->clippedx1, ptd->clippedy1);
|
| 5148 |
ripley |
415 |
fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
|
|
|
416 |
ptd->clippedx0, ptd->clippedy0,
|
|
|
417 |
ptd->clippedx1, ptd->clippedy1);
|
| 12976 |
pd |
418 |
}
|
| 5148 |
ripley |
419 |
}
|
|
|
420 |
|
| 17112 |
murrell |
421 |
static void PicTeX_Polyline(int n, double *x, double *y,
|
| 44500 |
ripley |
422 |
const pGEcontext gc,
|
| 44299 |
ripley |
423 |
pDevDesc dd)
|
| 5148 |
ripley |
424 |
{
|
| 9004 |
ripley |
425 |
double x1, y1, x2, y2;
|
|
|
426 |
int i;
|
|
|
427 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
428 |
|
| 27236 |
murrell |
429 |
SetLinetype(gc->lty, gc->lwd, dd);
|
| 9004 |
ripley |
430 |
x1 = x[0];
|
|
|
431 |
y1 = y[0];
|
| 12976 |
pd |
432 |
for (i = 1; i < n; i++) {
|
| 9004 |
ripley |
433 |
x2 = x[i];
|
|
|
434 |
y2 = y[i];
|
|
|
435 |
PicTeX_ClipLine(x1, y1, x2, y2, ptd);
|
|
|
436 |
fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
|
|
|
437 |
ptd->clippedx0, ptd->clippedy0,
|
|
|
438 |
ptd->clippedx1, ptd->clippedy1);
|
| 12976 |
pd |
439 |
x1 = x2;
|
|
|
440 |
y1 = y2;
|
| 9004 |
ripley |
441 |
}
|
| 5148 |
ripley |
442 |
}
|
|
|
443 |
|
|
|
444 |
/* String Width in Rasters */
|
|
|
445 |
/* For the current font in pointsize fontsize */
|
|
|
446 |
|
| 44271 |
ripley |
447 |
static double PicTeX_StrWidth(const char *str,
|
| 44500 |
ripley |
448 |
const pGEcontext gc,
|
| 44299 |
ripley |
449 |
pDevDesc dd)
|
| 5148 |
ripley |
450 |
{
|
| 9004 |
ripley |
451 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
452 |
|
| 44271 |
ripley |
453 |
const char *p;
|
| 37387 |
ripley |
454 |
int size;
|
| 9004 |
ripley |
455 |
double sum;
|
| 37368 |
ripley |
456 |
|
| 59184 |
ripley |
457 |
size = (int)(gc->cex * gc->ps + 0.5);
|
| 27236 |
murrell |
458 |
SetFont(gc->fontface, size, ptd);
|
| 9004 |
ripley |
459 |
sum = 0;
|
| 35825 |
ripley |
460 |
if(mbcslocale && ptd->fontface != 5) {
|
| 37368 |
ripley |
461 |
/* This version at least uses the state of the MBCS */
|
| 59184 |
ripley |
462 |
size_t i, ucslen = mbcsToUcs2(str, NULL, 0, CE_NATIVE);
|
| 37368 |
ripley |
463 |
if (ucslen != (size_t)-1) {
|
| 77916 |
ripley |
464 |
R_ucs2_t ucs[ucslen];
|
| 59184 |
ripley |
465 |
int status = (int) mbcsToUcs2(str, ucs, (int)ucslen, CE_NATIVE);
|
| 37370 |
ripley |
466 |
if (status >= 0)
|
|
|
467 |
for (i = 0; i < ucslen; i++)
|
|
|
468 |
if(ucs[i] < 128) sum += charwidth[ptd->fontface-1][ucs[i]];
|
| 79776 |
ripley |
469 |
else {
|
|
|
470 |
#ifdef USE_RI18N_WIDTH
|
|
|
471 |
sum += (double) Ri18n_wcwidth(ucs[i]) * 0.5; /* A guess */
|
|
|
472 |
#else
|
|
|
473 |
sum += (double) wcwidth((wchar_t)ucs[i]) * 0.5; /* A guess */
|
|
|
474 |
#endif
|
|
|
475 |
}
|
| 37370 |
ripley |
476 |
else
|
|
|
477 |
warning(_("invalid string in '%s'"), "PicTeX_StrWidth");
|
| 37368 |
ripley |
478 |
} else
|
|
|
479 |
warning(_("invalid string in '%s'"), "PicTeX_StrWidth");
|
| 35825 |
ripley |
480 |
} else
|
|
|
481 |
for(p = str; *p; p++)
|
|
|
482 |
sum += charwidth[ptd->fontface-1][(int)*p];
|
| 49591 |
ripley |
483 |
|
| 9004 |
ripley |
484 |
return sum * ptd->fontsize;
|
| 5148 |
ripley |
485 |
}
|
|
|
486 |
|
|
|
487 |
|
|
|
488 |
/* Possibly Filled Rectangle */
|
|
|
489 |
static void PicTeX_Rect(double x0, double y0, double x1, double y1,
|
| 44500 |
ripley |
490 |
const pGEcontext gc,
|
| 44299 |
ripley |
491 |
pDevDesc dd)
|
| 5148 |
ripley |
492 |
{
|
| 9004 |
ripley |
493 |
double x[4], y[4];
|
| 12976 |
pd |
494 |
|
| 9004 |
ripley |
495 |
x[0] = x0; y[0] = y0;
|
|
|
496 |
x[1] = x0; y[1] = y1;
|
|
|
497 |
x[2] = x1; y[2] = y1;
|
|
|
498 |
x[3] = x1; y[3] = y0;
|
| 27236 |
murrell |
499 |
PicTeX_Polygon(4, x, y, gc, dd);
|
| 5148 |
ripley |
500 |
}
|
|
|
501 |
|
| 52406 |
murrell |
502 |
|
| 17112 |
murrell |
503 |
static void PicTeX_Circle(double x, double y, double r,
|
| 44500 |
ripley |
504 |
const pGEcontext gc,
|
| 44299 |
ripley |
505 |
pDevDesc dd)
|
| 5148 |
ripley |
506 |
{
|
| 9004 |
ripley |
507 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
508 |
|
| 9004 |
ripley |
509 |
fprintf(ptd->texfp,
|
|
|
510 |
"\\circulararc 360 degrees from %.2f %.2f center at %.2f %.2f\n",
|
|
|
511 |
x, (y + r), x, y);
|
| 5148 |
ripley |
512 |
}
|
|
|
513 |
|
| 17112 |
murrell |
514 |
static void PicTeX_Polygon(int n, double *x, double *y,
|
| 44500 |
ripley |
515 |
const pGEcontext gc,
|
| 44299 |
ripley |
516 |
pDevDesc dd)
|
| 5148 |
ripley |
517 |
{
|
| 9004 |
ripley |
518 |
double x1, y1, x2, y2;
|
|
|
519 |
int i;
|
|
|
520 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
521 |
|
| 27236 |
murrell |
522 |
SetLinetype(gc->lty, gc->lwd, dd);
|
| 9004 |
ripley |
523 |
x1 = x[0];
|
|
|
524 |
y1 = y[0];
|
|
|
525 |
for (i=1; i<n; i++) {
|
|
|
526 |
x2 = x[i];
|
|
|
527 |
y2 = y[i];
|
| 5148 |
ripley |
528 |
PicTeX_ClipLine(x1, y1, x2, y2, ptd);
|
|
|
529 |
fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
|
|
|
530 |
ptd->clippedx0, ptd->clippedy0,
|
|
|
531 |
ptd->clippedx1, ptd->clippedy1);
|
| 9004 |
ripley |
532 |
x1 = x2;
|
|
|
533 |
y1 = y2;
|
|
|
534 |
}
|
|
|
535 |
x2 = x[0];
|
|
|
536 |
y2 = y[0];
|
|
|
537 |
PicTeX_ClipLine(x1, y1, x2, y2, ptd);
|
|
|
538 |
fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
|
|
|
539 |
ptd->clippedx0, ptd->clippedy0,
|
|
|
540 |
ptd->clippedx1, ptd->clippedy1);
|
| 5148 |
ripley |
541 |
}
|
|
|
542 |
|
|
|
543 |
/* TeX Text Translations */
|
| 44271 |
ripley |
544 |
static void textext(const char *str, picTeXDesc *ptd)
|
| 5148 |
ripley |
545 |
{
|
| 9004 |
ripley |
546 |
fputc('{', ptd->texfp);
|
|
|
547 |
for( ; *str ; str++)
|
|
|
548 |
switch(*str) {
|
|
|
549 |
case '$':
|
|
|
550 |
fprintf(ptd->texfp, "\\$");
|
|
|
551 |
break;
|
| 5148 |
ripley |
552 |
|
| 9004 |
ripley |
553 |
case '%':
|
|
|
554 |
fprintf(ptd->texfp, "\\%%");
|
|
|
555 |
break;
|
| 5148 |
ripley |
556 |
|
| 9004 |
ripley |
557 |
case '{':
|
|
|
558 |
fprintf(ptd->texfp, "\\{");
|
|
|
559 |
break;
|
| 5148 |
ripley |
560 |
|
| 9004 |
ripley |
561 |
case '}':
|
|
|
562 |
fprintf(ptd->texfp, "\\}");
|
|
|
563 |
break;
|
| 5148 |
ripley |
564 |
|
| 9004 |
ripley |
565 |
case '^':
|
|
|
566 |
fprintf(ptd->texfp, "\\^{}");
|
|
|
567 |
break;
|
| 5148 |
ripley |
568 |
|
| 9004 |
ripley |
569 |
default:
|
|
|
570 |
fputc(*str, ptd->texfp);
|
|
|
571 |
break;
|
|
|
572 |
}
|
|
|
573 |
fprintf(ptd->texfp,"} ");
|
| 5148 |
ripley |
574 |
}
|
|
|
575 |
|
|
|
576 |
/* Rotated Text */
|
|
|
577 |
|
| 44271 |
ripley |
578 |
static void PicTeX_Text(double x, double y, const char *str,
|
| 27236 |
murrell |
579 |
double rot, double hadj,
|
| 44500 |
ripley |
580 |
const pGEcontext gc,
|
| 44299 |
ripley |
581 |
pDevDesc dd)
|
| 5148 |
ripley |
582 |
{
|
| 9004 |
ripley |
583 |
int size;
|
|
|
584 |
double xoff = 0.0, yoff = 0.0;
|
|
|
585 |
picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
|
| 5148 |
ripley |
586 |
|
| 59184 |
ripley |
587 |
size = (int)(gc->cex * gc->ps + 0.5);
|
| 27236 |
murrell |
588 |
SetFont(gc->fontface, size, ptd);
|
| 11067 |
maechler |
589 |
if(ptd->debug)
|
|
|
590 |
fprintf(ptd->texfp,
|
|
|
591 |
"%% Writing string of length %.2f, at %.2f %.2f, xc = %.2f yc = %.2f\n",
|
| 27236 |
murrell |
592 |
(double)PicTeX_StrWidth(str, gc, dd),
|
| 17112 |
murrell |
593 |
x, y, 0.0, 0.0);
|
| 35776 |
ripley |
594 |
#if 0 /* Original */
|
| 9004 |
ripley |
595 |
fprintf(ptd->texfp,"\\put ");
|
|
|
596 |
textext(str, ptd);
|
|
|
597 |
if (rot == 90 )
|
| 12976 |
pd |
598 |
fprintf(ptd->texfp," [rB] <%.2fpt,%.2fpt>", xoff, yoff);
|
| 9004 |
ripley |
599 |
else fprintf(ptd->texfp," [lB] <%.2fpt,%.2fpt>", xoff, yoff);
|
| 35776 |
ripley |
600 |
#else /* use rotatebox */
|
|
|
601 |
if (rot == 90 ){
|
|
|
602 |
fprintf(ptd->texfp,"\\put {\\rotatebox{%d}",(int)rot);
|
|
|
603 |
textext(str, ptd);
|
|
|
604 |
fprintf(ptd->texfp,"} [rB] <%.2fpt,%.2fpt>", xoff, yoff);
|
| 35795 |
ripley |
605 |
} else {
|
| 35776 |
ripley |
606 |
fprintf(ptd->texfp,"\\put ");
|
|
|
607 |
textext(str, ptd);
|
|
|
608 |
fprintf(ptd->texfp," [lB] <%.2fpt,%.2fpt>", xoff, yoff);
|
|
|
609 |
}
|
|
|
610 |
#endif
|
| 9004 |
ripley |
611 |
fprintf(ptd->texfp," at %.2f %.2f\n", x, y);
|
| 5148 |
ripley |
612 |
}
|
|
|
613 |
|
| 78759 |
murrell |
614 |
static SEXP PicTeX_setPattern(SEXP pattern, pDevDesc dd) {
|
|
|
615 |
return R_NilValue;
|
|
|
616 |
}
|
|
|
617 |
|
|
|
618 |
static void PicTeX_releasePattern(SEXP ref, pDevDesc dd) {}
|
|
|
619 |
|
|
|
620 |
static SEXP PicTeX_setClipPath(SEXP path, SEXP ref, pDevDesc dd) {
|
|
|
621 |
return R_NilValue;
|
|
|
622 |
}
|
|
|
623 |
|
|
|
624 |
static void PicTeX_releaseClipPath(SEXP ref, pDevDesc dd) {}
|
|
|
625 |
|
|
|
626 |
static SEXP PicTeX_setMask(SEXP path, SEXP ref, pDevDesc dd) {
|
|
|
627 |
return R_NilValue;
|
|
|
628 |
}
|
|
|
629 |
|
|
|
630 |
static void PicTeX_releaseMask(SEXP ref, pDevDesc dd) {}
|
|
|
631 |
|
|
|
632 |
|
| 32250 |
ripley |
633 |
static
|
| 87953 |
ripley |
634 |
bool PicTeXDeviceDriver(pDevDesc dd, const char *filename,
|
|
|
635 |
const char *bg, const char *fg,
|
|
|
636 |
double width, double height,
|
|
|
637 |
bool debug)
|
| 5148 |
ripley |
638 |
{
|
| 9004 |
ripley |
639 |
picTeXDesc *ptd;
|
| 5148 |
ripley |
640 |
|
| 9004 |
ripley |
641 |
if (!(ptd = (picTeXDesc *) malloc(sizeof(picTeXDesc))))
|
| 11067 |
maechler |
642 |
return FALSE;
|
| 72944 |
maechler |
643 |
if (!(ptd->texfp = R_fopen(R_ExpandFileName(filename), "w"))) {
|
|
|
644 |
free(ptd);
|
| 87953 |
ripley |
645 |
return false;
|
| 72944 |
maechler |
646 |
}
|
| 5148 |
ripley |
647 |
|
| 9004 |
ripley |
648 |
strcpy(ptd->filename, filename);
|
| 5148 |
ripley |
649 |
|
| 44240 |
ripley |
650 |
dd->startfill = R_GE_str2col(bg);
|
|
|
651 |
dd->startcol = R_GE_str2col(fg);
|
| 17165 |
murrell |
652 |
dd->startps = 10;
|
|
|
653 |
dd->startlty = 0;
|
|
|
654 |
dd->startfont = 1;
|
|
|
655 |
dd->startgamma = 1;
|
|
|
656 |
|
| 17112 |
murrell |
657 |
dd->close = PicTeX_Close;
|
|
|
658 |
dd->clip = PicTeX_Clip;
|
|
|
659 |
dd->size = PicTeX_Size;
|
|
|
660 |
dd->newPage = PicTeX_NewPage;
|
|
|
661 |
dd->line = PicTeX_Line;
|
|
|
662 |
dd->text = PicTeX_Text;
|
|
|
663 |
dd->strWidth = PicTeX_StrWidth;
|
|
|
664 |
dd->rect = PicTeX_Rect;
|
|
|
665 |
dd->circle = PicTeX_Circle;
|
| 56857 |
ripley |
666 |
/* dd->path = PicTeX_Path; not implemented */
|
| 17112 |
murrell |
667 |
dd->polygon = PicTeX_Polygon;
|
|
|
668 |
dd->polyline = PicTeX_Polyline;
|
|
|
669 |
dd->metricInfo = PicTeX_MetricInfo;
|
| 43975 |
ripley |
670 |
dd->hasTextUTF8 = FALSE;
|
| 44170 |
ripley |
671 |
dd->useRotatedTextInContour = FALSE;
|
| 78759 |
murrell |
672 |
dd->setPattern = PicTeX_setPattern;
|
|
|
673 |
dd->releasePattern = PicTeX_releasePattern;
|
|
|
674 |
dd->setClipPath = PicTeX_setClipPath;
|
|
|
675 |
dd->releaseClipPath = PicTeX_releaseClipPath;
|
|
|
676 |
dd->setMask = PicTeX_setMask;
|
|
|
677 |
dd->releaseMask = PicTeX_releaseMask;
|
| 5148 |
ripley |
678 |
|
| 9004 |
ripley |
679 |
/* Screen Dimensions in Pixels */
|
| 6251 |
pd |
680 |
|
| 17112 |
murrell |
681 |
dd->left = 0; /* left */
|
|
|
682 |
dd->right = in2dots(width);/* right */
|
|
|
683 |
dd->bottom = 0; /* bottom */
|
|
|
684 |
dd->top = in2dots(height);/* top */
|
| 65257 |
ripley |
685 |
dd->clipLeft = dd->left; dd->clipRight = dd->right;
|
|
|
686 |
dd->clipBottom = dd->bottom; dd->clipTop = dd->top;
|
| 9004 |
ripley |
687 |
ptd->width = width;
|
|
|
688 |
ptd->height = height;
|
| 5148 |
ripley |
689 |
|
| 72944 |
maechler |
690 |
// PicTeX_Open():
|
|
|
691 |
ptd->fontsize = 0;
|
|
|
692 |
ptd->fontface = 0;
|
|
|
693 |
ptd->debug = FALSE;
|
|
|
694 |
fprintf(ptd->texfp, "\\hbox{\\beginpicture\n");
|
|
|
695 |
fprintf(ptd->texfp, "\\setcoordinatesystem units <1pt,1pt>\n");
|
|
|
696 |
fprintf(ptd->texfp,
|
|
|
697 |
"\\setplotarea x from 0 to %.2f, y from 0 to %.2f\n",
|
|
|
698 |
in2dots(ptd->width), in2dots(ptd->height));
|
|
|
699 |
fprintf(ptd->texfp,"\\setlinear\n");
|
|
|
700 |
fprintf(ptd->texfp, "\\font\\picfont cmss10\\picfont\n");
|
|
|
701 |
SetFont(1, 10, ptd);
|
|
|
702 |
ptd->pageno++;
|
| 5148 |
ripley |
703 |
|
| 9004 |
ripley |
704 |
/* Base Pointsize */
|
|
|
705 |
/* Nominal Character Sizes in Pixels */
|
| 5148 |
ripley |
706 |
|
| 44444 |
ripley |
707 |
dd->cra[0] = 9;
|
|
|
708 |
dd->cra[1] = 12;
|
| 5148 |
ripley |
709 |
|
| 9004 |
ripley |
710 |
/* Character Addressing Offsets */
|
|
|
711 |
/* These offsets should center a single */
|
|
|
712 |
/* plotting character over the plotting point. */
|
|
|
713 |
/* Pure guesswork and eyeballing ... */
|
| 5148 |
ripley |
714 |
|
| 17112 |
murrell |
715 |
dd->xCharOffset = 0; /*0.4900;*/
|
|
|
716 |
dd->yCharOffset = 0; /*0.3333;*/
|
|
|
717 |
dd->yLineBias = 0; /*0.1;*/
|
| 5148 |
ripley |
718 |
|
| 9004 |
ripley |
719 |
/* Inches per Raster Unit */
|
| 11067 |
maechler |
720 |
/* We use printer points, i.e. 72.27 dots per inch : */
|
| 17112 |
murrell |
721 |
dd->ipr[0] = dd->ipr[1] = 1./DOTSperIN;
|
| 5148 |
ripley |
722 |
|
| 17112 |
murrell |
723 |
dd->canClip = TRUE;
|
|
|
724 |
dd->canHAdj = 0;
|
| 17165 |
murrell |
725 |
dd->canChangeGamma = FALSE;
|
| 5148 |
ripley |
726 |
|
| 9004 |
ripley |
727 |
ptd->lty = 1;
|
|
|
728 |
ptd->pageno = 0;
|
|
|
729 |
ptd->debug = debug;
|
| 5148 |
ripley |
730 |
|
| 56848 |
ripley |
731 |
dd->haveTransparency = 1;
|
| 56850 |
ripley |
732 |
dd->haveTransparentBg = 2;
|
| 56848 |
ripley |
733 |
|
| 9004 |
ripley |
734 |
dd->deviceSpecific = (void *) ptd;
|
| 11067 |
maechler |
735 |
dd->displayListOn = FALSE;
|
| 78759 |
murrell |
736 |
dd->deviceVersion = R_GE_definitions;
|
|
|
737 |
|
| 11067 |
maechler |
738 |
return TRUE;
|
| 5148 |
ripley |
739 |
}
|
| 17112 |
murrell |
740 |
|
| 32250 |
ripley |
741 |
/* PicTeX Device Driver Parameters
|
|
|
742 |
* --------------------
|
|
|
743 |
* file = output filename
|
|
|
744 |
* bg = background color
|
|
|
745 |
* fg = foreground color
|
|
|
746 |
* width = width in inches
|
|
|
747 |
* height = height in inches
|
| 87953 |
ripley |
748 |
* debug = if TRUE, write TeX-Comments into output.
|
| 32250 |
ripley |
749 |
*/
|
|
|
750 |
|
| 32254 |
ripley |
751 |
SEXP PicTeX(SEXP args)
|
| 17112 |
murrell |
752 |
{
|
| 44500 |
ripley |
753 |
pGEDevDesc dd;
|
| 41781 |
ripley |
754 |
const char *file, *bg, *fg;
|
| 32250 |
ripley |
755 |
double height, width;
|
| 87953 |
ripley |
756 |
int debug;
|
| 32250 |
ripley |
757 |
|
| 63181 |
ripley |
758 |
const void *vmax = vmaxget();
|
| 32254 |
ripley |
759 |
args = CDR(args); /* skip entry point name */
|
| 85447 |
ripley |
760 |
|
|
|
761 |
SEXP tmp = asChar(CAR(args));
|
|
|
762 |
if (tmp == NA_STRING)
|
|
|
763 |
error(_("invalid 'file' parameter in %s"), "pictex");
|
|
|
764 |
file = translateCharFP(tmp); args = CDR(args);
|
| 33771 |
murdoch |
765 |
bg = CHAR(asChar(CAR(args))); args = CDR(args);
|
|
|
766 |
fg = CHAR(asChar(CAR(args))); args = CDR(args);
|
| 32250 |
ripley |
767 |
width = asReal(CAR(args)); args = CDR(args);
|
|
|
768 |
height = asReal(CAR(args)); args = CDR(args);
|
| 87953 |
ripley |
769 |
debug = asLogical(CAR(args)); args = CDR(args);
|
| 32250 |
ripley |
770 |
if(debug == NA_LOGICAL) debug = FALSE;
|
|
|
771 |
|
|
|
772 |
R_CheckDeviceAvailable();
|
|
|
773 |
BEGIN_SUSPEND_INTERRUPTS {
|
| 44299 |
ripley |
774 |
pDevDesc dev;
|
| 88803 |
murrell |
775 |
if (!(dev = GEcreateDD()))
|
| 87953 |
ripley |
776 |
error(_("unable to start %s() device"), "pictex");
|
|
|
777 |
// return 0; // that is not a SEXP
|
|
|
778 |
if(!PicTeXDeviceDriver(dev, file, bg, fg, width, height,
|
|
|
779 |
(bool) debug)) {
|
| 88803 |
murrell |
780 |
GEfreeDD(dev);
|
| 52764 |
ripley |
781 |
error(_("unable to start %s() device"), "pictex");
|
| 32250 |
ripley |
782 |
}
|
|
|
783 |
dd = GEcreateDevDesc(dev);
|
| 65632 |
ripley |
784 |
GEaddDevice2f(dd, "pictex", file);
|
| 32250 |
ripley |
785 |
} END_SUSPEND_INTERRUPTS;
|
|
|
786 |
vmaxset(vmax);
|
|
|
787 |
return R_NilValue;
|
| 17112 |
murrell |
788 |
}
|