The R Project SVN R

Rev

Rev 19912 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 19912 Rev 27236
1
/*
1
/*
2
 *  A PicTeX device, (C) 1996 Valerio Aimale, for
2
 *  A PicTeX device, (C) 1996 Valerio Aimale, for
3
 *  R : A Computer Language for Statistical Data Analysis
3
 *  R : A Computer Language for Statistical Data Analysis
4
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
4
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
5
 *  Copyright (C) 2001  The R Development Core Team
5
 *  Copyright (C) 2001  The R Development Core Team
6
 *
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
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
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
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
10
 *  (at your option) any later version.
11
 *
11
 *
12
 *  This program is distributed in the hope that it will be useful,
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
15
 *  GNU General Public License for more details.
16
 *
16
 *
17
 *  You should have received a copy of the GNU General Public License
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
20
 */
21
 
21
 
22
#ifdef HAVE_CONFIG_H
22
#ifdef HAVE_CONFIG_H
23
#include <config.h>
23
#include <config.h>
24
#endif
24
#endif
25
 
25
 
26
#include "Defn.h"
26
#include "Defn.h"
27
#include "Graphics.h"
27
#include "Graphics.h"
28
#include "Fileio.h"
28
#include "Fileio.h"
29
#include <Rdevices.h>
29
#include <Rdevices.h>
30
 
30
 
31
	/* device-specific information per picTeX device */
31
	/* device-specific information per picTeX device */
32
 
32
 
33
#define DOTSperIN	72.27
33
#define DOTSperIN	72.27
34
#define in2dots(x) 	(DOTSperIN * x)
34
#define in2dots(x) 	(DOTSperIN * x)
35
 
35
 
36
typedef struct {
36
typedef struct {
37
    FILE *texfp;
37
    FILE *texfp;
38
    char filename[128];
38
    char filename[128];
39
    int pageno;
39
    int pageno;
40
    int landscape;
40
    int landscape;
41
    double width;
41
    double width;
42
    double height;
42
    double height;
43
    double pagewidth;
43
    double pagewidth;
44
    double pageheight;
44
    double pageheight;
45
    double xlast;
45
    double xlast;
46
    double ylast;
46
    double ylast;
47
    double clipleft, clipright, cliptop, clipbottom;
47
    double clipleft, clipright, cliptop, clipbottom;
48
    double clippedx0, clippedy0, clippedx1, clippedy1;
48
    double clippedx0, clippedy0, clippedx1, clippedy1;
49
    int lty;
49
    int lty;
50
    rcolor col;
50
    rcolor col;
51
    rcolor fill;
51
    rcolor fill;
52
    int fontsize;
52
    int fontsize;
53
    int fontface;
53
    int fontface;
54
    Rboolean debug;
54
    Rboolean debug;
55
} picTeXDesc;
55
} picTeXDesc;
56
 
56
 
57
 
57
 
58
	/* Global device information */
58
	/* Global device information */
59
 
59
 
60
static const double charwidth[4][128] = {
60
static const double charwidth[4][128] = {
61
{
61
{
62
  0.5416690, 0.8333360, 0.7777810, 0.6111145, 0.6666690, 0.7083380, 0.7222240,
62
  0.5416690, 0.8333360, 0.7777810, 0.6111145, 0.6666690, 0.7083380, 0.7222240,
63
  0.7777810, 0.7222240, 0.7777810, 0.7222240, 0.5833360, 0.5361130, 0.5361130,
63
  0.7777810, 0.7222240, 0.7777810, 0.7222240, 0.5833360, 0.5361130, 0.5361130,
64
  0.8138910, 0.8138910, 0.2388900, 0.2666680, 0.5000020, 0.5000020, 0.5000020,
64
  0.8138910, 0.8138910, 0.2388900, 0.2666680, 0.5000020, 0.5000020, 0.5000020,
65
  0.5000020, 0.5000020, 0.6666700, 0.4444460, 0.4805580, 0.7222240, 0.7777810,
65
  0.5000020, 0.5000020, 0.6666700, 0.4444460, 0.4805580, 0.7222240, 0.7777810,
66
  0.5000020, 0.8611145, 0.9722260, 0.7777810, 0.2388900, 0.3194460, 0.5000020,
66
  0.5000020, 0.8611145, 0.9722260, 0.7777810, 0.2388900, 0.3194460, 0.5000020,
67
  0.8333360, 0.5000020, 0.8333360, 0.7583360, 0.2777790, 0.3888900, 0.3888900,
67
  0.8333360, 0.5000020, 0.8333360, 0.7583360, 0.2777790, 0.3888900, 0.3888900,
68
  0.5000020, 0.7777810, 0.2777790, 0.3333340, 0.2777790, 0.5000020, 0.5000020,
68
  0.5000020, 0.7777810, 0.2777790, 0.3333340, 0.2777790, 0.5000020, 0.5000020,
69
  0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020,
69
  0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020,
70
  0.5000020, 0.5000020, 0.2777790, 0.2777790, 0.3194460, 0.7777810, 0.4722240,
70
  0.5000020, 0.5000020, 0.2777790, 0.2777790, 0.3194460, 0.7777810, 0.4722240,
71
  0.4722240, 0.6666690, 0.6666700, 0.6666700, 0.6388910, 0.7222260, 0.5972240,
71
  0.4722240, 0.6666690, 0.6666700, 0.6666700, 0.6388910, 0.7222260, 0.5972240,
72
  0.5694475, 0.6666690, 0.7083380, 0.2777810, 0.4722240, 0.6944480, 0.5416690,
72
  0.5694475, 0.6666690, 0.7083380, 0.2777810, 0.4722240, 0.6944480, 0.5416690,
73
  0.8750050, 0.7083380, 0.7361130, 0.6388910, 0.7361130, 0.6458360, 0.5555570,
73
  0.8750050, 0.7083380, 0.7361130, 0.6388910, 0.7361130, 0.6458360, 0.5555570,
74
  0.6805570, 0.6875050, 0.6666700, 0.9444480, 0.6666700, 0.6666700, 0.6111130,
74
  0.6805570, 0.6875050, 0.6666700, 0.9444480, 0.6666700, 0.6666700, 0.6111130,
75
  0.2888900, 0.5000020, 0.2888900, 0.5000020, 0.2777790, 0.2777790, 0.4805570,
75
  0.2888900, 0.5000020, 0.2888900, 0.5000020, 0.2777790, 0.2777790, 0.4805570,
76
  0.5166680, 0.4444460, 0.5166680, 0.4444460, 0.3055570, 0.5000020, 0.5166680,
76
  0.5166680, 0.4444460, 0.5166680, 0.4444460, 0.3055570, 0.5000020, 0.5166680,
77
  0.2388900, 0.2666680, 0.4888920, 0.2388900, 0.7944470, 0.5166680, 0.5000020,
77
  0.2388900, 0.2666680, 0.4888920, 0.2388900, 0.7944470, 0.5166680, 0.5000020,
78
  0.5166680, 0.5166680, 0.3416690, 0.3833340, 0.3611120, 0.5166680, 0.4611130,
78
  0.5166680, 0.5166680, 0.3416690, 0.3833340, 0.3611120, 0.5166680, 0.4611130,
79
  0.6833360, 0.4611130, 0.4611130, 0.4347230, 0.5000020, 1.0000030, 0.5000020,
79
  0.6833360, 0.4611130, 0.4611130, 0.4347230, 0.5000020, 1.0000030, 0.5000020,
80
  0.5000020, 0.5000020
80
  0.5000020, 0.5000020
81
},
81
},
82
{
82
{
83
  0.5805590, 0.9166720, 0.8555600, 0.6722260, 0.7333370, 0.7944490, 0.7944490,
83
  0.5805590, 0.9166720, 0.8555600, 0.6722260, 0.7333370, 0.7944490, 0.7944490,
84
  0.8555600, 0.7944490, 0.8555600, 0.7944490, 0.6416700, 0.5861150, 0.5861150,
84
  0.8555600, 0.7944490, 0.8555600, 0.7944490, 0.6416700, 0.5861150, 0.5861150,
85
  0.8916720, 0.8916720, 0.2555570, 0.2861130, 0.5500030, 0.5500030, 0.5500030,
85
  0.8916720, 0.8916720, 0.2555570, 0.2861130, 0.5500030, 0.5500030, 0.5500030,
86
  0.5500030, 0.5500030, 0.7333370, 0.4888920, 0.5652800, 0.7944490, 0.8555600,
86
  0.5500030, 0.5500030, 0.7333370, 0.4888920, 0.5652800, 0.7944490, 0.8555600,
87
  0.5500030, 0.9472275, 1.0694500, 0.8555600, 0.2555570, 0.3666690, 0.5583360,
87
  0.5500030, 0.9472275, 1.0694500, 0.8555600, 0.2555570, 0.3666690, 0.5583360,
88
  0.9166720, 0.5500030, 1.0291190, 0.8305610, 0.3055570, 0.4277800, 0.4277800,
88
  0.9166720, 0.5500030, 1.0291190, 0.8305610, 0.3055570, 0.4277800, 0.4277800,
89
  0.5500030, 0.8555600, 0.3055570, 0.3666690, 0.3055570, 0.5500030, 0.5500030,
89
  0.5500030, 0.8555600, 0.3055570, 0.3666690, 0.3055570, 0.5500030, 0.5500030,
90
  0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030,
90
  0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030,
91
  0.5500030, 0.5500030, 0.3055570, 0.3055570, 0.3666690, 0.8555600, 0.5194470,
91
  0.5500030, 0.5500030, 0.3055570, 0.3055570, 0.3666690, 0.8555600, 0.5194470,
92
  0.5194470, 0.7333370, 0.7333370, 0.7333370, 0.7027820, 0.7944490, 0.6416700,
92
  0.5194470, 0.7333370, 0.7333370, 0.7333370, 0.7027820, 0.7944490, 0.6416700,
93
  0.6111145, 0.7333370, 0.7944490, 0.3305570, 0.5194470, 0.7638930, 0.5805590,
93
  0.6111145, 0.7333370, 0.7944490, 0.3305570, 0.5194470, 0.7638930, 0.5805590,
94
  0.9777830, 0.7944490, 0.7944490, 0.7027820, 0.7944490, 0.7027820, 0.6111145,
94
  0.9777830, 0.7944490, 0.7944490, 0.7027820, 0.7944490, 0.7027820, 0.6111145,
95
  0.7333370, 0.7638930, 0.7333370, 1.0388950, 0.7333370, 0.7333370, 0.6722260,
95
  0.7333370, 0.7638930, 0.7333370, 1.0388950, 0.7333370, 0.7333370, 0.6722260,
96
  0.3430580, 0.5583360, 0.3430580, 0.5500030, 0.3055570, 0.3055570, 0.5250030,
96
  0.3430580, 0.5583360, 0.3430580, 0.5500030, 0.3055570, 0.3055570, 0.5250030,
97
  0.5611140, 0.4888920, 0.5611140, 0.5111140, 0.3361130, 0.5500030, 0.5611140,
97
  0.5611140, 0.4888920, 0.5611140, 0.5111140, 0.3361130, 0.5500030, 0.5611140,
98
  0.2555570, 0.2861130, 0.5305590, 0.2555570, 0.8666720, 0.5611140, 0.5500030,
98
  0.2555570, 0.2861130, 0.5305590, 0.2555570, 0.8666720, 0.5611140, 0.5500030,
99
  0.5611140, 0.5611140, 0.3722250, 0.4216690, 0.4041690, 0.5611140, 0.5000030,
99
  0.5611140, 0.5611140, 0.3722250, 0.4216690, 0.4041690, 0.5611140, 0.5000030,
100
  0.7444490, 0.5000030, 0.5000030, 0.4763920, 0.5500030, 1.1000060, 0.5500030,
100
  0.7444490, 0.5000030, 0.5000030, 0.4763920, 0.5500030, 1.1000060, 0.5500030,
101
  0.5500030, 0.550003 },
101
  0.5500030, 0.550003 },
102
{
102
{
103
  0.5416690, 0.8333360, 0.7777810, 0.6111145, 0.6666690, 0.7083380, 0.7222240,
103
  0.5416690, 0.8333360, 0.7777810, 0.6111145, 0.6666690, 0.7083380, 0.7222240,
104
  0.7777810, 0.7222240, 0.7777810, 0.7222240, 0.5833360, 0.5361130, 0.5361130,
104
  0.7777810, 0.7222240, 0.7777810, 0.7222240, 0.5833360, 0.5361130, 0.5361130,
105
  0.8138910, 0.8138910, 0.2388900, 0.2666680, 0.5000020, 0.5000020, 0.5000020,
105
  0.8138910, 0.8138910, 0.2388900, 0.2666680, 0.5000020, 0.5000020, 0.5000020,
106
  0.5000020, 0.5000020, 0.7375210, 0.4444460, 0.4805580, 0.7222240, 0.7777810,
106
  0.5000020, 0.5000020, 0.7375210, 0.4444460, 0.4805580, 0.7222240, 0.7777810,
107
  0.5000020, 0.8611145, 0.9722260, 0.7777810, 0.2388900, 0.3194460, 0.5000020,
107
  0.5000020, 0.8611145, 0.9722260, 0.7777810, 0.2388900, 0.3194460, 0.5000020,
108
  0.8333360, 0.5000020, 0.8333360, 0.7583360, 0.2777790, 0.3888900, 0.3888900,
108
  0.8333360, 0.5000020, 0.8333360, 0.7583360, 0.2777790, 0.3888900, 0.3888900,
109
  0.5000020, 0.7777810, 0.2777790, 0.3333340, 0.2777790, 0.5000020, 0.5000020,
109
  0.5000020, 0.7777810, 0.2777790, 0.3333340, 0.2777790, 0.5000020, 0.5000020,
110
  0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020,
110
  0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020, 0.5000020,
111
  0.5000020, 0.5000020, 0.2777790, 0.2777790, 0.3194460, 0.7777810, 0.4722240,
111
  0.5000020, 0.5000020, 0.2777790, 0.2777790, 0.3194460, 0.7777810, 0.4722240,
112
  0.4722240, 0.6666690, 0.6666700, 0.6666700, 0.6388910, 0.7222260, 0.5972240,
112
  0.4722240, 0.6666690, 0.6666700, 0.6666700, 0.6388910, 0.7222260, 0.5972240,
113
  0.5694475, 0.6666690, 0.7083380, 0.2777810, 0.4722240, 0.6944480, 0.5416690,
113
  0.5694475, 0.6666690, 0.7083380, 0.2777810, 0.4722240, 0.6944480, 0.5416690,
114
  0.8750050, 0.7083380, 0.7361130, 0.6388910, 0.7361130, 0.6458360, 0.5555570,
114
  0.8750050, 0.7083380, 0.7361130, 0.6388910, 0.7361130, 0.6458360, 0.5555570,
115
  0.6805570, 0.6875050, 0.6666700, 0.9444480, 0.6666700, 0.6666700, 0.6111130,
115
  0.6805570, 0.6875050, 0.6666700, 0.9444480, 0.6666700, 0.6666700, 0.6111130,
116
  0.2888900, 0.5000020, 0.2888900, 0.5000020, 0.2777790, 0.2777790, 0.4805570,
116
  0.2888900, 0.5000020, 0.2888900, 0.5000020, 0.2777790, 0.2777790, 0.4805570,
117
  0.5166680, 0.4444460, 0.5166680, 0.4444460, 0.3055570, 0.5000020, 0.5166680,
117
  0.5166680, 0.4444460, 0.5166680, 0.4444460, 0.3055570, 0.5000020, 0.5166680,
118
  0.2388900, 0.2666680, 0.4888920, 0.2388900, 0.7944470, 0.5166680, 0.5000020,
118
  0.2388900, 0.2666680, 0.4888920, 0.2388900, 0.7944470, 0.5166680, 0.5000020,
119
  0.5166680, 0.5166680, 0.3416690, 0.3833340, 0.3611120, 0.5166680, 0.4611130,
119
  0.5166680, 0.5166680, 0.3416690, 0.3833340, 0.3611120, 0.5166680, 0.4611130,
120
  0.6833360, 0.4611130, 0.4611130, 0.4347230, 0.5000020, 1.0000030, 0.5000020,
120
  0.6833360, 0.4611130, 0.4611130, 0.4347230, 0.5000020, 1.0000030, 0.5000020,
121
  0.5000020, 0.5000020 },
121
  0.5000020, 0.5000020 },
122
{
122
{
123
  0.5805590, 0.9166720, 0.8555600, 0.6722260, 0.7333370, 0.7944490, 0.7944490,
123
  0.5805590, 0.9166720, 0.8555600, 0.6722260, 0.7333370, 0.7944490, 0.7944490,
124
  0.8555600, 0.7944490, 0.8555600, 0.7944490, 0.6416700, 0.5861150, 0.5861150,
124
  0.8555600, 0.7944490, 0.8555600, 0.7944490, 0.6416700, 0.5861150, 0.5861150,
125
  0.8916720, 0.8916720, 0.2555570, 0.2861130, 0.5500030, 0.5500030, 0.5500030,
125
  0.8916720, 0.8916720, 0.2555570, 0.2861130, 0.5500030, 0.5500030, 0.5500030,
126
  0.5500030, 0.5500030, 0.8002530, 0.4888920, 0.5652800, 0.7944490, 0.8555600,
126
  0.5500030, 0.5500030, 0.8002530, 0.4888920, 0.5652800, 0.7944490, 0.8555600,
127
  0.5500030, 0.9472275, 1.0694500, 0.8555600, 0.2555570, 0.3666690, 0.5583360,
127
  0.5500030, 0.9472275, 1.0694500, 0.8555600, 0.2555570, 0.3666690, 0.5583360,
128
  0.9166720, 0.5500030, 1.0291190, 0.8305610, 0.3055570, 0.4277800, 0.4277800,
128
  0.9166720, 0.5500030, 1.0291190, 0.8305610, 0.3055570, 0.4277800, 0.4277800,
129
  0.5500030, 0.8555600, 0.3055570, 0.3666690, 0.3055570, 0.5500030, 0.5500030,
129
  0.5500030, 0.8555600, 0.3055570, 0.3666690, 0.3055570, 0.5500030, 0.5500030,
130
  0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030,
130
  0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030, 0.5500030,
131
  0.5500030, 0.5500030, 0.3055570, 0.3055570, 0.3666690, 0.8555600, 0.5194470,
131
  0.5500030, 0.5500030, 0.3055570, 0.3055570, 0.3666690, 0.8555600, 0.5194470,
132
  0.5194470, 0.7333370, 0.7333370, 0.7333370, 0.7027820, 0.7944490, 0.6416700,
132
  0.5194470, 0.7333370, 0.7333370, 0.7333370, 0.7027820, 0.7944490, 0.6416700,
133
  0.6111145, 0.7333370, 0.7944490, 0.3305570, 0.5194470, 0.7638930, 0.5805590,
133
  0.6111145, 0.7333370, 0.7944490, 0.3305570, 0.5194470, 0.7638930, 0.5805590,
134
  0.9777830, 0.7944490, 0.7944490, 0.7027820, 0.7944490, 0.7027820, 0.6111145,
134
  0.9777830, 0.7944490, 0.7944490, 0.7027820, 0.7944490, 0.7027820, 0.6111145,
135
  0.7333370, 0.7638930, 0.7333370, 1.0388950, 0.7333370, 0.7333370, 0.6722260,
135
  0.7333370, 0.7638930, 0.7333370, 1.0388950, 0.7333370, 0.7333370, 0.6722260,
136
  0.3430580, 0.5583360, 0.3430580, 0.5500030, 0.3055570, 0.3055570, 0.5250030,
136
  0.3430580, 0.5583360, 0.3430580, 0.5500030, 0.3055570, 0.3055570, 0.5250030,
137
  0.5611140, 0.4888920, 0.5611140, 0.5111140, 0.3361130, 0.5500030, 0.5611140,
137
  0.5611140, 0.4888920, 0.5611140, 0.5111140, 0.3361130, 0.5500030, 0.5611140,
138
  0.2555570, 0.2861130, 0.5305590, 0.2555570, 0.8666720, 0.5611140, 0.5500030,
138
  0.2555570, 0.2861130, 0.5305590, 0.2555570, 0.8666720, 0.5611140, 0.5500030,
139
  0.5611140, 0.5611140, 0.3722250, 0.4216690, 0.4041690, 0.5611140, 0.5000030,
139
  0.5611140, 0.5611140, 0.3722250, 0.4216690, 0.4041690, 0.5611140, 0.5000030,
140
  0.7444490, 0.5000030, 0.5000030, 0.4763920, 0.5500030, 1.1000060, 0.5500030,
140
  0.7444490, 0.5000030, 0.5000030, 0.4763920, 0.5500030, 1.1000060, 0.5500030,
141
  0.5500030, 0.550003
141
  0.5500030, 0.550003
142
}
142
}
143
};
143
};
144
 
144
 
145
static const char * const fontname[] = {
145
static const char * const fontname[] = {
146
    "cmss10",
146
    "cmss10",
147
    "cmssbx10",
147
    "cmssbx10",
148
    "cmssi10",
148
    "cmssi10",
149
    "cmssxi10"
149
    "cmssxi10"
150
};
150
};
151
 
151
 
152
 
152
 
153
	/* Device driver actions */
153
	/* Device driver actions */
154
 
154
 
155
static void PicTeX_Activate(NewDevDesc *dd);
155
static void PicTeX_Activate(NewDevDesc *dd);
156
static void PicTeX_Circle(double x, double y, double r,
156
static void PicTeX_Circle(double x, double y, double r,
157
		       int col, int fill, double gamma, int lty, double lwd,
157
			  R_GE_gcontext *gc,
158
		       NewDevDesc *dd);
158
			  NewDevDesc *dd);
159
static void PicTeX_Clip(double x0, double x1, double y0, double y1, 
159
static void PicTeX_Clip(double x0, double x1, double y0, double y1, 
160
		     NewDevDesc *dd);
160
			NewDevDesc *dd);
161
static void PicTeX_Close(NewDevDesc *dd);
161
static void PicTeX_Close(NewDevDesc *dd);
162
static void PicTeX_Deactivate(NewDevDesc *dd);
162
static void PicTeX_Deactivate(NewDevDesc *dd);
163
static void PicTeX_Hold(NewDevDesc *dd);
163
static void PicTeX_Hold(NewDevDesc *dd);
164
static Rboolean PicTeX_Locator(double *x, double *y, NewDevDesc *dd);
164
static Rboolean PicTeX_Locator(double *x, double *y, NewDevDesc *dd);
165
static void PicTeX_Line(double x1, double y1, double x2, double y2,
165
static void PicTeX_Line(double x1, double y1, double x2, double y2,
166
		     int col, double gamma, int lty, double lwd,
166
			R_GE_gcontext *gc,
167
		     NewDevDesc *dd);
167
			NewDevDesc *dd);
168
static void PicTeX_MetricInfo(int c, int font, double cex, double ps,
168
static void PicTeX_MetricInfo(int c,
-
 
169
			      R_GE_gcontext *gc,
169
			      double* ascent, double* descent,
170
			      double* ascent, double* descent,
170
			      double* width, NewDevDesc *dd);
171
			      double* width, NewDevDesc *dd);
171
static void PicTeX_Mode(int mode, NewDevDesc *dd);
172
static void PicTeX_Mode(int mode, NewDevDesc *dd);
172
static void PicTeX_NewPage(int fill, double gamma, NewDevDesc *dd);
173
static void PicTeX_NewPage(R_GE_gcontext *gc, NewDevDesc *dd);
173
static void PicTeX_Polygon(int n, double *x, double *y, 
174
static void PicTeX_Polygon(int n, double *x, double *y, 
174
			int col, int fill, double gamma, int lty, double lwd,
175
			   R_GE_gcontext *gc,
175
			NewDevDesc *dd);
176
			   NewDevDesc *dd);
176
static void PicTeX_Rect(double x0, double y0, double x1, double y1,
177
static void PicTeX_Rect(double x0, double y0, double x1, double y1,
177
		     int col, int fill, double gamma, int lty, double lwd,
178
			R_GE_gcontext *gc,
178
		     NewDevDesc *dd);
179
			NewDevDesc *dd);
179
static void PicTeX_Size(double *left, double *right,
180
static void PicTeX_Size(double *left, double *right,
180
		     double *bottom, double *top,
181
			double *bottom, double *top,
181
		     NewDevDesc *dd);
182
			NewDevDesc *dd);
182
static double PicTeX_StrWidth(char *str, int font,
183
static double PicTeX_StrWidth(char *str, 
-
 
184
			      R_GE_gcontext *gc,
183
			      double cex, double ps, NewDevDesc *dd);
185
			      NewDevDesc *dd);
184
static void PicTeX_Text(double x, double y, char *str, 
186
static void PicTeX_Text(double x, double y, char *str, 
185
		     double rot, double hadj, 
187
			double rot, double hadj, 
186
		     int col, double gamma, int font, double cex, double ps,
188
			R_GE_gcontext *gc,
187
		     NewDevDesc *dd);
189
			NewDevDesc *dd);
188
static Rboolean PicTeX_Open(NewDevDesc*, picTeXDesc*);
190
static Rboolean PicTeX_Open(NewDevDesc*, picTeXDesc*);
189
 
191
 
190
	/* Support routines */
192
	/* Support routines */
191
 
193
 
192
static void SetLinetype(int newlty, int newlwd, NewDevDesc *dd)
194
static void SetLinetype(int newlty, int newlwd, NewDevDesc *dd)
193
{
195
{
194
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
196
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
195
 
197
 
196
    int i, templty;
198
    int i, templty;
197
    ptd->lty = newlty;
199
    ptd->lty = newlty;
198
    if (ptd->lty) {
200
    if (ptd->lty) {
199
	fprintf(ptd->texfp,"\\setdashpattern <");
201
	fprintf(ptd->texfp,"\\setdashpattern <");
200
	for(i=0 ; i<8 && newlty&15 ; i++) {
202
	for(i=0 ; i<8 && newlty&15 ; i++) {
201
	    fprintf(ptd->texfp,"%dpt", newlwd * newlty&15);
203
	    fprintf(ptd->texfp,"%dpt", newlwd * newlty&15);
202
	    templty = newlty>>4;
204
	    templty = newlty>>4;
203
	    if ((i+1)<8 && templty&15) fprintf(ptd->texfp,", ");
205
	    if ((i+1)<8 && templty&15) fprintf(ptd->texfp,", ");
204
	    newlty = newlty>>4;
206
	    newlty = newlty>>4;
205
	}
207
	}
206
	fprintf(ptd->texfp,">\n");
208
	fprintf(ptd->texfp,">\n");
207
    } else fprintf(ptd->texfp,"\\setsolid\n");
209
    } else fprintf(ptd->texfp,"\\setsolid\n");
208
}
210
}
209
 
211
 
210
 
212
 
211
static void SetFont(int face, int size, picTeXDesc *ptd)
213
static void SetFont(int face, int size, picTeXDesc *ptd)
212
{
214
{
213
    int lface=face, lsize= size;
215
    int lface=face, lsize= size;
214
    if(lface < 1 || lface > 4) lface = 1;
216
    if(lface < 1 || lface > 4 ) lface = 1;
215
    if(lsize < 1 || lsize > 24) lsize = 10;
217
    if(lsize < 1 || lsize > 24) lsize = 10;
216
    if(lsize != ptd->fontsize || lface != ptd->fontface) {
218
    if(lsize != ptd->fontsize || lface != ptd->fontface) {
217
	fprintf(ptd->texfp, "\\font\\picfont %s at %dpt\\picfont\n",
219
	fprintf(ptd->texfp, "\\font\\picfont %s at %dpt\\picfont\n",
218
		fontname[lface-1], lsize);
220
		fontname[lface-1], lsize);
219
	ptd->fontsize = lsize;
221
	ptd->fontsize = lsize;
220
	ptd->fontface = lface;
222
	ptd->fontface = lface;
221
    }
223
    }
222
}
224
}
223
 
225
 
224
static void PicTeX_Activate(NewDevDesc *dd)
226
static void PicTeX_Activate(NewDevDesc *dd)
225
{
227
{
226
}
228
}
227
 
229
 
228
static void PicTeX_Deactivate(NewDevDesc *dd)
230
static void PicTeX_Deactivate(NewDevDesc *dd)
229
{
231
{
230
}
232
}
231
 
233
 
232
static void PicTeX_MetricInfo(int c, int font, double cex, double ps,
234
static void PicTeX_MetricInfo(int c, 
-
 
235
			      R_GE_gcontext *gc,
233
			      double* ascent, double* descent,
236
			      double* ascent, double* descent,
234
			      double* width, NewDevDesc *dd)
237
			      double* width, NewDevDesc *dd)
235
{
238
{
236
    /* metric information not available => return 0,0,0 */
239
    /* metric information not available => return 0,0,0 */
237
    *ascent = 0.0;
240
    *ascent = 0.0;
238
    *descent = 0.0;
241
    *descent = 0.0;
239
    *width = 0.0;
242
    *width = 0.0;
240
}
243
}
241
 
244
 
242
	/* Initialize the device */
245
	/* Initialize the device */
243
 
246
 
244
static Rboolean PicTeX_Open(NewDevDesc *dd, picTeXDesc *ptd)
247
static Rboolean PicTeX_Open(NewDevDesc *dd, picTeXDesc *ptd)
245
{
248
{
246
    ptd->fontsize = 0;
249
    ptd->fontsize = 0;
247
    ptd->fontface = 0;
250
    ptd->fontface = 0;
248
    ptd->debug = FALSE;
251
    ptd->debug = FALSE;
249
    if (!(ptd->texfp = R_fopen(R_ExpandFileName(ptd->filename), "w")))
252
    if (!(ptd->texfp = R_fopen(R_ExpandFileName(ptd->filename), "w")))
250
	return FALSE;
253
	return FALSE;
251
    fprintf(ptd->texfp, "\\hbox{\\beginpicture\n");
254
    fprintf(ptd->texfp, "\\hbox{\\beginpicture\n");
252
    fprintf(ptd->texfp, "\\setcoordinatesystem units <1pt,1pt>\n");
255
    fprintf(ptd->texfp, "\\setcoordinatesystem units <1pt,1pt>\n");
253
    fprintf(ptd->texfp,
256
    fprintf(ptd->texfp,
254
	    "\\setplotarea x from 0 to %.2f, y from 0 to %.2f\n",
257
	    "\\setplotarea x from 0 to %.2f, y from 0 to %.2f\n",
255
	    in2dots(ptd->width), in2dots(ptd->height));
258
	    in2dots(ptd->width), in2dots(ptd->height));
256
    fprintf(ptd->texfp,"\\setlinear\n");
259
    fprintf(ptd->texfp,"\\setlinear\n");
257
    fprintf(ptd->texfp, "\\font\\picfont cmss10\\picfont\n");
260
    fprintf(ptd->texfp, "\\font\\picfont cmss10\\picfont\n");
258
    SetFont(1, 10, ptd);
261
    SetFont(1, 10, ptd);
259
    ptd->pageno++;
262
    ptd->pageno++;
260
    return TRUE;
263
    return TRUE;
261
}
264
}
262
 
265
 
263
 
266
 
264
	/* Interactive Resize */
267
	/* Interactive Resize */
265
 
268
 
266
static void PicTeX_Size(double *left, double *right,
269
static void PicTeX_Size(double *left, double *right,
267
		     double *bottom, double *top,
270
		     double *bottom, double *top,
268
		     NewDevDesc *dd)
271
		     NewDevDesc *dd)
269
{
272
{
270
    *left = dd->left;		/* left */
273
    *left = dd->left;		/* left */
271
    *right = dd->right;/* right */
274
    *right = dd->right;/* right */
272
    *bottom = dd->bottom;		/* bottom */
275
    *bottom = dd->bottom;		/* bottom */
273
    *top = dd->top;/* top */
276
    *top = dd->top;/* top */
274
}
277
}
275
 
278
 
276
static void PicTeX_Clip(double x0, double x1, double y0, double y1,
279
static void PicTeX_Clip(double x0, double x1, double y0, double y1,
277
			NewDevDesc *dd)
280
			NewDevDesc *dd)
278
{
281
{
279
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
282
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
280
 
283
 
281
    if(ptd->debug)
284
    if(ptd->debug)
282
	fprintf(ptd->texfp, "%% Setting Clip Region to %.2f %.2f %.2f %.2f\n",
285
	fprintf(ptd->texfp, "%% Setting Clip Region to %.2f %.2f %.2f %.2f\n",
283
		x0, y0, x1, y1);
286
		x0, y0, x1, y1);
284
    ptd->clipleft = x0;
287
    ptd->clipleft = x0;
285
    ptd->clipright = x1;
288
    ptd->clipright = x1;
286
    ptd->clipbottom = y0;
289
    ptd->clipbottom = y0;
287
    ptd->cliptop = y1;
290
    ptd->cliptop = y1;
288
}
291
}
289
 
292
 
290
	/* Start a new page */
293
	/* Start a new page */
291
 
294
 
292
static void PicTeX_NewPage(int fill, double gamma, NewDevDesc *dd)
295
static void PicTeX_NewPage(R_GE_gcontext *gc,
-
 
296
			   NewDevDesc *dd)
293
{
297
{
294
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
298
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
295
 
299
 
296
    int face, size;
300
    int face, size;
297
    if (ptd->pageno) {
301
    if (ptd->pageno) {
298
	fprintf(ptd->texfp, "\\endpicture\n}\n\n\n");
302
	fprintf(ptd->texfp, "\\endpicture\n}\n\n\n");
299
	fprintf(ptd->texfp, "\\hbox{\\beginpicture\n");
303
	fprintf(ptd->texfp, "\\hbox{\\beginpicture\n");
300
	fprintf(ptd->texfp, "\\setcoordinatesystem units <1pt,1pt>\n");
304
	fprintf(ptd->texfp, "\\setcoordinatesystem units <1pt,1pt>\n");
301
	fprintf(ptd->texfp,
305
	fprintf(ptd->texfp,
302
		"\\setplotarea x from 0 to %.2f, y from 0 to %.2f\n",
306
		"\\setplotarea x from 0 to %.2f, y from 0 to %.2f\n",
303
		in2dots(ptd->width), in2dots(ptd->height));
307
		in2dots(ptd->width), in2dots(ptd->height));
304
	fprintf(ptd->texfp,"\\setlinear\n");
308
	fprintf(ptd->texfp,"\\setlinear\n");
305
	fprintf(ptd->texfp, "\\font\\picfont cmss10\\picfont\n");
309
	fprintf(ptd->texfp, "\\font\\picfont cmss10\\picfont\n");
306
    }
310
    }
307
    ptd->pageno++;
311
    ptd->pageno++;
308
    face = ptd->fontface;
312
    face = ptd->fontface;
309
    size = ptd->fontsize;
313
    size = ptd->fontsize;
310
    ptd->fontface = 0;
314
    ptd->fontface = 0;
311
    ptd->fontsize = 0;
315
    ptd->fontsize = 0;
312
    SetFont(face, size, ptd);
316
    SetFont(face, size, ptd);
313
}
317
}
314
 
318
 
315
	/* Close down the driver */
319
	/* Close down the driver */
316
 
320
 
317
static void PicTeX_Close(NewDevDesc *dd)
321
static void PicTeX_Close(NewDevDesc *dd)
318
{
322
{
319
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
323
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
320
 
324
 
321
    fprintf(ptd->texfp, "\\endpicture\n}\n");
325
    fprintf(ptd->texfp, "\\endpicture\n}\n");
322
    fclose(ptd->texfp);
326
    fclose(ptd->texfp);
323
 
327
 
324
    free(ptd);
328
    free(ptd);
325
}
329
}
326
 
330
 
327
	/* Draw To */
331
	/* Draw To */
328
 
332
 
329
static void PicTeX_ClipLine(double x0, double y0, double x1, double y1,
333
static void PicTeX_ClipLine(double x0, double y0, double x1, double y1,
330
			    picTeXDesc *ptd)
334
			    picTeXDesc *ptd)
331
{
335
{
332
    ptd->clippedx0 = x0; ptd->clippedx1 = x1;
336
    ptd->clippedx0 = x0; ptd->clippedx1 = x1;
333
    ptd->clippedy0 = y0; ptd->clippedy1 = y1;
337
    ptd->clippedy0 = y0; ptd->clippedy1 = y1;
334
 
338
 
335
    if ((ptd->clippedx0 < ptd->clipleft &&
339
    if ((ptd->clippedx0 < ptd->clipleft &&
336
	 ptd->clippedx1 < ptd->clipleft) ||
340
	 ptd->clippedx1 < ptd->clipleft) ||
337
	(ptd->clippedx0 > ptd->clipright &&
341
	(ptd->clippedx0 > ptd->clipright &&
338
	 ptd->clippedx1 > ptd->clipright) ||
342
	 ptd->clippedx1 > ptd->clipright) ||
339
	(ptd->clippedy0 < ptd->clipbottom &&
343
	(ptd->clippedy0 < ptd->clipbottom &&
340
	 ptd->clippedy1 < ptd->clipbottom) ||
344
	 ptd->clippedy1 < ptd->clipbottom) ||
341
	(ptd->clippedy0 > ptd->cliptop &&
345
	(ptd->clippedy0 > ptd->cliptop &&
342
	 ptd->clippedy1 > ptd->cliptop)) {
346
	 ptd->clippedy1 > ptd->cliptop)) {
343
	ptd->clippedx0 = ptd->clippedx1;
347
	ptd->clippedx0 = ptd->clippedx1;
344
	ptd->clippedy0 = ptd->clippedy1;
348
	ptd->clippedy0 = ptd->clippedy1;
345
	return;
349
	return;
346
    }
350
    }
347
 
351
 
348
    /*Clipping Left */
352
    /*Clipping Left */
349
    if (ptd->clippedx1 >= ptd->clipleft && ptd->clippedx0 < ptd->clipleft) {
353
    if (ptd->clippedx1 >= ptd->clipleft && ptd->clippedx0 < ptd->clipleft) {
350
	ptd->clippedy0 = ((ptd->clippedy1-ptd->clippedy0) /
354
	ptd->clippedy0 = ((ptd->clippedy1-ptd->clippedy0) /
351
			  (ptd->clippedx1-ptd->clippedx0) *
355
			  (ptd->clippedx1-ptd->clippedx0) *
352
			  (ptd->clipleft-ptd->clippedx0)) +
356
			  (ptd->clipleft-ptd->clippedx0)) +
353
	    ptd->clippedy0;
357
	    ptd->clippedy0;
354
	ptd->clippedx0 = ptd->clipleft;
358
	ptd->clippedx0 = ptd->clipleft;
355
    }
359
    }
356
    if (ptd->clippedx1 <= ptd->clipleft && ptd->clippedx0 > ptd->clipleft) {
360
    if (ptd->clippedx1 <= ptd->clipleft && ptd->clippedx0 > ptd->clipleft) {
357
	ptd->clippedy1 = ((ptd->clippedy1-ptd->clippedy0) /
361
	ptd->clippedy1 = ((ptd->clippedy1-ptd->clippedy0) /
358
			  (ptd->clippedx1-ptd->clippedx0) *
362
			  (ptd->clippedx1-ptd->clippedx0) *
359
			  (ptd->clipleft-ptd->clippedx0)) +
363
			  (ptd->clipleft-ptd->clippedx0)) +
360
	    ptd->clippedy0;
364
	    ptd->clippedy0;
361
	ptd->clippedx1 = ptd->clipleft;
365
	ptd->clippedx1 = ptd->clipleft;
362
    }
366
    }
363
    /* Clipping Right */
367
    /* Clipping Right */
364
    if (ptd->clippedx1 >= ptd->clipright &&
368
    if (ptd->clippedx1 >= ptd->clipright &&
365
	ptd->clippedx0 < ptd->clipright) {
369
	ptd->clippedx0 < ptd->clipright) {
366
	ptd->clippedy1 = ((ptd->clippedy1-ptd->clippedy0) /
370
	ptd->clippedy1 = ((ptd->clippedy1-ptd->clippedy0) /
367
			  (ptd->clippedx1-ptd->clippedx0) *
371
			  (ptd->clippedx1-ptd->clippedx0) *
368
			  (ptd->clipright-ptd->clippedx0)) +
372
			  (ptd->clipright-ptd->clippedx0)) +
369
	    ptd->clippedy0;
373
	    ptd->clippedy0;
370
	ptd->clippedx1 = ptd->clipright;
374
	ptd->clippedx1 = ptd->clipright;
371
    }
375
    }
372
    if (ptd->clippedx1 <= ptd->clipright &&
376
    if (ptd->clippedx1 <= ptd->clipright &&
373
	ptd->clippedx0 > ptd->clipright) {
377
	ptd->clippedx0 > ptd->clipright) {
374
	ptd->clippedy0 = ((ptd->clippedy1-ptd->clippedy0) /
378
	ptd->clippedy0 = ((ptd->clippedy1-ptd->clippedy0) /
375
			  (ptd->clippedx1-ptd->clippedx0) *
379
			  (ptd->clippedx1-ptd->clippedx0) *
376
			  (ptd->clipright-ptd->clippedx0)) +
380
			  (ptd->clipright-ptd->clippedx0)) +
377
	    ptd->clippedy0;
381
	    ptd->clippedy0;
378
	ptd->clippedx0 = ptd->clipright;
382
	ptd->clippedx0 = ptd->clipright;
379
    }
383
    }
380
    /*Clipping Bottom */
384
    /*Clipping Bottom */
381
    if (ptd->clippedy1 >= ptd->clipbottom  &&
385
    if (ptd->clippedy1 >= ptd->clipbottom  &&
382
	ptd->clippedy0 < ptd->clipbottom ) {
386
	ptd->clippedy0 < ptd->clipbottom ) {
383
	ptd->clippedx0 = ((ptd->clippedx1-ptd->clippedx0) /
387
	ptd->clippedx0 = ((ptd->clippedx1-ptd->clippedx0) /
384
			  (ptd->clippedy1-ptd->clippedy0) *
388
			  (ptd->clippedy1-ptd->clippedy0) *
385
			  (ptd->clipbottom -ptd->clippedy0)) +
389
			  (ptd->clipbottom -ptd->clippedy0)) +
386
	    ptd->clippedx0;
390
	    ptd->clippedx0;
387
	ptd->clippedy0 = ptd->clipbottom ;
391
	ptd->clippedy0 = ptd->clipbottom ;
388
    }
392
    }
389
    if (ptd->clippedy1 <= ptd->clipbottom &&
393
    if (ptd->clippedy1 <= ptd->clipbottom &&
390
	ptd->clippedy0 > ptd->clipbottom ) {
394
	ptd->clippedy0 > ptd->clipbottom ) {
391
	ptd->clippedx1 = ((ptd->clippedx1-ptd->clippedx0) /
395
	ptd->clippedx1 = ((ptd->clippedx1-ptd->clippedx0) /
392
			  (ptd->clippedy1-ptd->clippedy0) *
396
			  (ptd->clippedy1-ptd->clippedy0) *
393
			  (ptd->clipbottom -ptd->clippedy0)) +
397
			  (ptd->clipbottom -ptd->clippedy0)) +
394
	    ptd->clippedx0;
398
	    ptd->clippedx0;
395
	ptd->clippedy1 = ptd->clipbottom ;
399
	ptd->clippedy1 = ptd->clipbottom ;
396
    }
400
    }
397
    /*Clipping Top */
401
    /*Clipping Top */
398
    if (ptd->clippedy1 >= ptd->cliptop  && ptd->clippedy0 < ptd->cliptop ) {
402
    if (ptd->clippedy1 >= ptd->cliptop  && ptd->clippedy0 < ptd->cliptop ) {
399
	ptd->clippedx1 = ((ptd->clippedx1-ptd->clippedx0) /
403
	ptd->clippedx1 = ((ptd->clippedx1-ptd->clippedx0) /
400
			  (ptd->clippedy1-ptd->clippedy0) *
404
			  (ptd->clippedy1-ptd->clippedy0) *
401
			  (ptd->cliptop -ptd->clippedy0)) +
405
			  (ptd->cliptop -ptd->clippedy0)) +
402
	    ptd->clippedx0;
406
	    ptd->clippedx0;
403
	ptd->clippedy1 = ptd->cliptop ;
407
	ptd->clippedy1 = ptd->cliptop ;
404
    }
408
    }
405
    if (ptd->clippedy1 <= ptd->cliptop && ptd->clippedy0 > ptd->cliptop ) {
409
    if (ptd->clippedy1 <= ptd->cliptop && ptd->clippedy0 > ptd->cliptop ) {
406
	ptd->clippedx0 = ((ptd->clippedx1-ptd->clippedx0) /
410
	ptd->clippedx0 = ((ptd->clippedx1-ptd->clippedx0) /
407
			  (ptd->clippedy1-ptd->clippedy0) *
411
			  (ptd->clippedy1-ptd->clippedy0) *
408
			  (ptd->cliptop -ptd->clippedy0)) +
412
			  (ptd->cliptop -ptd->clippedy0)) +
409
	    ptd->clippedx0;
413
	    ptd->clippedx0;
410
	ptd->clippedy0 = ptd->cliptop ;
414
	ptd->clippedy0 = ptd->cliptop ;
411
    }
415
    }
412
}
416
}
413
 
417
 
414
static void PicTeX_Line(double x1, double y1, double x2, double y2,
418
static void PicTeX_Line(double x1, double y1, double x2, double y2,
415
		     int col, double gamma, int lty, double lwd,
419
			R_GE_gcontext *gc,
416
		     NewDevDesc *dd)
420
			NewDevDesc *dd)
417
{
421
{
418
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
422
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
419
 
423
 
420
    if (x1 != x2 || y1 != y2) {
424
    if (x1 != x2 || y1 != y2) {
421
	SetLinetype(lty, lwd, dd);
425
	SetLinetype(gc->lty, gc->lwd, dd);
422
	if(ptd->debug)
426
	if(ptd->debug)
423
	    fprintf(ptd->texfp,
427
	    fprintf(ptd->texfp,
424
		    "%% Drawing line from %.2f, %.2f to %.2f, %.2f\n",
428
		    "%% Drawing line from %.2f, %.2f to %.2f, %.2f\n",
425
		    x1, y1, x2, y2);
429
		    x1, y1, x2, y2);
426
	PicTeX_ClipLine(x1, y1, x2, y2, ptd);
430
	PicTeX_ClipLine(x1, y1, x2, y2, ptd);
427
	if (ptd->debug)
431
	if (ptd->debug)
428
	    fprintf(ptd->texfp,
432
	    fprintf(ptd->texfp,
429
		    "%% Drawing clipped line from %.2f, %.2f to %.2f, %.2f\n",
433
		    "%% Drawing clipped line from %.2f, %.2f to %.2f, %.2f\n",
430
		    ptd->clippedx0, ptd->clippedy0,
434
		    ptd->clippedx0, ptd->clippedy0,
431
		    ptd->clippedx1, ptd->clippedy1);
435
		    ptd->clippedx1, ptd->clippedy1);
432
	fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
436
	fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
433
		ptd->clippedx0, ptd->clippedy0,
437
		ptd->clippedx0, ptd->clippedy0,
434
		ptd->clippedx1, ptd->clippedy1);
438
		ptd->clippedx1, ptd->clippedy1);
435
    }
439
    }
436
}
440
}
437
 
441
 
438
static void PicTeX_Polyline(int n, double *x, double *y, 
442
static void PicTeX_Polyline(int n, double *x, double *y, 
439
			    int col, double gamma, int lty, double lwd,
443
			    R_GE_gcontext *gc,
440
			    NewDevDesc *dd)
444
			    NewDevDesc *dd)
441
{
445
{
442
    double x1, y1, x2, y2;
446
    double x1, y1, x2, y2;
443
    int i;
447
    int i;
444
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
448
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
445
 
449
 
446
    SetLinetype(lty, lwd, dd);
450
    SetLinetype(gc->lty, gc->lwd, dd);
447
    x1 = x[0];
451
    x1 = x[0];
448
    y1 = y[0];
452
    y1 = y[0];
449
    for (i = 1; i < n; i++) {
453
    for (i = 1; i < n; i++) {
450
	x2 = x[i];
454
	x2 = x[i];
451
	y2 = y[i];
455
	y2 = y[i];
452
	PicTeX_ClipLine(x1, y1, x2, y2, ptd);
456
	PicTeX_ClipLine(x1, y1, x2, y2, ptd);
453
	fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
457
	fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
454
		ptd->clippedx0, ptd->clippedy0,
458
		ptd->clippedx0, ptd->clippedy0,
455
		ptd->clippedx1, ptd->clippedy1);
459
		ptd->clippedx1, ptd->clippedy1);
456
	x1 = x2;
460
	x1 = x2;
457
	y1 = y2;
461
	y1 = y2;
458
    }
462
    }
459
}
463
}
460
 
464
 
461
	/* String Width in Rasters */
465
	/* String Width in Rasters */
462
	/* For the current font in pointsize fontsize */
466
	/* For the current font in pointsize fontsize */
463
 
467
 
464
static double PicTeX_StrWidth(char *str, int font,
468
static double PicTeX_StrWidth(char *str, 
-
 
469
			      R_GE_gcontext *gc,
465
			      double cex, double ps, NewDevDesc *dd)
470
			      NewDevDesc *dd)
466
{
471
{
467
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
472
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
468
 
473
 
469
    char *p;
474
    char *p;
470
    int size;
475
    int size;
471
    double sum;
476
    double sum;
472
    size = cex * ps + 0.5;
477
    size = gc->cex * gc->ps + 0.5;
473
    SetFont(font, size, ptd);
478
    SetFont(gc->fontface, size, ptd);
474
    sum = 0;
479
    sum = 0;
475
    for(p=str ; *p ; p++)
480
    for(p=str ; *p ; p++)
476
	sum += charwidth[ptd->fontface-1][(int)*p];
481
	sum += charwidth[ptd->fontface-1][(int)*p];
477
    return sum * ptd->fontsize;
482
    return sum * ptd->fontsize;
478
}
483
}
479
 
484
 
480
 
485
 
481
/* Possibly Filled Rectangle */
486
/* Possibly Filled Rectangle */
482
static void PicTeX_Rect(double x0, double y0, double x1, double y1,
487
static void PicTeX_Rect(double x0, double y0, double x1, double y1,
483
		     int col, int fill, double gamma, int lty, double lwd,
488
			R_GE_gcontext *gc,
484
		     NewDevDesc *dd)
489
			NewDevDesc *dd)
485
{
490
{
486
    double x[4], y[4];
491
    double x[4], y[4];
487
 
492
 
488
    x[0] = x0; y[0] = y0;
493
    x[0] = x0; y[0] = y0;
489
    x[1] = x0; y[1] = y1;
494
    x[1] = x0; y[1] = y1;
490
    x[2] = x1; y[2] = y1;
495
    x[2] = x1; y[2] = y1;
491
    x[3] = x1; y[3] = y0;
496
    x[3] = x1; y[3] = y0;
492
    PicTeX_Polygon(4, x, y, col, fill, gamma, lty, lwd, dd);
497
    PicTeX_Polygon(4, x, y, gc, dd);
493
}
498
}
494
 
499
 
495
static void PicTeX_Circle(double x, double y, double r,
500
static void PicTeX_Circle(double x, double y, double r,
496
		       int col, int fill, double gamma, int lty, double lwd,
501
			  R_GE_gcontext *gc,
497
		       NewDevDesc *dd)
502
			  NewDevDesc *dd)
498
{
503
{
499
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
504
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
500
 
505
 
501
    fprintf(ptd->texfp,
506
    fprintf(ptd->texfp,
502
	    "\\circulararc 360 degrees from %.2f %.2f center at %.2f %.2f\n",
507
	    "\\circulararc 360 degrees from %.2f %.2f center at %.2f %.2f\n",
503
	    x, (y + r), x, y);
508
	    x, (y + r), x, y);
504
}
509
}
505
 
510
 
506
static void PicTeX_Polygon(int n, double *x, double *y, 
511
static void PicTeX_Polygon(int n, double *x, double *y, 
507
			int col, int fill, double gamma, int lty, double lwd,
512
			   R_GE_gcontext *gc,
508
			NewDevDesc *dd)
513
			   NewDevDesc *dd)
509
{
514
{
510
    double x1, y1, x2, y2;
515
    double x1, y1, x2, y2;
511
    int i;
516
    int i;
512
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
517
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
513
 
518
 
514
    SetLinetype(lty, lwd, dd);
519
    SetLinetype(gc->lty, gc->lwd, dd);
515
    x1 = x[0];
520
    x1 = x[0];
516
    y1 = y[0];
521
    y1 = y[0];
517
    for (i=1; i<n; i++) {
522
    for (i=1; i<n; i++) {
518
	x2 = x[i];
523
	x2 = x[i];
519
	y2 = y[i];
524
	y2 = y[i];
520
	PicTeX_ClipLine(x1, y1, x2, y2, ptd);
525
	PicTeX_ClipLine(x1, y1, x2, y2, ptd);
521
	fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
526
	fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
522
		ptd->clippedx0, ptd->clippedy0,
527
		ptd->clippedx0, ptd->clippedy0,
523
		ptd->clippedx1, ptd->clippedy1);
528
		ptd->clippedx1, ptd->clippedy1);
524
	x1 = x2;
529
	x1 = x2;
525
	y1 = y2;
530
	y1 = y2;
526
    }
531
    }
527
    x2 = x[0];
532
    x2 = x[0];
528
    y2 = y[0];
533
    y2 = y[0];
529
    PicTeX_ClipLine(x1, y1, x2, y2, ptd);
534
    PicTeX_ClipLine(x1, y1, x2, y2, ptd);
530
    fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
535
    fprintf(ptd->texfp, "\\plot %.2f %.2f %.2f %.2f /\n",
531
	    ptd->clippedx0, ptd->clippedy0,
536
	    ptd->clippedx0, ptd->clippedy0,
532
	    ptd->clippedx1, ptd->clippedy1);
537
	    ptd->clippedx1, ptd->clippedy1);
533
}
538
}
534
 
539
 
535
/* TeX Text Translations */
540
/* TeX Text Translations */
536
static void textext(char *str, picTeXDesc *ptd)
541
static void textext(char *str, picTeXDesc *ptd)
537
{
542
{
538
    fputc('{', ptd->texfp);
543
    fputc('{', ptd->texfp);
539
    for( ; *str ; str++)
544
    for( ; *str ; str++)
540
	switch(*str) {
545
	switch(*str) {
541
	case '$':
546
	case '$':
542
	    fprintf(ptd->texfp, "\\$");
547
	    fprintf(ptd->texfp, "\\$");
543
	    break;
548
	    break;
544
 
549
 
545
	case '%':
550
	case '%':
546
	    fprintf(ptd->texfp, "\\%%");
551
	    fprintf(ptd->texfp, "\\%%");
547
	    break;
552
	    break;
548
 
553
 
549
	case '{':
554
	case '{':
550
	    fprintf(ptd->texfp, "\\{");
555
	    fprintf(ptd->texfp, "\\{");
551
	    break;
556
	    break;
552
 
557
 
553
	case '}':
558
	case '}':
554
	    fprintf(ptd->texfp, "\\}");
559
	    fprintf(ptd->texfp, "\\}");
555
	    break;
560
	    break;
556
 
561
 
557
	case '^':
562
	case '^':
558
	    fprintf(ptd->texfp, "\\^{}");
563
	    fprintf(ptd->texfp, "\\^{}");
559
	    break;
564
	    break;
560
 
565
 
561
	default:
566
	default:
562
	    fputc(*str, ptd->texfp);
567
	    fputc(*str, ptd->texfp);
563
	    break;
568
	    break;
564
	}
569
	}
565
    fprintf(ptd->texfp,"} ");
570
    fprintf(ptd->texfp,"} ");
566
}
571
}
567
 
572
 
568
/* Rotated Text */
573
/* Rotated Text */
569
 
574
 
570
static void PicTeX_Text(double x, double y, char *str, 
575
static void PicTeX_Text(double x, double y, char *str, 
571
		     double rot, double hadj, 
576
			double rot, double hadj, 
572
		     int col, double gamma, int font, double cex, double ps,
577
			R_GE_gcontext *gc,
573
		     NewDevDesc *dd)
578
			NewDevDesc *dd)
574
{
579
{
575
    int size;
580
    int size;
576
    double xoff = 0.0, yoff = 0.0;
581
    double xoff = 0.0, yoff = 0.0;
577
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
582
    picTeXDesc *ptd = (picTeXDesc *) dd->deviceSpecific;
578
 
583
 
579
    size = cex * ps + 0.5;
584
    size = gc->cex * gc->ps + 0.5;
580
    SetFont(font, size, ptd);
585
    SetFont(gc->fontface, size, ptd);
581
    if(ptd->debug) 
586
    if(ptd->debug) 
582
	fprintf(ptd->texfp,
587
	fprintf(ptd->texfp,
583
		"%% Writing string of length %.2f, at %.2f %.2f, xc = %.2f yc = %.2f\n",
588
		"%% Writing string of length %.2f, at %.2f %.2f, xc = %.2f yc = %.2f\n",
584
		(double)PicTeX_StrWidth(str, font, cex, ps, dd), 
589
		(double)PicTeX_StrWidth(str, gc, dd), 
585
		x, y, 0.0, 0.0);
590
		x, y, 0.0, 0.0);
586
    fprintf(ptd->texfp,"\\put ");
591
    fprintf(ptd->texfp,"\\put ");
587
    textext(str, ptd);
592
    textext(str, ptd);
588
    if (rot == 90 )
593
    if (rot == 90 )
589
	fprintf(ptd->texfp," [rB] <%.2fpt,%.2fpt>", xoff, yoff);
594
	fprintf(ptd->texfp," [rB] <%.2fpt,%.2fpt>", xoff, yoff);
590
    else fprintf(ptd->texfp," [lB] <%.2fpt,%.2fpt>", xoff, yoff);
595
    else fprintf(ptd->texfp," [lB] <%.2fpt,%.2fpt>", xoff, yoff);
591
    fprintf(ptd->texfp," at %.2f %.2f\n", x, y);
596
    fprintf(ptd->texfp," at %.2f %.2f\n", x, y);
592
}
597
}
593
 
598
 
594
/* Pick */
599
/* Pick */
595
static Rboolean PicTeX_Locator(double *x, double *y, NewDevDesc *dd)
600
static Rboolean PicTeX_Locator(double *x, double *y, NewDevDesc *dd)
596
{
601
{
597
    return FALSE;
602
    return FALSE;
598
}
603
}
599
 
604
 
600
 
605
 
601
static void PicTeX_Mode(int mode, NewDevDesc* dd)
606
static void PicTeX_Mode(int mode, NewDevDesc* dd)
602
{
607
{
603
}
608
}
604
 
609
 
605
static void PicTeX_Hold(NewDevDesc *dd)
610
static void PicTeX_Hold(NewDevDesc *dd)
606
{
611
{
607
}
612
}
608
 
613
 
609
Rboolean internalPicTeXDeviceDriver(NewDevDesc *dd, char *filename, 
614
Rboolean internalPicTeXDeviceDriver(NewDevDesc *dd, char *filename, 
610
				    char *bg, char *fg,
615
				    char *bg, char *fg,
611
				    double width, double height, 
616
				    double width, double height, 
612
				    Rboolean debug)
617
				    Rboolean debug)
613
{
618
{
614
    picTeXDesc *ptd;
619
    picTeXDesc *ptd;
615
 
620
 
616
    if (!(ptd = (picTeXDesc *) malloc(sizeof(picTeXDesc))))
621
    if (!(ptd = (picTeXDesc *) malloc(sizeof(picTeXDesc))))
617
	return FALSE;
622
	return FALSE;
618
 
623
 
619
    strcpy(ptd->filename, filename);
624
    strcpy(ptd->filename, filename);
620
 
625
 
621
    dd->startfill = str2col(bg);
626
    dd->startfill = str2col(bg);
622
    dd->startcol = str2col(fg);
627
    dd->startcol = str2col(fg);
623
    dd->startps = 10;
628
    dd->startps = 10;
624
    dd->startlty = 0;
629
    dd->startlty = 0;
625
    dd->startfont = 1;
630
    dd->startfont = 1;
626
    dd->startgamma = 1;
631
    dd->startgamma = 1;
627
 
632
 
628
    dd->newDevStruct = 1;
633
    dd->newDevStruct = 1;
629
    
634
    
630
    dd->activate = PicTeX_Activate;
635
    dd->activate = PicTeX_Activate;
631
    dd->deactivate = PicTeX_Deactivate;
636
    dd->deactivate = PicTeX_Deactivate;
632
    dd->open = PicTeX_Open;
637
    dd->open = PicTeX_Open;
633
    dd->close = PicTeX_Close;
638
    dd->close = PicTeX_Close;
634
    dd->clip = PicTeX_Clip;
639
    dd->clip = PicTeX_Clip;
635
    dd->size = PicTeX_Size;
640
    dd->size = PicTeX_Size;
636
    dd->newPage = PicTeX_NewPage;
641
    dd->newPage = PicTeX_NewPage;
637
    dd->line = PicTeX_Line;
642
    dd->line = PicTeX_Line;
638
    dd->text = PicTeX_Text;
643
    dd->text = PicTeX_Text;
639
    dd->strWidth = PicTeX_StrWidth;
644
    dd->strWidth = PicTeX_StrWidth;
640
    dd->rect = PicTeX_Rect;
645
    dd->rect = PicTeX_Rect;
641
    dd->circle = PicTeX_Circle;
646
    dd->circle = PicTeX_Circle;
642
    dd->polygon = PicTeX_Polygon;
647
    dd->polygon = PicTeX_Polygon;
643
    dd->polyline = PicTeX_Polyline;
648
    dd->polyline = PicTeX_Polyline;
644
    dd->locator = PicTeX_Locator;
649
    dd->locator = PicTeX_Locator;
645
    dd->mode = PicTeX_Mode;
650
    dd->mode = PicTeX_Mode;
646
    dd->hold = PicTeX_Hold;
651
    dd->hold = PicTeX_Hold;
647
    dd->metricInfo = PicTeX_MetricInfo;
652
    dd->metricInfo = PicTeX_MetricInfo;
648
 
653
 
649
    /* Screen Dimensions in Pixels */
654
    /* Screen Dimensions in Pixels */
650
 
655
 
651
    dd->left = 0;		/* left */
656
    dd->left = 0;		/* left */
652
    dd->right = in2dots(width);/* right */
657
    dd->right = in2dots(width);/* right */
653
    dd->bottom = 0;		/* bottom */
658
    dd->bottom = 0;		/* bottom */
654
    dd->top = in2dots(height);/* top */
659
    dd->top = in2dots(height);/* top */
655
    ptd->width = width;
660
    ptd->width = width;
656
    ptd->height = height;
661
    ptd->height = height;
657
 
662
 
658
    if( ! PicTeX_Open(dd, ptd) ) 
663
    if( ! PicTeX_Open(dd, ptd) ) 
659
	return FALSE;
664
	return FALSE;
660
 
665
 
661
    /* Base Pointsize */
666
    /* Base Pointsize */
662
    /* Nominal Character Sizes in Pixels */
667
    /* Nominal Character Sizes in Pixels */
663
 
668
 
664
    dd->cra[0] =	 (6.0/12.0) * 10.0;
669
    dd->cra[0] =	 (6.0/12.0) * 10.0;
665
    dd->cra[1] =	(10.0/12.0) * 10.0;
670
    dd->cra[1] =	(10.0/12.0) * 10.0;
666
 
671
 
667
    /* Character Addressing Offsets */
672
    /* Character Addressing Offsets */
668
    /* These offsets should center a single */
673
    /* These offsets should center a single */
669
    /* plotting character over the plotting point. */
674
    /* plotting character over the plotting point. */
670
    /* Pure guesswork and eyeballing ... */
675
    /* Pure guesswork and eyeballing ... */
671
 
676
 
672
    dd->xCharOffset =  0; /*0.4900;*/
677
    dd->xCharOffset =  0; /*0.4900;*/
673
    dd->yCharOffset =  0; /*0.3333;*/
678
    dd->yCharOffset =  0; /*0.3333;*/
674
    dd->yLineBias = 0; /*0.1;*/
679
    dd->yLineBias = 0; /*0.1;*/
675
 
680
 
676
    /* Inches per Raster Unit */
681
    /* Inches per Raster Unit */
677
    /* We use printer points, i.e. 72.27 dots per inch : */
682
    /* We use printer points, i.e. 72.27 dots per inch : */
678
    dd->ipr[0] = dd->ipr[1] = 1./DOTSperIN;
683
    dd->ipr[0] = dd->ipr[1] = 1./DOTSperIN;
679
 
684
 
680
    dd->canResizePlot = FALSE;
685
    dd->canResizePlot = FALSE;
681
    dd->canChangeFont = TRUE;
686
    dd->canChangeFont = TRUE;
682
    dd->canRotateText = FALSE;
687
    dd->canRotateText = FALSE;
683
    dd->canResizeText = TRUE;
688
    dd->canResizeText = TRUE;
684
    dd->canClip = TRUE;
689
    dd->canClip = TRUE;
685
    dd->canHAdj = 0;
690
    dd->canHAdj = 0;
686
    dd->canChangeGamma = FALSE;
691
    dd->canChangeGamma = FALSE;
687
 
692
 
688
    ptd->lty = 1;
693
    ptd->lty = 1;
689
    ptd->pageno = 0;
694
    ptd->pageno = 0;
690
    ptd->debug = debug;
695
    ptd->debug = debug;
691
 
696
 
692
    dd->deviceSpecific = (void *) ptd;
697
    dd->deviceSpecific = (void *) ptd;
693
    dd->displayListOn = FALSE;
698
    dd->displayListOn = FALSE;
694
    return TRUE;
699
    return TRUE;
695
}
700
}
696
 
701
 
697
Rboolean PicTeXDeviceDriver(DevDesc *dd, char *filename, char *bg, char *fg,
702
Rboolean PicTeXDeviceDriver(DevDesc *dd, char *filename, char *bg, char *fg,
698
			    double width, double height, Rboolean debug)
703
			    double width, double height, Rboolean debug)
699
{
704
{
700
    return internalPicTeXDeviceDriver((NewDevDesc*) dd, filename, bg, fg,
705
    return internalPicTeXDeviceDriver((NewDevDesc*) dd, filename, bg, fg,
701
				      width, height, debug);
706
				      width, height, debug);
702
}
707
}
703
 
708