3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/28/2010 Added this text. :-)
17 #include "filtercxf.h"
28 * Default constructor.
30 FilterCXF::FilterCXF(): FilterInterface()
32 DEBUG->print("Setting up CXF filter...");
34 addImportFormat(RS2::FormatCXF);
35 addExportFormat(RS2::FormatCXF);
38 FilterCXF::~FilterCXF()
43 * Implementation of the method used for RS_Import to communicate
46 * @param g The graphic in which the entities from the file
47 * will be created or the graphics from which the entities are
48 * taken to be stored in a file.
50 bool FilterCXF::fileImport(Drawing & g, const QString & file, RS2::FormatType /*type*/)
52 DEBUG->print("CXF Filter: importing file '%s'...", file.toLatin1().data());
57 // Load font file as we normally do, but the font doesn't own the
58 // letters (we'll add them to the graphic instead. Hence 'false').
59 Font font(file, false);
60 success = font.loadFont();
64 DEBUG->print(Debug::D_WARNING, "Cannot open CXF file '%s'.", file.toLatin1().data());
68 g.addVariable("Names", font.getNames().join(","), 0);
69 g.addVariable("LetterSpacing", font.getLetterSpacing(), 0);
70 g.addVariable("WordSpacing", font.getWordSpacing(), 0);
71 g.addVariable("LineSpacingFactor", font.getLineSpacingFactor(), 0);
72 g.addVariable("Authors", font.getAuthors().join(","), 0);
74 if (!font.getEncoding().isEmpty())
75 g.addVariable("Encoding", font.getEncoding(), 0);
77 BlockList * letterList = font.getLetterList();
79 for(uint i=0; i<font.countLetters(); i++)
81 Block * ch = font.letterAt(i);
84 uCode.setNum(ch->getName().at(0).unicode(), 16);
86 while (uCode.length() < 4)
89 //ch->setName("[" + uCode + "] " + ch->getName());
90 //letterList->rename(ch, QString("[%1]").arg(ch->getName()));
91 letterList->rename(ch, QString("[%1] %2").arg(uCode).arg(ch->getName().at(0)));
93 g.addBlock(ch, false);
97 g.addBlockNotification();
103 * Implementation of the method used for RS_Export to communicate
106 * @param file Full path to the CXF file that will be written.
108 bool FilterCXF::fileExport(Drawing & g, const QString & file, RS2::FormatType /*type*/)
110 DEBUG->print("CXF Filter: exporting file '%s'...", file.toAscii().data());
112 // crashes under windoze xp:
113 //std::ofstream fout;
115 DEBUG->print("FilterCXF::fileExport: open");
116 //fout.open((const char*)file.local8Bit());
119 if ((fp = fopen((const char *)file.toLocal8Bit(), "wt")) != NULL)
121 DEBUG->print("FilterCXF::fileExport: open: OK");
122 DEBUG->print("FilterCXF::fileExport: header");
125 fprintf(fp, "# Format: QCad II Font\n");
126 fprintf(fp, "# Creator: %s\n", (const char *)SYSTEM->getAppName().toLocal8Bit());
127 fprintf(fp, "# Version: %s\n", (const char *)SYSTEM->getAppVersion().toLocal8Bit());
130 QString ns = g.getVariableString("Names", "");
134 QStringList names = ns.split(',');
137 for(QStringList::Iterator it=names.begin(); it!=names.end(); ++it)
139 fprintf(fp, "# Name: %s\n", (const char*)((*it).toLocal8Bit()));
145 QString es = g.getVariableString("Encoding", "");
148 fprintf(fp, "# Encoding: %s\n", (const char *)es.toLocal8Bit());
150 DEBUG->print("004a");
152 fprintf(fp, "# LetterSpacing: %f\n", g.getVariableDouble("LetterSpacing", 3.0));
153 fprintf(fp, "# WordSpacing: %f\n", g.getVariableDouble("WordSpacing", 6.75));
154 fprintf(fp, "# LineSpacingFactor: %f\n", g.getVariableDouble("LineSpacingFactor", 1.0));
156 QString sa = g.getVariableString("Authors", "");
157 DEBUG->print("authors: %s", (const char *)sa.toLocal8Bit());
161 QStringList authors = sa.split(',');
163 DEBUG->print("count: %d", authors.count());
167 for(QStringList::Iterator it2=authors.begin(); it2!=authors.end(); ++it2)
169 DEBUG->print("006a");
171 DEBUG->print("006b");
172 DEBUG->print("string is: %s", a.toAscii().data());
173 DEBUG->print("006b0");
174 fprintf(fp, "# Author: ");
175 DEBUG->print("006b1");
176 fprintf(fp, "%s\n", a.toAscii().data());
177 //fout << "# Author: " << a.ascii() << "\n";
183 DEBUG->print("FilterCXF::fileExport: header: OK");
186 // iterate through blocks (=letters of font)
187 for(uint i=0; i<g.countBlocks(); ++i)
189 Block * blk = g.blockAt(i);
191 DEBUG->print("block: %d", i);
197 DEBUG->print("002a: %s", (const char *)(blk->getName().toLocal8Bit()));
199 fprintf(fp, "\n%s\n", (const char *)(blk->getName().toLocal8Bit()));
201 // iterate through entities of this letter:
202 for(Entity * e=blk->firstEntity(RS2::ResolveAll); e!=NULL;
203 e=blk->nextEntity(RS2::ResolveAll))
210 if (e->rtti() == RS2::EntityLine)
212 Line * l = (Line *)e;
214 fprintf(fp, "L %f,%f,%f,%f\n", l->getStartpoint().x, l->getStartpoint().y,
215 l->getEndpoint().x, l->getEndpoint().y);
218 else if (e->rtti() == RS2::EntityArc)
222 if (!a->isReversed())
231 fprintf(fp, "%f,%f,%f,%f,%f\n", a->getCenter().x, a->getCenter().y,
232 a->getRadius(), a->getAngle1() * ARAD, a->getAngle2() * ARAD);
234 // Ignore entities other than arcs / lines
249 DEBUG->print("CXF Filter: exporting file: OK");
254 DEBUG->print("CXF Filter: exporting file failed");
261 * Streams a double value to the given stream cutting away trailing 0's.
263 * @param value A double value. e.g. 2.700000
265 void FilterCXF::stream(std::ofstream & fs, double value)
267 fs << (const char *)Utility::doubleToString(value).toAscii().data();