#endif
-#endif /* qh_DEFuser */
-
-
+#endif /* qh_DEFuser */
diff --git a/3rdparty/qhull/usermem.c b/3rdparty/qhull/usermem.c
index 0e99e8f66..b21a7fec2 100644
--- a/3rdparty/qhull/usermem.c
+++ b/3rdparty/qhull/usermem.c
@@ -2,7 +2,7 @@
>--------------------------------
usermem.c
- qh_exit(), qh_free(), and qh_malloc()
+ user redefinable functions -- qh_exit, qh_free, and qh_malloc
See README.txt.
@@ -28,6 +28,8 @@
qh_exit( exitcode )
exit program
+ the exitcode must be 255 or less. Zero indicates success.
+ Note: Exit status ('$?') in bash reports 256 as 0
notes:
qh_exit() is called when qh_errexit() and longjmp() are not available.
@@ -47,6 +49,7 @@ void qh_exit(int exitcode) {
notes:
qh_fprintf_stderr() is called when qh.ferr is not defined, usually due to an initialization error
+ if msgcode is a MSG_ERROR (6000), caller should set qh.last_errcode (like qh_fprintf) or variable 'last_errcode'
It is typically followed by qh_errexit().
diff --git a/3rdparty/qhull/userprintf.c b/3rdparty/qhull/userprintf.c
index 190d7cd79..e77d89494 100644
--- a/3rdparty/qhull/userprintf.c
+++ b/3rdparty/qhull/userprintf.c
@@ -1,66 +1,98 @@
/* ---------------------------------
- userprintf.c
- qh_fprintf()
+ userprintf.c
+ user redefinable function -- qh_fprintf
- see README.txt see COPYING.txt for copyright information.
+ see README.txt see COPYING.txt for copyright information.
- If you recompile and load this file, then userprintf.o will not be loaded
- from qhull.a or qhull.lib
+ If you recompile and load this file, then userprintf.o will not be loaded
+ from qhull.a or qhull.lib
- See libqhull.h for data structures, macros, and user-callable functions.
- See user.c for qhull-related, redefinable functions
- see user.h for user-definable constants
- See usermem.c for qh_exit(), qh_free(), and qh_malloc()
- see Qhull.cpp and RboxPoints.cpp for examples.
+ See libqhull.h for data structures, macros, and user-callable functions.
+ See user.c for qhull-related, redefinable functions
+ see user.h for user-definable constants
+ See usermem.c for qh_exit(), qh_free(), and qh_malloc()
+ see Qhull.cpp and RboxPoints.cpp for examples.
- Please report any errors that you fix to qhull@qhull.org
+ qh_printf is a good location for debugging traps, checked on each log line
+
+ Please report any errors that you fix to qhull@qhull.org
*/
#include "libqhull.h"
-#include "mem.h"
+#include "poly.h" /* for qh.tracefacet */
#include
#include
#include
/*---------------------------------
+ >--------------------------------
- qh_fprintf(fp, msgcode, format, list of args )
- print arguments to *fp according to format
- Use qh_fprintf_rbox() for rboxlib.c
+ qh_fprintf( fp, msgcode, format, list of args )
+ print arguments to *fp according to format
+ Use qh_fprintf_rbox() for rboxlib.c
- notes:
- same as fprintf()
- fgets() is not trapped like fprintf()
- exit qh_fprintf via qh_errexit()
- may be called for errors in qh_initstatistics and qh_meminit
+ notes:
+ sets qh.last_errcode if msgcode is error 6000..6999
+ same as fprintf()
+ fgets() is not trapped like fprintf()
+ exit qh_fprintf via qh_errexit()
+ may be called for errors in qh_initstatistics and qh_meminit
*/
void qh_fprintf(FILE *fp, int msgcode, const char *fmt, ... ) {
- va_list args;
+ va_list args;
+ facetT *neighbor, **neighborp;
- if (!fp) {
- /* could use qhmem.ferr, but probably better to be cautious */
- qh_fprintf_stderr(6232, "Qhull internal error (userprintf.c): fp is 0. Wrong qh_fprintf called.\n");
- qh_errexit(6232, NULL, NULL);
- }
- va_start(args, fmt);
+ if (!fp) {
+ /* could use qhmem.ferr, but probably better to be cautious */
+ qh_fprintf_stderr(6028, "qhull internal error (userprintf.c): fp is 0. Perhaps the wrong qh_fprintf was called.\n");
+ qh last_errcode= 6028;
+ qh_errexit(qh_ERRqhull, NULL, NULL);
+ }
#if qh_QHpointer
- if (qh_qh && qh ANNOTATEoutput) {
+ if ((qh_qh && qh ANNOTATEoutput) || msgcode < MSG_TRACE4) {
#else
- if (qh ANNOTATEoutput) {
+ if (msgcode < MSG_TRACE4) {
#endif
- fprintf(fp, "[QH%.4d]", msgcode);
- }else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
- fprintf(fp, "QH%.4d ", msgcode);
+ fprintf(fp, "[QH%.4d]", msgcode);
+ }else if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR ) {
+ fprintf(fp, "QH%.4d ", msgcode);
+ }
+ va_start(args, fmt);
+ vfprintf(fp, fmt, args);
+ va_end(args);
+
+#if qh_QHpointer
+ if (qh_qh) {
+#else
+ {
+#endif
+ if (msgcode >= MSG_ERROR && msgcode < MSG_WARNING)
+ qh last_errcode= msgcode;
+ /* Place debugging traps here. Use with trace option 'Tn'
+ Set qh.tracefacet_id, qh.traceridge_id, and/or qh.tracevertex_id in global.c
+ */
+ if (False) { /* in production skip test for debugging traps */
+ if (qh tracefacet && qh tracefacet->tested) {
+ if (qh_setsize(qh tracefacet->neighbors) < qh hull_dim)
+ qh_errexit(qh_ERRdebug, qh tracefacet, qh traceridge);
+ FOREACHneighbor_(qh tracefacet) {
+ if (neighbor != qh_DUPLICATEridge && neighbor != qh_MERGEridge && neighbor->visible)
+ qh_errexit2(qh_ERRdebug, qh tracefacet, neighbor);
+ }
+ }
+ if (qh traceridge && qh traceridge->top->id == 234342223) {
+ qh_errexit(qh_ERRdebug, qh tracefacet, qh traceridge);
+ }
+ if (qh tracevertex && qh_setsize(qh tracevertex->neighbors)>3434334) {
+ qh_errexit(qh_ERRdebug, qh tracefacet, qh traceridge);
+ }
}
- vfprintf(fp, fmt, args);
- va_end(args);
-
- /* Place debugging traps here. Use with option 'Tn' */
-
+ if (qh FLUSHprint)
+ fflush(fp);
+ }
} /* qh_fprintf */
diff --git a/3rdparty/qhull/userprintf_rbox.c b/3rdparty/qhull/userprintf_rbox.c
index 8edd2001a..1d7c98ce2 100644
--- a/3rdparty/qhull/userprintf_rbox.c
+++ b/3rdparty/qhull/userprintf_rbox.c
@@ -2,7 +2,7 @@
>--------------------------------
userprintf_rbox.c
- qh_fprintf_rbox()
+ user redefinable function -- qh_fprintf_rbox
see README.txt see COPYING.txt for copyright information.
@@ -27,7 +27,7 @@
/*---------------------------------
- qh_fprintf_rbox(fp, msgcode, format, list of args )
+ qh_fprintf_rbox( fp, msgcode, format, list of args )
print arguments to *fp according to format
Use qh_fprintf_rbox() for rboxlib.c
@@ -41,8 +41,8 @@ void qh_fprintf_rbox(FILE *fp, int msgcode, const char *fmt, ... ) {
va_list args;
if (!fp) {
- qh_fprintf_stderr(6231, "Qhull internal error (userprintf_rbox.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
- qh_errexit_rbox(6231);
+ qh_fprintf_stderr(6231, "qhull internal error (userprintf_rbox.c): fp is 0. Wrong qh_fprintf_rbox called.\n");
+ qh_errexit_rbox(qh_ERRqhull);
}
if (msgcode >= MSG_ERROR && msgcode < MSG_STDERR)
fprintf(fp, "QH%.4d ", msgcode);
diff --git a/lib/gks/gks.h b/lib/gks/gks.h
index df3a6145f..476058677 100644
--- a/lib/gks/gks.h
+++ b/lib/gks/gks.h
@@ -241,6 +241,7 @@ extern "C" {
#define GKS_K_GDP_DRAW_LINES 2
#define GKS_K_GDP_DRAW_MARKERS 3
#define GKS_K_GDP_DRAW_TRIANGLES 4
+#define GKS_K_GDP_FILL_POLYGONS 5
/* GKS error codes */
diff --git a/lib/gks/pdf.c b/lib/gks/pdf.c
index c8028b869..5587eb4ff 100644
--- a/lib/gks/pdf.c
+++ b/lib/gks/pdf.c
@@ -1907,6 +1907,56 @@ static void draw_triangles(int n, double *px, double *py, int ntri, int *tri)
}
}
+static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
+{
+ double x, y, xd, yd;
+ int j, k, len, fl_color = MAX_COLOR;
+ unsigned int rgba;
+ int alpha;
+
+ pdf_setlinewidth(p, gkss->bwidth * p->nominal_size);
+ set_color(gkss->bcoli);
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+ for (k = 0; k < len; ++k)
+ {
+ WC_to_NDC(px[ply[j] - 1], py[ply[j] - 1], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, xd, yd);
+ j++;
+
+ if (k == 0)
+ {
+ pdf_moveto(p, xd, yd);
+ }
+ else
+ {
+ pdf_lineto(p, xd, yd);
+ }
+ }
+
+ rgba = (unsigned int)ply[j++];
+ p->red[fl_color] = (rgba & 0xff) / 255.0;
+ p->green[fl_color] = ((rgba >> 8) & 0xff) / 255.0;
+ p->blue[fl_color] = ((rgba >> 16) & 0xff) / 255.0;
+ alpha = (rgba >> 24) & 0xff;
+
+ pdf_setfillcolor(p, p->red[fl_color], p->green[fl_color], p->blue[fl_color]);
+ set_transparency(alpha);
+ if (gkss->bwidth != 0)
+ {
+ pdf_printf(p->content, "h b*\n");
+ }
+ else
+ {
+ pdf_printf(p->content, "h f*\n");
+ }
+ }
+}
+
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
if (gkss->clip_tnr != 0)
@@ -1928,6 +1978,9 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
case GKS_K_GDP_DRAW_TRIANGLES:
draw_triangles(n, px, py, nc, codes);
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ fill_polygons(n, px, py, nc, codes);
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
diff --git a/lib/gks/plugin/cairoplugin.c b/lib/gks/plugin/cairoplugin.c
index 3029e00ca..ecdd5c04f 100644
--- a/lib/gks/plugin/cairoplugin.c
+++ b/lib/gks/plugin/cairoplugin.c
@@ -1592,7 +1592,7 @@ static void write_page(void)
long size = ftell(stream);
fseek(stream, 0, SEEK_SET);
- char *string = (char *)gks_malloc(size + 1);
+ unsigned char *string = (unsigned char *)gks_malloc(size + 1);
fread(string, 1, size, stream);
fclose(stream);
string[size] = 0;
@@ -1951,6 +1951,55 @@ static void draw_triangles(int n, double *px, double *py, int ntri, int *tri)
}
}
+static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
+{
+ double x, y;
+ int i, j, k, len, fill_color = MAX_COLOR;
+ unsigned int rgba;
+
+ if (n > p->max_points)
+ {
+ p->points = (cairo_point *)gks_realloc(p->points, n * sizeof(cairo_point));
+ p->max_points = n;
+ }
+
+ for (i = 0; i < n; ++i)
+ {
+ WC_to_NDC(px[i], py[i], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, p->points[i].x, p->points[i].y);
+ }
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+ cairo_move_to(p->cr, p->points[ply[j] - 1].x, p->points[ply[j] - 1].y);
+ j++;
+ for (k = 1; k < len; k++)
+ {
+ cairo_line_to(p->cr, p->points[ply[j] - 1].x, p->points[ply[j] - 1].y);
+ j++;
+ }
+
+ rgba = (unsigned int)ply[j++];
+ p->rgb[fill_color][0] = (rgba & 0xff) / 255.0;
+ p->rgb[fill_color][1] = ((rgba >> 8) & 0xff) / 255.0;
+ p->rgb[fill_color][2] = ((rgba >> 16) & 0xff) / 255.0;
+ p->transparency = ((rgba >> 24) & 0xff) / 255.0;
+ set_color(fill_color);
+
+ cairo_close_path(p->cr);
+ cairo_fill_preserve(p->cr);
+
+ set_color(gkss->bcoli);
+ cairo_set_line_cap(p->cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_join(p->cr, CAIRO_LINE_JOIN_ROUND);
+ cairo_set_line_width(p->cr, gkss->bwidth * p->nominal_size);
+ cairo_stroke(p->cr);
+ }
+}
+
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
switch (primid)
@@ -1967,6 +2016,9 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
case GKS_K_GDP_DRAW_TRIANGLES:
draw_triangles(n, px, py, nc, codes);
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ fill_polygons(n, px, py, nc, codes);
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
diff --git a/lib/gks/plugin/gsplugin.c b/lib/gks/plugin/gsplugin.c
index 64a783a31..a4ad128e9 100644
--- a/lib/gks/plugin/gsplugin.c
+++ b/lib/gks/plugin/gsplugin.c
@@ -1835,6 +1835,53 @@ static void draw_triangles(int n, double *px, double *py, int ntri, int *tri)
}
}
+static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
+{
+ double x, y, xd, yd;
+ int j, k, len, fl_color = MAX_COLOR;
+ unsigned int rgba;
+ char buffer[50];
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+
+ packb("np");
+ for (k = 0; k < len; ++k)
+ {
+ WC_to_NDC(px[ply[j] - 1], py[ply[j] - 1], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, xd, yd);
+ j++;
+
+ if (k == 0)
+ {
+ sprintf(buffer, "%.2f %.2f m", xd, yd);
+ }
+ else
+ {
+ sprintf(buffer, "%.2f %.2f l", xd, yd);
+ }
+ packb(buffer);
+ }
+
+ rgba = (unsigned int)ply[j++];
+ p->red[fl_color] = (rgba & 0xff) / 255.0;
+ p->green[fl_color] = ((rgba >> 8) & 0xff) / 255.0;
+ p->blue[fl_color] = ((rgba >> 16) & 0xff) / 255.0;
+
+ packb("cp gs");
+ set_color(-fl_color, p->wtype);
+ packb("fi gr");
+
+ sprintf(buffer, "%.4g %.4g %.4g sc", p->red[gkss->bcoli], p->green[gkss->bcoli], p->blue[gkss->bcoli]);
+ packb(buffer);
+ set_linewidth(gkss->bwidth);
+ packb("sk");
+ }
+}
+
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
switch (primid)
@@ -1851,6 +1898,9 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
case GKS_K_GDP_DRAW_TRIANGLES:
draw_triangles(n, px, py, nc, codes);
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ fill_polygons(n, px, py, nc, codes);
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
diff --git a/lib/gks/plugin/pgfplugin.c b/lib/gks/plugin/pgfplugin.c
index d8eda0097..a727284b8 100644
--- a/lib/gks/plugin/pgfplugin.c
+++ b/lib/gks/plugin/pgfplugin.c
@@ -1342,6 +1342,55 @@ static void draw_triangles(int n, double *px, double *py, int ntri, int *tri)
}
}
+static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
+{
+ double x, y;
+ int i, j, k, len;
+ unsigned int rgba;
+ int red, green, blue;
+ double alpha;
+
+ if (n > p->max_points)
+ {
+ p->points = (PGF_point *)realloc(p->points, n * sizeof(PGF_point));
+ p->max_points = n;
+ }
+
+ for (i = 0; i < n; ++i)
+ {
+ WC_to_NDC(px[i], py[i], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, p->points[i].x, p->points[i].y);
+ }
+
+ pgf_printf(p->stream, "\\definecolor{pathstroke}{HTML}{%s}\n", p->rgb[gkss->bcoli]);
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+ rgba = (unsigned int)ply[j + len];
+ red = rgba & 0xff;
+ green = (rgba >> 8) & 0xff;
+ blue = (rgba >> 16) & 0xff;
+ p->transparency = ((rgba >> 24) & 0xff) / 255.0;
+
+ pgf_printf(p->stream, "\\definecolor{mycolor}{RGB}{%d,%d,%d}\n", red, green, blue);
+
+ pgf_printf(p->stream, "\\draw[color=pathstroke, fill=mycolor, line width=%fpt, opacity=%f] ",
+ gkss->bwidth * p->nominal_size, p->transparency);
+
+ for (k = 0; k < len; ++k)
+ {
+ pgf_printf(p->stream, "(%f,%f) -- ", p->points[ply[j] - 1].x, p->points[ply[j] - 1].y);
+ j++;
+ }
+
+ pgf_printf(p->stream, "cycle;\n");
+ j++;
+ }
+}
+
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
switch (primid)
@@ -1358,6 +1407,9 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
case GKS_K_GDP_DRAW_TRIANGLES:
draw_triangles(n, px, py, nc, codes);
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ fill_polygons(n, px, py, nc, codes);
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
diff --git a/lib/gks/plugin/qtplugin_impl.cxx b/lib/gks/plugin/qtplugin_impl.cxx
index 0474d35ac..ee67b75cd 100644
--- a/lib/gks/plugin/qtplugin_impl.cxx
+++ b/lib/gks/plugin/qtplugin_impl.cxx
@@ -33,6 +33,7 @@ DLLEXPORT void QT_PLUGIN_ENTRY_NAME(int fctid, int dx, int dy, int dimx, int *i_
#ifndef NO_QT
#define MAX_POINTS 2048
+#define MAX_POLYGON 32
#define MAX_SELECTIONS 100
#define PATTERNS 120
#define HATCH_STYLE 108
@@ -98,6 +99,8 @@ typedef struct ws_state_list_t
int transparency;
QPolygonF *points;
int npoints, max_points;
+ QPolygonF *polygon;
+ int max_polygon;
QFont *font;
int family, capheight;
double alpha, angle;
@@ -1146,6 +1149,64 @@ static void draw_triangles(int n, double *px, double *py, int ntri, int *tri)
p->pixmap->restore();
}
+static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
+{
+ double x, y, xi, yi;
+ int i, j, k, rgba, len;
+ int red, green, blue, alpha;
+ QColor fill_color;
+
+ p->pixmap->save();
+ p->pixmap->setRenderHint(QPainter::Antialiasing);
+
+ QColor border_color(p->rgb[gkss->bcoli]);
+ border_color.setAlpha(p->transparency);
+
+ if (n > p->max_points)
+ {
+ p->points->resize(n);
+ p->max_points = n;
+ }
+
+ for (i = 0; i < n; ++i)
+ {
+ WC_to_NDC(px[i], py[i], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, xi, yi);
+ (*p->points)[i] = QPointF(xi, yi);
+ }
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+ if (len > p->max_polygon)
+ {
+ p->polygon->resize(len);
+ p->max_polygon = len;
+ }
+ for (k = 0; k < len; ++k)
+ {
+ (*p->polygon)[k] = (*p->points)[ply[j] - 1];
+ j++;
+ }
+
+ rgba = (unsigned int)ply[j++];
+ red = rgba & 0xff;
+ green = (rgba >> 8) & 0xff;
+ blue = (rgba >> 16) & 0xff;
+ alpha = (rgba >> 24) & 0xff;
+ fill_color.setRgb(red, green, blue);
+ fill_color.setAlpha(alpha);
+
+ p->pixmap->setBrush(QBrush(fill_color, Qt::SolidPattern));
+ p->pixmap->setPen(QPen(border_color, gkss->bwidth * p->nominal_size, Qt::SolidLine, Qt::FlatCap, Qt::RoundJoin));
+ p->pixmap->drawPolygon(p->polygon->constData(), len);
+ }
+
+ p->pixmap->restore();
+}
+
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
switch (primid)
@@ -1162,6 +1223,9 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
case GKS_K_GDP_DRAW_TRIANGLES:
draw_triangles(n, px, py, nc, codes);
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ fill_polygons(n, px, py, nc, codes);
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
@@ -1526,6 +1590,9 @@ static void initialize_data()
p->npoints = 0;
p->max_points = MAX_POINTS;
+ p->polygon = new QPolygonF(MAX_POLYGON);
+ p->max_polygon = MAX_POLYGON;
+
for (i = 0; i < PATTERNS; i++)
{
p->pattern[i] = NULL;
@@ -1549,6 +1616,7 @@ static void release_data()
for (i = 0; i < PATTERNS; i++)
if (p->pattern[i] != NULL) free(p->pattern[i]);
+ delete p->polygon;
delete p->points;
delete p->font;
delete p;
diff --git a/lib/gks/plugin/svgplugin.c b/lib/gks/plugin/svgplugin.c
index 510cfb2e0..1d7cd5a69 100644
--- a/lib/gks/plugin/svgplugin.c
+++ b/lib/gks/plugin/svgplugin.c
@@ -1364,6 +1364,55 @@ static void draw_triangles(int n, double *px, double *py, int ntri, int *tri)
}
}
+static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
+{
+ double x, y;
+ int i, j, k, len;
+ unsigned int rgba;
+ int red, green, blue;
+ double alpha;
+
+ if (n > p->max_points)
+ {
+ p->points = (SVG_point *)realloc(p->points, n * sizeof(SVG_point));
+ p->max_points = n;
+ }
+
+ for (i = 0; i < n; ++i)
+ {
+ WC_to_NDC(px[i], py[i], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, p->points[i].x, p->points[i].y);
+ }
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+ svg_printf(p->stream, "rect_index);
+ svg_printf(p->stream, "M%g %g", p->points[ply[j] - 1].x, p->points[ply[j] - 1].y);
+ j++;
+ for (k = 1; k < len; ++k)
+ {
+ svg_printf(p->stream, " L%g %g", p->points[ply[j] - 1].x, p->points[ply[j] - 1].y);
+ j++;
+ }
+
+ rgba = (unsigned int)ply[j++];
+ red = rgba & 0xff;
+ green = (rgba >> 8) & 0xff;
+ blue = (rgba >> 16) & 0xff;
+ alpha = ((rgba >> 24) & 0xff) / 255.0;
+
+ svg_printf(p->stream, " Z\" fill=\"#%02x%02x%02x\" fill-rule=\"evenodd\" fill-opacity=\"%g\" ", red, green, blue,
+ alpha);
+ svg_printf(p->stream,
+ "stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-linejoin=\"round\" stroke-width=\"%g\" />",
+ p->rgb[gkss->bcoli][0], p->rgb[gkss->bcoli][1], p->rgb[gkss->bcoli][2], alpha,
+ gkss->bwidth * p->nominal_size);
+ }
+}
+
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
switch (primid)
@@ -1380,6 +1429,9 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
case GKS_K_GDP_DRAW_TRIANGLES:
draw_triangles(n, px, py, nc, codes);
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ fill_polygons(n, px, py, nc, codes);
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
diff --git a/lib/gks/ps.c b/lib/gks/ps.c
index 6756770ab..154922679 100644
--- a/lib/gks/ps.c
+++ b/lib/gks/ps.c
@@ -1777,6 +1777,53 @@ static void draw_triangles(int n, double *px, double *py, int ntri, int *tri)
}
}
+static void fill_polygons(int n, double *px, double *py, int nply, int *ply)
+{
+ double x, y, xd, yd;
+ int j, k, len, fl_color = MAX_COLOR;
+ unsigned int rgba;
+ char buffer[50];
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+
+ packb("np");
+ for (k = 0; k < len; ++k)
+ {
+ WC_to_NDC(px[ply[j] - 1], py[ply[j] - 1], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, xd, yd);
+ j++;
+
+ if (k == 0)
+ {
+ sprintf(buffer, "%.2f %.2f m", xd, yd);
+ }
+ else
+ {
+ sprintf(buffer, "%.2f %.2f l", xd, yd);
+ }
+ packb(buffer);
+ }
+
+ rgba = (unsigned int)ply[j++];
+ p->red[fl_color] = (rgba & 0xff) / 255.0;
+ p->green[fl_color] = ((rgba >> 8) & 0xff) / 255.0;
+ p->blue[fl_color] = ((rgba >> 16) & 0xff) / 255.0;
+
+ packb("cp gs");
+ set_color(-fl_color, p->wtype);
+ packb("fi gr");
+
+ sprintf(buffer, "%.4g %.4g %.4g sc", p->red[gkss->bcoli], p->green[gkss->bcoli], p->blue[gkss->bcoli]);
+ packb(buffer);
+ set_linewidth(gkss->bwidth);
+ packb("sk");
+ }
+}
+
static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
{
switch (primid)
@@ -1793,6 +1840,9 @@ static void gdp(int n, double *px, double *py, int primid, int nc, int *codes)
case GKS_K_GDP_DRAW_TRIANGLES:
draw_triangles(n, px, py, nc, codes);
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ fill_polygons(n, px, py, nc, codes);
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
diff --git a/lib/gks/quartz/GKSView.m b/lib/gks/quartz/GKSView.m
index 588435f5a..934b811a2 100644
--- a/lib/gks/quartz/GKSView.m
+++ b/lib/gks/quartz/GKSView.m
@@ -1837,10 +1837,10 @@ - (void)draw_markers:(int)n:(double *)px:(double *)py:(int *)attributes
- (void)draw_triangles:(int)n:(double *)px:(double *)py:(int)ntri:(int *)tri
{
- double x, y, xt[3], yt[3];
+ double x, y;
int i, j, k, rgba;
- CGFloat color[4];
CGPoint triangle[3];
+ CGFloat color[4];
begin_context(context);
@@ -1895,6 +1895,72 @@ - (void)draw_triangles:(int)n:(double *)px:(double *)py:(int)ntri:(int *)tri
}
+- (void)fill_polygons:(int)n:(double *)px:(double *)py:(int)nply:(int *)ply
+{
+ double x, y;
+ int i, j, k, len;
+ CGPoint polygon[6];
+ unsigned int rgba;
+ CGFloat *border_color, color[4];
+
+ begin_context(context);
+
+ if (colorSpace == NULL)
+ {
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+ }
+ CGContextSetStrokeColorSpace(context, colorSpace);
+ CGContextSetFillColorSpace(context, colorSpace);
+
+ CGContextSetLineWidth(context, gkss->bwidth * p->nominal_size);
+ border_color = CGColorGetComponents(p->rgb[gkss->bcoli]);
+
+ if (n > num_points)
+ {
+ while (n > num_points) num_points += NUM_POINTS;
+ points = (CGPoint *)gks_realloc(points, num_points * sizeof(CGPoint));
+ }
+
+ for (i = 0; i < n; ++i)
+ {
+ WC_to_NDC(px[i], py[i], gkss->cntnr, x, y);
+ seg_xform(&x, &y);
+ NDC_to_DC(x, y, points[i].x, points[i].y);
+ }
+
+ j = 0;
+ while (j < nply)
+ {
+ len = ply[j++];
+
+ CGContextBeginPath(context);
+ CGContextMoveToPoint(context, points[ply[j] - 1].x, points[ply[j] - 1].y);
+ j++;
+ for (k = 1; k < len; ++k)
+ {
+ CGContextAddLineToPoint(context, points[ply[j] - 1].x, points[ply[j] - 1].y);
+ j++;
+ }
+
+ CGContextSetLineJoin(context, kCGLineJoinRound);
+ CGContextSetLineWidth(context, gkss->bwidth * p->nominal_size);
+
+ rgba = (unsigned int)ply[j++];
+ color[0] = (rgba & 0xff) / 255.0;
+ color[1] = ((rgba >> 8) & 0xff) / 255.0;
+ color[2] = ((rgba >> 16) & 0xff) / 255.0;
+ color[3] = ((rgba >> 24) & 0xff) / 255.0;
+ CGContextSetStrokeColor(context, border_color);
+ CGContextSetFillColor(context, color);
+
+ CGContextClosePath(context);
+ CGContextDrawPath(context, kCGPathFillStroke);
+ }
+
+ end_context(context);
+}
+
+
- (void)gdp:(int)n:(double *)px:(double *)py:(int)primid:(int)nc:(int *)codes
{
switch (primid)
@@ -1911,6 +1977,9 @@ - (void)gdp:(int)n:(double *)px:(double *)py:(int)primid:(int)nc:(int *)codes
case GKS_K_GDP_DRAW_TRIANGLES:
[self draw_triangles:n:px:py:nc:codes];
break;
+ case GKS_K_GDP_FILL_POLYGONS:
+ [self fill_polygons:n:px:py:nc:codes];
+ break;
default:
gks_perror("invalid drawing primitive ('%d')", primid);
exit(1);
diff --git a/lib/gr/gr.c b/lib/gr/gr.c
index 312a96848..0c89001ca 100644
--- a/lib/gr/gr.c
+++ b/lib/gr/gr.c
@@ -1037,6 +1037,7 @@ static void apply_world_xform(double *x, double *y, double *z)
{
xw = wx.a1 * *x + wx.a2 * *y + wx.b;
yw = wx.c1 * *x + wx.c2 * *y + wx.c3 * *z + wx.d;
+ zw = wx.a2 * wx.c3 * *x - wx.a1 * wx.c3 * *y - wx.c1 * wx.a2 * *z + wx.a1 * wx.c2 * *z;
}
else
{
@@ -1086,6 +1087,7 @@ static void apply_world_xform(double *x, double *y, double *z)
*x = xw;
*y = yw;
+ *z = zw;
}
static void foreach_openws(void (*routine)(int, void *), void *arg)
@@ -10386,7 +10388,6 @@ static void drawimage_calculation(double xmin, double xmax, double ymin, double
*/
void gr_drawimage(double xmin, double xmax, double ymin, double ymax, int width, int height, int *data, int model)
{
- int *img = data;
int n;
check_autoinit;
@@ -12516,7 +12517,6 @@ static void ray_casting_thread(void *arg)
int algorithm = rc->algorithm;
double *data = rc->data, *pixels = rc->pixels;
double *dmax_ptr = rc->dmax_ptr, *dmin_ptr = rc->dmin_ptr;
- double *max_val = rc->max_val, *min_val = rc->min_val;
double eps = 1e-8; /* precision parameter for comparisons */
double x_spacing = 1. / nx;
@@ -13235,7 +13235,7 @@ void gr_cpubasedvolume(int nx, int ny, int nz, double *data, int algorithm, doub
}
double **ptr = &data;
- struct ray_casting_attr f[1] = {nx, ny, nz, algorithm, ptr[0], min_ptr, max_ptr, min_val, max_val, pixels};
+ struct ray_casting_attr f[1] = {{nx, ny, nz, algorithm, ptr[0], min_ptr, max_ptr, min_val, max_val, pixels}};
vt.ray_casting = f;
int x_start = 0, x_end = 0, y_start = 0, y_end = 0;
@@ -13333,7 +13333,6 @@ void gr_cpubasedvolume(int nx, int ny, int nz, double *data, int algorithm, doub
}
}
-
void gr_inqvpsize(int *width, int *height, double *device_pixel_ratio)
{
int n = 1, errind, wkid, ol;
@@ -13343,3 +13342,109 @@ void gr_inqvpsize(int *width, int *height, double *device_pixel_ratio)
gks_inq_open_ws(n, &errind, &ol, &wkid);
gks_inq_vp_size(wkid, &errind, width, height, device_pixel_ratio);
}
+
+static double mean(const double *a, const int len, const int *connections)
+{
+ double sum = 0;
+ int i;
+
+ for (i = 0; i < len; i++)
+ {
+ sum += a[connections[i] - 1];
+ }
+ return sum / len;
+}
+
+static int compare_depth(const void *_a, const void *_b)
+{
+ double a = *(double *)_a, b = *(double *)_b;
+ return a > b ? 1 : a < b ? -1 : 0;
+}
+
+void gr_polygonmesh3d(int num_points, const double *px, const double *py, const double *pz, int num_connections,
+ const int *connections, const int *colors)
+{
+ int i, j, k, len, maxlen = 0, len_connections;
+ double *x, *y, *z;
+ int *faces, *faceP, *attributes;
+ double cam_x, cam_y, cam_z, up_x, up_y, up_z, foc_x, foc_y, foc_z, depth;
+
+ x = (double *)xcalloc(num_points, sizeof(double));
+ y = (double *)xcalloc(num_points, sizeof(double));
+ z = (double *)xcalloc(num_points, sizeof(double));
+ for (i = 0; i < num_points; i++)
+ {
+ x[i] = px[i];
+ y[i] = py[i];
+ z[i] = pz[i];
+ gr_wc3towc(&x[i], &y[i], &z[i]);
+ }
+
+ j = 0;
+ for (i = 0; i < num_connections; i++)
+ {
+ len = connections[j++];
+ if (len > maxlen) maxlen = len;
+ j += len;
+ }
+ len_connections = j;
+
+ faces = (int *)xcalloc(num_connections, sizeof(double) + (1 + maxlen + 1) * sizeof(int));
+ gr_inqtransformationparameters(&cam_x, &cam_y, &cam_z, &up_x, &up_y, &up_z, &foc_x, &foc_y, &foc_z);
+
+ j = 0;
+ faceP = faces;
+ for (i = 0; i < num_connections; i++)
+ {
+ len = connections[j++];
+ depth = mean(z, len, connections + j);
+ memcpy(faceP, &depth, sizeof(double));
+ faceP += sizeof(double) / sizeof(int);
+ memcpy(faceP, &len, sizeof(int));
+ faceP += 1;
+ memcpy(faceP, connections + j, len * sizeof(int));
+ faceP += maxlen;
+ memcpy(faceP, &colors[i], sizeof(int));
+ faceP += 1;
+ j += len;
+ }
+ qsort(faces, num_connections, (sizeof(double) + (1 + maxlen + 1) * sizeof(int)), compare_depth);
+
+ attributes = (int *)xcalloc(num_connections, (1 + maxlen + 1) * sizeof(int));
+ k = 0;
+ faceP = faces;
+ for (i = 0; i < num_connections; i++)
+ {
+ faceP += sizeof(double) / sizeof(int);
+ len = attributes[k++] = *faceP;
+ faceP += 1;
+ for (j = 0; j < len; j++)
+ {
+ attributes[k++] = faceP[j];
+ }
+ faceP += maxlen;
+ attributes[k++] = *faceP;
+ faceP += 1;
+ }
+
+ gks_gdp(num_points, x, y, GKS_K_GDP_FILL_POLYGONS, k, attributes);
+
+ free(attributes);
+ free(faces);
+ free(z);
+ free(y);
+ free(x);
+
+ if (flag_graphics)
+ {
+ gr_writestream("\n");
+ }
+}
diff --git a/lib/gr/gr.h b/lib/gr/gr.h
index 40741d7fc..9d8fc6653 100644
--- a/lib/gr/gr.h
+++ b/lib/gr/gr.h
@@ -222,6 +222,7 @@ DLLEXPORT void gr_setapproximativecalculation(int);
DLLEXPORT void gr_inqvolumeflags(int *, int *, int *, int *, int *);
DLLEXPORT void gr_cpubasedvolume(int, int, int, double *, int, double *, double *, double *, double *);
DLLEXPORT void gr_inqvpsize(int *, int *, double *);
+DLLEXPORT void gr_polygonmesh3d(int, const double *, const double *, const double *, int, const int *, const int *);
#ifdef __cplusplus
}
diff --git a/lib/gr/import.c b/lib/gr/import.c
index 9b16a65c8..014cd7717 100644
--- a/lib/gr/import.c
+++ b/lib/gr/import.c
@@ -44,6 +44,7 @@ static char *format[] = {
"hexbin:iFFi",
"loadfont:s",
"mathtex:ffs",
+ "polygonmesh3d:iFFFiIiI",
"polyline:iFF",
"polyline3d:iFFF",
"polymarker:iFF",
@@ -112,7 +113,7 @@ static int nel = sizeof(format) / sizeof(format[0]);
static double f_arg[9], *f_arr[5];
-static int i_arg[6], *i_arr, i_arr_size, f_arr_size[4], v_arr_size, b_arr_size;
+static int i_arg[6], *i_arr[2], i_arr_size[2], f_arr_size[5], v_arr_size, b_arr_size;
static vertex_t *v_arr;
@@ -120,7 +121,7 @@ static unsigned char *b_arr;
static char *s_arg[3];
-static int i_argc, f_argc, s_argc, i_arrc, f_arrp, f_arrc, v_arrc, b_arrc;
+static int i_argc, f_argc, s_argc, i_arrc, i_arrp, f_arrp, f_arrc, v_arrc, b_arrc;
static char *xmalloc(int size)
{
@@ -176,7 +177,7 @@ static char *xml(char *s, char *fmt)
{
char *attr, *p;
- i_argc = i_arrc = 0;
+ i_argc = i_arrp = i_arrc = 0;
f_argc = f_arrp = f_arrc = 0;
v_arrc = 0;
b_arrc = 0;
@@ -213,14 +214,16 @@ static char *xml(char *s, char *fmt)
p = strtok(attr, " \t\"");
while (p != NULL)
{
- if (i_arrc >= i_arr_size)
+ if (i_arrc >= i_arr_size[i_arrp])
{
- i_arr_size += BUFFSIZE;
- i_arr = (int *)xrealloc(i_arr, sizeof(int) * i_arr_size);
+ i_arr_size[i_arrp] += BUFFSIZE;
+ i_arr[i_arrp] = (int *)xrealloc(i_arr[i_arrp], sizeof(int) * i_arr_size[i_arrp]);
}
- i_arr[i_arrc++] = atoi(p);
+ i_arr[i_arrp][i_arrc++] = atoi(p);
p = strtok(NULL, " \t\"");
}
+ i_arrp++;
+ i_arrc = 0;
break;
case 'F':
p = strtok(attr, " \t\"");
@@ -294,7 +297,7 @@ static void gr(int id)
break;
case 3:
gr_cellarray(f_arg[0], f_arg[1], f_arg[2], f_arg[3], i_arg[0], i_arg[1], i_arg[2], i_arg[3], i_arg[4], i_arg[5],
- i_arr);
+ i_arr[0]);
break;
case 4:
gr_colorbar();
@@ -318,7 +321,7 @@ static void gr(int id)
gr_drawarrow(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
case 11:
- gr_drawimage(f_arg[0], f_arg[1], f_arg[2], f_arg[3], i_arg[0], i_arg[1], i_arr, i_arg[2]);
+ gr_drawimage(f_arg[0], f_arg[1], f_arg[2], f_arg[3], i_arg[0], i_arg[1], i_arr[0], i_arg[2]);
break;
case 12:
gr_drawpath(i_arg[0], v_arr, b_arrc != 0 ? b_arr : NULL, i_arg[1]);
@@ -336,7 +339,7 @@ static void gr(int id)
gr_fillrect(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
case 17:
- gr_gdp(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arr);
+ gr_gdp(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arr[0]);
break;
case 18:
gr_grid(f_arg[0], f_arg[1], f_arg[2], f_arg[3], i_arg[0], i_arg[1]);
@@ -357,190 +360,193 @@ static void gr(int id)
gr_mathtex(f_arg[0], f_arg[1], s_arg[0]);
break;
case 24:
- gr_polyline(i_arg[0], f_arr[0], f_arr[1]);
+ gr_polygonmesh3d(i_arg[0], f_arr[0], f_arr[1], f_arr[2], i_arg[1], i_arr[0], i_arr[1]);
break;
case 25:
- gr_polyline3d(i_arg[0], f_arr[0], f_arr[1], f_arr[2]);
+ gr_polyline(i_arg[0], f_arr[0], f_arr[1]);
break;
case 26:
- gr_polymarker(i_arg[0], f_arr[0], f_arr[1]);
+ gr_polyline3d(i_arg[0], f_arr[0], f_arr[1], f_arr[2]);
break;
case 27:
- gr_quiver(i_arg[0], i_arg[1], f_arr[0], f_arr[1], f_arr[2], f_arr[3], i_arg[2]);
+ gr_polymarker(i_arg[0], f_arr[0], f_arr[1]);
break;
case 28:
- gr_restorestate();
+ gr_quiver(i_arg[0], i_arg[1], f_arr[0], f_arr[1], f_arr[2], f_arr[3], i_arg[2]);
break;
case 29:
- gr_savestate();
+ gr_restorestate();
break;
case 30:
- gr_selectclipxform(i_arg[0]);
+ gr_savestate();
break;
case 31:
- gr_selectcontext(i_arg[0]);
+ gr_selectclipxform(i_arg[0]);
break;
case 32:
- gr_selntran(i_arg[0]);
+ gr_selectcontext(i_arg[0]);
break;
case 33:
- gr_setapproximativecalculation(i_arg[0]);
+ gr_selntran(i_arg[0]);
break;
case 34:
- gr_setarrowsize(f_arg[0]);
+ gr_setapproximativecalculation(i_arg[0]);
break;
case 35:
- gr_setarrowstyle(i_arg[0]);
+ gr_setarrowsize(f_arg[0]);
break;
case 36:
- gr_setbordercolorind(i_arg[0]);
+ gr_setarrowstyle(i_arg[0]);
break;
case 37:
- gr_setborderwidth(f_arg[0]);
+ gr_setbordercolorind(i_arg[0]);
break;
case 38:
- gr_setcharexpan(f_arg[0]);
+ gr_setborderwidth(f_arg[0]);
break;
case 39:
- gr_setcharheight(f_arg[0]);
+ gr_setcharexpan(f_arg[0]);
break;
case 40:
- gr_setcharspace(f_arg[0]);
+ gr_setcharheight(f_arg[0]);
break;
case 41:
- gr_setcharup(f_arg[0], f_arg[1]);
+ gr_setcharspace(f_arg[0]);
break;
case 42:
- gr_setclip(i_arg[0]);
+ gr_setcharup(f_arg[0], f_arg[1]);
break;
case 43:
- gr_setcolormap(i_arg[0]);
+ gr_setclip(i_arg[0]);
break;
case 44:
- gr_setcolorrep(i_arg[0], f_arg[0], f_arg[1], f_arg[2]);
+ gr_setcolormap(i_arg[0]);
break;
case 45:
- gr_setfillcolorind(i_arg[0]);
+ gr_setcolorrep(i_arg[0], f_arg[0], f_arg[1], f_arg[2]);
break;
case 46:
- gr_setfillintstyle(i_arg[0]);
+ gr_setfillcolorind(i_arg[0]);
break;
case 47:
- gr_setfillstyle(i_arg[0]);
+ gr_setfillintstyle(i_arg[0]);
break;
case 48:
- gr_setlinecolorind(i_arg[0]);
+ gr_setfillstyle(i_arg[0]);
break;
case 49:
- gr_setlinetype(i_arg[0]);
+ gr_setlinecolorind(i_arg[0]);
break;
case 50:
- gr_setlinewidth(f_arg[0]);
+ gr_setlinetype(i_arg[0]);
break;
case 51:
- gr_setmarkercolorind(i_arg[0]);
+ gr_setlinewidth(f_arg[0]);
break;
case 52:
- gr_setmarkersize(f_arg[0]);
+ gr_setmarkercolorind(i_arg[0]);
break;
case 53:
- gr_setmarkertype(i_arg[0]);
+ gr_setmarkersize(f_arg[0]);
break;
case 54:
- gr_setorthographicprojection(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5]);
+ gr_setmarkertype(i_arg[0]);
break;
case 55:
- gr_setperspectiveprojection(f_arg[0], f_arg[1], f_arg[2]);
+ gr_setorthographicprojection(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5]);
break;
case 56:
- gr_setpicturesizeforvolume(i_arg[0], i_arg[1]);
+ gr_setperspectiveprojection(f_arg[0], f_arg[1], f_arg[2]);
break;
case 57:
- gr_setprojectiontype(i_arg[0]);
+ gr_setpicturesizeforvolume(i_arg[0], i_arg[1]);
break;
case 58:
- gr_setscale(i_arg[0]);
+ gr_setprojectiontype(i_arg[0]);
break;
case 59:
- gr_setscalefactors3d(f_arg[0], f_arg[1], f_arg[2]);
+ gr_setscale(i_arg[0]);
break;
case 60:
- gr_setspace(f_arg[0], f_arg[1], i_arg[0], i_arg[1]);
+ gr_setscalefactors3d(f_arg[0], f_arg[1], f_arg[2]);
break;
case 61:
- gr_settextalign(i_arg[0], i_arg[1]);
+ gr_setspace(f_arg[0], f_arg[1], i_arg[0], i_arg[1]);
break;
case 62:
- gr_settextcolorind(i_arg[0]);
+ gr_settextalign(i_arg[0], i_arg[1]);
break;
case 63:
- gr_settextencoding(i_arg[0]);
+ gr_settextcolorind(i_arg[0]);
break;
case 64:
- gr_settextfontprec(i_arg[0], i_arg[1]);
+ gr_settextencoding(i_arg[0]);
break;
case 65:
- gr_settextpath(i_arg[0]);
+ gr_settextfontprec(i_arg[0], i_arg[1]);
break;
case 66:
- gr_setthreadnumber(i_arg[0]);
+ gr_settextpath(i_arg[0]);
break;
case 67:
- gr_settransformationparameters(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5], f_arg[6], f_arg[7],
- f_arg[8]);
+ gr_setthreadnumber(i_arg[0]);
break;
case 68:
- gr_settransparency(f_arg[0]);
+ gr_settransformationparameters(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5], f_arg[6], f_arg[7],
+ f_arg[8]);
break;
case 69:
- gr_setviewport(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
+ gr_settransparency(f_arg[0]);
break;
case 70:
- gr_setvolumebordercalculation(i_arr[0]);
+ gr_setviewport(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
case 71:
- gr_setwindow(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
+ gr_setvolumebordercalculation(i_arg[0]);
break;
case 72:
- gr_setwindow3d(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5]);
+ gr_setwindow(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
case 73:
- gr_setwsviewport(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
+ gr_setwindow3d(f_arg[0], f_arg[1], f_arg[2], f_arg[3], f_arg[4], f_arg[5]);
break;
case 74:
- gr_setwswindow(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
+ gr_setwsviewport(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
case 75:
- gr_shadelines(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arg[3]);
+ gr_setwswindow(f_arg[0], f_arg[1], f_arg[2], f_arg[3]);
break;
case 76:
- gr_shadepoints(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arg[3]);
+ gr_shadelines(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arg[3]);
break;
case 77:
- gr_spline(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2]);
+ gr_shadepoints(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2], i_arg[3]);
break;
case 78:
- gr_surface(i_arg[0], i_arg[1], f_arr[0], f_arr[1], f_arr[2], i_arg[2]);
+ gr_spline(i_arg[0], f_arr[0], f_arr[1], i_arg[1], i_arg[2]);
break;
case 79:
- gr_text(f_arg[0], f_arg[1], s_arg[0]);
+ gr_surface(i_arg[0], i_arg[1], f_arr[0], f_arr[1], f_arr[2], i_arg[2]);
break;
case 80:
- gr_textext(f_arg[0], f_arg[1], s_arg[0]);
+ gr_text(f_arg[0], f_arg[1], s_arg[0]);
break;
case 81:
- gr_titles3d(s_arg[0], s_arg[1], s_arg[2]);
+ gr_textext(f_arg[0], f_arg[1], s_arg[0]);
break;
case 82:
- gr_tricontour(i_arg[0], f_arr[0], f_arr[1], f_arr[2], i_arg[2], f_arr[3]);
+ gr_titles3d(s_arg[0], s_arg[1], s_arg[2]);
break;
case 83:
- gr_trisurface(i_arg[0], f_arr[0], f_arr[1], f_arr[2]);
+ gr_tricontour(i_arg[0], f_arr[0], f_arr[1], f_arr[2], i_arg[2], f_arr[3]);
break;
case 84:
- gr_uselinespec(s_arg[0]);
+ gr_trisurface(i_arg[0], f_arr[0], f_arr[1], f_arr[2]);
break;
case 85:
+ gr_uselinespec(s_arg[0]);
+ break;
+ case 86:
gr_verrorbars(i_arg[0], f_arr[0], f_arr[1], f_arr[2], f_arr[3]);
break;
}
@@ -551,9 +557,12 @@ int gr_drawgraphics(char *string)
char *s = string, *el, *fmt;
int i, id;
- i_arr = (int *)xmalloc(sizeof(int) * BUFFSIZE);
- i_arr_size = BUFFSIZE;
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 2; i++)
+ {
+ i_arr[i] = (int *)xmalloc(sizeof(int) * BUFFSIZE);
+ i_arr_size[i] = BUFFSIZE;
+ }
+ for (i = 0; i < 5; i++)
{
f_arr[i] = (double *)xmalloc(sizeof(double) * BUFFSIZE);
f_arr_size[i] = BUFFSIZE;
@@ -589,8 +598,8 @@ int gr_drawgraphics(char *string)
free(b_arr);
free(v_arr);
- for (i = 0; i < 4; i++) free(f_arr[i]);
- free(i_arr);
+ for (i = 0; i < 5; i++) free(f_arr[i]);
+ for (i = 0; i < 2; i++) free(i_arr[i]);
return 0;
}
diff --git a/lib/gr/mathtex2_kerning.c b/lib/gr/mathtex2_kerning.c
index 370327310..99973e03d 100644
--- a/lib/gr/mathtex2_kerning.c
+++ b/lib/gr/mathtex2_kerning.c
@@ -73,6 +73,16 @@ double gr_get_kerning_offset(unsigned int left_codepoint, unsigned int right_cod
static int get_index(unsigned int codepoint)
{
+ /* kerning offsets can be disabled for codepoints by adding them here */
+ switch (codepoint)
+ {
+ case '.':
+ case ',':
+ case ';':
+ case '!':
+ return -1;
+ }
+
switch (codepoint)
{
case 35: