Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Testing latest pari + WASM + node.js... and it works?! Wow.

28495 views
License: GPL3
ubuntu2004
1
/* Copyright (C) 2000 The PARI group.
2
3
This file is part of the PARI/GP package.
4
5
PARI/GP is free software; you can redistribute it and/or modify it under the
6
terms of the GNU General Public License as published by the Free Software
7
Foundation; either version 2 of the License, or (at your option) any later
8
version. It is distributed in the hope that it will be useful, but WITHOUT
9
ANY WARRANTY WHATSOEVER.
10
11
Check the License for details. You should have received a copy of it, along
12
with the package; see the file 'COPYING'. If not, write to the Free Software
13
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
14
/////////////////////////////////////////////////////////////////////////////
15
//
16
// High resolution plot using Trolltech's Qt library
17
//
18
// You may possibly want to use this file with a "Qt Free Edition"
19
// which is distributed under the terms of the Q PUBLIC LICENSE (QPL),
20
// or with a "Qt/Embedded Free Edition" which is
21
// distributed under the terms of the GNU General Public License (GPL).
22
// Please check http://www.trolltech.com for details.
23
//
24
// ---Nils-Peter Skoruppa (www.countnumber.de)
25
/////////////////////////////////////////////////////////////////////////////
26
#include <Qt/qapplication.h>
27
#include <Qt/qwidget.h>
28
#include <Qt/qpainter.h>
29
#include <Qt/qcolor.h>
30
#include <Qt/qdesktopwidget.h>
31
#include <Qt/qevent.h>
32
#include <Qt/qpixmap.h>
33
#include <Qt/qsignalmapper.h>
34
#include <Qt/qimage.h>
35
#include <Qt/qimagewriter.h>
36
#include <Qt/qmainwindow.h>
37
#include <Qt/qmenubar.h>
38
#include <Qt/qtoolbar.h>
39
#include <Qt/qaction.h>
40
#include <Qt/qfiledialog.h>
41
#include <Qt/qmessagebox.h>
42
#include <Qt/qfile.h>
43
#include <Qt/qstatusbar.h>
44
#include <Qt/qimage.h>
45
#include <Qt/qlabel.h>
46
#include <Qt/qspinbox.h>
47
#include <Qt/qlayout.h>
48
49
extern "C" {
50
#include "pari.h"
51
#include "rect.h"
52
#undef grem
53
}
54
55
using namespace Qt;
56
57
class Plotter: public QWidget {
58
59
Q_OBJECT
60
61
signals:
62
void clicked();
63
64
protected:
65
void mouseReleaseEvent(QMouseEvent*);
66
67
public:
68
Plotter(PARI_plot *T, GEN w, GEN x, GEN y, QWidget* parent = 0);
69
void save(const QString& s = *plotFile + ".xpm",
70
const QString& f = QString("XPM"));
71
72
protected:
73
void paintEvent(QPaintEvent *);
74
75
private:
76
PARI_plot *T;
77
GEN w, x, y;
78
QColor color0;
79
QFont font;
80
static QString *plotFile;
81
void draw(QPainter *p);
82
};
83
84
QString *Plotter::plotFile = new QString("pariplot");
85
86
static QColor
87
rgb_color(long c)
88
{
89
int r, g, b; long_to_rgb(c, &r, &g, &b);
90
return QColor(r, g, b);
91
}
92
Plotter::Plotter(PARI_plot *T, GEN w, GEN x, GEN y, QWidget* parent)
93
: QWidget(parent), font("lucida", 9) {
94
this->w = w;
95
this->x = x;
96
this->y = y;
97
this->T = T;
98
this->setFont(font);
99
{
100
int r, g, b;
101
color_to_rgb(gel(GP_DATA->colormap,1), &r, &g, &b);
102
color0 = QColor(r, g, b);
103
}
104
QPalette palette;
105
palette.setColor(backgroundRole(), color0);
106
setPalette(palette);
107
}
108
109
static void
110
SetForeground(void *data, long col)
111
{
112
QPainter *p = (QPainter *)data;
113
p->setPen(rgb_color(col));
114
}
115
116
static void
117
DrawPoint(void *data, long x, long y)
118
{
119
QPainter *p = (QPainter *)data;
120
p->drawPoint(x, y);
121
}
122
123
static void
124
DrawLine(void *data, long x1, long y1, long x2, long y2)
125
{
126
QPainter *p = (QPainter *)data;
127
p->drawLine(x1, y1, x2, y2);
128
}
129
130
static void
131
DrawRectangle(void *data, long x, long y, long w, long h)
132
{
133
QPainter *p = (QPainter *)data;
134
p->drawRect(x, y, w, h);
135
}
136
137
static void
138
FillRectangle(void *data, long x, long y, long w, long h)
139
{
140
QPainter *p = (QPainter *)data;
141
p->fillRect(x, y, w, h, p->pen().color());
142
}
143
144
static void
145
DrawPoints(void *data, long nb, struct plot_points *pt)
146
{
147
QPainter *p = (QPainter *)data;
148
QPolygon xp = QPolygon(nb);
149
long i;
150
for (i = 0;i < nb; i++) xp.setPoint(i,pt[i].x, pt[i].y);
151
p->drawPoints(xp);
152
}
153
154
static void
155
DrawLines(void *data, long nb, struct plot_points *pt)
156
{
157
QPainter *p = (QPainter *)data;
158
QPolygon xp = QPolygon(nb);
159
long i;
160
for (i = 0;i < nb; i++) xp.setPoint(i, pt[i].x, pt[i].y);
161
p->drawPolyline(xp);
162
}
163
164
static void
165
DrawString(void *data, long x, long y, char *text, long numtext)
166
{
167
QPainter *p = (QPainter *)data;
168
p->drawText(x, y, QString(text).left(numtext));
169
}
170
171
void
172
Plotter::draw(QPainter *p)
173
{
174
struct plot_eng plotQt;
175
plotQt.sc=&SetForeground;
176
plotQt.pt=&DrawPoint;
177
plotQt.ln=&DrawLine;
178
plotQt.bx=&DrawRectangle;
179
plotQt.fb=&FillRectangle;
180
plotQt.mp=&DrawPoints;
181
plotQt.mp=&DrawPoints;
182
plotQt.ml=&DrawLines;
183
plotQt.st=&DrawString;
184
plotQt.pl=T;
185
plotQt.data=(void *)p;
186
double xs = double(this->width()) / T->width;
187
double ys = double(this->height()) / T->height;
188
gen_draw(&plotQt, this->w, this->x, this->y, xs, ys);
189
}
190
191
void
192
Plotter::save(const QString& s, const QString& f)
193
{
194
QPixmap pm(this->width(), this->height());
195
QPainter p;
196
p.begin(&pm);
197
p.initFrom(this);
198
p.fillRect(0, 0, pm.width(), pm.height(), color0);
199
draw(&p);
200
p.end();
201
pm.save(s, f.toAscii().data());
202
}
203
204
void
205
Plotter::paintEvent(QPaintEvent *)
206
{
207
QPainter p;
208
p.begin(this);
209
this->draw(&p);
210
p.end();
211
}
212
213
void Plotter::mouseReleaseEvent(QMouseEvent*) { emit clicked(); }
214
215
/* XPM */
216
static const char * const fullscreen_xpm[] = {
217
"14 14 2 1",
218
" c None",
219
". c #000000",
220
"..............",
221
". .. .",
222
". .. .",
223
". .... .",
224
". .. .",
225
". . .. . .",
226
"..............",
227
"..............",
228
". . .. . .",
229
". .. .",
230
". .... .",
231
". .. .",
232
". .. .",
233
".............."};
234
235
class PlotWindow: public QMainWindow
236
{
237
Q_OBJECT
238
239
public:
240
PlotWindow(PARI_plot *T, GEN w, GEN x, GEN y, QWidget* parent = 0);
241
~PlotWindow();
242
243
protected:
244
void resizeEvent(QResizeEvent *);
245
246
private slots:
247
void fullScreen();
248
void normalView();
249
void save();
250
void save(int);
251
252
private:
253
static const QList<QByteArray> file_formats;
254
Plotter *plr;
255
QString saveFileName;
256
int saveFileFormat;
257
QLabel *res;
258
QMenu* menuFile;
259
QMenu* menuView;
260
QMenu* menuFormat;
261
QAction* quitAction;
262
QAction* saveAction;
263
QAction* fullScreenAction;
264
QSignalMapper* signalMapper;
265
QIcon* icon;
266
};
267
268
const QList<QByteArray> PlotWindow::file_formats = QImageWriter::supportedImageFormats();
269
270
PlotWindow::PlotWindow(PARI_plot *T, GEN w, GEN x, GEN y, QWidget* parent)
271
: QMainWindow(parent), saveFileName("pariplot"), saveFileFormat(0)
272
{
273
setWindowTitle("Pari QtPlot");
274
275
QPalette palette;
276
palette.setColor(this->backgroundRole(), white);
277
this->setPalette(palette);
278
279
menuFile = menuBar()->addMenu("&File");
280
281
saveAction = new QAction("&Save",this);
282
saveAction->setShortcut(QKeySequence(CTRL+Key_S));
283
connect (saveAction, SIGNAL(triggered()), this, SLOT(save()));
284
menuFile->addAction(saveAction);
285
menuFormat = menuFile->addMenu("Save &as");
286
287
signalMapper = new QSignalMapper(this);
288
289
for(int i = 0; i < file_formats.count(); i++)
290
{
291
QAction* tmpAction;
292
tmpAction = new QAction(QString(file_formats.at(i)),this);
293
connect (tmpAction, SIGNAL(triggered()), signalMapper, SLOT(map()));
294
signalMapper->setMapping(tmpAction,i);
295
menuFormat->addAction(tmpAction);
296
}
297
298
connect (signalMapper, SIGNAL(mapped(int)), this,SLOT(save(int)));
299
300
quitAction = new QAction("&Quit",this);
301
quitAction->setShortcut(QKeySequence(CTRL+Key_Q));
302
connect (quitAction, SIGNAL(triggered()), this, SLOT(close()));
303
menuFile->addAction(quitAction);
304
305
menuView = menuBar()->addMenu("&View");
306
307
fullScreenAction = new QAction("Use &full screen", this);
308
fullScreenAction->setShortcut(QKeySequence(CTRL+Key_F));
309
icon = new QIcon();
310
icon->addPixmap(QPixmap((const char ** )fullscreen_xpm));
311
fullScreenAction->setIcon(*icon);
312
connect(fullScreenAction, SIGNAL(triggered()), this, SLOT(fullScreen()));
313
menuView->addAction(fullScreenAction);
314
315
// Setting up an instance of plotter
316
plr = new Plotter(T, w, x, y, this);
317
connect(plr, SIGNAL(clicked()), this, SLOT(normalView()));
318
this->setCentralWidget(plr);
319
320
this->resize(T->width, T->height + 24);
321
res = new QLabel();
322
statusBar()->addWidget(res);
323
}
324
325
PlotWindow::~PlotWindow() {}
326
327
void
328
PlotWindow::resizeEvent(QResizeEvent *e)
329
{
330
QMainWindow::resizeEvent(e);
331
res->setText(QString("Resolution: ") +
332
QString::number(plr->width()) + "x" +
333
QString::number(plr->height()));
334
res->setFixedSize(res->sizeHint());
335
}
336
337
void
338
PlotWindow::fullScreen()
339
{
340
plr->setParent(0);
341
plr->showMaximized();
342
plr->show();
343
}
344
345
void
346
PlotWindow::normalView()
347
{
348
if (!plr->parentWidget())
349
{
350
plr->setParent(this);
351
this->setCentralWidget(plr);
352
plr->show();
353
}
354
}
355
356
void
357
PlotWindow::save()
358
{
359
QString ff = QString(file_formats.at(saveFileFormat));
360
QString fn = saveFileName + "." + ff.toLower();
361
plr->save(fn, ff);
362
setWindowTitle(QString("Pari QtPlot:") + fn);
363
}
364
365
void
366
PlotWindow::save(int id)
367
{
368
QString ff(file_formats.at(id));
369
QString s(ff + " (*." + ff.toLower() +");;All (*)");
370
QString fn = QFileDialog::getSaveFileName(this, saveFileName + "." + ff,
371
saveFileName + "." + ff, s);
372
if (!fn.isEmpty())
373
{
374
saveFileName = fn;
375
int p;
376
if ((p = saveFileName.lastIndexOf("." + ff, -1)) >= 0)
377
saveFileName.truncate(p);
378
saveFileFormat = id;
379
save();
380
}
381
}
382
383
#include "plotQt4.moc.cpp"
384
385
static void
386
draw(PARI_plot *T, GEN w, GEN x, GEN y)
387
{
388
if (pari_daemon()) return; // parent process returns
389
390
// launch Qt window
391
int argc = 1; // set argc = 2 for cross
392
const char * argv[] = { "gp", "-qws"}; // development using qvfb
393
QApplication a(argc, (char**) argv);
394
PlotWindow *win = new PlotWindow(T, w, x, y);
395
win->show();
396
a.exec();
397
pari_close(); exit(0);
398
}
399
400
INLINE void
401
gp_get_display_sizes(long *dwidth, long *dheight, long *fwidth, long *fheight)
402
{
403
/* There must be an easier way to get desktop size... */
404
int argc = 1;
405
const char * argv[] = { "gp", "-qws"};
406
QApplication a(argc, (char**) argv);
407
QDesktopWidget *qw = new QDesktopWidget();
408
if (qw)
409
{
410
QRect rec = qw->screenGeometry();
411
*dwidth = rec.width(); // screen width
412
*dheight = rec.height(); // and height
413
}
414
else
415
{
416
*dwidth = 0;
417
*dheight = 0;
418
}
419
*fwidth = 6; // font width
420
*fheight = 9; // and height
421
}
422
423
void
424
gp_get_plot(PARI_plot *T)
425
{
426
gp_get_plot_generic(T,gp_get_display_sizes);
427
T->draw = &draw;
428
}
429
430