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 "rs_filtercxf.h"
24 #include "rs_utility.h"
25 #include "rs_system.h"
28 * Default constructor.
30 RS_FilterCXF::RS_FilterCXF(): RS_FilterInterface()
32 RS_DEBUG->print("Setting up CXF filter...");
34 addImportFormat(RS2::FormatCXF);
35 addExportFormat(RS2::FormatCXF);
38 RS_FilterCXF::~RS_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 RS_FilterCXF::fileImport(Drawing & g, const QString & file, RS2::FormatType /*type*/)
52 RS_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 RS_Font font(file, false);
60 success = font.loadFont();
64 RS_DEBUG->print(RS_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 RS_BlockList * letterList = font.getLetterList();
79 for(uint i=0; i<font.countLetters(); i++)
81 RS_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 RS_FilterCXF::fileExport(Drawing & g, const QString & file, RS2::FormatType /*type*/)
110 RS_DEBUG->print("CXF Filter: exporting file '%s'...", file.toAscii().data());
112 // crashes under windoze xp:
113 //std::ofstream fout;
115 RS_DEBUG->print("RS_FilterCXF::fileExport: open");
116 //fout.open((const char*)file.local8Bit());
119 if ((fp = fopen((const char *)file.toLocal8Bit(), "wt")) != NULL)
121 RS_DEBUG->print("RS_FilterCXF::fileExport: open: OK");
122 RS_DEBUG->print("RS_FilterCXF::fileExport: header");
125 fprintf(fp, "# Format: QCad II Font\n");
126 fprintf(fp, "# Creator: %s\n", (const char *)RS_SYSTEM->getAppName().toLocal8Bit());
127 fprintf(fp, "# Version: %s\n", (const char *)RS_SYSTEM->getAppVersion().toLocal8Bit());
129 RS_DEBUG->print("001");
130 QString ns = g.getVariableString("Names", "");
134 QStringList names = ns.split(',');
135 RS_DEBUG->print("002");
137 for(QStringList::Iterator it=names.begin(); it!=names.end(); ++it)
139 fprintf(fp, "# Name: %s\n", (const char*)((*it).toLocal8Bit()));
143 RS_DEBUG->print("003");
145 QString es = g.getVariableString("Encoding", "");
148 fprintf(fp, "# Encoding: %s\n", (const char *)es.toLocal8Bit());
150 RS_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 RS_DEBUG->print("authors: %s", (const char *)sa.toLocal8Bit());
161 QStringList authors = sa.split(',');
162 RS_DEBUG->print("006");
163 RS_DEBUG->print("count: %d", authors.count());
167 for(QStringList::Iterator it2=authors.begin(); it2!=authors.end(); ++it2)
169 RS_DEBUG->print("006a");
171 RS_DEBUG->print("006b");
172 RS_DEBUG->print("string is: %s", a.toAscii().data());
173 RS_DEBUG->print("006b0");
174 fprintf(fp, "# Author: ");
175 RS_DEBUG->print("006b1");
176 fprintf(fp, "%s\n", a.toAscii().data());
177 //fout << "# Author: " << a.ascii() << "\n";
180 RS_DEBUG->print("007");
183 RS_DEBUG->print("RS_FilterCXF::fileExport: header: OK");
185 RS_DEBUG->print("008");
186 // iterate through blocks (=letters of font)
187 for(uint i=0; i<g.countBlocks(); ++i)
189 RS_Block * blk = g.blockAt(i);
191 RS_DEBUG->print("block: %d", i);
192 RS_DEBUG->print("001");
196 RS_DEBUG->print("002");
197 RS_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(RS_Entity * e=blk->firstEntity(RS2::ResolveAll); e!=NULL;
203 e=blk->nextEntity(RS2::ResolveAll))
207 RS_DEBUG->print("004");
210 if (e->rtti() == RS2::EntityLine)
212 RS_Line * l = (RS_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)
220 RS_Arc * a = (RS_Arc *)e;
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
240 RS_DEBUG->print("005");
242 RS_DEBUG->print("006");
244 RS_DEBUG->print("007");
249 RS_DEBUG->print("CXF Filter: exporting file: OK");
254 RS_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 RS_FilterCXF::stream(std::ofstream & fs, double value)
267 fs << (const char *)RS_Utility::doubleToString(value).toAscii().data();