diff options
Diffstat (limited to 'js/RrdGfxPdf.js')
-rw-r--r-- | js/RrdGfxPdf.js | 1014 |
1 files changed, 1014 insertions, 0 deletions
diff --git a/js/RrdGfxPdf.js b/js/RrdGfxPdf.js new file mode 100644 index 0000000..9203020 --- /dev/null +++ b/js/RrdGfxPdf.js | |||
@@ -0,0 +1,1014 @@ | |||
1 | /** | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify it | ||
4 | * under the terms of the GNU General Public License as published by the Free | ||
5 | * Software Foundation; either version 2 of the License, or (at your option) | ||
6 | * any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | |||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
16 | |||
17 | **/ | ||
18 | /******************************************************************************* | ||
19 | * FPDF * | ||
20 | * * | ||
21 | * Version: 1.7 * | ||
22 | * Date: 2011-06-18 * | ||
23 | * Author: Olivier PLATHEY * | ||
24 | *******************************************************************************/ | ||
25 | |||
26 | // define('FPDF_VERSION','1.7'); | ||
27 | |||
28 | "use strict"; | ||
29 | |||
30 | /** | ||
31 | * RrdGfxPdf | ||
32 | * @constructor | ||
33 | */ | ||
34 | var RrdGfxPdf = function (orientation, unit, size) | ||
35 | { | ||
36 | if (orientation === undefined) | ||
37 | orientation='P'; | ||
38 | if (unit === undefined) | ||
39 | unit='mm'; | ||
40 | if (size === undefined) | ||
41 | size='A4'; | ||
42 | |||
43 | this.lMargin = 0; // left margin | ||
44 | this.tMargin = 0; // top margin | ||
45 | this.rMargin = 0; // right margin | ||
46 | this.bMargin = 0; // page break margin | ||
47 | this.cMargin = 0; // cell margin | ||
48 | |||
49 | this.x = 0; // current position in user unit | ||
50 | this.y = 0; | ||
51 | |||
52 | this.ZoomMode = null; // zoom display mode | ||
53 | this.LayoutMode = null; // layout display mode | ||
54 | this.title = null; // title | ||
55 | this.subject = null; // subject | ||
56 | this.author = null; // author | ||
57 | this.keywords = null; // keywords | ||
58 | this.creator = null; // creator | ||
59 | |||
60 | // Initialization of properties | ||
61 | this.page = 0; // current page number | ||
62 | this.offsets = []; // array of object offsets | ||
63 | this.n = 2; // current object number | ||
64 | this.buffer = ''; // buffer holding in-memory PDF | ||
65 | this.pages = []; // array containing pages | ||
66 | this.PageSizes = []; // used for pages with non default sizes or orientations | ||
67 | this.state = 0; // current document state | ||
68 | this.fonts = {}; // array of used fonts | ||
69 | this.diffs = []; // array of encoding differences | ||
70 | this.FontFamily = ''; // current font family | ||
71 | this.FontStyle = ''; // current font style | ||
72 | this.FontSizePt = 12; // current font size in points | ||
73 | this.FontSize = this.FontSizePt/this.k; | ||
74 | this.DrawColor = '0 G'; // commands for drawing color | ||
75 | this.FillColor = '0 g'; // commands for filling color | ||
76 | this.TextColor = '0 g'; // commands for text color | ||
77 | this.ColorFlag = false; // indicates whether fill and text colors are different | ||
78 | this.ws = 0; // word spacing | ||
79 | |||
80 | // Core fonts | ||
81 | this.CoreFonts = ['courier', 'helvetica', 'times', 'symbol', 'zapfdingbats']; | ||
82 | // Scale factor (number of points in user unit) | ||
83 | if(unit === 'pt') | ||
84 | this.k = 1; | ||
85 | else if(unit === 'mm') | ||
86 | this.k = 72/25.4; | ||
87 | else if(unit === 'cm') | ||
88 | this.k = 72/2.54; | ||
89 | else if(unit === 'in') | ||
90 | this.k = 72; | ||
91 | else | ||
92 | throw 'Incorrect unit: '+unit; | ||
93 | // Page sizes | ||
94 | this.StdPageSizes = { | ||
95 | 'a3': [841.89 , 1190.55], | ||
96 | 'a4': [595.28 , 841.89], | ||
97 | 'a5': [420.94 , 595.28], | ||
98 | 'letter': [612 , 792], | ||
99 | 'legal': [612 , 1008] | ||
100 | }; | ||
101 | |||
102 | size = this._getpagesize(size); | ||
103 | this.DefPageSize = size; | ||
104 | this.CurPageSize = size; | ||
105 | // Page orientation | ||
106 | orientation = orientation.toLowerCase(); | ||
107 | if(orientation=='p' || orientation=='portrait') { | ||
108 | this.DefOrientation = 'P'; | ||
109 | this.w = size[0]; | ||
110 | this.h = size[1]; | ||
111 | } else if(orientation=='l' || orientation=='landscape') { | ||
112 | this.DefOrientation = 'L'; | ||
113 | this.w = size[1]; | ||
114 | this.h = size[0]; | ||
115 | } else { | ||
116 | throw 'Incorrect orientation: '+orientation; | ||
117 | } | ||
118 | this.CurOrientation = this.DefOrientation; | ||
119 | this.wPt = this.w*this.k; | ||
120 | this.hPt = this.h*this.k; | ||
121 | // Page margins (1 cm) | ||
122 | var margin = 28.35/this.k; | ||
123 | this.SetMargins(margin,margin); | ||
124 | // Interior cell margin (1 mm) | ||
125 | this.cMargin = margin/10; | ||
126 | // Line width (0.2 mm) | ||
127 | this.LineWidth = .567/this.k; | ||
128 | // Default display mode | ||
129 | this.SetDisplayMode('default'); | ||
130 | // Set default PDF version number | ||
131 | this.PDFVersion = '1.3'; | ||
132 | }; | ||
133 | |||
134 | RrdGfxPdf.CORE_FONTS= { | ||
135 | 'courierBI': {name: 'Courier-BoldOblique', up: -100, ut: 50, cw: [600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600] }, | ||
136 | 'courierB': {name: 'Courier-Bold', up: -100, ut: 50, cw: [600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600] }, | ||
137 | 'courierI': {name: 'Courier-Oblique', up: -100, ut: 50, cw: [600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600] }, | ||
138 | 'courier': {name: 'Courier', up: -100, ut: 50, cw: [600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600] }, | ||
139 | 'helveticaBI': {name: 'Helvetica-BoldOblique', up: -100, ut: 50, cw: [ 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, 278,278,278,278,278,278,278,278,278,278,278,333,474,556,556,889,722,238,333,333,389,584, 278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722, 722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944, 667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889, 611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,350,556,350,278,556, 500,1000,556,556,333,1000,667,333,1000,350,611,350,350,278,278,500,500,350,556,1000,333,1000, 556,333,944,350,500,667,278,333,556,556,556,556,280,556,333,737,370,556,584,333,737,333, 400,584,333,333,333,611,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722, 1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722, 722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611, 611,611,611,611,611,584,611,611,611,611,611,556,611,556] }, | ||
140 | 'helveticaB': {name: 'Helvetica-Bold', up: -100, ut: 50, cw: [ 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, 278,278,278,278,278,278,278,278,278,278,278,333,474,556,556,889,722,238,333,333,389,584, 278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722, 722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944, 667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889, 611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,350,556,350,278,556, 500,1000,556,556,333,1000,667,333,1000,350,611,350,350,278,278,500,500,350,556,1000,333,1000, 556,333,944,350,500,667,278,333,556,556,556,556,280,556,333,737,370,556,584,333,737,333, 400,584,333,333,333,611,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722, 1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722, 722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611, 611,611,611,611,611,584,611,611,611,611,611,556,611,556] }, | ||
141 | 'helveticaI': {name: 'Helvetica-Oblique', up: -100, ut: 50, cw: [ 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, 278,278,278,278,278,278,278,278,278,278,278,278,355,556,556,889,667,191,333,333,389,584, 278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667, 667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944, 667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833, 556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,350,556,350,222,556, 333,1000,556,556,333,1000,667,333,1000,350,611,350,350,222,222,333,333,350,556,1000,333,1000, 500,333,944,350,500,667,278,333,556,556,556,556,260,556,333,737,370,556,584,333,737,333, 400,584,333,333,333,556,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667, 1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722, 722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556, 556,556,556,556,556,584,611,556,556,556,556,500,556,500] }, | ||
142 | 'helvetica': {name: 'Helvetica', up: -100, ut: 50, cw: [ 278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, 278,278,278,278,278,278,278,278,278,278,278,278,355,556,556,889,667,191,333,333,389,584, 278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667, 667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944, 667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833, 556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,350,556,350,222,556, 333,1000,556,556,333,1000,667,333,1000,350,611,350,350,222,222,333,333,350,556,1000,333,1000, 500,333,944,350,500,667,278,333,556,556,556,556,260,556,333,737,370,556,584,333,737,333, 400,584,333,333,333,556,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667, 1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722, 722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556, 556,556,556,556,556,584,611,556,556,556,556,500,556,500] }, | ||
143 | 'timesBI': {name: 'Times-BoldItalic', up: -100, ut: 50, cw: [ 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, 250,250,250,250,250,250,250,250,250,250,250,389,555,500,500,833,778,278,333,333,500,570, 250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,832,667, 667,667,722,667,667,722,778,389,500,667,611,889,722,722,611,722,667,556,611,722,667,889, 667,611,611,333,278,333,570,500,333,500,500,444,500,444,333,500,556,278,278,500,278,778, 556,500,500,500,389,389,278,556,444,667,500,444,389,348,220,348,570,350,500,350,333,500, 500,1000,500,500,333,1000,556,333,944,350,611,350,350,333,333,500,500,350,500,1000,333,1000, 389,333,722,350,389,611,250,389,500,500,500,500,220,500,333,747,266,500,606,333,747,333, 400,570,300,300,333,576,500,250,333,300,300,500,750,750,750,500,667,667,667,667,667,667, 944,667,667,667,667,667,389,389,389,389,722,722,722,722,722,722,722,570,722,722,722,722, 722,611,611,500,500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,500,556, 500,500,500,500,500,570,500,556,556,556,556,444,500,444] }, | ||
144 | 'timesB': {name: 'Times-Bold', up: -100, ut: 50, cw: [ 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, 250,250,250,250,250,250,250,250,250,250,250,333,555,500,500,1000,833,278,333,333,500,570, 250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,930,722, 667,722,722,667,611,778,778,389,500,778,667,944,722,778,611,778,722,556,667,722,722,1000, 722,722,667,333,278,333,581,500,333,500,556,444,556,444,333,500,556,278,333,556,278,833, 556,500,556,556,444,389,333,556,500,722,500,500,444,394,220,394,520,350,500,350,333,500, 500,1000,500,500,333,1000,556,333,1000,350,667,350,350,333,333,500,500,350,500,1000,333,1000, 389,333,722,350,444,722,250,333,500,500,500,500,220,500,333,747,300,500,570,333,747,333, 400,570,300,300,333,556,540,250,333,300,330,500,750,750,750,500,722,722,722,722,722,722, 1000,722,667,667,667,667,389,389,389,389,722,722,778,778,778,778,778,570,778,722,722,722, 722,722,611,556,500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,500,556, 500,500,500,500,500,570,500,556,556,556,556,500,556,500] }, | ||
145 | 'timesI': {name: 'Times-Italic', up: -100, ut: 50, cw: [ 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, 250,250,250,250,250,250,250,250,250,250,250,333,420,500,500,833,778,214,333,333,500,675, 250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,675,675,675,500,920,611, 611,667,722,611,611,722,722,333,444,667,556,833,667,722,611,722,611,500,556,722,611,833, 611,556,556,389,278,389,422,500,333,500,500,444,500,444,278,500,500,278,278,444,278,722, 500,500,500,500,389,389,278,500,444,667,444,444,389,400,275,400,541,350,500,350,333,500, 556,889,500,500,333,1000,500,333,944,350,556,350,350,333,333,556,556,350,500,889,333,980, 389,333,667,350,389,556,250,389,500,500,500,500,275,500,333,760,276,500,675,333,760,333, 400,675,300,300,333,500,523,250,333,300,310,500,750,750,750,500,611,611,611,611,611,611, 889,667,611,611,611,611,333,333,333,333,722,667,722,722,722,722,722,675,722,722,722,722, 722,556,611,500,500,500,500,500,500,500,667,444,444,444,444,444,278,278,278,278,500,500, 500,500,500,500,500,675,500,500,500,500,500,444,500,444] }, | ||
146 | 'times': {name: 'Times-Roman', up: -100, ut: 50, cw: [ 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, 250,250,250,250,250,250,250,250,250,250,250,333,408,500,500,833,778,180,333,333,500,564, 250,333,250,278,500,500,500,500,500,500,500,500,500,500,278,278,564,564,564,444,921,722, 667,667,722,611,556,722,722,333,389,722,611,889,722,722,556,722,667,556,611,722,722,944, 722,722,611,333,278,333,469,500,333,444,500,444,500,444,333,500,500,278,278,500,278,778, 500,500,500,500,333,389,278,500,500,722,500,500,444,480,200,480,541,350,500,350,333,500, 444,1000,500,500,333,1000,556,333,889,350,611,350,350,333,333,444,444,350,500,1000,333,980, 389,333,722,350,444,722,250,333,500,500,500,500,200,500,333,760,276,500,564,333,760,333, 400,564,300,300,333,500,453,250,333,300,310,500,750,750,750,444,722,722,722,722,722,722, 889,667,611,611,611,611,333,333,333,333,722,722,722,722,722,722,722,564,722,722,722,722, 722,722,556,500,444,444,444,444,444,444,667,444,444,444,444,444,278,278,278,278,500,500, 500,500,500,500,500,564,500,500,500,500,500,500,500,500] }, | ||
147 | 'symbol': {name: 'Symbol', up: -100, ut: 50, cw: [ 250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250, 250,250,250,250,250,250,250,250,250,250,250,333,713,500,549,833,778,439,333,333,500,549, 250,549,250,278,500,500,500,500,500,500,500,500,500,500,278,278,549,549,549,444,549,722, 667,722,612,611,763,603,722,333,631,722,686,889,722,722,768,741,556,592,611,690,439,768, 645,795,611,333,863,333,658,500,500,631,549,549,494,439,521,411,603,329,603,549,549,576, 521,549,549,521,549,603,439,576,713,686,493,686,494,480,200,480,549,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,750,620,247,549,167,713,500,753,753,753,753,1042,987,603,987,603, 400,549,411,549,549,713,494,460,549,549,549,549,1000,603,1000,658,823,686,795,987,768,768, 823,768,768,713,713,713,713,713,713,713,768,713,790,790,890,823,549,250,713,603,603,1042, 987,603,987,603,494,329,790,790,786,713,384,384,384,384,384,384,494,494,494,494,0,329,274,686,686,686,384,384,384,384,384,384,494,494,494,0] }, | ||
148 | 'zapfdingbats': {name: 'ZapfDingbats', up: -100, ut: 50, cw: [ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278,974,961,974,980,719,789,790,791,690,960,939, 549,855,911,933,911,945,974,755,846,762,761,571,677,763,760,759,754,494,552,537,577,692, 786,788,788,790,793,794,816,823,789,841,823,833,816,831,923,744,723,749,790,792,695,776, 768,792,759,707,708,682,701,826,815,789,789,707,687,696,689,786,787,713,791,785,791,873, 761,762,762,759,759,892,892,788,784,438,138,277,415,392,392,668,668,0,390,390,317,317, 276,276,509,509,410,410,234,234,334,334,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,732,544,544,910,667,760,760,776,595,694,626,788,788,788,788, 788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, 788,788,788,788,788,788,788,788,788,788,788,788,788,788,894,838,1016,458,748,924,748,918, 927,928,928,834,873,828,924,924,917,930,931,463,883,836,836,867,867,696,696,874,0,874, 760,946,771,865,771,888,967,888,831,873,927,970,918,0] } | ||
149 | }; | ||
150 | |||
151 | RrdGfxPdf.prototype.parse_color = function(str) | ||
152 | { | ||
153 | var bits; | ||
154 | if ((bits = /^#?([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/.exec(str))) { | ||
155 | return [parseInt(bits[1]+bits[1], 16), parseInt(bits[2]+bits[2], 16), parseInt(bits[3]+bits[3], 16), 1.0]; | ||
156 | } else if ((bits = /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/.exec(str))) { | ||
157 | return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16), 1.0]; | ||
158 | } else if ((bits = /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/.exec(str))) { | ||
159 | return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16), parseInt(bits[4], 16)/255]; | ||
160 | } else if ((bits = /^rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\)$/.exec(str))) { | ||
161 | return [parseInt(bits[1], 10), parseInt(bits[2], 10), parseInt(bits[3], 10), 1.0]; | ||
162 | } else if ((bits = /^rgba\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*([0-9.]+)\)$/.exec(str))) { | ||
163 | return [parseInt(bits[1], 10), parseInt(bits[2], 10), parseInt(bits[3], 10), parseFloat(bits[4], 10)]; | ||
164 | } else { | ||
165 | throw "Unknow color format '"+str+"'"; | ||
166 | } | ||
167 | }; | ||
168 | |||
169 | RrdGfxPdf.prototype.size = function (width, height) | ||
170 | { | ||
171 | var size = [height, width]; | ||
172 | this.DefPageSize = size; | ||
173 | this.CurPageSize = size; | ||
174 | this.DefOrientation = 'L'; | ||
175 | this.w = size[1]; | ||
176 | this.h = size[0]; | ||
177 | this.CurOrientation = this.DefOrientation; | ||
178 | this.wPt = this.w*this.k; | ||
179 | this.hPt = this.h*this.k; | ||
180 | this.AddPage(); | ||
181 | }; | ||
182 | |||
183 | RrdGfxPdf.prototype.set_dash = function (dashes, n, offset) | ||
184 | { | ||
185 | }; | ||
186 | |||
187 | RrdGfxPdf.prototype.line = function (X0, Y0, X1, Y1, width, color) | ||
188 | { | ||
189 | this._save(); | ||
190 | this._setLineWidth(width); | ||
191 | var rgba = this.parse_color(color); | ||
192 | this._setDrawColor(rgba[0], rgba[1], rgba[2]); | ||
193 | this._moveTo(X0, Y0); | ||
194 | this._lineTo(X1, Y1); | ||
195 | this._stroke(); | ||
196 | this._restore(); | ||
197 | }; | ||
198 | |||
199 | RrdGfxPdf.prototype.dashed_line = function (X0, Y0, X1, Y1, width, color, dash_on, dash_off) | ||
200 | { | ||
201 | this._save(); | ||
202 | this._setLineWidth(width); | ||
203 | var rgba = this.parse_color(color); | ||
204 | this._setDrawColor(rgba[0], rgba[1], rgba[2]); | ||
205 | this._out('['+(dash_on*this.k)+' '+(dash_off*this.k)+'] 0 d'); | ||
206 | this._moveTo(X0, Y0); | ||
207 | this._lineTo(X1, Y1); | ||
208 | this._stroke(); | ||
209 | this._restore(); | ||
210 | }; | ||
211 | |||
212 | RrdGfxPdf.prototype.rectangle = function (X0, Y0, X1, Y1, width, style) | ||
213 | { | ||
214 | this._save(); | ||
215 | this._setLineWidth(width); | ||
216 | var rgba = this.parse_color(style); | ||
217 | this._setDrawColor(rgba[0], rgba[1], rgba[2]); | ||
218 | this._moveTo(X0, Y0); | ||
219 | this._lineTo(X1, Y0); | ||
220 | this._lineTo(X1, Y1); | ||
221 | this._lineTo(X0, Y1); | ||
222 | this._closePath(); | ||
223 | this._stroke(); | ||
224 | this._restore(); | ||
225 | }; | ||
226 | |||
227 | RrdGfxPdf.prototype.new_area = function (X0, Y0, X1, Y1, X2, Y2, color) | ||
228 | { | ||
229 | var rgba = this.parse_color(color); | ||
230 | this._setFillColor(rgba[0], rgba[1], rgba[2]); | ||
231 | this._moveTo(X0, Y0); | ||
232 | this._lineTo(X1, Y1); | ||
233 | this._lineTo(X2, Y2); | ||
234 | }; | ||
235 | |||
236 | RrdGfxPdf.prototype.add_point = function (x, y) | ||
237 | { | ||
238 | this._lineTo(x, y); | ||
239 | }; | ||
240 | |||
241 | RrdGfxPdf.prototype.close_path = function () | ||
242 | { | ||
243 | this._closePath(); | ||
244 | this._fill(); | ||
245 | }; | ||
246 | |||
247 | RrdGfxPdf.prototype.stroke_begin = function (width, style) | ||
248 | { | ||
249 | this._save(); | ||
250 | this._setLineWidth(width); | ||
251 | var rgba = this.parse_color(style); | ||
252 | this._setDrawColor(rgba[0], rgba[1], rgba[2]); | ||
253 | this._out('0 J'); // line cap | ||
254 | this._out('0 j'); // line join | ||
255 | }; | ||
256 | |||
257 | RrdGfxPdf.prototype.stroke_end = function () | ||
258 | { | ||
259 | this._stroke(); | ||
260 | this._restore(); | ||
261 | }; | ||
262 | |||
263 | RrdGfxPdf.prototype.moveTo = function (x,y) | ||
264 | { | ||
265 | this._moveTo(x, y); | ||
266 | }; | ||
267 | |||
268 | RrdGfxPdf.prototype.lineTo = function (x,y) | ||
269 | { | ||
270 | this._lineTo(x, y) | ||
271 | }; | ||
272 | |||
273 | RrdGfxPdf.prototype.text = function (x, y, color, font, tabwidth, angle, h_align, v_align, text) | ||
274 | { | ||
275 | this._save(); | ||
276 | this._setFont('courier', '', font.size*this.k); | ||
277 | |||
278 | var width = this._getStringWidth('courier', '', font.size*this.k, text); | ||
279 | var height = font.size; | ||
280 | /* | ||
281 | this._moveTo(x,y-5); this._lineTo(x,y+5); | ||
282 | this._moveTo(x-5,y); this._lineTo(x+5,y); | ||
283 | this._moveTo(x+width,y-height-5); this._lineTo(x+width,y-height+5); | ||
284 | this._moveTo(x+width-5,y-height); this._lineTo(x+width+5,y-height); | ||
285 | this._stroke(); | ||
286 | */ | ||
287 | switch (h_align) { | ||
288 | case RrdGraph.GFX_H_LEFT: | ||
289 | if (angle == -90) { | ||
290 | x = x-height/2; | ||
291 | } | ||
292 | break; | ||
293 | case RrdGraph.GFX_H_RIGHT: | ||
294 | x = x-width; | ||
295 | break; | ||
296 | case RrdGraph.GFX_H_CENTER: | ||
297 | if (angle != 90) { | ||
298 | x = x-width/2; | ||
299 | } | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | switch (v_align) { | ||
304 | case RrdGraph.GFX_V_TOP: | ||
305 | if (angle != -90) { | ||
306 | y = y + height/2; | ||
307 | } | ||
308 | break; | ||
309 | case RrdGraph.GFX_V_BOTTOM: | ||
310 | y = y - height/3; | ||
311 | break; | ||
312 | case RrdGraph.GFX_V_CENTER: | ||
313 | if (angle == 90) { | ||
314 | y = y + width/2; | ||
315 | } else { | ||
316 | y = y + height/4; | ||
317 | } | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | x = x*this.k; | ||
322 | y = (this.h-y)*this.k | ||
323 | |||
324 | var tm = []; | ||
325 | tm[0] = Math.cos(angle*Math.PI/180.0); | ||
326 | tm[1] = Math.sin(angle*Math.PI/180.0); | ||
327 | tm[2] = -tm[1]; | ||
328 | tm[3] = tm[0]; | ||
329 | |||
330 | tm[4] = x + (tm[1] * y) - (tm[0] * x); | ||
331 | tm[5] = y - (tm[0] * y) - (tm[1] * x); | ||
332 | |||
333 | var rgba = this.parse_color(color); | ||
334 | this._save(); | ||
335 | this._out('BT'); | ||
336 | this._out(sprintf('%.3F %.3F %.3F rg', rgba[0]/255,rgba[1]/255,rgba[2]/255)); | ||
337 | this._out(sprintf('%.2F %.2F Td', x, y)); | ||
338 | this._out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', tm[0], tm[1], tm[2], tm[3], tm[4], tm[5])); | ||
339 | this._out(sprintf('(%s) Tj',this._escape(text))); | ||
340 | this._out('ET'); | ||
341 | this._restore(); | ||
342 | }; | ||
343 | |||
344 | RrdGfxPdf.prototype.get_text_width = function(start, font, tabwidth, text) | ||
345 | { | ||
346 | var width = this._getStringWidth('courier', '', font.size*this.k, text); | ||
347 | return width; | ||
348 | }; | ||
349 | |||
350 | /**** Public methods *****/ | ||
351 | |||
352 | RrdGfxPdf.prototype.SetMargins = function(left, top, right) | ||
353 | { | ||
354 | if (right === undefined) | ||
355 | right = null; | ||
356 | // Set left, top and right margins | ||
357 | this.lMargin = left; | ||
358 | this.tMargin = top; | ||
359 | if(right===null) | ||
360 | right = left; | ||
361 | this.rMargin = right; | ||
362 | }; | ||
363 | |||
364 | RrdGfxPdf.prototype.SetLeftMargin = function(margin) | ||
365 | { | ||
366 | // Set left margin | ||
367 | this.lMargin = margin; | ||
368 | if(this.page>0 && this.x<margin) | ||
369 | this.x = margin; | ||
370 | }; | ||
371 | |||
372 | RrdGfxPdf.prototype.SetTopMargin = function(margin) | ||
373 | { | ||
374 | // Set top margin | ||
375 | this.tMargin = margin; | ||
376 | }; | ||
377 | |||
378 | RrdGfxPdf.prototype.SetRightMargin = function(margin) | ||
379 | { | ||
380 | // Set right margin | ||
381 | this.rMargin = margin; | ||
382 | }; | ||
383 | |||
384 | RrdGfxPdf.prototype.SetDisplayMode = function(zoom, layout) | ||
385 | { | ||
386 | // Set display mode in viewer | ||
387 | if(zoom === 'fullpage' || zoom === 'fullwidth' || zoom === 'real' || zoom == 'default' || !(typeof zoom === "string")) | ||
388 | this.ZoomMode = zoom; | ||
389 | else | ||
390 | throw 'Incorrect zoom display mode: '+zoom; | ||
391 | |||
392 | if(layout === undefined) { | ||
393 | this.LayoutMode = 'default'; | ||
394 | } else if(layout === 'single' || layout === 'continuous' || layout === 'two' || layout === 'default') { | ||
395 | this.LayoutMode = layout; | ||
396 | } else { | ||
397 | throw 'Incorrect layout display mode: '+layout; | ||
398 | } | ||
399 | }; | ||
400 | |||
401 | RrdGfxPdf.prototype.SetTitle = function(title) | ||
402 | { | ||
403 | // Title of document | ||
404 | this.title = title; | ||
405 | }; | ||
406 | |||
407 | RrdGfxPdf.prototype.SetSubject = function(subject) | ||
408 | { | ||
409 | // Subject of document | ||
410 | this.subject = subject; | ||
411 | }; | ||
412 | |||
413 | RrdGfxPdf.prototype.SetAuthor = function(author) | ||
414 | { | ||
415 | // Author of document | ||
416 | this.author = author; | ||
417 | }; | ||
418 | |||
419 | RrdGfxPdf.prototype.SetKeywords = function(keywords) | ||
420 | { | ||
421 | // Keywords of document | ||
422 | this.keywords = keywords; | ||
423 | }; | ||
424 | |||
425 | RrdGfxPdf.prototype.SetCreator = function(creator) | ||
426 | { | ||
427 | // Creator of document | ||
428 | this.creator = creator; | ||
429 | }; | ||
430 | |||
431 | RrdGfxPdf.prototype.Open = function() | ||
432 | { | ||
433 | // Begin document | ||
434 | this.state = 1; | ||
435 | }; | ||
436 | |||
437 | RrdGfxPdf.prototype.Close = function() | ||
438 | { | ||
439 | // Terminate document | ||
440 | if(this.state==3) | ||
441 | return; | ||
442 | if(this.page==0) | ||
443 | this.AddPage(); | ||
444 | // Close page | ||
445 | this._endpage(); | ||
446 | // Close document | ||
447 | this._enddoc(); | ||
448 | }; | ||
449 | |||
450 | RrdGfxPdf.prototype.AddPage = function(orientation, size) | ||
451 | { | ||
452 | if (orientation === undefined) orientation=''; | ||
453 | if (size === undefined) size=''; | ||
454 | |||
455 | // Start a new page | ||
456 | if(this.state==0) | ||
457 | this.Open(); | ||
458 | |||
459 | var family = this.FontFamily; | ||
460 | var style = this.FontStyle; | ||
461 | var fontsize = this.FontSizePt; | ||
462 | var lw = this.LineWidth; | ||
463 | var dc = this.DrawColor; | ||
464 | var fc = this.FillColor; | ||
465 | var tc = this.TextColor; | ||
466 | var cf = this.ColorFlag; | ||
467 | |||
468 | if(this.page>0) | ||
469 | { | ||
470 | // Close page | ||
471 | this._endpage(); | ||
472 | } | ||
473 | // Start new page | ||
474 | this._beginpage(orientation,size); | ||
475 | // Set line cap style to square | ||
476 | this._out('2 J'); | ||
477 | // Set line width | ||
478 | this.LineWidth = lw; | ||
479 | this._out(sprintf('%.2F w',lw*this.k)); | ||
480 | // Set font | ||
481 | if(family) | ||
482 | this._setFont(family,style,fontsize); | ||
483 | // Set colors | ||
484 | this.DrawColor = dc; | ||
485 | if(dc!='0 G') | ||
486 | this._out(dc); | ||
487 | this.FillColor = fc; | ||
488 | if(fc!='0 g') | ||
489 | this._out(fc); | ||
490 | this.TextColor = tc; | ||
491 | this.ColorFlag = cf; | ||
492 | // Restore line width | ||
493 | if(this.LineWidth!=lw) | ||
494 | { | ||
495 | this.LineWidth = lw; | ||
496 | this._out(sprintf('%.2F w',lw*this.k)); | ||
497 | } | ||
498 | // Restore font | ||
499 | if(family) | ||
500 | this._setFont(family,style,fontsize); | ||
501 | // Restore colors | ||
502 | if(this.DrawColor!=dc) | ||
503 | { | ||
504 | this.DrawColor = dc; | ||
505 | this._out(dc); | ||
506 | } | ||
507 | if(this.FillColor!=fc) | ||
508 | { | ||
509 | this.FillColor = fc; | ||
510 | this._out(fc); | ||
511 | } | ||
512 | this.TextColor = tc; | ||
513 | this.ColorFlag = cf; | ||
514 | }; | ||
515 | |||
516 | RrdGfxPdf.prototype.PageNo = function() | ||
517 | { | ||
518 | // Get current page number | ||
519 | return this.page; | ||
520 | }; | ||
521 | |||
522 | RrdGfxPdf.prototype._setDrawColor = function(r, g, b) | ||
523 | { | ||
524 | if (g === undefined) g=null; | ||
525 | if (b === undefined) b=null; | ||
526 | // Set color for all stroking operations | ||
527 | if((r==0 && g==0 && b==0) || g===null) | ||
528 | this.DrawColor = sprintf('%.3F G',r/255); | ||
529 | else | ||
530 | this.DrawColor = sprintf('%.3F %.3F %.3F RG',r/255,g/255,b/255); | ||
531 | if(this.page>0) | ||
532 | this._out(this.DrawColor); | ||
533 | }; | ||
534 | |||
535 | RrdGfxPdf.prototype._setFillColor = function(r, g, b) | ||
536 | { | ||
537 | if (g === undefined) g=null; | ||
538 | if (b === undefined) b=null; | ||
539 | // Set color for all filling operations | ||
540 | if((r==0 && g==0 && b==0) || g===null) | ||
541 | this.FillColor = sprintf('%.3F g',r/255); | ||
542 | else | ||
543 | this.FillColor = sprintf('%.3F %.3F %.3F rg',r/255,g/255,b/255); | ||
544 | this.ColorFlag = (this.FillColor!=this.TextColor); | ||
545 | if(this.page>0) | ||
546 | this._out(this.FillColor); | ||
547 | }; | ||
548 | |||
549 | RrdGfxPdf.prototype._setTextColor = function(r, g, b) | ||
550 | { | ||
551 | if (g === undefined) g=null; | ||
552 | if (b === undefined) b=null; | ||
553 | // Set color for text | ||
554 | if((r==0 && g==0 && b==0) || g===null) | ||
555 | this.TextColor = sprintf('%.3F g',r/255); | ||
556 | else | ||
557 | this.TextColor = sprintf('%.3F %.3F %.3F rg',r/255,g/255,b/255); | ||
558 | this.ColorFlag = (this.FillColor!=this.TextColor); | ||
559 | }; | ||
560 | |||
561 | RrdGfxPdf.prototype._getStringWidth = function(family, style, size, s) | ||
562 | { | ||
563 | if (style === undefined) style = ''; | ||
564 | if (size === undefined) size = 0; | ||
565 | // Select a font; size given in points | ||
566 | |||
567 | if(family=='') family = this.FontFamily; | ||
568 | else family = family.toLowerCase(); | ||
569 | |||
570 | style = style.toUpperCase(); | ||
571 | if(style=='IB') style = 'BI'; | ||
572 | |||
573 | if(size==0) size = this.FontSizePt; | ||
574 | |||
575 | // Test if font is already loaded | ||
576 | var fontkey = family+style; | ||
577 | if(!(fontkey in this.fonts)) { | ||
578 | // Test if one of the core fonts | ||
579 | if(family=='arial') family = 'helvetica'; | ||
580 | if(family=='symbol' || family=='zapfdingbats') style = ''; | ||
581 | fontkey = family+style; | ||
582 | |||
583 | if (!(fontkey in this.fonts)) | ||
584 | this.AddFont(family, style); | ||
585 | } | ||
586 | // Select it | ||
587 | size = size/this.k; | ||
588 | var cw = this.fonts[fontkey].cw; | ||
589 | var w = 0; | ||
590 | var l = s.length; | ||
591 | for(var i=0; i<l; i++) { | ||
592 | w += cw[s.charCodeAt(i)]; | ||
593 | } | ||
594 | return w*size/1000; | ||
595 | }; | ||
596 | |||
597 | RrdGfxPdf.prototype._setLineWidth = function(width) | ||
598 | { | ||
599 | // Set line width | ||
600 | this.LineWidth = width; | ||
601 | if(this.page>0) | ||
602 | this._out(sprintf('%.2F w',width*this.k)); | ||
603 | }; | ||
604 | |||
605 | RrdGfxPdf.prototype._moveTo = function(x, y) | ||
606 | { | ||
607 | this._out(sprintf('%.2F %.2F m',x*this.k,(this.h-y)*this.k)); | ||
608 | }; | ||
609 | |||
610 | RrdGfxPdf.prototype._lineTo = function(x, y) | ||
611 | { | ||
612 | this._out(sprintf('%.2F %.2F l',x*this.k,(this.h-y)*this.k)); | ||
613 | }; | ||
614 | |||
615 | RrdGfxPdf.prototype._stroke = function() | ||
616 | { | ||
617 | this._out('S'); | ||
618 | }; | ||
619 | |||
620 | RrdGfxPdf.prototype._save = function() | ||
621 | { | ||
622 | this._out('q'); | ||
623 | }; | ||
624 | |||
625 | RrdGfxPdf.prototype._restore = function() | ||
626 | { | ||
627 | this._out('Q'); | ||
628 | }; | ||
629 | |||
630 | RrdGfxPdf.prototype._closePath = function() | ||
631 | { | ||
632 | this._out('h'); | ||
633 | }; | ||
634 | |||
635 | RrdGfxPdf.prototype._fill = function() | ||
636 | { | ||
637 | this._out('f'); | ||
638 | }; | ||
639 | |||
640 | RrdGfxPdf.prototype._line = function(x1, y1, x2, y2) | ||
641 | { | ||
642 | // Draw a line | ||
643 | this._out(sprintf('%.2F %.2F m %.2F %.2F l S',x1*this.k,(this.h-y1)*this.k,x2*this.k,(this.h-y2)*this.k)); | ||
644 | }; | ||
645 | |||
646 | RrdGfxPdf.prototype._rect = function(x, y, w, h, style) | ||
647 | { | ||
648 | var op; | ||
649 | // Draw a rectangle | ||
650 | if(style=='F') | ||
651 | op = 'f'; | ||
652 | else if(style=='FD' || style=='DF') | ||
653 | op = 'B'; | ||
654 | else | ||
655 | op = 'S'; | ||
656 | this._out(sprintf('%.2F %.2F %.2F %.2F re %s',x*this.k,(this.h-y)*this.k,w*this.k,-h*this.k,op)); | ||
657 | }; | ||
658 | |||
659 | RrdGfxPdf.prototype.AddFont = function (family, style, file) | ||
660 | { | ||
661 | if (style === undefined) style = ''; | ||
662 | |||
663 | if(family=='') family = this.FontFamily; | ||
664 | else family = family.toLowerCase(); | ||
665 | |||
666 | style = style.toUpperCase(); | ||
667 | if(style=='IB') style = 'BI'; | ||
668 | |||
669 | var fontkey = family+style; | ||
670 | if(fontkey in this.fonts) | ||
671 | return; | ||
672 | |||
673 | if(fontkey in RrdGfxPdf.CORE_FONTS){ | ||
674 | var font = RrdGfxPdf.CORE_FONTS[fontkey]; | ||
675 | this.fonts[fontkey] = font; | ||
676 | var i=0; | ||
677 | for (var n in this.fonts) i++; | ||
678 | font['i'] = i; | ||
679 | } else { | ||
680 | throw 'Undefined font: '+family+' '+style; | ||
681 | } | ||
682 | }; | ||
683 | |||
684 | RrdGfxPdf.prototype._setFont = function(family, style, size) | ||
685 | { | ||
686 | if (style === undefined) style = ''; | ||
687 | if (size === undefined) size = 0; | ||
688 | // Select a font; size given in points | ||
689 | |||
690 | if(family=='') family = this.FontFamily; | ||
691 | else family = family.toLowerCase(); | ||
692 | |||
693 | style = style.toUpperCase(); | ||
694 | if(style=='IB') style = 'BI'; | ||
695 | |||
696 | if(size==0) size = this.FontSizePt; | ||
697 | |||
698 | // Test if font is already selected | ||
699 | //if(this.FontFamily==family && this.FontStyle==style && this.FontSizePt==size) | ||
700 | // return; | ||
701 | |||
702 | // Test if font is already loaded | ||
703 | var fontkey = family+style; | ||
704 | if(!(fontkey in this.fonts)) { | ||
705 | // Test if one of the core fonts | ||
706 | if(family=='arial') family = 'helvetica'; | ||
707 | if(family=='symbol' || family=='zapfdingbats') style = ''; | ||
708 | fontkey = family+style; | ||
709 | |||
710 | if (!(fontkey in this.fonts)) | ||
711 | this.AddFont(family, style); | ||
712 | } | ||
713 | // Select it | ||
714 | this.FontFamily = family; | ||
715 | this.FontStyle = style; | ||
716 | this.FontSizePt = size; | ||
717 | this.FontSize = size/this.k; | ||
718 | this.CurrentFont = this.fonts[fontkey]; | ||
719 | if(this.page>0) | ||
720 | this._out(sprintf('BT /F%d %.2F Tf ET',this.CurrentFont['i'],this.FontSizePt)); // FIXME i | ||
721 | }; | ||
722 | |||
723 | RrdGfxPdf.prototype._setFontSize = function(size) | ||
724 | { | ||
725 | // Set font size in points | ||
726 | //if(this.FontSizePt==size) | ||
727 | // return; | ||
728 | this.FontSizePt = size; | ||
729 | this.FontSize = size/this.k; | ||
730 | if(this.page>0) | ||
731 | this._out(sprintf('BT /F%d %.2F Tf ET',this.CurrentFont['i'],this.FontSizePt)); | ||
732 | }; | ||
733 | |||
734 | RrdGfxPdf.prototype._text = function(x, y, txt) | ||
735 | { | ||
736 | // Output a string | ||
737 | var s = sprintf('BT %.2F %.2F Td (%s) Tj ET',x*this.k,(this.h-y)*this.k,this._escape(txt)); | ||
738 | if(this.ColorFlag) | ||
739 | s = 'q '+this.TextColor+' '+s+' Q'; | ||
740 | this._out(s); | ||
741 | }; | ||
742 | |||
743 | RrdGfxPdf.prototype.output = function() | ||
744 | { | ||
745 | // Output PDF to some destination | ||
746 | if(this.state<3) | ||
747 | this.Close(); | ||
748 | document.location.href = 'data:application/pdf;base64,' + Base64.encode(this.buffer); | ||
749 | //return this.buffer; | ||
750 | }; | ||
751 | |||
752 | RrdGfxPdf.prototype._getpagesize = function(size) // FIXME | ||
753 | { | ||
754 | if(typeof size === "string" ) { | ||
755 | size = size.toLowerCase(); | ||
756 | if(!(size in this.StdPageSizes)) | ||
757 | throw 'Unknown page size: '+size; | ||
758 | var a = this.StdPageSizes[size]; | ||
759 | return [a[0]/this.k, a[1]/this.k]; | ||
760 | } else { | ||
761 | if(size[0]>size[1]) { | ||
762 | return [size[1], size[0]]; | ||
763 | } else { | ||
764 | return size; | ||
765 | } | ||
766 | } | ||
767 | }; | ||
768 | |||
769 | RrdGfxPdf.prototype._beginpage = function(orientation, size) | ||
770 | { | ||
771 | this.page++; | ||
772 | this.pages[this.page] = ''; | ||
773 | this.state = 2; | ||
774 | this.x = this.lMargin; | ||
775 | this.y = this.tMargin; | ||
776 | this.FontFamily = ''; | ||
777 | // Check page size and orientation | ||
778 | if(orientation=='') orientation = this.DefOrientation; | ||
779 | else orientation = strtoupper(orientation[0]); | ||
780 | |||
781 | if(size=='') size = this.DefPageSize; | ||
782 | else size = this._getpagesize(size); | ||
783 | |||
784 | if(orientation!=this.CurOrientation || size[0]!=this.CurPageSize[0] || size[1]!=this.CurPageSize[1]) | ||
785 | { | ||
786 | // New size or orientation | ||
787 | if(orientation=='P') { | ||
788 | this.w = size[0]; | ||
789 | this.h = size[1]; | ||
790 | } else { | ||
791 | this.w = size[1]; | ||
792 | this.h = size[0]; | ||
793 | } | ||
794 | this.wPt = this.w*this.k; | ||
795 | this.hPt = this.h*this.k; | ||
796 | this.CurOrientation = orientation; | ||
797 | this.CurPageSize = size; | ||
798 | } | ||
799 | if(orientation!=this.DefOrientation || size[0]!=this.DefPageSize[0] || size[1]!=this.DefPageSize[1]) | ||
800 | this.PageSizes[this.page] = [this.wPt, this.hPt]; | ||
801 | }; | ||
802 | |||
803 | RrdGfxPdf.prototype._endpage = function() | ||
804 | { | ||
805 | this.state = 1; | ||
806 | }; | ||
807 | |||
808 | RrdGfxPdf.prototype._escape = function(s) // FIXME | ||
809 | { | ||
810 | // Escape special characters in strings | ||
811 | //s = str_replace('\\','\\\\',s); | ||
812 | //s = str_replace('(','\\(',s); | ||
813 | //s = str_replace(')','\\)',s); | ||
814 | //s = str_replace("\r",'\\r',s); | ||
815 | return s.replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)'); | ||
816 | }; | ||
817 | |||
818 | RrdGfxPdf.prototype._textstring = function(s) | ||
819 | { | ||
820 | // Format a text string | ||
821 | return '('+this._escape(s)+')'; | ||
822 | }; | ||
823 | |||
824 | RrdGfxPdf.prototype._newobj = function() | ||
825 | { | ||
826 | // Begin a new object | ||
827 | this.n++; | ||
828 | this.offsets[this.n] = this.buffer.length; | ||
829 | this._out(this.n+' 0 obj'); | ||
830 | }; | ||
831 | |||
832 | RrdGfxPdf.prototype._putstream = function(s) | ||
833 | { | ||
834 | this._out('stream'); | ||
835 | this._out(s); | ||
836 | this._out('endstream'); | ||
837 | }, | ||
838 | |||
839 | RrdGfxPdf.prototype._out = function(s) | ||
840 | { | ||
841 | // Add a line to the document | ||
842 | if(this.state==2) | ||
843 | this.pages[this.page] += s+"\n"; | ||
844 | else | ||
845 | this.buffer += s+"\n"; | ||
846 | }; | ||
847 | |||
848 | RrdGfxPdf.prototype._putpages = function() | ||
849 | { | ||
850 | var wPt, hPt; | ||
851 | var nb = this.page; | ||
852 | if(this.DefOrientation=='P') { | ||
853 | wPt = this.DefPageSize[0]*this.k; | ||
854 | hPt = this.DefPageSize[1]*this.k; | ||
855 | } else { | ||
856 | wPt = this.DefPageSize[1]*this.k; | ||
857 | hPt = this.DefPageSize[0]*this.k; | ||
858 | } | ||
859 | for(var n=1;n<=nb;n++) | ||
860 | { | ||
861 | // Page | ||
862 | this._newobj(); | ||
863 | this._out('<</Type /Page'); | ||
864 | this._out('/Parent 1 0 R'); | ||
865 | if(this.PageSizes[n] !== undefined) | ||
866 | this._out(sprintf('/MediaBox [0 0 %.2F %.2F]',this.PageSizes[n][0],this.PageSizes[n][1])); | ||
867 | this._out('/Resources 2 0 R'); | ||
868 | if(this.PDFVersion>'1.3') | ||
869 | this._out('/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>'); | ||
870 | this._out('/Contents '+(this.n+1)+' 0 R>>'); | ||
871 | this._out('endobj'); | ||
872 | // Page content | ||
873 | this._newobj(); | ||
874 | this._out('<</Length '+this.pages[n].length+'>>'); | ||
875 | this._putstream(this.pages[n]); | ||
876 | this._out('endobj'); | ||
877 | } | ||
878 | // Pages root | ||
879 | this.offsets[1] = this.buffer.length; | ||
880 | this._out('1 0 obj'); | ||
881 | this._out('<</Type /Pages'); | ||
882 | var kids = '/Kids ['; | ||
883 | for(var i=0;i<nb;i++) | ||
884 | kids += (3+2*i)+' 0 R '; | ||
885 | this._out(kids+']'); | ||
886 | this._out('/Count '+nb); | ||
887 | this._out(sprintf('/MediaBox [0 0 %.2F %.2F]',wPt,hPt)); | ||
888 | this._out('>>'); | ||
889 | this._out('endobj'); | ||
890 | }; | ||
891 | |||
892 | RrdGfxPdf.prototype._putfonts = function() | ||
893 | { | ||
894 | var nf = this.n; | ||
895 | for(var diff in this.diffs) { | ||
896 | // Encodings | ||
897 | this._newobj(); | ||
898 | this._out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['+diff+']>>'); | ||
899 | this._out('endobj'); | ||
900 | } | ||
901 | for(var font in this.fonts) { // FIXME | ||
902 | // Font objects | ||
903 | this.fonts[font]['n'] = this.n+1; | ||
904 | var name = this.fonts[font]['name']; | ||
905 | // Core font | ||
906 | this._newobj(); | ||
907 | this._out('<</Type /Font'); | ||
908 | this._out('/BaseFont /'+name); | ||
909 | this._out('/Subtype /Type1'); | ||
910 | if(name!='Symbol' && name!='ZapfDingbats') | ||
911 | this._out('/Encoding /WinAnsiEncoding'); | ||
912 | this._out('>>'); | ||
913 | this._out('endobj'); | ||
914 | } | ||
915 | }; | ||
916 | |||
917 | RrdGfxPdf.prototype._putresourcedict = function() | ||
918 | { | ||
919 | this._out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); | ||
920 | this._out('/Font <<'); | ||
921 | for(var font in this.fonts) | ||
922 | this._out('/F'+this.fonts[font]['i']+' '+this.fonts[font]['n']+' 0 R'); | ||
923 | this._out('>>'); | ||
924 | this._out('/XObject <<'); | ||
925 | this._out('>>'); | ||
926 | }; | ||
927 | |||
928 | RrdGfxPdf.prototype._putresources = function() | ||
929 | { | ||
930 | this._putfonts(); | ||
931 | // Resource dictionary | ||
932 | this.offsets[2] = this.buffer.length; | ||
933 | this._out('2 0 obj'); | ||
934 | this._out('<<'); | ||
935 | this._putresourcedict(); | ||
936 | this._out('>>'); | ||
937 | this._out('endobj'); | ||
938 | }; | ||
939 | |||
940 | RrdGfxPdf.prototype._putinfo = function() | ||
941 | { | ||
942 | // this._out('/Producer '+this._textstring('FPDF '+FPDF_VERSION)); FIXME | ||
943 | if(this.title != null) | ||
944 | this._out('/Title '+this._textstring(this.title)); | ||
945 | if(this.subject != null) | ||
946 | this._out('/Subject '+this._textstring(this.subject)); | ||
947 | if(this.author != null) | ||
948 | this._out('/Author '+this._textstring(this.author)); | ||
949 | if(this.keywords != null) | ||
950 | this._out('/Keywords '+this._textstring(this.keywords)); | ||
951 | if(this.creator != null) | ||
952 | this._out('/Creator '+this._textstring(this.creator)); | ||
953 | // this._out('/CreationDate '+this._textstring('D:'+date('YmdHis'))); // FIXME | ||
954 | }; | ||
955 | |||
956 | RrdGfxPdf.prototype._putcatalog = function() | ||
957 | { | ||
958 | this._out('/Type /Catalog'); | ||
959 | this._out('/Pages 1 0 R'); | ||
960 | |||
961 | if(this.ZoomMode=='fullpage') | ||
962 | this._out('/OpenAction [3 0 R /Fit]'); | ||
963 | else if(this.ZoomMode=='fullwidth') | ||
964 | this._out('/OpenAction [3 0 R /FitH null]'); | ||
965 | else if(this.ZoomMode=='real') | ||
966 | this._out('/OpenAction [3 0 R /XYZ null null 1]'); | ||
967 | else if(!(typeof this.ZoomMode === 'string')) | ||
968 | this._out('/OpenAction [3 0 R /XYZ null null '+sprintf('%.2F',this.ZoomMode/100)+']'); | ||
969 | |||
970 | if(this.LayoutMode=='single') | ||
971 | this._out('/PageLayout /SinglePage'); | ||
972 | else if(this.LayoutMode=='continuous') | ||
973 | this._out('/PageLayout /OneColumn'); | ||
974 | else if(this.LayoutMode=='two') | ||
975 | this._out('/PageLayout /TwoColumnLeft'); | ||
976 | }; | ||
977 | |||
978 | RrdGfxPdf.prototype._enddoc = function() | ||
979 | { | ||
980 | this._out('%PDF-'+this.PDFVersion); | ||
981 | this._putpages(); | ||
982 | this._putresources(); | ||
983 | // Info | ||
984 | this._newobj(); | ||
985 | this._out('<<'); | ||
986 | this._putinfo(); | ||
987 | this._out('>>'); | ||
988 | this._out('endobj'); | ||
989 | // Catalog | ||
990 | this._newobj(); | ||
991 | this._out('<<'); | ||
992 | this._putcatalog(); | ||
993 | this._out('>>'); | ||
994 | this._out('endobj'); | ||
995 | // Cross-ref | ||
996 | var o = this.buffer.length; | ||
997 | this._out('xref'); | ||
998 | this._out('0 '+(this.n+1)); | ||
999 | this._out('0000000000 65535 f '); | ||
1000 | for(var i=1;i<=this.n;i++) | ||
1001 | this._out(sprintf('%010d 00000 n ',this.offsets[i])); | ||
1002 | // Trailer | ||
1003 | this._out('trailer'); | ||
1004 | this._out('<<'); | ||
1005 | this._out('/Size '+(this.n+1)); | ||
1006 | this._out('/Root '+this.n+' 0 R'); | ||
1007 | this._out('/Info '+(this.n-1)+' 0 R'); | ||
1008 | this._out('>>'); | ||
1009 | this._out('startxref'); | ||
1010 | this._out(o); | ||
1011 | this._out('%%EOF'); | ||
1012 | this.state = 3; | ||
1013 | }; | ||
1014 | |||