[MERGE] Remove the embedded pychart library, and use the online version
[odoo/odoo.git] /
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
4
5 # Jockey is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2, or (at your option) any
8 # later version.
9 #
10 # Jockey is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 # for more details.
14 #
15 import sys
16 import re
17 import theme
18 import version
19 import basecanvas
20 from scaling import *
21
22 comment_p = 0
23
24 class T(basecanvas.T):
25     def __init__(self, fname):
26         basecanvas.T.__init__(self)
27         self.__out_fname = fname
28         self.__reset_context()
29         self.__output_lines = []
30         self.__nr_gsave = 0
31         self.__font_ids = {}
32         self.__nr_fonts = 0
33         
34     def __reset_context(self):
35         self.__font_name = None
36         self.__font_size = -1
37         self.__line_style = None
38         self.__color = None
39         self.__mtx_pushed = 0
40         self.__txtmtx_pushed = 0
41
42     def __intern_font(self, name):
43         if self.__font_ids.has_key(name):
44             return self.__font_ids[name]
45         id = "F%d" % self.__nr_fonts
46         self.__nr_fonts += 1
47         self.__font_ids[name] = id
48         return id
49     
50     def newpath(self):
51         self.__write("N\n")
52     def stroke(self):
53         self.__write("ST\n")
54     def closepath(self):
55         self.__write("CP\n")
56     def moveto(self, x, y):
57         self.__write('%g %g M\n' % (x, y))
58     
59     def set_fill_color(self, color):
60         if self.__color == color:
61             pass
62         else:
63             if color.r == color.g and color.r == color.b:
64                 self.__write("%g SG\n" % color.r)
65             else:
66                 self.__write("%g %g %g SC\n" % (color.r, color.g, color.b))
67             self.__color = color
68     def set_stroke_color(self, color):
69         self.set_fill_color(color)
70         
71     def set_line_style(self, style):
72         self.set_stroke_color(style.color)
73         if (self.__line_style == style):
74             pass
75         else:
76             self.__write("%g %d %d " % (nscale(style.width), 
77                                       style.cap_style, style.join_style))
78             if style.dash != None:
79                 self.__write("[%s] 0 SLD " % 
80                            " ".join(map(str, nscale_seq(style.dash))))
81             else:
82                 self.__write("SL ")
83         self.__line_style = style
84             
85     def gsave(self):
86         self.__nr_gsave += 1
87         self.__write("GS\n")
88     def grestore(self):
89         self.__write("GR\n")
90         self.__nr_gsave -= 1
91         self.__reset_context()
92
93     def clip_sub(self):
94         self.__write("clip\n")
95         
96     def path_arc(self, x, y, radius, ratio, start_angle, end_angle):
97         self.push_transformation((x, y), (1, ratio), None)
98         self.__write("0 0 %g %g %g arc\n" % (radius, start_angle, end_angle))
99         self.pop_transformation()
100
101     def curveto(self, a,b,c,d,e,f):    
102         self.__write("%g %g %g %g %g %g curveto\n" % (a,b,c,d,e,f))
103
104     def push_transformation(self, baseloc, scale, angle, in_text=0):
105         self.__mtx_pushed += 1
106         self.__write("GB\n")
107         if baseloc != None:
108             self.__write("%g %g T\n" % (baseloc[0], baseloc[1]))
109         if angle != None and angle != 0:
110             self.__write("%g R\n" % (angle))
111         if scale != None:
112             self.__write("%g %g scale\n" % (scale[0], scale[1]))
113     def pop_transformation(self, in_text=0):
114         if self.__mtx_pushed == 0:
115             raise ValueError, "mtx not pushed"
116         self.__mtx_pushed -= 1
117         self.__write("GE\n")
118     def text_begin(self):
119         self.__txtmtx_pushed += 1
120         self.__write("TB\n")
121     def text_end(self):
122         self.__txtmtx_pushed -= 1
123         self.__write("TE\n")
124     def text_moveto(self, x, y, angle):
125         self.__write("%g %g T " % (x,y))
126         if angle != None and angle != 0:
127             self.__write("%g R " % angle)
128         self.moveto(0, 0)
129         
130     def text_show(self, font_name, size, color, str):
131         self.set_fill_color(color)
132         if (self.__font_name == font_name and self.__font_size == size):
133             pass
134         else:
135             id = self.__intern_font(font_name)
136             self.__write("%g %s\n" % (size, id))
137             self.__font_name = font_name
138             self.__font_size = size
139         self.__write("(%s) show\n" % (str))
140
141     def _path_polygon(self, points):
142         if (len(points) == 4 
143             and points[0][0] == points[1][0] 
144             and points[2][0] == points[3][0] 
145             and points[0][1] == points[3][1] 
146             and points[1][1] == points[2][1]):
147             # a rectangle.
148             (xmin, ymin, xmax, ymax) = basecanvas._compute_bounding_box(points)
149             if basecanvas.invisible_p(xmax, ymax):
150                 return
151             self.setbb(xmin, ymin)
152             self.setbb(xmax, ymax)
153             self.__write("%g %g %g %g RECT\n" % \
154                        (xscale(points[0][0]), yscale(points[0][1]),
155                         xscale(points[2][0]), yscale(points[2][1])))
156         else:
157             basecanvas.T._path_polygon(self, points)
158             
159     def lineto(self, x, y):
160         self.__write("%g %g L\n" % (x, y))
161     def fill(self):
162         self.__write("fill\n")
163     def comment(self, str):
164         if comment_p:
165             self.verbatim("%" + str)
166     def verbatim(self, str):
167         self.__write(str)
168         
169     def close(self):
170         basecanvas.T.close(self)
171         if self.__output_lines == []:
172             return
173
174         fp, need_close = self.open_output(self.__out_fname)
175             
176         if self.__nr_gsave != 0:
177             raise Exception, "gsave misnest (%d)" % (self.__nr_gsave)
178         self.write_preamble(fp)
179         
180         fp.writelines(self.__output_lines)
181         fp.writelines(["showpage end\n",
182                        "%%Trailer\n",
183                        "%%EOF\n"])
184         if need_close:
185             fp.close()
186             
187     def __write(self, str):
188         self.__output_lines.append(str)
189     
190     def writelines(self, l):
191         self.__output_lines.extend(l)
192
193     def write_preamble(self, fp):
194         bbox = [self.__xmin-1, self.__ymin-1, self.__xmax+1, self.__ymax+1]
195         fp.write("%!PS-Adobe-2.0 EPSF-1.2\n")
196         fp.write("%%Title: " + self.title + "\n")
197         fp.write("%%Creator: " + self.creator + "\n")
198         if self.author:
199             fp.write("%%Author: " + self.author + "\n")
200         fp.write("%%CreationDate: " + self.creation_date + "\n")
201         fp.write("%%DocumentFonts: " + " ".join(self.__font_ids.keys()) + "\n")
202         fp.write("%%Pages: 1\n")
203
204         bbox = theme.adjust_bounding_box(bbox)
205
206         fp.write("%%%%BoundingBox: %d %d %d %d\n" % \
207                  (round(xscale(bbox[0])),
208                   round(yscale(bbox[1])),
209                   round(xscale(bbox[2])),
210                   round(yscale(bbox[3]))))
211         fp.write("%%EndComments\n")
212         if self.aux_comments != "":
213             for line in self.aux_comments.split("\n"):
214                 fp.write("% " + line + "\n")
215
216         fp.write(preamble_text)
217         for name, id in self.__font_ids.items():
218             fp.write("/%s {/%s findfont SF} def\n" % (id, name))
219         fp.write("%%EndProlog\n%%Page: 1 1\n")
220
221
222 preamble_text="""
223 40 dict begin
224 /RECT {4 dict begin
225   /y2 exch def
226   /x2 exch def
227   /y1 exch def
228   /x1 exch def
229   newpath x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto closepath
230   end
231 } def
232
233 /SF {exch scalefont setfont} def
234 /TB {matrix currentmatrix} def
235 /TE {setmatrix} def
236 /GB {matrix currentmatrix} def
237 /GE {setmatrix} def
238 /SG {1 1 1 setrgbcolor setgray} def
239 /SC {1 setgray setrgbcolor} def
240 /SL {[] 0 setdash setlinejoin setlinecap setlinewidth} def
241 /SLD {setdash setlinejoin setlinecap setlinewidth} def
242 /M {moveto} def
243 /L {lineto} def
244 /T {translate} def
245 /R {rotate} def
246 /N {newpath} def
247 /ST {stroke} def
248 /CP {closepath} def
249 /GR {grestore} def
250 /GS {gsave} def
251 """
252
253 # SL: set line style.
254 # width [dash] x linecap linejoin SL -> 
255
256 # SF: set font.
257 # name size SF -> 
258