You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
761 lines
21 KiB
761 lines
21 KiB
/*
|
|
Copyright (C) 1998 Kai-Uwe Sattler <kus@iti.cs.uni-magdeburg.de>
|
|
Copyright (C) 2001, Rob Buis <rwlbuis@wanadoo.nl>
|
|
Copyright (C) 2003, Rob Buis <buis@kde.org>
|
|
This file is part of the KDE project
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
DESCRIPTION
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <fstream.h>
|
|
#include <limits.h>
|
|
#include <math.h>
|
|
|
|
#include <GDocument.h>
|
|
#include <GPage.h>
|
|
#include <GGroup.h>
|
|
#include <GPolyline.h>
|
|
#include <GOval.h>
|
|
#include <GPolygon.h>
|
|
#include <GText.h>
|
|
#include <xfigimport.h>
|
|
#include <xfigimport.moc>
|
|
|
|
#include <tqtl.h>
|
|
#include <kdebug.h>
|
|
|
|
#include <core/vdocument.h>
|
|
namespace std { };
|
|
using namespace std;
|
|
|
|
#define RAD_FACTOR 180.0 / M_PI
|
|
|
|
unsigned int colors[] = {
|
|
0x000090,
|
|
0x0000b0,
|
|
0x0000d0,
|
|
0x87ceff,
|
|
0x009000,
|
|
0x00b000,
|
|
0x00d000,
|
|
0x009090,
|
|
0x00b0b0,
|
|
0x00d0d0,
|
|
0x900000,
|
|
0xb00000,
|
|
0xd00000,
|
|
0x900090,
|
|
0xb000b0,
|
|
0xd000d0,
|
|
0x803000,
|
|
0xa04000,
|
|
0xc06000,
|
|
0xff8080,
|
|
0xffa0a0,
|
|
0xffc0c0,
|
|
0xffe0e0,
|
|
0xffd700
|
|
};
|
|
|
|
int arrow_ids[] = {
|
|
6, 1, 2, 7
|
|
};
|
|
|
|
struct PSFont {
|
|
const char* family;
|
|
TQFont::Weight weight;
|
|
bool italic;
|
|
} psFontTable[] = {
|
|
{ "times", TQFont::Normal, false }, // Times Roman
|
|
{ "times", TQFont::Normal, true }, // Times Italic
|
|
{ "times", TQFont::Bold, false }, // Times Bold
|
|
{ "times", TQFont::Bold, true }, // Times Bold Italic
|
|
{ "avantgarde", TQFont::Normal, false }, // AvantGarde Book
|
|
{ "avantgarde", TQFont::Normal, true }, // AvantGarde Book Oblique
|
|
{ "avantgarde", TQFont::DemiBold, false }, // AvantGarde Demi
|
|
{ "avantgarde", TQFont::DemiBold, true }, // AvantGarde Demi Oblique
|
|
{ "bookman", TQFont::Light, false }, // Bookman Light
|
|
{ "bookman", TQFont::Light, true }, // Bookman Light Italic
|
|
{ "bookman", TQFont::DemiBold, false }, // Bookman Demi
|
|
{ "bookman", TQFont::DemiBold, true }, // Bookman Demi Italic
|
|
{ "courier", TQFont::Normal, false }, // Courier
|
|
{ "courier", TQFont::Normal, true }, // Courier Oblique
|
|
{ "courier", TQFont::Bold, false }, // Courier Bold
|
|
{ "courier", TQFont::Bold, true }, // Courier Bold Oblique
|
|
{ "helvetica", TQFont::Normal, false }, // Helvetica
|
|
{ "helvetica", TQFont::Normal, true }, // Helvetica Oblique
|
|
{ "helvetica", TQFont::Bold, false }, // Helvetica Bold
|
|
{ "helvetica", TQFont::Bold, true }, // Helvetica Bold Oblique
|
|
{ "helvetica", TQFont::Normal, false }, // Helvetica Narrow
|
|
{ "helvetica", TQFont::Normal, true }, // Helvetica Narrow Oblique
|
|
{ "helvetica", TQFont::Bold, false }, // Helvetica Narrow Bold
|
|
{ "helvetica", TQFont::Bold, true }, // Helvetica Narrow Bold Oblique
|
|
{ "newcenturyschoolbook", TQFont::Normal, false },// New Century Schoolbook
|
|
{ "newcenturyschoolbook", TQFont::Normal, true }, // New Century Italic
|
|
{ "newcenturyschoolbook", TQFont::Bold, false }, // New Century Bold
|
|
{ "newcenturyschoolbook", TQFont::Bold, true }, // New Century Bold Italic
|
|
{ "palatino", TQFont::Normal, false }, // Palatino Roman
|
|
{ "palatino", TQFont::Normal, true }, // Palatino Italic
|
|
{ "palatino", TQFont::Bold, false }, // Palatino Bold
|
|
{ "palatino", TQFont::Bold, true }, // Palatino Bold Italic
|
|
{ "symbol", TQFont::Normal, false }, // Symbol
|
|
{ "zapfchancery", TQFont::Normal, false }, // Zapf Chancery Medium Italic
|
|
{ "zapfdingbats", TQFont::Normal, false }, // Zapf Dingbats
|
|
};
|
|
|
|
int hexstrToInt (const char *str) {
|
|
const int fak[] = { 16, 1 };
|
|
int value = 0, v;
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
if (str[i] >= '0' && str[i] <= '9')
|
|
v = str[i] - '0';
|
|
else
|
|
v = str[i] - 'a' + 10;
|
|
value += v * fak[i];
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
XFIGImport::XFIGImport( KoFilter *parent, const char *name ) : KoFilter(parent, name)
|
|
{
|
|
fig_resolution = 1200.0 / 72.0;
|
|
coordinate_system = 2;
|
|
|
|
colorTable.insert (0, new TQColor (TQt::black));
|
|
colorTable.insert (1, new TQColor (TQt::blue));
|
|
colorTable.insert (2, new TQColor (TQt::green));
|
|
colorTable.insert (3, new TQColor (TQt::cyan));
|
|
colorTable.insert (4, new TQColor (TQt::red));
|
|
colorTable.insert (5, new TQColor (TQt::magenta));
|
|
colorTable.insert (6, new TQColor (TQt::yellow));
|
|
colorTable.insert (7, new TQColor (TQt::white));
|
|
|
|
for (int i = 0; i <= 23; i++)
|
|
colorTable.insert (i + 8, new TQColor (colors[i]));
|
|
|
|
objList.clear ();
|
|
}
|
|
|
|
XFIGImport::~XFIGImport()
|
|
{
|
|
}
|
|
|
|
bool XFIGImport::filterImport( const TQString &file, KoDocument *doc,
|
|
const TQString &from, const TQString &to,
|
|
const TQString & ) {
|
|
|
|
if( to != "application/x-karbon" || from != "image/x-xfig" )
|
|
return false;
|
|
|
|
char buf[255];
|
|
int value;
|
|
KoPageLayout layout;
|
|
|
|
ifstream fin( file.local8Bit() );
|
|
if (! fin)
|
|
return false;
|
|
|
|
KIllustratorDocument *kidoc = (KIllustratorDocument *) doc;
|
|
GDocument *gdoc = kidoc->gdoc();
|
|
//GPage *activePage = gdoc->activePage();
|
|
|
|
layout = gdoc->activePage()->pageLayout ();
|
|
|
|
fin.getline (buf, 255);
|
|
if (::strncmp (buf, "#FIG 3", 6)) {
|
|
kdDebug() << "ERROR: no xfig file or wrong header" << endl;
|
|
return false;
|
|
}
|
|
|
|
if (buf[7] == '2') {
|
|
version = 320;
|
|
}
|
|
else if (buf[7] == '1') {
|
|
version = 310;
|
|
}
|
|
else {
|
|
kdDebug() << "ERROR: unsupported xfig version" << endl;
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* read the header
|
|
*/
|
|
|
|
// orientation
|
|
fin.getline (buf, 255);
|
|
if (::strcmp (buf, "Landscape") == 0)
|
|
layout.orientation = PG_LANDSCAPE;
|
|
else if (::strcmp (buf, "Portrait") == 0)
|
|
layout.orientation = PG_PORTRAIT;
|
|
else
|
|
kdDebug() << "ERROR: invalid orientation" << endl;
|
|
|
|
// justification (don't know how to handle this)
|
|
fin.getline (buf, 255);
|
|
|
|
// units
|
|
fin.getline (buf, 255);
|
|
if (::strcmp (buf, "Metric") == 0)
|
|
layout.unit = PG_MM;
|
|
else if (::strcmp (buf, "Inches") == 0)
|
|
layout.unit = PG_INCH;
|
|
else
|
|
kdDebug() << "ERROR: invalid units" << endl;
|
|
|
|
if (version >= 320) {
|
|
// paper size (don't know how to handle this)
|
|
fin.getline (buf, 255);
|
|
|
|
// magnification
|
|
float magnification;
|
|
fin >> magnification;
|
|
fin.ignore (INT_MAX, '\n');
|
|
|
|
//multiple page (not supported yet)
|
|
fin.getline (buf, 255);
|
|
|
|
// transparent color (not supported yet)
|
|
int transColor;
|
|
fin >> transColor;
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
// resolution and coordinate system
|
|
fin >> value >> coordinate_system;
|
|
fig_resolution = value / 72.0;
|
|
fin.ignore (INT_MAX, '\n');
|
|
|
|
// now read in the objects
|
|
while (! fin.eof ()) {
|
|
int tag = -1;
|
|
fin >> tag;
|
|
if (tag == -1) {
|
|
// EOF
|
|
buildDocument (gdoc);
|
|
return true;
|
|
}
|
|
|
|
switch (tag) {
|
|
case 0:
|
|
// a color pseudo object
|
|
parseColorObject (fin);
|
|
break;
|
|
case 1:
|
|
// a ellipse
|
|
parseEllipse (fin, gdoc);
|
|
break;
|
|
case 2:
|
|
// a polyline
|
|
parsePolyline (fin, gdoc);
|
|
break;
|
|
case 3:
|
|
// a spline
|
|
parseSpline (fin, gdoc);
|
|
break;
|
|
case 4:
|
|
// a text
|
|
parseText (fin, gdoc);
|
|
break;
|
|
case 5:
|
|
// an arc
|
|
parseArc (fin, gdoc);
|
|
break;
|
|
case 6:
|
|
// a compound object
|
|
parseCompoundObject (fin, gdoc);
|
|
break;
|
|
case -6:
|
|
// end of compound object --> ignore it
|
|
break;
|
|
default:
|
|
// should not occur
|
|
kdDebug() << "unknown object type: " << tag << endl;
|
|
break;
|
|
}
|
|
}
|
|
buildDocument (gdoc);
|
|
return true;
|
|
}
|
|
|
|
|
|
void XFIGImport::parseColorObject (istream& fin) {
|
|
int number, red, green, blue;
|
|
char buf[20], red_str[3], green_str[3], blue_str[3];
|
|
|
|
fin >> number >> buf;
|
|
strncpy (red_str, &buf[1], 2); red_str[2] = '\0';
|
|
strncpy (green_str, &buf[3], 2); green_str[2] = '\0';
|
|
strncpy (blue_str, &buf[5], 2); blue_str[2] = '\0';
|
|
|
|
red = hexstrToInt (red_str);
|
|
green = hexstrToInt (green_str);
|
|
blue = hexstrToInt (blue_str);
|
|
|
|
colorTable.insert (number, new TQColor (red, green, blue));
|
|
}
|
|
|
|
void XFIGImport::parseArc (istream& fin, GDocument* doc) {
|
|
int sub_type, line_style, thickness, pen_color, fill_color,
|
|
depth, pen_style, area_fill, cap_style, direction,
|
|
forward_arrow, backward_arrow, x1, y1, x2, y2, x3, y3;
|
|
float center_x, center_y;
|
|
float style_val;
|
|
GOval *obj = new GOval (doc);
|
|
|
|
// first line
|
|
fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
|
|
>> depth >> pen_style >> area_fill >> style_val >> cap_style
|
|
>> direction >> forward_arrow >> backward_arrow
|
|
>> center_x >> center_y >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
|
|
|
|
if (forward_arrow > 0) {
|
|
// forward arow line
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
if (backward_arrow > 0) {
|
|
// backward arrow line
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
// compute radius
|
|
float dx = x1 - center_x;
|
|
float dy = y1 - center_y;
|
|
float radius = sqrt (dx * dx + dy * dy);
|
|
|
|
if (radius==0) {
|
|
delete obj;
|
|
return;
|
|
}
|
|
|
|
Coord p1 ((center_x - radius) / fig_resolution,
|
|
(center_y - radius) / fig_resolution);
|
|
Coord p2 ((center_x + radius) / fig_resolution,
|
|
(center_y + radius) / fig_resolution);
|
|
|
|
obj->setStartPoint (p1);
|
|
obj->setEndPoint (p2);
|
|
|
|
if (sub_type == 0)
|
|
obj->setOutlineShape (GObject::OutlineInfo::PieShape);
|
|
else if (sub_type == 1)
|
|
obj->setOutlineShape (GObject::OutlineInfo::ArcShape);
|
|
|
|
p1 = Coord (center_x / fig_resolution, center_y /fig_resolution);
|
|
float m;
|
|
|
|
float angle1;
|
|
p2 = Coord (x1 / fig_resolution, y1 /fig_resolution);
|
|
if (p2.x () == p1.x ()) {
|
|
if (p2.y () > p1.y ())
|
|
angle1 = 90;
|
|
else
|
|
angle1 = -90;
|
|
}
|
|
else {
|
|
m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ()));
|
|
if ( p2.x () > p1.x ())
|
|
angle1 = atan (m) * RAD_FACTOR;
|
|
else
|
|
angle1 = 180 + atan (m) * RAD_FACTOR;
|
|
}
|
|
|
|
float angle2;
|
|
p2 = Coord (x3 / fig_resolution, y3 /fig_resolution);
|
|
if (p2.x () == p1.x ()) {
|
|
if (p2.y () > p1.y ())
|
|
angle2 = 90;
|
|
else
|
|
angle2 = -90;
|
|
}
|
|
else {
|
|
m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ()));
|
|
if ( p2.x () > p1.x ())
|
|
angle2 = atan (m) * RAD_FACTOR;
|
|
else
|
|
angle2 = 180 + atan (m) * RAD_FACTOR;
|
|
}
|
|
|
|
if (direction==0) // clockwise
|
|
obj->setAngles (angle2, angle1);
|
|
else if (direction==1) // counterclockwise
|
|
obj->setAngles (angle1, angle2);
|
|
|
|
// now set the properties
|
|
setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color);
|
|
objList.append( GObjectListItem( depth, obj ) );
|
|
}
|
|
|
|
void XFIGImport::parseEllipse (istream& fin, GDocument* doc) {
|
|
int sub_type, line_style, thickness, pen_color, fill_color,
|
|
depth, pen_style, area_fill, direction, center_x, center_y,
|
|
radius_x, radius_y, start_x, start_y, end_x, end_y;
|
|
float style_val, angle;
|
|
GOval *obj = new GOval (doc);
|
|
|
|
// first line
|
|
fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
|
|
>> depth >> pen_style >> area_fill >> style_val >> direction
|
|
>> angle >> center_x >> center_y >> radius_x >> radius_y
|
|
>> start_x >> start_y >> end_x >> end_y;
|
|
Coord p1, p2;
|
|
|
|
p1 = Coord ((center_x - radius_x) /fig_resolution,
|
|
(center_y - radius_y) /fig_resolution);
|
|
p2 = Coord ((center_x + radius_x) /fig_resolution,
|
|
(center_y + radius_y) /fig_resolution);
|
|
|
|
obj->setStartPoint (p1);
|
|
obj->setEndPoint (p2);
|
|
|
|
// now set the properties
|
|
setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color);
|
|
objList.append( GObjectListItem( depth, obj ) );
|
|
}
|
|
|
|
void XFIGImport::parsePolyline (istream& fin, GDocument* doc) {
|
|
int sub_type, line_style, thickness, pen_color, fill_color,
|
|
depth, pen_style, area_fill, join_style, cap_style, radius,
|
|
forward_arrow, backward_arrow, npoints;
|
|
float style_val;
|
|
GPolyline *obj = NULL;
|
|
|
|
// first line
|
|
fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
|
|
>> depth >> pen_style >> area_fill >> style_val >> join_style
|
|
>> cap_style >> radius >> forward_arrow >> backward_arrow
|
|
>> npoints;
|
|
fin.ignore (INT_MAX, '\n');
|
|
|
|
switch (sub_type) {
|
|
case 1: // polyline
|
|
obj = new GPolyline (doc);
|
|
break;
|
|
case 2: // box
|
|
obj = new GPolygon (doc);
|
|
break;
|
|
case 3: // polygon
|
|
obj = new GPolygon (doc);
|
|
break;
|
|
case 4: // arc-box
|
|
obj = new GPolygon (doc);
|
|
break;
|
|
case 5: // imported picture
|
|
return;
|
|
break;
|
|
default:
|
|
// doesn't occur
|
|
kdDebug() << "unknown subtype: " << sub_type << endl;
|
|
break;
|
|
}
|
|
|
|
assert (obj != NULL);
|
|
|
|
int arrow_type, arrow_style;
|
|
float arrow_thickness, arrow_width, arrow_height;
|
|
GObject::OutlineInfo oinfo;
|
|
oinfo.mask = GObject::OutlineInfo::Custom;
|
|
oinfo.startArrowId = oinfo.endArrowId = 0;
|
|
|
|
if (forward_arrow > 0) {
|
|
|
|
// forward arrow line
|
|
fin >> arrow_type >> arrow_style >> arrow_thickness
|
|
>> arrow_width >> arrow_height;
|
|
oinfo.endArrowId = arrow_ids[arrow_type];
|
|
if (oinfo.endArrowId == 1 && arrow_style == 0)
|
|
oinfo.endArrowId = 4;
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
if (backward_arrow > 0) {
|
|
// backward arrow line
|
|
fin >> arrow_type >> arrow_style >> arrow_thickness
|
|
>> arrow_width >> arrow_height;
|
|
oinfo.startArrowId = arrow_ids[arrow_type];
|
|
if (oinfo.startArrowId == 1 && arrow_style == 0)
|
|
oinfo.startArrowId = 4;
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
// points line
|
|
for (int i = 0; i < npoints; i++) {
|
|
int x, y;
|
|
fin >> x >> y;
|
|
if ((sub_type == 2 || sub_type == 3) && i == npoints -1)
|
|
// first point == last point
|
|
break;
|
|
|
|
Coord p (x / fig_resolution, y / fig_resolution);
|
|
obj->_addPoint (i, p);
|
|
}
|
|
|
|
if (oinfo.startArrowId || oinfo.endArrowId)
|
|
obj->setOutlineInfo (oinfo);
|
|
|
|
// now set the properties
|
|
setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color);
|
|
|
|
// and insert the object
|
|
objList.append( GObjectListItem( depth, obj ) );
|
|
}
|
|
|
|
void XFIGImport::parseSpline (istream& fin, GDocument* doc)
|
|
{
|
|
int sub_type, line_style, thickness, pen_color, fill_color, depth,
|
|
pen_style, area_fill, cap_style, forward_arrow, backward_arrow, npoints;
|
|
float style_val;
|
|
|
|
// this should be a spline
|
|
GPolyline *obj = 0L;
|
|
fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color
|
|
>> depth >> pen_style >> area_fill >> style_val >> cap_style
|
|
>> forward_arrow >> backward_arrow >> npoints;
|
|
if (sub_type == 1 || sub_type == 3 || sub_type == 5)
|
|
obj = new GPolygon (doc);
|
|
else
|
|
obj = new GPolyline (doc);
|
|
|
|
int arrow_type, arrow_style;
|
|
float arrow_thickness, arrow_width, arrow_height;
|
|
GObject::OutlineInfo oinfo;
|
|
oinfo.mask = GObject::OutlineInfo::Custom;
|
|
oinfo.startArrowId = oinfo.endArrowId = 0;
|
|
|
|
if (forward_arrow > 0) {
|
|
|
|
// forward arrow line
|
|
fin >> arrow_type >> arrow_style >> arrow_thickness
|
|
>> arrow_width >> arrow_height;
|
|
oinfo.endArrowId = arrow_ids[arrow_type];
|
|
if (oinfo.endArrowId == 1 && arrow_style == 0)
|
|
oinfo.endArrowId = 4;
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
if (backward_arrow > 0) {
|
|
// backward arrow line
|
|
fin >> arrow_type >> arrow_style >> arrow_thickness
|
|
>> arrow_width >> arrow_height;
|
|
oinfo.startArrowId = arrow_ids[arrow_type];
|
|
if (oinfo.startArrowId == 1 && arrow_style == 0)
|
|
oinfo.startArrowId = 4;
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
// points line
|
|
for (int i = 0; i < npoints; i++) {
|
|
int x, y;
|
|
fin >> x >> y;
|
|
if ((sub_type == 1 || sub_type == 3 || sub_type == 5) && i == npoints -1)
|
|
// first point == last point
|
|
break;
|
|
|
|
Coord p (x / fig_resolution, y / fig_resolution);
|
|
obj->_addPoint (i, p);
|
|
}
|
|
|
|
// control points line
|
|
for (int i = 0; i < npoints; i++) {
|
|
float fac;
|
|
fin >> fac;
|
|
// ignore it now
|
|
// fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
if (oinfo.startArrowId || oinfo.endArrowId)
|
|
obj->setOutlineInfo (oinfo);
|
|
|
|
// now set the properties
|
|
setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color);
|
|
|
|
// and insert the object
|
|
objList.append( GObjectListItem( depth, obj ) );
|
|
}
|
|
|
|
void XFIGImport::parseText (istream& fin, GDocument* doc)
|
|
{
|
|
int sub_type, color, depth, pen_style, font, font_flags, x, y;
|
|
float font_size, angle, height, length;
|
|
GText *obj = new GText (doc);
|
|
char c;
|
|
char ocode[4];
|
|
bool finished = false;
|
|
TQString text;
|
|
TQFont qfont;
|
|
|
|
fin >> sub_type >> color >> depth >> pen_style >> font >> font_size
|
|
>> angle >> font_flags >> height >> length >> x >> y;
|
|
|
|
if (font_flags & 4) {
|
|
// PostScript font
|
|
if (font == -1)
|
|
font = 0;
|
|
qfont = TQFont (psFontTable[font].family, tqRound (font_size),
|
|
psFontTable[font].weight, psFontTable[font].italic);
|
|
}
|
|
else {
|
|
// LaTeX font
|
|
switch (font) {
|
|
case 1: // Roman
|
|
qfont.setFamily ("times");
|
|
break;
|
|
case 2: // Bold
|
|
qfont.setBold (true);
|
|
break;
|
|
case 3: // Italic
|
|
qfont.setItalic (true);
|
|
break;
|
|
case 4: // Sans Serif
|
|
qfont.setFamily ("helvetica");
|
|
break;
|
|
case 5: // Typewriter
|
|
qfont.setFamily ("Courier");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
qfont.setPointSize (tqRound (font_size));
|
|
obj->setFont (qfont);
|
|
|
|
while (! finished) {
|
|
fin.get (c);
|
|
if (c == '\\') {
|
|
fin.get (ocode, 4);
|
|
int code = (ocode[0] - '0') * 64 +
|
|
(ocode[1] - '0') * 8 +
|
|
(ocode[2] - '0');
|
|
if (code == 1)
|
|
finished = true;
|
|
else
|
|
text += (char) code;
|
|
}
|
|
else
|
|
text += c;
|
|
}
|
|
obj->setText (text);
|
|
|
|
if (sub_type == 1) {
|
|
GText::TextInfo ti = obj->getTextInfo ();
|
|
ti.align = GText::TextInfo::AlignCenter;
|
|
obj->setTextInfo (ti);
|
|
}
|
|
else if (sub_type == 2) {
|
|
GText::TextInfo ti = obj->getTextInfo ();
|
|
ti.align = GText::TextInfo::AlignRight;
|
|
obj->setTextInfo (ti);
|
|
}
|
|
Coord origin (x / fig_resolution, y / fig_resolution - qfont.pointSize ());
|
|
obj->setOrigin (origin);
|
|
|
|
if (angle != 0) {
|
|
// rotate the text
|
|
float nangle = angle * RAD_FACTOR;
|
|
TQWMatrix m1, m2, m3;
|
|
Coord rotCenter;
|
|
|
|
if (sub_type == 0) {
|
|
rotCenter = Coord (obj->boundingBox ().left (),
|
|
obj->boundingBox ().bottom ());
|
|
}
|
|
else if (sub_type == 1) {
|
|
rotCenter = Coord (obj->boundingBox ().width () / 2,
|
|
obj->boundingBox ().bottom ());
|
|
}
|
|
else if (sub_type == 2) {
|
|
rotCenter = Coord (obj->boundingBox ().right (),
|
|
obj->boundingBox ().bottom ());
|
|
}
|
|
m1.translate (-rotCenter.x (), -rotCenter.y ());
|
|
m2.rotate (-nangle);
|
|
m3.translate (rotCenter.x (), rotCenter.y ());
|
|
obj->transform (m1);
|
|
obj->transform (m2);
|
|
obj->transform (m3, true);
|
|
}
|
|
|
|
objList.append( GObjectListItem( depth, obj ) );
|
|
}
|
|
|
|
void XFIGImport::parseCompoundObject (istream& fin, GDocument* /*doc*/) {
|
|
int upperright_x, upperright_y, lowerleft_x, lowerleft_y;
|
|
|
|
fin >> upperright_x >> upperright_y >> lowerleft_x >> lowerleft_y;
|
|
fin.ignore (INT_MAX, '\n');
|
|
}
|
|
|
|
|
|
/**
|
|
* Copy all parsed objects from the sorted list to the document.
|
|
*/
|
|
void XFIGImport::buildDocument (GDocument *doc) {
|
|
doc->setAutoUpdate (false);
|
|
// This will sort all object, by decreasing depth
|
|
qBubbleSort(objList);
|
|
|
|
// Now all we need to do is insert them in the document, in that order
|
|
TQValueList<GObjectListItem>::Iterator it=objList.begin();
|
|
for ( ; it != objList.end() ; ++it )
|
|
{
|
|
//kdDebug() << "Inserting object with depth=" << (*it).depth << endl;
|
|
GObject* obj = (*it).object;
|
|
obj->ref ();
|
|
doc->activePage()->insertObject (obj);
|
|
}
|
|
doc->setAutoUpdate (true);
|
|
objList.clear(); // save memory
|
|
}
|
|
|
|
void XFIGImport::setProperties (GObject* obj, int pen_color, int style,
|
|
int thickness, int area_fill, int fill_color) {
|
|
if (pen_color >= 0)
|
|
obj->setOutlineColor (*colorTable[pen_color]);
|
|
|
|
if (style < 1)
|
|
obj->setOutlineStyle (TQt::SolidLine);
|
|
else if (style == 1)
|
|
obj->setOutlineStyle (TQt::DashLine);
|
|
else if (style == 2)
|
|
obj->setOutlineStyle (TQt::DotLine);
|
|
|
|
obj->setOutlineWidth (thickness * 72.0 / 80.0);
|
|
|
|
if (area_fill == -1)
|
|
obj->setFillStyle (GObject::FillInfo::NoFill);
|
|
else {
|
|
obj->setFillStyle (GObject::FillInfo::SolidFill);
|
|
if (fill_color < 1) {
|
|
// for BLACK or DEFAULT color
|
|
int val = tqRound ((20 - area_fill) * 255.0 / 20.0);
|
|
obj->setFillColor (TQColor (val, val, val));
|
|
}
|
|
else if (fill_color == 7) {
|
|
// for WHITE color
|
|
int val = tqRound ( area_fill * 255.0 / 20.0);
|
|
obj->setFillColor (TQColor (val, val, val));
|
|
}
|
|
else
|
|
obj->setFillColor (*colorTable[fill_color]);
|
|
}
|
|
}
|
|
|