filters

xfigimport.cc

00001 /*
00002     Copyright (C) 1998 Kai-Uwe Sattler <kus@iti.cs.uni-magdeburg.de>
00003     Copyright (C) 2001, Rob Buis <rwlbuis@wanadoo.nl>
00004     Copyright (C) 2003, Rob Buis <buis@kde.org>
00005     This file is part of the KDE project
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021 
00022 DESCRIPTION
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 },      // Times Roman
00086   { "times", QFont::Normal, true },       // Times Italic
00087   { "times", QFont::Bold, false },        // Times Bold
00088   { "times", QFont::Bold, true },         // Times Bold Italic
00089   { "avantgarde", QFont::Normal, false },   // AvantGarde Book
00090   { "avantgarde", QFont::Normal, true },    // AvantGarde Book Oblique
00091   { "avantgarde", QFont::DemiBold, false }, // AvantGarde Demi
00092   { "avantgarde", QFont::DemiBold, true },  // AvantGarde Demi Oblique
00093   { "bookman", QFont::Light, false },     // Bookman Light
00094   { "bookman", QFont::Light, true },      // Bookman Light Italic
00095   { "bookman", QFont::DemiBold, false },  // Bookman Demi
00096   { "bookman", QFont::DemiBold, true },   // Bookman Demi Italic
00097   { "courier", QFont::Normal, false },    // Courier
00098   { "courier", QFont::Normal, true },     // Courier Oblique
00099   { "courier", QFont::Bold, false },      // Courier Bold
00100   { "courier", QFont::Bold, true },       // Courier Bold Oblique
00101   { "helvetica", QFont::Normal, false },  // Helvetica
00102   { "helvetica", QFont::Normal, true },   // Helvetica Oblique
00103   { "helvetica", QFont::Bold, false },    // Helvetica Bold
00104   { "helvetica", QFont::Bold, true },     // Helvetica Bold Oblique
00105   { "helvetica", QFont::Normal, false },  // Helvetica Narrow
00106   { "helvetica", QFont::Normal, true },   // Helvetica Narrow Oblique
00107   { "helvetica", QFont::Bold, false },    // Helvetica Narrow Bold
00108   { "helvetica", QFont::Bold, true },     // Helvetica Narrow Bold Oblique
00109   { "newcenturyschoolbook", QFont::Normal, false },// New Century Schoolbook
00110   { "newcenturyschoolbook", QFont::Normal, true }, // New Century Italic
00111   { "newcenturyschoolbook", QFont::Bold, false },  // New Century Bold
00112   { "newcenturyschoolbook", QFont::Bold, true },   // New Century Bold Italic
00113   { "palatino", QFont::Normal, false },   // Palatino Roman
00114   { "palatino", QFont::Normal, true },    // Palatino Italic
00115   { "palatino", QFont::Bold, false },     // Palatino Bold
00116   { "palatino", QFont::Bold, true },      // Palatino Bold Italic
00117   { "symbol", QFont::Normal, false },     // Symbol
00118   { "zapfchancery", QFont::Normal, false }, // Zapf Chancery Medium Italic
00119   { "zapfdingbats", QFont::Normal, false }, // Zapf Dingbats
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     //GPage *activePage           = gdoc->activePage();
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    * read the header
00201    */
00202 
00203   // orientation
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   // justification (don't know how to handle this)
00213   fin.getline (buf, 255);
00214 
00215   // units
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       // paper size (don't know how to handle this)
00226       fin.getline (buf, 255);
00227 
00228       // magnification
00229       float magnification;
00230       fin >> magnification;
00231       fin.ignore (INT_MAX, '\n');
00232 
00233       //multiple page (not supported yet)
00234       fin.getline (buf, 255);
00235 
00236       // transparent color (not supported yet)
00237       int transColor;
00238       fin >> transColor;
00239       fin.ignore (INT_MAX, '\n');
00240   }
00241 
00242   // resolution and coordinate system
00243   fin >> value >> coordinate_system;
00244   fig_resolution = value / 72.0;
00245   fin.ignore (INT_MAX, '\n');
00246 
00247   // now read in the objects
00248   while (! fin.eof ()) {
00249     int tag = -1;
00250     fin >> tag;
00251     if (tag == -1) {
00252       // EOF
00253       buildDocument (gdoc);
00254       return true;
00255     }
00256 
00257     switch (tag) {
00258     case 0:
00259       // a color pseudo object
00260       parseColorObject (fin);
00261       break;
00262     case 1:
00263       // a ellipse
00264       parseEllipse (fin, gdoc);
00265       break;
00266     case 2:
00267       // a polyline
00268       parsePolyline (fin, gdoc);
00269       break;
00270     case 3:
00271       // a spline
00272       parseSpline (fin, gdoc);
00273       break;
00274     case 4:
00275       // a text
00276       parseText (fin, gdoc);
00277       break;
00278     case 5:
00279       // an arc
00280       parseArc (fin, gdoc);
00281       break;
00282     case 6:
00283       // a compound object
00284       parseCompoundObject (fin, gdoc);
00285       break;
00286     case -6:
00287       // end of compound object --> ignore it
00288       break;
00289     default:
00290       // should not occur
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   // first line
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     // forward arow line
00332     fin.ignore (INT_MAX, '\n');
00333   }
00334 
00335   if (backward_arrow > 0) {
00336     // backward arrow line
00337     fin.ignore (INT_MAX, '\n');
00338   }
00339 
00340   // compute radius
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) // clockwise
00399     obj->setAngles (angle2, angle1);
00400   else if (direction==1) // counterclockwise
00401     obj->setAngles (angle1, angle2);
00402 
00403   // now set the properties
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   // first line
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   // now set the properties
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   // first line
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: // polyline
00451     obj = new GPolyline (doc);
00452     break;
00453   case 2: // box
00454     obj = new GPolygon (doc);
00455     break;
00456   case 3: // polygon
00457     obj = new GPolygon (doc);
00458     break;
00459   case 4: // arc-box
00460     obj = new GPolygon (doc);
00461     break;
00462   case 5: // imported picture
00463     return;
00464     break;
00465   default:
00466     // doesn't occur
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     // forward arrow line
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     // backward arrow line
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   // points line
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       // first point == last point
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   // now set the properties
00515   setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color);
00516 
00517   // and insert the object
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   // this should be a spline
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     // forward arrow line
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     // backward arrow line
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   // points line
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       // first point == last point
00570       break;
00571 
00572     Coord p (x / fig_resolution, y / fig_resolution);
00573     obj->_addPoint (i, p);
00574   }
00575 
00576   // control points line
00577   for (int i = 0; i < npoints; i++) {
00578     float fac;
00579     fin >> fac;
00580     // ignore it now
00581     // fin.ignore (INT_MAX, '\n');
00582   }
00583 
00584   if (oinfo.startArrowId || oinfo.endArrowId)
00585     obj->setOutlineInfo (oinfo);
00586 
00587   // now set the properties
00588   setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color);
00589 
00590   // and insert the object
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     // PostScript font
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     // LaTeX font
00617     switch (font) {
00618     case 1: // Roman
00619       qfont.setFamily ("times");
00620       break;
00621     case 2: // Bold
00622       qfont.setBold (true);
00623       break;
00624     case 3: // Italic
00625       qfont.setItalic (true);
00626       break;
00627     case 4: // Sans Serif
00628       qfont.setFamily ("helvetica");
00629       break;
00630     case 5: // Typewriter
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     // rotate the text
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* /*doc*/) {
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   // This will sort all object, by decreasing depth
00713   qBubbleSort(objList);
00714 
00715   // Now all we need to do is insert them in the document, in that order
00716   QValueList<GObjectListItem>::Iterator it=objList.begin();
00717   for ( ; it != objList.end() ; ++it )
00718   {
00719       //kdDebug() << "Inserting object with depth=" << (*it).depth << endl;
00720       GObject* obj = (*it).object;
00721       obj->ref ();
00722       doc->activePage()->insertObject (obj);
00723   }
00724   doc->setAutoUpdate (true);
00725   objList.clear(); // save memory
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       // for BLACK or DEFAULT color
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       // for WHITE color
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 
KDE Home | KDE Accessibility Home | Description of Access Keys