~librecad-dev/librecad/librecad

« back to all changes in this revision

Viewing changes to librecad/src/lib/filters/rs_filtercxf.cpp

  • Committer: Scott Howard
  • Date: 2014-02-21 19:07:55 UTC
  • Revision ID: showard@debian.org-20140221190755-csjax9wb146hgdq4
first commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** This file is part of the LibreCAD project, a 2D CAD program
 
4
**
 
5
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
 
6
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
 
7
**
 
8
**
 
9
** This file may be distributed and/or modified under the terms of the
 
10
** GNU General Public License version 2 as published by the Free Software 
 
11
** Foundation and appearing in the file gpl-2.0.txt included in the
 
12
** packaging of this file.
 
13
**
 
14
** This program is distributed in the hope that it will be useful,
 
15
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
** GNU General Public License for more details.
 
18
** 
 
19
** You should have received a copy of the GNU General Public License
 
20
** along with this program; if not, write to the Free Software
 
21
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
22
**
 
23
** This copyright notice MUST APPEAR in all copies of the script!  
 
24
**
 
25
**********************************************************************/
 
26
 
 
27
 
 
28
#include "rs_filtercxf.h"
 
29
 
 
30
#include <iostream>
 
31
#include <fstream>
 
32
 
 
33
#include "rs_font.h"
 
34
#include "rs_utility.h"
 
35
#include "rs_system.h"
 
36
#include "rs_block.h"
 
37
#include <QStringList>
 
38
 
 
39
 
 
40
/**
 
41
 * Default constructor.
 
42
 */
 
43
RS_FilterCXF::RS_FilterCXF() : RS_FilterInterface() {
 
44
 
 
45
    RS_DEBUG->print("Setting up CXF filter...");
 
46
}
 
47
 
 
48
/**
 
49
 * Implementation of the method used for RS_Import to communicate
 
50
 * with this filter.
 
51
 *
 
52
 * @param g The graphic in which the entities from the file
 
53
 * will be created or the graphics from which the entities are
 
54
 * taken to be stored in a file.
 
55
 */
 
56
bool RS_FilterCXF::fileImport(RS_Graphic& g, const QString& file, RS2::FormatType /*type*/) {
 
57
    RS_DEBUG->print("CXF Filter: importing file '%s'...", file.toLatin1().data());
 
58
 
 
59
    //this->graphic = &g;
 
60
    bool success = false;
 
61
 
 
62
    // Load font file as we normally do, but the font doesn't own the
 
63
    //  letters (we'll add them to the graphic instead. Hence 'false').
 
64
    RS_Font font(file, false);
 
65
    success = font.loadFont();
 
66
 
 
67
    if (success==false) {
 
68
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
69
                        "Cannot open CXF file '%s'.", file.toLatin1().data());
 
70
                return false;
 
71
    }
 
72
 
 
73
    g.addVariable("Names",
 
74
                         font.getNames().join(","), 0);
 
75
    g.addVariable("LetterSpacing", font.getLetterSpacing(), 0);
 
76
    g.addVariable("WordSpacing", font.getWordSpacing(), 0);
 
77
    g.addVariable("LineSpacingFactor", font.getLineSpacingFactor(), 0);
 
78
    g.addVariable("Authors", font.getAuthors().join(","), 0);
 
79
    if (!font.getEncoding().isEmpty()) {
 
80
        g.addVariable("Encoding", font.getEncoding(), 0);
 
81
    }
 
82
 
 
83
    RS_BlockList* letterList = font.getLetterList();
 
84
    for (unsigned i=0; i<font.countLetters(); ++i) {
 
85
        RS_Block* ch = font.letterAt(i);
 
86
 
 
87
        QString uCode;
 
88
        uCode.setNum(ch->getName().at(0).unicode(), 16);
 
89
        while (uCode.length()<4) {
 
90
            uCode="0"+uCode;
 
91
        }
 
92
        //ch->setName("[" + uCode + "] " + ch->getName());
 
93
        //letterList->rename(ch, QString("[%1]").arg(ch->getName()));
 
94
        letterList->rename(ch,
 
95
                           QString("[%1] %2").arg(uCode).arg(ch->getName().at(0)));
 
96
 
 
97
        g.addBlock(ch, false);
 
98
        ch->reparent(&g);
 
99
    }
 
100
 
 
101
    g.addBlockNotification();
 
102
 
 
103
        return true;
 
104
}
 
105
 
 
106
 
 
107
 
 
108
/**
 
109
 * Implementation of the method used for RS_Export to communicate
 
110
 * with this filter.
 
111
 *
 
112
 * @param file Full path to the CXF file that will be written.
 
113
 */
 
114
bool RS_FilterCXF::fileExport(RS_Graphic& g, const QString& file, RS2::FormatType /*type*/) {
 
115
 
 
116
    RS_DEBUG->print("CXF Filter: exporting file '%s'...", file.toLatin1().data());
 
117
 
 
118
    // crashes under windoze xp:
 
119
    //std::ofstream fout;
 
120
 
 
121
    RS_DEBUG->print("RS_FilterCXF::fileExport: open");
 
122
    //fout.open((const char*)file.toLocal8Bit());
 
123
    FILE* fp;
 
124
 
 
125
    if ((fp = fopen(file.toLocal8Bit(), "wt")) != NULL) {
 
126
 
 
127
        RS_DEBUG->print("RS_FilterCXF::fileExport: open: OK");
 
128
 
 
129
        RS_DEBUG->print("RS_FilterCXF::fileExport: header");
 
130
 
 
131
        // header:
 
132
        fprintf(fp, "# Format:            QCad II Font\n");
 
133
 
 
134
        fprintf(fp, "# Creator:           %s\n",
 
135
                (const char*)RS_SYSTEM->getAppName().toLocal8Bit());
 
136
        fprintf(fp, "# Version:           %s\n",
 
137
                (const char*)RS_SYSTEM->getAppVersion().toLocal8Bit());
 
138
 
 
139
        RS_DEBUG->print("001");
 
140
        QString ns = g.getVariableString("Names", "");
 
141
        if (!ns.isEmpty()) {
 
142
            QStringList names = ns.split(',');
 
143
            RS_DEBUG->print("002");
 
144
            for (int i = 0; i < names.size(); ++i) {
 
145
                fprintf(fp, "# Name:              %s\n",
 
146
                        names.at(i).toLocal8Bit().data() );
 
147
             }
 
148
        }
 
149
 
 
150
        RS_DEBUG->print("003");
 
151
 
 
152
        QString es = g.getVariableString("Encoding", "");
 
153
        if (!es.isEmpty()) {
 
154
            fprintf(fp, "# Encoding:          %s\n",
 
155
                    es.toLocal8Bit().data());
 
156
        }
 
157
 
 
158
        RS_DEBUG->print("004a");
 
159
 
 
160
        fprintf(fp, "# LetterSpacing:     %f\n",
 
161
                g.getVariableDouble("LetterSpacing", 3.0));
 
162
        fprintf(fp, "# WordSpacing:       %f\n",
 
163
                g.getVariableDouble("WordSpacing", 6.75));
 
164
        fprintf(fp, "# LineSpacingFactor: %f\n",
 
165
                g.getVariableDouble("LineSpacingFactor", 1.0));
 
166
 
 
167
        QString sa = g.getVariableString("Authors", "");
 
168
        RS_DEBUG->print("authors: %s", sa.toLocal8Bit().data());
 
169
        if (!sa.isEmpty()) {
 
170
            QStringList authors = sa.split(',');
 
171
            RS_DEBUG->print("006");
 
172
            RS_DEBUG->print("count: %d", authors.count());
 
173
 
 
174
            QString a;
 
175
            for (QStringList::Iterator it2 = authors.begin();
 
176
                    it2!=authors.end(); ++it2) {
 
177
 
 
178
                RS_DEBUG->print("006a");
 
179
                a = QString(*it2);
 
180
                RS_DEBUG->print("006b");
 
181
                RS_DEBUG->print("string is: %s", a.toLatin1().data());
 
182
                RS_DEBUG->print("006b0");
 
183
                fprintf(fp, "# Author:            ");
 
184
                RS_DEBUG->print("006b1");
 
185
                fprintf(fp, "%s\n", a.toLatin1().data());
 
186
                //fout << "# Author:            " << a.ascii() << "\n";
 
187
            }
 
188
            RS_DEBUG->print("007");
 
189
        }
 
190
 
 
191
        RS_DEBUG->print("RS_FilterCXF::fileExport: header: OK");
 
192
 
 
193
        RS_DEBUG->print("008");
 
194
        // iterate through blocks (=letters of font)
 
195
        for (unsigned i=0; i<g.countBlocks(); ++i) {
 
196
            RS_Block* blk = g.blockAt(i);
 
197
 
 
198
            RS_DEBUG->print("block: %d", i);
 
199
            RS_DEBUG->print("001");
 
200
 
 
201
            if (blk!=NULL && !blk->isUndone()) {
 
202
                RS_DEBUG->print("002");
 
203
                RS_DEBUG->print("002a: %s",
 
204
                                (blk->getName().toLocal8Bit().data()));
 
205
 
 
206
                fprintf(fp, "\n%s\n",
 
207
                        (blk->getName().toLocal8Bit().data()));
 
208
 
 
209
 
 
210
                // iterate through entities of this letter:
 
211
                for (RS_Entity* e=blk->firstEntity(RS2::ResolveAll);
 
212
                        e!=NULL;
 
213
                        e=blk->nextEntity(RS2::ResolveAll)) {
 
214
 
 
215
                    if (!e->isUndone()) {
 
216
 
 
217
                        RS_DEBUG->print("004");
 
218
 
 
219
                        // lines:
 
220
                        if (e->rtti()==RS2::EntityLine) {
 
221
                            RS_Line* l = (RS_Line*)e;
 
222
 
 
223
                            fprintf(fp, "L %f,%f,%f,%f\n",
 
224
                                    l->getStartpoint().x,
 
225
                                    l->getStartpoint().y,
 
226
                                    l->getEndpoint().x,
 
227
                                    l->getEndpoint().y);
 
228
                        }
 
229
 
 
230
                        // arcs:
 
231
                        else if (e->rtti()==RS2::EntityArc) {
 
232
                            RS_Arc* a = (RS_Arc*)e;
 
233
 
 
234
                            if (!a->isReversed()) {
 
235
                                fprintf(fp, "A ");
 
236
                            } else {
 
237
                                fprintf(fp, "AR ");
 
238
                            }
 
239
 
 
240
                            fprintf(fp, "%f,%f,%f,%f,%f\n",
 
241
                                    a->getCenter().x,
 
242
                                    a->getCenter().y,
 
243
                                    a->getRadius(),
 
244
                                    a->getAngle1()*ARAD,
 
245
                                    a->getAngle2()*ARAD);
 
246
                        }
 
247
                        // Ignore entities other than arcs / lines
 
248
                        else {}
 
249
                    }
 
250
 
 
251
                    RS_DEBUG->print("005");
 
252
                }
 
253
                RS_DEBUG->print("006");
 
254
            }
 
255
            RS_DEBUG->print("007");
 
256
        }
 
257
        //fout.close();
 
258
        fclose(fp);
 
259
        RS_DEBUG->print("CXF Filter: exporting file: OK");
 
260
                return true;
 
261
    }
 
262
        else {
 
263
        RS_DEBUG->print("CXF Filter: exporting file failed");
 
264
        }
 
265
 
 
266
        return false;
 
267
}
 
268
 
 
269
 
 
270
 
 
271
/**
 
272
 * Streams a double value to the gien stream cutting away trailing 0's.
 
273
 *
 
274
 * @param value A double value. e.g. 2.700000
 
275
 */
 
276
void RS_FilterCXF::stream(std::ofstream& fs, double value) {
 
277
    fs << RS_Utility::doubleToString(value).toLatin1().data();
 
278
}
 
279