00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <assert.h>
00026 #include <fstream.h>
00027 #include <limits.h>
00028 #include <math.h>
00029
00030 #include <GDocument.h>
00031 #include <GPage.h>
00032 #include <GGroup.h>
00033 #include <GPolyline.h>
00034 #include <GOval.h>
00035 #include <GPolygon.h>
00036 #include <GText.h>
00037 #include <xfigimport.h>
00038 #include <xfigimport.moc>
00039
00040 #include <qtl.h>
00041 #include <kdebug.h>
00042
00043 #include <core/vdocument.h>
00044 namespace std { };
00045 using namespace std;
00046
00047 #define RAD_FACTOR 180.0 / M_PI
00048
00049 unsigned int colors[] = {
00050 0x000090,
00051 0x0000b0,
00052 0x0000d0,
00053 0x87ceff,
00054 0x009000,
00055 0x00b000,
00056 0x00d000,
00057 0x009090,
00058 0x00b0b0,
00059 0x00d0d0,
00060 0x900000,
00061 0xb00000,
00062 0xd00000,
00063 0x900090,
00064 0xb000b0,
00065 0xd000d0,
00066 0x803000,
00067 0xa04000,
00068 0xc06000,
00069 0xff8080,
00070 0xffa0a0,
00071 0xffc0c0,
00072 0xffe0e0,
00073 0xffd700
00074 };
00075
00076 int arrow_ids[] = {
00077 6, 1, 2, 7
00078 };
00079
00080 struct PSFont {
00081 const char* family;
00082 QFont::Weight weight;
00083 bool italic;
00084 } psFontTable[] = {
00085 { "times", QFont::Normal, false },
00086 { "times", QFont::Normal, true },
00087 { "times", QFont::Bold, false },
00088 { "times", QFont::Bold, true },
00089 { "avantgarde", QFont::Normal, false },
00090 { "avantgarde", QFont::Normal, true },
00091 { "avantgarde", QFont::DemiBold, false },
00092 { "avantgarde", QFont::DemiBold, true },
00093 { "bookman", QFont::Light, false },
00094 { "bookman", QFont::Light, true },
00095 { "bookman", QFont::DemiBold, false },
00096 { "bookman", QFont::DemiBold, true },
00097 { "courier", QFont::Normal, false },
00098 { "courier", QFont::Normal, true },
00099 { "courier", QFont::Bold, false },
00100 { "courier", QFont::Bold, true },
00101 { "helvetica", QFont::Normal, false },
00102 { "helvetica", QFont::Normal, true },
00103 { "helvetica", QFont::Bold, false },
00104 { "helvetica", QFont::Bold, true },
00105 { "helvetica", QFont::Normal, false },
00106 { "helvetica", QFont::Normal, true },
00107 { "helvetica", QFont::Bold, false },
00108 { "helvetica", QFont::Bold, true },
00109 { "newcenturyschoolbook", QFont::Normal, false },
00110 { "newcenturyschoolbook", QFont::Normal, true },
00111 { "newcenturyschoolbook", QFont::Bold, false },
00112 { "newcenturyschoolbook", QFont::Bold, true },
00113 { "palatino", QFont::Normal, false },
00114 { "palatino", QFont::Normal, true },
00115 { "palatino", QFont::Bold, false },
00116 { "palatino", QFont::Bold, true },
00117 { "symbol", QFont::Normal, false },
00118 { "zapfchancery", QFont::Normal, false },
00119 { "zapfdingbats", QFont::Normal, false },
00120 };
00121
00122 int hexstrToInt (const char *str) {
00123 const int fak[] = { 16, 1 };
00124 int value = 0, v;
00125
00126 for (int i = 0; i < 2; i++) {
00127 if (str[i] >= '0' && str[i] <= '9')
00128 v = str[i] - '0';
00129 else
00130 v = str[i] - 'a' + 10;
00131 value += v * fak[i];
00132 }
00133
00134 return value;
00135 }
00136
00137 XFIGImport::XFIGImport( KoFilter *parent, const char *name ) : KoFilter(parent, name)
00138 {
00139 fig_resolution = 1200.0 / 72.0;
00140 coordinate_system = 2;
00141
00142 colorTable.insert (0, new QColor (Qt::black));
00143 colorTable.insert (1, new QColor (Qt::blue));
00144 colorTable.insert (2, new QColor (Qt::green));
00145 colorTable.insert (3, new QColor (Qt::cyan));
00146 colorTable.insert (4, new QColor (Qt::red));
00147 colorTable.insert (5, new QColor (Qt::magenta));
00148 colorTable.insert (6, new QColor (Qt::yellow));
00149 colorTable.insert (7, new QColor (Qt::white));
00150
00151 for (int i = 0; i <= 23; i++)
00152 colorTable.insert (i + 8, new QColor (colors[i]));
00153
00154 objList.clear ();
00155 }
00156
00157 XFIGImport::~XFIGImport()
00158 {
00159 }
00160
00161 bool XFIGImport::filterImport( const QString &file, KoDocument *doc,
00162 const QString &from, const QString &to,
00163 const QString & ) {
00164
00165 if( to != "application/x-karbon" || from != "image/x-xfig" )
00166 return false;
00167
00168 char buf[255];
00169 int value;
00170 KoPageLayout layout;
00171
00172 ifstream fin( file.local8Bit() );
00173 if (! fin)
00174 return false;
00175
00176 KIllustratorDocument *kidoc = (KIllustratorDocument *) doc;
00177 GDocument *gdoc = kidoc->gdoc();
00178
00179
00180 layout = gdoc->activePage()->pageLayout ();
00181
00182 fin.getline (buf, 255);
00183 if (::strncmp (buf, "#FIG 3", 6)) {
00184 kdDebug() << "ERROR: no xfig file or wrong header" << endl;
00185 return false;
00186 }
00187
00188 if (buf[7] == '2') {
00189 version = 320;
00190 }
00191 else if (buf[7] == '1') {
00192 version = 310;
00193 }
00194 else {
00195 kdDebug() << "ERROR: unsupported xfig version" << endl;
00196 return false;
00197 }
00198
00199
00200
00201
00202
00203
00204 fin.getline (buf, 255);
00205 if (::strcmp (buf, "Landscape") == 0)
00206 layout.orientation = PG_LANDSCAPE;
00207 else if (::strcmp (buf, "Portrait") == 0)
00208 layout.orientation = PG_PORTRAIT;
00209 else
00210 kdDebug() << "ERROR: invalid orientation" << endl;
00211
00212
00213 fin.getline (buf, 255);
00214
00215
00216 fin.getline (buf, 255);
00217 if (::strcmp (buf, "Metric") == 0)
00218 layout.unit = PG_MM;
00219 else if (::strcmp (buf, "Inches") == 0)
00220 layout.unit = PG_INCH;
00221 else
00222 kdDebug() << "ERROR: invalid units" << endl;
00223
00224 if (version >= 320) {
00225
00226 fin.getline (buf, 255);
00227
00228
00229 float magnification;
00230 fin >> magnification;
00231 fin.ignore (INT_MAX, '\n');
00232
00233
00234 fin.getline (buf, 255);
00235
00236
00237 int transColor;
00238 fin >> transColor;
00239 fin.ignore (INT_MAX, '\n');
00240 }
00241
00242
00243 fin >> value >> coordinate_system;
00244 fig_resolution = value / 72.0;
00245 fin.ignore (INT_MAX, '\n');
00246
00247
00248 while (! fin.eof ()) {
00249 int tag = -1;
00250 fin >> tag;
00251 if (tag == -1) {
00252
00253 buildDocument (gdoc);
00254 return true;
00255 }
00256
00257 switch (tag) {
00258 case 0:
00259
00260 parseColorObject (fin);
00261 break;
00262 case 1:
00263
00264 parseEllipse (fin, gdoc);
00265 break;
00266 case 2:
00267
00268 parsePolyline (fin, gdoc);
00269 break;
00270 case 3:
00271
00272 parseSpline (fin, gdoc);
00273 break;
00274 case 4:
00275
00276 parseText (fin, gdoc);
00277 break;
00278 case 5:
00279
00280 parseArc (fin, gdoc);
00281 break;
00282 case 6:
00283
00284 parseCompoundObject (fin, gdoc);
00285 break;
00286 case -6:
00287
00288 break;
00289 default:
00290
00291 kdDebug() << "unknown object type: " << tag << endl;
00292 break;
00293 }
00294 }
00295 buildDocument (gdoc);
00296 return true;
00297 }
00298
00299
00300 void XFIGImport::parseColorObject (istream& fin) {
00301 int number, red, green, blue;
00302 char buf[20], red_str[3], green_str[3], blue_str[3];
00303
00304 fin >> number >> buf;
00305 strncpy (red_str, &buf[1], 2); red_str[2] = '\0';
00306 strncpy (green_str, &buf[3], 2); green_str[2] = '\0';
00307 strncpy (blue_str, &buf[5], 2); blue_str[2] = '\0';
00308
00309 red = hexstrToInt (red_str);
00310 green = hexstrToInt (green_str);
00311 blue = hexstrToInt (blue_str);
00312
00313 colorTable.insert (number, new QColor (red, green, blue));
00314 }
00315
00316 void XFIGImport::parseArc (istream& fin, GDocument* doc) {
00317 int sub_type, line_style, thickness, pen_color, fill_color,
00318 depth, pen_style, area_fill, cap_style, direction,
00319 forward_arrow, backward_arrow, x1, y1, x2, y2, x3, y3;
00320 float center_x, center_y;
00321 float style_val;
00322 GOval *obj = new GOval (doc);
00323
00324
00325 fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
00326 >> depth >> pen_style >> area_fill >> style_val >> cap_style
00327 >> direction >> forward_arrow >> backward_arrow
00328 >> center_x >> center_y >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
00329
00330 if (forward_arrow > 0) {
00331
00332 fin.ignore (INT_MAX, '\n');
00333 }
00334
00335 if (backward_arrow > 0) {
00336
00337 fin.ignore (INT_MAX, '\n');
00338 }
00339
00340
00341 float dx = x1 - center_x;
00342 float dy = y1 - center_y;
00343 float radius = sqrt (dx * dx + dy * dy);
00344
00345 if (radius==0) {
00346 delete obj;
00347 return;
00348 }
00349
00350 Coord p1 ((center_x - radius) / fig_resolution,
00351 (center_y - radius) / fig_resolution);
00352 Coord p2 ((center_x + radius) / fig_resolution,
00353 (center_y + radius) / fig_resolution);
00354
00355 obj->setStartPoint (p1);
00356 obj->setEndPoint (p2);
00357
00358 if (sub_type == 0)
00359 obj->setOutlineShape (GObject::OutlineInfo::PieShape);
00360 else if (sub_type == 1)
00361 obj->setOutlineShape (GObject::OutlineInfo::ArcShape);
00362
00363 p1 = Coord (center_x / fig_resolution, center_y /fig_resolution);
00364 float m;
00365
00366 float angle1;
00367 p2 = Coord (x1 / fig_resolution, y1 /fig_resolution);
00368 if (p2.x () == p1.x ()) {
00369 if (p2.y () > p1.y ())
00370 angle1 = 90;
00371 else
00372 angle1 = -90;
00373 }
00374 else {
00375 m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ()));
00376 if ( p2.x () > p1.x ())
00377 angle1 = atan (m) * RAD_FACTOR;
00378 else
00379 angle1 = 180 + atan (m) * RAD_FACTOR;
00380 }
00381
00382 float angle2;
00383 p2 = Coord (x3 / fig_resolution, y3 /fig_resolution);
00384 if (p2.x () == p1.x ()) {
00385 if (p2.y () > p1.y ())
00386 angle2 = 90;
00387 else
00388 angle2 = -90;
00389 }
00390 else {
00391 m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ()));
00392 if ( p2.x () > p1.x ())
00393 angle2 = atan (m) * RAD_FACTOR;
00394 else
00395 angle2 = 180 + atan (m) * RAD_FACTOR;
00396 }
00397
00398 if (direction==0)
00399 obj->setAngles (angle2, angle1);
00400 else if (direction==1)
00401 obj->setAngles (angle1, angle2);
00402
00403
00404 setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color);
00405 objList.append( GObjectListItem( depth, obj ) );
00406 }
00407
00408 void XFIGImport::parseEllipse (istream& fin, GDocument* doc) {
00409 int sub_type, line_style, thickness, pen_color, fill_color,
00410 depth, pen_style, area_fill, direction, center_x, center_y,
00411 radius_x, radius_y, start_x, start_y, end_x, end_y;
00412 float style_val, angle;
00413 GOval *obj = new GOval (doc);
00414
00415
00416 fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
00417 >> depth >> pen_style >> area_fill >> style_val >> direction
00418 >> angle >> center_x >> center_y >> radius_x >> radius_y
00419 >> start_x >> start_y >> end_x >> end_y;
00420 Coord p1, p2;
00421
00422 p1 = Coord ((center_x - radius_x) /fig_resolution,
00423 (center_y - radius_y) /fig_resolution);
00424 p2 = Coord ((center_x + radius_x) /fig_resolution,
00425 (center_y + radius_y) /fig_resolution);
00426
00427 obj->setStartPoint (p1);
00428 obj->setEndPoint (p2);
00429
00430
00431 setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color);
00432 objList.append( GObjectListItem( depth, obj ) );
00433 }
00434
00435 void XFIGImport::parsePolyline (istream& fin, GDocument* doc) {
00436 int sub_type, line_style, thickness, pen_color, fill_color,
00437 depth, pen_style, area_fill, join_style, cap_style, radius,
00438 forward_arrow, backward_arrow, npoints;
00439 float style_val;
00440 GPolyline *obj = NULL;
00441
00442
00443 fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
00444 >> depth >> pen_style >> area_fill >> style_val >> join_style
00445 >> cap_style >> radius >> forward_arrow >> backward_arrow
00446 >> npoints;
00447 fin.ignore (INT_MAX, '\n');
00448
00449 switch (sub_type) {
00450 case 1:
00451 obj = new GPolyline (doc);
00452 break;
00453 case 2:
00454 obj = new GPolygon (doc);
00455 break;
00456 case 3:
00457 obj = new GPolygon (doc);
00458 break;
00459 case 4:
00460 obj = new GPolygon (doc);
00461 break;
00462 case 5:
00463 return;
00464 break;
00465 default:
00466
00467 kdDebug() << "unknown subtype: " << sub_type << endl;
00468 break;
00469 }
00470
00471 assert (obj != NULL);
00472
00473 int arrow_type, arrow_style;
00474 float arrow_thickness, arrow_width, arrow_height;
00475 GObject::OutlineInfo oinfo;
00476 oinfo.mask = GObject::OutlineInfo::Custom;
00477 oinfo.startArrowId = oinfo.endArrowId = 0;
00478
00479 if (forward_arrow > 0) {
00480
00481
00482 fin >> arrow_type >> arrow_style >> arrow_thickness
00483 >> arrow_width >> arrow_height;
00484 oinfo.endArrowId = arrow_ids[arrow_type];
00485 if (oinfo.endArrowId == 1 && arrow_style == 0)
00486 oinfo.endArrowId = 4;
00487 fin.ignore (INT_MAX, '\n');
00488 }
00489
00490 if (backward_arrow > 0) {
00491
00492 fin >> arrow_type >> arrow_style >> arrow_thickness
00493 >> arrow_width >> arrow_height;
00494 oinfo.startArrowId = arrow_ids[arrow_type];
00495 if (oinfo.startArrowId == 1 && arrow_style == 0)
00496 oinfo.startArrowId = 4;
00497 fin.ignore (INT_MAX, '\n');
00498 }
00499
00500 for (int i = 0; i < npoints; i++) {
00501 int x, y;
00502 fin >> x >> y;
00503 if ((sub_type == 2 || sub_type == 3) && i == npoints -1)
00504
00505 break;
00506
00507 Coord p (x / fig_resolution, y / fig_resolution);
00508 obj->_addPoint (i, p);
00509 }
00510
00511 if (oinfo.startArrowId || oinfo.endArrowId)
00512 obj->setOutlineInfo (oinfo);
00513
00514
00515 setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color);
00516
00517
00518 objList.append( GObjectListItem( depth, obj ) );
00519 }
00520
00521 void XFIGImport::parseSpline (istream& fin, GDocument* doc)
00522 {
00523 int sub_type, line_style, thickness, pen_color, fill_color, depth,
00524 pen_style, area_fill, cap_style, forward_arrow, backward_arrow, npoints;
00525 float style_val;
00526
00527
00528 GPolyline *obj = 0L;
00529 fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
00530 >> depth >> pen_style >> area_fill >> style_val >> cap_style
00531 >> forward_arrow >> backward_arrow >> npoints;
00532 if (sub_type == 1 || sub_type == 3 || sub_type == 5)
00533 obj = new GPolygon (doc);
00534 else
00535 obj = new GPolyline (doc);
00536
00537 int arrow_type, arrow_style;
00538 float arrow_thickness, arrow_width, arrow_height;
00539 GObject::OutlineInfo oinfo;
00540 oinfo.mask = GObject::OutlineInfo::Custom;
00541 oinfo.startArrowId = oinfo.endArrowId = 0;
00542
00543 if (forward_arrow > 0) {
00544
00545
00546 fin >> arrow_type >> arrow_style >> arrow_thickness
00547 >> arrow_width >> arrow_height;
00548 oinfo.endArrowId = arrow_ids[arrow_type];
00549 if (oinfo.endArrowId == 1 && arrow_style == 0)
00550 oinfo.endArrowId = 4;
00551 fin.ignore (INT_MAX, '\n');
00552 }
00553
00554 if (backward_arrow > 0) {
00555
00556 fin >> arrow_type >> arrow_style >> arrow_thickness
00557 >> arrow_width >> arrow_height;
00558 oinfo.startArrowId = arrow_ids[arrow_type];
00559 if (oinfo.startArrowId == 1 && arrow_style == 0)
00560 oinfo.startArrowId = 4;
00561 fin.ignore (INT_MAX, '\n');
00562 }
00563
00564
00565 for (int i = 0; i < npoints; i++) {
00566 int x, y;
00567 fin >> x >> y;
00568 if ((sub_type == 1 || sub_type == 3 || sub_type == 5) && i == npoints -1)
00569
00570 break;
00571
00572 Coord p (x / fig_resolution, y / fig_resolution);
00573 obj->_addPoint (i, p);
00574 }
00575
00576
00577 for (int i = 0; i < npoints; i++) {
00578 float fac;
00579 fin >> fac;
00580
00581
00582 }
00583
00584 if (oinfo.startArrowId || oinfo.endArrowId)
00585 obj->setOutlineInfo (oinfo);
00586
00587
00588 setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color);
00589
00590
00591 objList.append( GObjectListItem( depth, obj ) );
00592 }
00593
00594 void XFIGImport::parseText (istream& fin, GDocument* doc)
00595 {
00596 int sub_type, color, depth, pen_style, font, font_flags, x, y;
00597 float font_size, angle, height, length;
00598 GText *obj = new GText (doc);
00599 char c;
00600 char ocode[4];
00601 bool finished = false;
00602 QString text;
00603 QFont qfont;
00604
00605 fin >> sub_type >> color >> depth >> pen_style >> font >> font_size
00606 >> angle >> font_flags >> height >> length >> x >> y;
00607
00608 if (font_flags & 4) {
00609
00610 if (font == -1)
00611 font = 0;
00612 qfont = QFont (psFontTable[font].family, qRound (font_size),
00613 psFontTable[font].weight, psFontTable[font].italic);
00614 }
00615 else {
00616
00617 switch (font) {
00618 case 1:
00619 qfont.setFamily ("times");
00620 break;
00621 case 2:
00622 qfont.setBold (true);
00623 break;
00624 case 3:
00625 qfont.setItalic (true);
00626 break;
00627 case 4:
00628 qfont.setFamily ("helvetica");
00629 break;
00630 case 5:
00631 qfont.setFamily ("Courier");
00632 break;
00633 default:
00634 break;
00635 }
00636 }
00637 qfont.setPointSize (qRound (font_size));
00638 obj->setFont (qfont);
00639
00640 while (! finished) {
00641 fin.get (c);
00642 if (c == '\\') {
00643 fin.get (ocode, 4);
00644 int code = (ocode[0] - '0') * 64 +
00645 (ocode[1] - '0') * 8 +
00646 (ocode[2] - '0');
00647 if (code == 1)
00648 finished = true;
00649 else
00650 text += (char) code;
00651 }
00652 else
00653 text += c;
00654 }
00655 obj->setText (text);
00656
00657 if (sub_type == 1) {
00658 GText::TextInfo ti = obj->getTextInfo ();
00659 ti.align = GText::TextInfo::AlignCenter;
00660 obj->setTextInfo (ti);
00661 }
00662 else if (sub_type == 2) {
00663 GText::TextInfo ti = obj->getTextInfo ();
00664 ti.align = GText::TextInfo::AlignRight;
00665 obj->setTextInfo (ti);
00666 }
00667 Coord origin (x / fig_resolution, y / fig_resolution - qfont.pointSize ());
00668 obj->setOrigin (origin);
00669
00670 if (angle != 0) {
00671
00672 float nangle = angle * RAD_FACTOR;
00673 QWMatrix m1, m2, m3;
00674 Coord rotCenter;
00675
00676 if (sub_type == 0) {
00677 rotCenter = Coord (obj->boundingBox ().left (),
00678 obj->boundingBox ().bottom ());
00679 }
00680 else if (sub_type == 1) {
00681 rotCenter = Coord (obj->boundingBox ().width () / 2,
00682 obj->boundingBox ().bottom ());
00683 }
00684 else if (sub_type == 2) {
00685 rotCenter = Coord (obj->boundingBox ().right (),
00686 obj->boundingBox ().bottom ());
00687 }
00688 m1.translate (-rotCenter.x (), -rotCenter.y ());
00689 m2.rotate (-nangle);
00690 m3.translate (rotCenter.x (), rotCenter.y ());
00691 obj->transform (m1);
00692 obj->transform (m2);
00693 obj->transform (m3, true);
00694 }
00695
00696 objList.append( GObjectListItem( depth, obj ) );
00697 }
00698
00699 void XFIGImport::parseCompoundObject (istream& fin, GDocument* ) {
00700 int upperright_x, upperright_y, lowerleft_x, lowerleft_y;
00701
00702 fin >> upperright_x >> upperright_y >> lowerleft_x >> lowerleft_y;
00703 fin.ignore (INT_MAX, '\n');
00704 }
00705
00706
00710 void XFIGImport::buildDocument (GDocument *doc) {
00711 doc->setAutoUpdate (false);
00712
00713 qBubbleSort(objList);
00714
00715
00716 QValueList<GObjectListItem>::Iterator it=objList.begin();
00717 for ( ; it != objList.end() ; ++it )
00718 {
00719
00720 GObject* obj = (*it).object;
00721 obj->ref ();
00722 doc->activePage()->insertObject (obj);
00723 }
00724 doc->setAutoUpdate (true);
00725 objList.clear();
00726 }
00727
00728 void XFIGImport::setProperties (GObject* obj, int pen_color, int style,
00729 int thickness, int area_fill, int fill_color) {
00730 if (pen_color >= 0)
00731 obj->setOutlineColor (*colorTable[pen_color]);
00732
00733 if (style < 1)
00734 obj->setOutlineStyle (Qt::SolidLine);
00735 else if (style == 1)
00736 obj->setOutlineStyle (Qt::DashLine);
00737 else if (style == 2)
00738 obj->setOutlineStyle (Qt::DotLine);
00739
00740 obj->setOutlineWidth (thickness * 72.0 / 80.0);
00741
00742 if (area_fill == -1)
00743 obj->setFillStyle (GObject::FillInfo::NoFill);
00744 else {
00745 obj->setFillStyle (GObject::FillInfo::SolidFill);
00746 if (fill_color < 1) {
00747
00748 int val = qRound ((20 - area_fill) * 255.0 / 20.0);
00749 obj->setFillColor (QColor (val, val, val));
00750 }
00751 else if (fill_color == 7) {
00752
00753 int val = qRound ( area_fill * 255.0 / 20.0);
00754 obj->setFillColor (QColor (val, val, val));
00755 }
00756 else
00757 obj->setFillColor (*colorTable[fill_color]);
00758 }
00759 }
00760