Code

Cleaned up virtual destructor problem and compile warnings.
[inkscape.git] / src / extension / internal / libwpg / WPG1Parser.cpp
1 /* libwpg
2  * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
3  * Copyright (C) 2005 Fridrich Strba (fridrich.strba@bluewin.ch)
4  * Copyright (C) 2004 Marc Oude Kotte (marc@solcon.nl)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the 
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
19  * Boston, MA  02111-1301 USA
20  *
21  * For further information visit http://libwpg.sourceforge.net
22  */
24 /* "This product is not manufactured, approved, or supported by
25  * Corel Corporation or Corel Corporation Limited."
26  */
28 #include "WPG1Parser.h"
29 #include "WPGPaintInterface.h"
30 #include "libwpg_utils.h"
32 static const unsigned char defaultWPG1PaletteRed[] = {
33         0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F,
34         0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
35         0x00, 0x14, 0x20, 0x2C, 0x38, 0x45, 0x51, 0x61,
36         0x71, 0x82, 0x92, 0xA2, 0xB6, 0xCB, 0xE3, 0xFF,
37         0x00, 0x41, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
38         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0x7D, 0x41,
39         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40         0x7D, 0x9E, 0xBE, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
41         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xBE, 0x9E,
42         0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
43         0xB6, 0xC7, 0xDB, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF,
44         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xDB, 0xC7,
45         0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
46         0x00, 0x1C, 0x38, 0x55, 0x71, 0x71, 0x71, 0x71,
47         0x71, 0x71, 0x71, 0x71, 0x71, 0x55, 0x38, 0x1C,
48         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49         0x38, 0x45, 0x55, 0x61, 0x71, 0x71, 0x71, 0x71,
50         0x71, 0x71, 0x71, 0x71, 0x71, 0x61, 0x55, 0x45,
51         0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
52         0x51, 0x59, 0x61, 0x69, 0x71, 0x71, 0x71, 0x71,
53         0x71, 0x71, 0x71, 0x71, 0x71, 0x69, 0x61, 0x59,
54         0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
55         0x00, 0x10, 0x20, 0x30, 0x41, 0x41, 0x41, 0x41,
56         0x41, 0x41, 0x41, 0x41, 0x41, 0x30, 0x20, 0x10,
57         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58         0x20, 0x28, 0x30, 0x38, 0x41, 0x41, 0x41, 0x41,
59         0x41, 0x41, 0x41, 0x41, 0x41, 0x38, 0x30, 0x28,
60         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
61         0x3C, 0x30, 0x34, 0x3C, 0x41, 0x41, 0x41, 0x41,
62         0x41, 0x41, 0x41, 0x41, 0x41, 0x3C, 0x34, 0x30,
63         0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C,
64         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 };
67 static const unsigned char defaultWPG1PaletteGreen[] = {
68         0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x3F, 0x7F,
69         0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
70         0x00, 0x14, 0x20, 0x2C, 0x38, 0x45, 0x51, 0x61,
71         0x71, 0x82, 0x92, 0xA2, 0xB6, 0xCB, 0xE3, 0xFF,
72         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73         0x00, 0x41, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
74         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0x7D, 0x41,
75         0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
76         0x7D, 0x9E, 0xBE, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
77         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xBE, 0x9E,
78         0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
79         0xB6, 0xC7, 0xDB, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF,
80         0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xDB, 0xC7,
81         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82         0x00, 0x1C, 0x38, 0x55, 0x71, 0x71, 0x71, 0x71,
83         0x71, 0x71, 0x71, 0x71, 0x71, 0x55, 0x38, 0x1C,
84         0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
85         0x38, 0x45, 0x55, 0x61, 0x71, 0x71, 0x71, 0x71,
86         0x71, 0x71, 0x71, 0x71, 0x71, 0x61, 0x55, 0x45,
87         0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
88         0x51, 0x59, 0x61, 0x69, 0x71, 0x71, 0x71, 0x71,
89         0x71, 0x71, 0x71, 0x71, 0x71, 0x69, 0x61, 0x59,
90         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91         0x00, 0x10, 0x20, 0x30, 0x41, 0x41, 0x41, 0x41,
92         0x41, 0x41, 0x41, 0x41, 0x41, 0x30, 0x20, 0x10,
93         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
94         0x20, 0x28, 0x30, 0x38, 0x41, 0x41, 0x41, 0x41,
95         0x41, 0x41, 0x41, 0x41, 0x41, 0x38, 0x30, 0x28,
96         0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
97         0x3C, 0x30, 0x34, 0x3C, 0x41, 0x41, 0x41, 0x41,
98         0x41, 0x41, 0x41, 0x41, 0x41, 0x3C, 0x34, 0x30,
99         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 };
102 static const unsigned char defaultWPG1PaletteBlue[] = {
103         0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F,
104         0xC0, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
105         0x00, 0x14, 0x20, 0x2C, 0x38, 0x45, 0x51, 0x61,
106         0x71, 0x82, 0x92, 0xA2, 0xB6, 0xCB, 0xE3, 0xFF,
107         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBE, 0x7D, 0x41,
108         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109         0x00, 0x41, 0x7D, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
110         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0xBE, 0x9E,
111         0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D,
112         0x7D, 0x9E, 0xBE, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
113         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEB, 0xDB, 0xC7,
114         0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6,
115         0xB6, 0xC7, 0xDB, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF,
116         0x71, 0x71, 0x71, 0x71, 0x71, 0x55, 0x38, 0x1C,
117         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118         0x00, 0x1C, 0x38, 0x55, 0x71, 0x71, 0x71, 0x71,
119         0x71, 0x71, 0x71, 0x71, 0x71, 0x61, 0x55, 0x45,
120         0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
121         0x38, 0x45, 0x55, 0x61, 0x71, 0x71, 0x71, 0x71,
122         0x71, 0x71, 0x71, 0x71, 0x71, 0x69, 0x61, 0x59,
123         0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
124         0x51, 0x59, 0x61, 0x69, 0x71, 0x71, 0x71, 0x71,
125         0x41, 0x41, 0x41, 0x41, 0x41, 0x30, 0x20, 0x10,
126         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127         0x00, 0x10, 0x20, 0x30, 0x41, 0x41, 0x41, 0x41,
128         0x41, 0x41, 0x41, 0x41, 0x41, 0x38, 0x30, 0x28,
129         0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
130         0x20, 0x28, 0x30, 0x38, 0x41, 0x41, 0x41, 0x41,
131         0x41, 0x41, 0x41, 0x41, 0x41, 0x3C, 0x34, 0x30,
132         0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C,
133         0x2C, 0x30, 0x34, 0x3C, 0x41, 0x41, 0x41, 0x41,
134         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 };
138 WPG1Parser::WPG1Parser(WPGInputStream *input, WPGPaintInterface* painter):
139         WPGXParser(input, painter),
140         m_success(true), m_exit(false),
141         m_width(0), m_height(0)
145 bool WPG1Parser::parse()
147         typedef void (WPG1Parser::*Method)();
149         struct RecordHandler
150         {
151                 int type;
152                 const char *name;
153                 Method handler;
154         };
156         static const struct RecordHandler handlers[] =
157         {
158                 { 0x01, "Fill Attributes",   &WPG1Parser::handleFillAttributes },        
159                 { 0x02, "Line Attributes",   &WPG1Parser::handleLineAttributes },        
160                 { 0x03, "Marker Atttibutes", 0 },        
161                 { 0x04, "Polymarker",        0 },        
162                 { 0x05, "Line",              &WPG1Parser::handleLine },  
163                 { 0x06, "Polyline",          &WPG1Parser::handlePolyline },      
164                 { 0x07, "Rectangle",         &WPG1Parser::handleRectangle },     
165                 { 0x08, "Polygon",           &WPG1Parser::handlePolygon },       
166                 { 0x09, "Ellipse",           &WPG1Parser::handleEllipse },       
167                 { 0x0e, "Colormap",          &WPG1Parser::handleColormap },
168                 { 0x0f, "Start WPG",         &WPG1Parser::handleStartWPG },
169                 { 0x10, "End WPG",           &WPG1Parser::handleEndWPG },
170                 { 0x00, 0, 0 } // end marker
171         };       
173         // initialization
174         m_success = true;
175         m_exit = false;
176         
177         // default style
178         m_pen.foreColor = WPGColor(0,0,0);
179         m_pen.backColor = WPGColor(0,0,0);
180         m_pen.width = 0.001;
181         m_pen.height = 0.001;
182         m_pen.solid = true;
183         m_pen.dashArray = WPGDashArray();
184         m_brush.foreColor = WPGColor(0,0,0);
185         m_brush.backColor = WPGColor(0,0,0);
186         resetPalette();
188         while(!m_input->atEnd())
189         {
190                 long recordPos = m_input->tell();
191                 int recordType = readU8();
192                 int length = readVariableLengthInteger();
193                 long nextPos = m_input->tell() + length;
194 #if !defined(DEBUG)
195                 (void)recordPos;
196 #endif // !defined(DEBUG)
198                 // search function to handler this record
199                 int index = -1;
200                 for(int i = 0; (index < 0) && handlers[i].name; i++)
201                         if(handlers[i].type == recordType)
202                                 index = i;
203                                 
204                 WPG_DEBUG_MSG(("\n"));
205                 if(index < 0)
206                         WPG_DEBUG_MSG(("Unknown record type 0x%02x at %d  size %d\n", 
207                                 recordType, recordPos, length));
208                 else
209                 {
210                         Method recordHandler = handlers[index].handler;
211                         if(!recordHandler)
212                                 WPG_DEBUG_MSG(("Record '%s' (ignored) type 0x%02x at %d  size %d\n", 
213                                         handlers[index].name, recordType, recordPos, length));
214                         else
215                         {
216                                 WPG_DEBUG_MSG(("Record '%s' type 0x%02x at %d  size %d\n", 
217                                         handlers[index].name, recordType, recordPos, length));
218                                         
219                                 // invoke the handler for this record
220                                 (this->*recordHandler)();
221                         }
222                 }
224                 //if(m_input->tell() > nextPos)
225                 {
226                         //WPG_DEBUG_MSG(("Record 0x%x consumes more bytes than necessary!\n", recordType));
227                         WPG_DEBUG_MSG(("Current stream position: %d\n", m_input->tell()));
228                 }
229         
230                 if(m_exit) break;
231                 
232                 m_input->seek(nextPos);
233         }
235         return m_success;
238 void WPG1Parser::handleStartWPG()
240         unsigned char version = readU8();
241         unsigned char bitFlags = readU8();
242         (void)version;
243         (void)bitFlags;
244         m_width = readU16();
245         m_height = readU16();
247         double width = (double)m_width / 1200.0;
248         double height = (double)m_height / 1200.0;
249         m_painter->startDocument(width, height);
251         WPG_DEBUG_MSG(("StartWPG\n"));
254 void WPG1Parser::handleEndWPG()
256         m_painter->endDocument();
257         m_exit = true;
258         
259         WPG_DEBUG_MSG(("EndWPG\n"));
262 void WPG1Parser::handleColormap()
264         unsigned startIndex = readU16();
265         unsigned numEntries = readU16();
267         WPG_DEBUG_MSG(("Colormap\n"));
268         for(int i = 0; i < static_cast<int>(numEntries); i++)
269         {
270                 WPGColor color;
271                 color.red = readU8();
272                 color.green = readU8();
273                 color.blue = readU8();
274                 m_colorPalette[startIndex+i] = color;
275                 WPG_DEBUG_MSG(("Index#%d: RGB %d %d %d\n", startIndex+i, color.red, color.green, color.blue));
276         }
279 void WPG1Parser::handleFillAttributes()
281         unsigned char style = readU8();
282         unsigned char color = readU8();
284         if(style == 0)
285                 m_brush.style = WPGBrush::NoBrush;
286         if(style == 1)
287                 m_brush.style = WPGBrush::Solid;
289         m_brush.foreColor = m_colorPalette[color];
291         WPG_DEBUG_MSG(("Fill Attributes\n"));
292         WPG_DEBUG_MSG(("         Fill style: %d\n", style));
293         WPG_DEBUG_MSG(("   Fill color index: %d\n", color));
296 void WPG1Parser::handleLineAttributes()
298         unsigned char style = readU8();
299         unsigned char color = readU8();
300         unsigned int width = readU16();
302         m_pen.solid = style != 0;
303         m_pen.foreColor = m_colorPalette[color];
304         m_pen.width = (double)width / 1200.0;
306         WPG_DEBUG_MSG(("Line Attributes\n"));
307         WPG_DEBUG_MSG(("         Line style: %d\n", style));
308         WPG_DEBUG_MSG(("   Line color index: %d\n", color));
309         WPG_DEBUG_MSG(("         Line width: %d\n", width));
312 void WPG1Parser::handleLine()
314         int sx = readS16();
315         int sy = readS16();
316         int ex = readS16();
317         int ey = readS16();
319         WPGPointArray points;
320         points.add(WPGPoint((double)sx/1200.0, (double)(m_height-sy)/1200.0));
321         points.add(WPGPoint((double)ex/1200.0, (double)(m_height-ey)/1200.0));
323         m_painter->setBrush(m_brush);
324         m_painter->setPen(m_pen);
325         m_painter->drawPolygon(points);
327         WPG_DEBUG_MSG(("Line\n"));
328         WPG_DEBUG_MSG(("    Starting point: %d,%d\n", sx, sy));
329         WPG_DEBUG_MSG(("         End point: %d,%d\n", ex, ey));
332 void WPG1Parser::handlePolyline()
334         unsigned int count = readU16();
336         WPGPointArray points;
337         for(unsigned int i = 0; i < count; i++ )
338         {
339                 long x = readS16();
340                 long y = readS16();
341                 points.add(WPGPoint((double)x/1200.0, (double)(m_height-y)/1200.0));
342         }
344         m_painter->setBrush(WPGBrush()); // not filled
345         m_painter->setPen(m_pen);
346         m_painter->drawPolygon(points);
348         WPG_DEBUG_MSG(("Polyline\n"));
351 void WPG1Parser::handleRectangle()
353         int x = readS16();
354         int y = readS16();
355         int w = readS16();
356         int h = readS16();
358         WPGRect rect;
359         rect.x1 = (double)x/1200.0;
360         rect.y1 = (double)(m_height-y)/1200.0;
361         rect.x2 = rect.x1 + (double)w/1200.0;
362         rect.y2 = rect.y1 + (double)h/1200.0;
364         m_painter->setBrush(m_brush);
365         m_painter->setPen(m_pen);
366         m_painter->drawRectangle(rect, 0, 0);
368         WPG_DEBUG_MSG(("Line\n"));
369         WPG_DEBUG_MSG(("    Corner point: %d,%d\n", x, y));
370         WPG_DEBUG_MSG(("           Width: %d\n", w));
371         WPG_DEBUG_MSG(("          Height: %d\n", h));
374 void WPG1Parser::handlePolygon()
376         unsigned int count = readU16();
378         WPGPointArray points;
379         for(unsigned int i = 0; i < count; i++ )
380         {
381                 long x = readS16();
382                 long y = readS16();
383                 points.add(WPGPoint((double)x/1200.0, (double)(m_height-y)/1200.0));
384         }
386         m_painter->setBrush(m_brush);
387         m_painter->setPen(m_pen);
388         m_painter->drawPolygon(points);
390         WPG_DEBUG_MSG(("Polygon\n"));
393 void WPG1Parser::handleEllipse()
395         int cx = readS16();
396         int cy = readS16();
397         int rx = readS16();
398         int ry = readS16();
400         WPGPoint center;
401         center.x = (double)cx/1200.0;
402         center.y = (double)(m_height-cy)/1200.0;
404         double radx = (double)rx/1200.0;
405         double rady = (double)ry/1200.0;
407         m_painter->setBrush(m_brush);
408         m_painter->setPen(m_pen);
409         m_painter->drawEllipse(center, radx, rady);
411         WPG_DEBUG_MSG(("Ellipse\n"));
412         WPG_DEBUG_MSG(("    Center point: %d,%d\n", cx, cy));
413         WPG_DEBUG_MSG(("        Radius x: %d\n", rx));
414         WPG_DEBUG_MSG(("        Radius y: %d\n", ry));
417 void WPG1Parser::resetPalette()
419         m_colorPalette.clear();
420         for (int i=0; i<256; i++)
421         {
422                 WPGColor color;
423                 color.red = defaultWPG1PaletteRed[i];
424                 color.green = defaultWPG1PaletteGreen[i];
425                 color.blue = defaultWPG1PaletteBlue[i];
426                 m_colorPalette[i] = color;
427         }