filters

karbonaiparserbase.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2002, Dirk Schönberger <dirk.schoenberger@sz-online.de>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "karbonaiparserbase.h"
21
22#include <core/vcolor.h>
23#include <core/vlayer.h>
24#include <core/vgroup.h>
25#include <core/vclipgroup.h>
26#include <core/vvisitor.h>
27#include "aicolor.h"
28#include <tqwmatrix.h>
29#include <commands/vtransformcmd.h>
30
31#include <KoPageLayout.h>
32
33const void pottoa (PathOutputType &data);
34
35// generic
36KarbonAIParserBase::KarbonAIParserBase() : m_pot(POT_Other), m_ptt (PTT_Output), m_bbox(0,0,612,792), m_emptyFill(), m_emptyStroke()
37/* , m_strokeColor(), m_fillColor() */ {
38
39 // A4, 70 dpi
40/* m_bbox.llx = 0;
41 m_bbox.lly = 0;
42 m_bbox.urx = 612;
43 m_bbox.ury = 792; */
44
45/* m_lineWidth = 0;
46 m_flatness = 0;
47 m_lineCaps = 0;
48 m_lineJoin = 0;
49 m_miterLimit = 10; */
50 m_windingOrder = 0;
51
52 m_fm = FM_NonZero;
53
54 m_curKarbonPath = new VPath( 0L );
55
56 m_document = new VDocument();
57 m_layer = NULL;
58 m_combination = NULL;
59
60 m_emptyFill.setType (VFill::none);
61 m_emptyStroke.setType (VStroke::none);
62
63 setupHandlers();
64}
65
66// generic
67KarbonAIParserBase::~KarbonAIParserBase(){
68 teardownHandlers();
69 delete m_curKarbonPath;
70
71 delete m_document;
72}
73
74// generic
75void KarbonAIParserBase::parsingStarted(){
76// tqDebug ( getHeader().latin1() );
77}
78
79// generic
80void KarbonAIParserBase::parsingFinished(){
81// tqDebug ( getFooter().latin1() );
82
83 // handle bounding box
84 if (m_document)
85 {
86 kdDebug() << "bbox 1 is " << m_bbox << endl;
87
88 if (m_bbox.width() > 0. )
89 m_document->setWidth (m_bbox.width());
90 if (m_bbox.height() > 0. )
91 m_document->setHeight (m_bbox.height());
92
93/* TQWMatrix matrix;
94 matrix.translate (-m_bbox.x(),-m_bbox.y());
95
96 VTransformNodes translator (matrix);
97 m_document->accept (translator); */
98 VTranslateCmd cmd (0L, -m_bbox.x(), -m_bbox.y());
99 m_document->accept (cmd);
100 }
101}
102
103// generic
104TQString KarbonAIParserBase::getParamList(Parameters& params){
105 TQString data("");
106
107 Parameter *param;
108
109 if (params.count() > 0)
110 {
111
112 for ( param=params.first(); param != 0; param=params.next() ) {
113 data += " " + param->first + "=\"" + param->second + "\"";
114 }
115 }
116
117 return data;
118}
119
120// generic
121void KarbonAIParserBase::gotStartTag (const char *tagName, Parameters& params){
122 tqDebug ("<%s%s>", tagName, getParamList (params).latin1() );
123}
124
125// generic
126void KarbonAIParserBase::gotEndTag (const char *tagName){
127 tqDebug ("</%s>", tagName );
128}
129
130// generic
131void KarbonAIParserBase::gotSimpleTag (const char *tagName, Parameters& params){
132 tqDebug ("<%s%s/>", tagName, getParamList (params).latin1() );
133}
134
135// generic
136void KarbonAIParserBase::gotPathElement (PathElement &element){
137 switch (element.petype)
138 {
139 case PET_MoveTo :
140 m_curKarbonPath->moveTo (KoPoint (element.pevalue.pointdata.x,element.pevalue.pointdata.y));
141 break;
142 case PET_LineTo :
143 m_curKarbonPath->lineTo (KoPoint (element.pevalue.pointdata.x,element.pevalue.pointdata.y));
144 break;
145 case PET_CurveTo :
146 m_curKarbonPath->curveTo (KoPoint (element.pevalue.bezierdata.x1,element.pevalue.bezierdata.y1),
147 KoPoint (element.pevalue.bezierdata.x2,element.pevalue.bezierdata.y2),
148 KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3));
149 break;
150 case PET_CurveToOmitC1 :
151 m_curKarbonPath->curve1To (KoPoint (element.pevalue.bezierdata.x2,element.pevalue.bezierdata.y2),
152 KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3));
153 break;
154 case PET_CurveToOmitC2 :
155 m_curKarbonPath->curve2To (KoPoint (element.pevalue.bezierdata.x1,element.pevalue.bezierdata.y1),
156 KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3));
157 break;
158 }
159}
160
161// generic
162void KarbonAIParserBase::gotFillPath (bool closed, bool reset, FillMode /*fm*/){
163// tqDebug ("found fill path");
164// if (!reset) tqDebug ("retain filled path");
165
166 if (closed) m_curKarbonPath->close();
167
168 if (!reset)
169 m_pot = POT_Filled;
170 else
171 {
172 doOutputCurrentPath2 (POT_Filled);
173 m_pot = POT_Other;
174 }
175}
176
177// generic
178void KarbonAIParserBase::gotIgnorePath (bool closed, bool reset){
179// tqDebug ("found ignore path");
180
181 if (closed) m_curKarbonPath->close();
182
183 if (! reset)
184 m_pot = POT_Other;
185 else
186 {
187 doOutputCurrentPath2 (POT_Ignore);
188 m_pot = POT_Other;
189 }
190}
191
192// generic
193void KarbonAIParserBase::gotStrokePath (bool closed) {
194// tqDebug ("found stroke path");
195
196 if (closed) m_curKarbonPath->close();
197
198 PathOutputType pot = POT_Stroked;
199 if (m_pot != POT_Other)
200 {
201 pot = POT_FilledStroked;
202 }
203
204 doOutputCurrentPath2 (pot);
205
206 m_pot = POT_Other;
207}
208
209// generic
210void KarbonAIParserBase::gotClipPath (bool /*closed*/){
211
212 doOutputCurrentPath2 (POT_Clip);
213}
214
215// generic
216void KarbonAIParserBase::gotFillColor (AIColor &color){
217// double r, g, b;
218// color.toRGB (r,g,b);
219// tqDebug ("set fillcolor to %f %f %f",r,g,b);
220// m_fillColor = color;
221
222 VColor karbonColor = toKarbonColor (color);
223 m_fill.setColor (karbonColor);
224}
225
226// generic
227void KarbonAIParserBase::gotStrokeColor (AIColor &color){
228// double r, g, b;
229// color.toRGB (r,g,b);
230// tqDebug ("set strokecolor to %f %f %f",r,g,b);
231// m_strokeColor = color;
232
233 VColor karbonColor = toKarbonColor (color);
234 m_stroke.setColor (karbonColor);
235}
236
237// generic
238void KarbonAIParserBase::gotBoundingBox (int llx, int lly, int urx, int ury){
239/* m_bbox.llx = llx;
240 m_bbox.lly = lly;
241 m_bbox.urx = urx;
242 m_bbox.ury = ury; */
243 m_bbox.setCoords(llx,lly,urx,ury);
244}
245
246void KarbonAIParserBase::gotLineWidth (double val){
247// m_lineWidth = val;
248 m_stroke.setLineWidth (val);
249}
250
251void KarbonAIParserBase::gotFlatness (double /*val*/)
252{
253// m_flatness = val;
254// m_stroke.setFlatness (val);
255}
256
257void KarbonAIParserBase::gotLineCaps (int val)
258{
259// m_lineCaps = val;
260 VStroke::VLineCap lineCap = VStroke::capButt;
261
262 switch (val)
263 {
264 case 0 : lineCap = VStroke::capButt; break;
265 case 1 : lineCap = VStroke::capRound; break;
266 case 2 : lineCap = VStroke::capSquare; break;
267 }
268
269 m_stroke.setLineCap (lineCap);
270}
271
272void KarbonAIParserBase::gotLineJoin (int val)
273{
274// m_lineJoin = val;
275
276 VStroke::VLineJoin lineJoin = VStroke::joinMiter;
277
278 switch (val)
279 {
280 case 0 : lineJoin = VStroke::joinMiter; break;
281 case 1 : lineJoin = VStroke::joinRound; break;
282 case 2 : lineJoin = VStroke::joinBevel; break;
283 }
284
285 m_stroke.setLineJoin (lineJoin);
286
287}
288
289void KarbonAIParserBase::gotMiterLimit (double val)
290{
291// m_miterLimit = val;
292 m_stroke.setMiterLimit (val);
293}
294
295void KarbonAIParserBase::gotWindingOrder (int val)
296{
297 m_windingOrder = val;
298}
299
300void KarbonAIParserBase::gotBeginGroup (bool clipping)
301{
302// tqDebug ("start begin group");
303 if (clipping)
304 {
305 VClipGroup *group = new VClipGroup( 0L );
306 m_groupStack.push (group);
307 }
308 else
309 {
310 VGroup *group = new VGroup( 0L );
311 m_groupStack.push (group);
312 }
313
314// tqDebug ("end begin group");
315
316}
317
318void KarbonAIParserBase::gotEndGroup (bool /*clipping*/)
319{
320// tqDebug ("start end group");
321
322 if (m_debug) tqDebug ("got end group");
323
324 if (m_groupStack.isEmpty()) return;
325
326 if (m_debug) tqDebug ("got end group 2");
327
328 VGroup *group = m_groupStack.pop();
329
330 if (m_debug) tqDebug ("got end group 3");
331
332 if (m_debug)
333 {
334 if (!group) tqDebug ("group is NULL");
335 }
336
337 if (m_groupStack.isEmpty())
338 {
339 if (m_debug) tqDebug ("insert object");
340 ensureLayer();
341 m_layer->append (group);
342 if (m_debug) tqDebug ("/insert object");
343 }
344 else
345 {
346 if (m_debug) tqDebug ("insert object to group");
347
348 m_groupStack.top()->append (group);
349 if (m_debug) tqDebug ("/insert object to group");
350 }
351
352 if (m_debug) tqDebug ("/got end group");
353
354// tqDebug ("end end group");
355}
356
357void KarbonAIParserBase::gotBeginCombination () {
358 m_ptt = PTT_Combine;
359}
360
361void KarbonAIParserBase::gotEndCombination () {
362// tqDebug ( "got end combination" );
363
364 m_ptt = PTT_Output;
365
366 if (m_combination != NULL)
367 {
368 m_curKarbonPath = m_combination;
369 doOutputCurrentPath2 (POT_Leave);
370 }
371
372 m_combination = NULL;
373}
374
375
376const VColor KarbonAIParserBase::toKarbonColor (const AIColor &color)
377{
378 AIColor temp (color);
379 VColor value;
380
381 double v1, v2, v3, v4;
382 temp.toCMYK (v1, v2, v3, v4);
383
384 float cv1 = v1;
385 float cv2 = v2;
386 float cv3 = v3;
387 float cv4 = v4;
388
389 value.setColorSpace (VColor::cmyk);
390 value.set (cv1, cv2, cv3, cv4);
391
392 return value;
393}
394
395void KarbonAIParserBase::doOutputCurrentPath2(PathOutputType type)
396{
397 ensureLayer();
398
399 if (type != POT_Leave)
400 {
401// pottoa(type);
402
403 m_curKarbonPath->setStroke(m_emptyStroke);
404 m_curKarbonPath->setFill(m_emptyFill);
405
406 if ((type != POT_Filled) && (type != POT_Stroked) && (type != POT_FilledStroked)) return;
407 if ((type == POT_Filled) || (type == POT_FilledStroked))
408 {
409/* VFill fill;
410 fill.setColor (toKarbonColor (m_fillColor));
411 m_curKarbonPath->setFill(fill); */
412// tqDebug ("set filled");
413 m_curKarbonPath->setFill(m_fill);
414 }
415
416 if ((type == POT_Stroked) || (type == POT_FilledStroked))
417 {
418/* VStroke stroke;
419 stroke.setColor (toKarbonColor (m_strokeColor));
420 m_curKarbonPath->setStroke (stroke); */
421// tqDebug ("set stroked");
422 m_curKarbonPath->setStroke (m_stroke);
423 }
424 }
425
426 if (m_ptt == PTT_Combine)
427 {
428// m_pot |= type;
429 if (m_combination == NULL)
430 m_combination = m_curKarbonPath;
431 else
432 m_combination->combine (*m_curKarbonPath);
433
434 m_curKarbonPath = new VPath( 0L );
435
436 return;
437 }
438
439 ensureLayer();
440
441 if (m_groupStack.isEmpty())
442 {
443 m_layer->append( m_curKarbonPath );
444 }
445 else
446 {
447 m_groupStack.top()->append( m_curKarbonPath );
448 }
449
450 m_curKarbonPath = new VPath( 0L );
451}
452
453bool KarbonAIParserBase::parse (TQIODevice& fin, TQDomDocument &doc)
454{
455
456 bool res = AIParserBase::parse (fin);
457
458// tqDebug ("document is %s",doc.toString().latin1());
459 if (res)
460 {
461 tqDebug ("before save document");
462 doc = m_document->saveXML();
463 // add paper info, we always need custom for svg (Rob)
464 TQDomElement paper = doc.createElement( "PAPER" );
465 doc.documentElement().appendChild( paper );
466 paper.setAttribute( "format", PG_CUSTOM );
467 paper.setAttribute( "width", m_document->width() );
468 paper.setAttribute( "height", m_document->height() );
469
470 tqDebug ("after save document");
471 }
472 else
473 {
474 TQDomDocument tempDoc;
475 doc = tempDoc;
476 }
477
478 return res;
479}
480
481void KarbonAIParserBase::ensureLayer ()
482{
483 if (!m_layer)
484 {
485 m_layer = new VLayer( 0 );
486 m_document->insertLayer (m_layer);
487 }
488}
489
490
491void KarbonAIParserBase::setupHandlers()
492{
493// tqDebug("setupHandler called");
494 m_gstateHandler = new KarbonGStateHandler(this);
495 m_structureHandler = new KarbonStructureHandler(this);
496 m_pathHandler = new KarbonPathHandler(this);
497 m_documentHandler = new KarbonDocumentHandler(this);
498
499 m_textHandler = new TextHandlerBase();
500
501}
502
503void KarbonAIParserBase::teardownHandlers()
504{
505// tqDebug("teardownHandler called");
506 delete m_textHandler;
507
508 delete m_gstateHandler;
509 delete m_structureHandler;
510 delete m_pathHandler;
511 delete m_documentHandler;
512}
513
514
515void KarbonDocumentHandler::gotBoundingBox (int llx, int lly, int urx, int ury)
516{
517 delegate->gotBoundingBox(llx,lly,urx,ury);
518}
519
520void KarbonDocumentHandler::gotCreationDate (const char */*val1*/,const char */*val2*/)
521{
522// tqDebug ("got creation date [%s], [%s]",val1,val2);
523}
524
525void KarbonDocumentHandler::gotProcessColors (int /*colors*/)
526{
527/* if (colors && PC_Cyan) tqDebug ("contains cyan");
528 if (colors && PC_Magenta) tqDebug ("contains magenta");
529 if (colors && PC_Yellow) tqDebug ("contains yellow");
530 if (colors && PC_Black) tqDebug ("contains black"); */
531}
532
533
534void KarbonGStateHandler::gotFillColor (AIColor &color)
535{
536 delegate->gotFillColor (color);
537}
538
539void KarbonGStateHandler::gotStrokeColor (AIColor &color)
540{
541 delegate->gotStrokeColor(color);
542}
543
544void KarbonGStateHandler::gotFlatness (double val)
545{
546 delegate->gotFlatness(val);
547}
548
549void KarbonGStateHandler::gotLineWidth (double val)
550{
551 delegate->gotLineWidth(val);
552}
553
554void KarbonGStateHandler::gotLineCaps (int val)
555{
556 delegate->gotLineCaps(val);
557}
558
559void KarbonGStateHandler::gotLineJoin (int val)
560{
561 delegate->gotLineJoin(val);
562}
563
564void KarbonGStateHandler::gotMiterLimit (double val)
565{
566 delegate->gotMiterLimit(val);
567}
568
569void KarbonGStateHandler::gotWindingOrder (int val)
570{
571 delegate->gotWindingOrder(val);
572}
573
574void KarbonStructureHandler::gotBeginGroup (bool clipping)
575{
576 delegate->gotBeginGroup(clipping);
577}
578
579void KarbonStructureHandler::gotEndGroup (bool clipping)
580{
581 delegate->gotEndGroup(clipping);
582}
583
584void KarbonStructureHandler::gotBeginCombination ()
585{
586 delegate->gotBeginCombination();
587}
588
589void KarbonStructureHandler::gotEndCombination ()
590{
591 delegate->gotEndCombination();
592}
593
594void KarbonPathHandler::gotPathElement (PathElement &element)
595{
596 delegate->gotPathElement (element);
597}
598
599void KarbonPathHandler::gotFillPath (bool closed, bool reset)
600{
601 delegate->gotFillPath(closed, reset, m_fm);
602}
603
604void KarbonPathHandler::gotFillMode (FillMode fm)
605{
606 m_fm = fm;
607}
608
609void KarbonPathHandler::gotStrokePath (bool closed)
610{
611 delegate->gotStrokePath(closed);
612}
613
614void KarbonPathHandler::gotIgnorePath (bool closed, bool reset)
615{
616 delegate->gotIgnorePath(closed, reset);
617}
618
619void KarbonPathHandler::gotClipPath (bool closed)
620{
621 delegate->gotClipPath(closed);
622}
623
624const void pottoa (PathOutputType &data)
625{
626 switch (data)
627 {
628 case POT_Filled : tqDebug ("filled"); break;
629 case POT_Stroked : tqDebug ("stroked"); break;
630 case POT_FilledStroked : tqDebug ("filled/stroked"); break;
631 case POT_Clip : tqDebug ("clip"); break;
632 case POT_Ignore : tqDebug ("ignore"); break;
633 case POT_Leave : tqDebug ("leave"); break;
634 default : tqDebug ("unknown");
635 }
636}
637