diff --git a/.clang-format b/.clang-format index bec747a96..ee882bd2d 100644 --- a/.clang-format +++ b/.clang-format @@ -18,6 +18,7 @@ BraceWrapping: AfterExternBlock: false BeforeCatch: true BeforeElse: true + BeforeWhile: true IndentBraces: true SplitEmptyFunction: true SplitEmptyRecord: true diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index cb0d754ea..de7dd26a6 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -9,3 +9,5 @@ 97151f7590c1c2e7893e6e3282cb01e8c1c62e7b # Commit which applied updated coding style guidelines for `extern "C"` blocks e9e9f129c8a87161b9727a5b94d3414d0e33a47c +# Commit which applied new code formatting by upgrading to `clang-format` 13 +c9a848ed891ef494e2251fb289824d04cab4ed66 diff --git a/.githooks/pre-commit b/.githooks/pre-commit index 46be32a63..30ffb9714 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -1,7 +1,7 @@ #!/bin/bash EXCLUDED_ROOT_DIRECTORIES=( "3rdparty" "apps" ) -PREFERRED_CLANG_FORMAT_VERSION="9" +PREFERRED_CLANG_FORMAT_VERSION="13" is_in_excluded_directory () { local file directory diff --git a/3rdparty/libpng16/Makefile b/3rdparty/libpng16/Makefile index 2122258f3..0e3ec1a2b 100644 --- a/3rdparty/libpng16/Makefile +++ b/3rdparty/libpng16/Makefile @@ -10,6 +10,9 @@ ifeq ($(shell arch),arm64) PNGCFLAGS += -DPNG_ARM_NEON_OPT=0 endif endif +endif +ifeq ($(shell arch),aarch64) +PNGCFLAGS += -DPNG_ARM_NEON_OPT=0 endif OBJS = \ png.o \ diff --git a/Makefile b/Makefile index ea625b625..be9e1c871 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ PKGCONFIGDIR = $(LIBDIR)/pkgconfig UNAME := $(shell uname) -PREFERRED_CLANG_FORMAT_VERSION="9" +PREFERRED_CLANG_FORMAT_VERSION="13" ifeq ($(shell command -v "clang-format-$(PREFERRED_CLANG_FORMAT_VERSION)"),) CLANG_FORMAT="clang-format" else diff --git a/js/api.js b/js/api.js index 10b8ae88a..9ae5893c0 100644 --- a/js/api.js +++ b/js/api.js @@ -532,12 +532,14 @@ gr_text = function(x, y, string) { gr_inqtext_c = Module.cwrap('gr_inqtext', '', ['number', 'number', 'number', 'number', 'number', ]); gr_inqtext = function(x, y, string) { var _string = uint8array(string); - var _tbx = Module._malloc(8); - var _tby = Module._malloc(8); + var _tbx = Module._malloc(8*4); + var _tby = Module._malloc(8*4); gr_inqtext_c(x, y, _string, _tbx, _tby); var result = new Array(2); - result[0] = Module.HEAPF64.subarray(_tbx / 8, _tbx / 8 + 1)[0]; - result[1] = Module.HEAPF64.subarray(_tby / 8, _tby / 8 + 1)[0]; + result[0] = Module.HEAPF64.subarray(_tbx / 8, _tbx / 8 + 4); + result[0] = Array.prototype.slice.call(result[0]); + result[1] = Module.HEAPF64.subarray(_tby / 8, _tby / 8 + 4); + result[1] = Array.prototype.slice.call(result[1]); freearray(_string); freearray(_tbx); freearray(_tby); diff --git a/lib/gks/dl.c b/lib/gks/dl.c index ac94fc016..29eeb1116 100644 --- a/lib/gks/dl.c +++ b/lib/gks/dl.c @@ -90,7 +90,7 @@ void gks_dl_write_item(gks_display_list_t *d, int fctid, int dx, int dy, int dim double *f_arr_1, int len_f_arr_2, double *f_arr_2, int len_c_arr, char *c_arr, gks_state_list_t *gkss) { - char s[132], *t = NULL; + char s[GKS_K_TEXT_MAX_SIZE], *t = NULL; int len = -1, slen, tp = 0; GKS_UNUSED(len_f_arr_1); @@ -169,19 +169,19 @@ void gks_dl_write_item(gks_display_list_t *d, int fctid, int dx, int dy, int dim if (d->state == GKS_K_WS_ACTIVE) { - len = 3 * sizeof(int) + 2 * sizeof(double) + 132; + len = 3 * sizeof(int) + 2 * sizeof(double) + GKS_K_TEXT_MAX_SIZE; if (d->nbytes + len > d->size) reallocate(d, len); - memset((void *)s, 0, 132); + memset((void *)s, 0, GKS_K_TEXT_MAX_SIZE); slen = strlen(c_arr); - memcpy(s, c_arr, slen < 132 ? slen : 131); + memcpy(s, c_arr, slen < GKS_K_TEXT_MAX_SIZE ? slen : GKS_K_TEXT_MAX_SIZE - 1); COPY(&len, sizeof(int)); COPY(&fctid, sizeof(int)); COPY(f_arr_1, sizeof(double)); COPY(f_arr_2, sizeof(double)); COPY(&slen, sizeof(int)); - COPY(s, 132); + COPY(s, GKS_K_TEXT_MAX_SIZE); d->empty = 0; } diff --git a/lib/gks/gks.c b/lib/gks/gks.c index f5780bf32..61bfb3231 100644 --- a/lib/gks/gks.c +++ b/lib/gks/gks.c @@ -1169,13 +1169,14 @@ void gks_text(double px, double py, char *str) /* ignore empty strings */ return; } - else if (strlen(str) < 132) + else if (strlen(str) < GKS_K_TEXT_MAX_SIZE) { if (s->txprec != GKS_K_TEXT_PRECISION_OUTLINE) { - /* double the string length as the longest utf8 representation of any latin1 character is two bytes long + /* double the output string size as the longest utf8 representation of any latin1 character is two bytes + * long */ - char utf8_str[2 * 131 + 1]; + char utf8_str[2 * (GKS_K_TEXT_MAX_SIZE - 1) + 1]; gks_input2utf8(str, utf8_str, s->input_encoding); f_arr_1[0] = px; diff --git a/lib/gks/gks.h b/lib/gks/gks.h index 476058677..538918a56 100644 --- a/lib/gks/gks.h +++ b/lib/gks/gks.h @@ -123,6 +123,10 @@ extern "C" { #define GKS_K_TEXT_PRECISION_STROKE 2 #define GKS_K_TEXT_PRECISION_OUTLINE 3 +/* maximum text size */ + +#define GKS_K_TEXT_MAX_SIZE 500 + /* workstation category */ #define GKS_K_WSCAT_OUTPUT 0 diff --git a/lib/gks/mf.c b/lib/gks/mf.c index 55b302d92..12ba898dc 100644 --- a/lib/gks/mf.c +++ b/lib/gks/mf.c @@ -55,7 +55,7 @@ static void reallocate(int len) static void write_item(int fctid, int dx, int dy, int dimx, int *i_arr, int len_farr_1, double *f_arr_1, int len_farr_2, double *f_arr_2, int len_c_arr, char *c_arr) { - char s[132]; + char s[GKS_K_TEXT_MAX_SIZE]; int len = -1, slen, tp; GKS_UNUSED(len_farr_1); GKS_UNUSED(len_farr_2); @@ -79,19 +79,19 @@ static void write_item(int fctid, int dx, int dy, int dimx, int *i_arr, int len_ case 14: /* text */ - len = 3 * sizeof(int) + 2 * sizeof(double) + 132; + len = 3 * sizeof(int) + 2 * sizeof(double) + GKS_K_TEXT_MAX_SIZE; if (p->nbytes + len > p->size) reallocate(len); - memset((void *)s, 0, 132); + memset((void *)s, 0, GKS_K_TEXT_MAX_SIZE); slen = strlen(c_arr); - memcpy(s, c_arr, slen < 132 ? slen : 131); + memcpy(s, c_arr, slen < GKS_K_TEXT_MAX_SIZE ? slen : GKS_K_TEXT_MAX_SIZE - 1); COPY(&len, sizeof(int)); COPY(&fctid, sizeof(int)); COPY(f_arr_1, sizeof(double)); COPY(f_arr_2, sizeof(double)); COPY(&slen, sizeof(int)); - COPY(s, 132); + COPY(s, GKS_K_TEXT_MAX_SIZE); break; case 16: /* cell array */ @@ -505,7 +505,7 @@ static void interp(char *str) RESOLVE(f_arr_1, double, sizeof(double)); RESOLVE(f_arr_2, double, sizeof(double)); RESOLVE(len_c_arr, int, sizeof(int)); - RESOLVE(c_arr, char, 132); + RESOLVE(c_arr, char, GKS_K_TEXT_MAX_SIZE); break; case 16: /* cell array */ diff --git a/lib/gks/plugin/glplugin.c b/lib/gks/plugin/glplugin.c index df5a2f344..408c6fd8c 100644 --- a/lib/gks/plugin/glplugin.c +++ b/lib/gks/plugin/glplugin.c @@ -871,7 +871,7 @@ static void interp(char *str) RESOLVE(f_arr_1, double, sizeof(double)); RESOLVE(f_arr_2, double, sizeof(double)); RESOLVE(len_c_arr, int, sizeof(int)); - RESOLVE(c_arr, char, 132); + RESOLVE(c_arr, char, GKS_K_TEXT_MAX_SIZE); /* dummy assignment to avoid warning 'set but not used' */ *len_c_arr = *len_c_arr; break; diff --git a/lib/gks/plugin/qtplugin_impl.cxx b/lib/gks/plugin/qtplugin_impl.cxx index 781380a52..e0f87dd60 100644 --- a/lib/gks/plugin/qtplugin_impl.cxx +++ b/lib/gks/plugin/qtplugin_impl.cxx @@ -1286,7 +1286,7 @@ static void interp(char *str) RESOLVE(f_arr_1, double, sizeof(double)); RESOLVE(f_arr_2, double, sizeof(double)); RESOLVE(len_c_arr, int, sizeof(int)); - RESOLVE(c_arr, char, 132); + RESOLVE(c_arr, char, GKS_K_TEXT_MAX_SIZE); break; case 16: /* cell array */ diff --git a/lib/gks/plugin/wxplugin.cxx b/lib/gks/plugin/wxplugin.cxx index ffb7b2c62..6c6bbcc95 100644 --- a/lib/gks/plugin/wxplugin.cxx +++ b/lib/gks/plugin/wxplugin.cxx @@ -856,7 +856,7 @@ static void interp(char *str) RESOLVE(f_arr_1, double, sizeof(double)); RESOLVE(f_arr_2, double, sizeof(double)); RESOLVE(len_c_arr, int, sizeof(int)); - RESOLVE(c_arr, char, 132); + RESOLVE(c_arr, char, GKS_K_TEXT_MAX_SIZE); /* dummy assignment to avoid warning 'set but not used' */ *len_c_arr = *len_c_arr; break; diff --git a/lib/gks/plugin/x11plugin.c b/lib/gks/plugin/x11plugin.c index 5c521d6ad..0ccb93f21 100644 --- a/lib/gks/plugin/x11plugin.c +++ b/lib/gks/plugin/x11plugin.c @@ -1498,8 +1498,7 @@ static void wait_for_expose(void) if (p->new_win) { - do - XWindowEvent(p->dpy, p->win, StructureNotifyMask, &event); + do XWindowEvent(p->dpy, p->win, StructureNotifyMask, &event); while (event.xany.type != MapNotify && event.xany.type != ConfigureNotify); while (XCheckTypedWindowEvent(p->dpy, p->win, Expose, &event)) ; diff --git a/lib/gks/quartz/GKSView.m b/lib/gks/quartz/GKSView.m index 68e69067d..05ce7179d 100644 --- a/lib/gks/quartz/GKSView.m +++ b/lib/gks/quartz/GKSView.m @@ -287,7 +287,7 @@ - (void)interp:(char *)str RESOLVE(f_arr_1, double, sizeof(double)); RESOLVE(f_arr_2, double, sizeof(double)); RESOLVE(len_c_arr, int, sizeof(int)); - RESOLVE(c_arr, char, 132); + RESOLVE(c_arr, char, GKS_K_TEXT_MAX_SIZE); break; case 16: /* cell array */ diff --git a/lib/gks/wiss.c b/lib/gks/wiss.c index d19f51316..57fd516bf 100644 --- a/lib/gks/wiss.c +++ b/lib/gks/wiss.c @@ -74,7 +74,7 @@ int cksum(void) static void write_item(int sgnum, int fctid, int dx, int dy, int dimx, int *i_arr, int len_farr_1, double *f_arr_1, int len_farr_2, double *f_arr_2, int len_c_arr, char *c_arr) { - char s[132]; + char s[GKS_K_TEXT_MAX_SIZE]; int len = -1, slen, tp = 0; GKS_UNUSED(len_farr_1); GKS_UNUSED(len_farr_2); @@ -99,12 +99,12 @@ static void write_item(int sgnum, int fctid, int dx, int dy, int dimx, int *i_ar case 14: /* text */ - len = 4 * sizeof(int) + 2 * sizeof(double) + 132; + len = 4 * sizeof(int) + 2 * sizeof(double) + GKS_K_TEXT_MAX_SIZE; if (p->nbytes + len > p->size) reallocate(len); - memset((void *)s, 0, 132); + memset((void *)s, 0, GKS_K_TEXT_MAX_SIZE); slen = strlen(c_arr); - memcpy(s, c_arr, slen < 132 ? slen : 131); + memcpy(s, c_arr, slen < GKS_K_TEXT_MAX_SIZE ? slen : GKS_K_TEXT_MAX_SIZE - 1); COPY(&len, sizeof(int)); COPY(&sgnum, sizeof(int)); @@ -112,7 +112,7 @@ static void write_item(int sgnum, int fctid, int dx, int dy, int dimx, int *i_ar COPY(f_arr_1, sizeof(double)); COPY(f_arr_2, sizeof(double)); COPY(&slen, sizeof(int)); - COPY(s, 132); + COPY(s, GKS_K_TEXT_MAX_SIZE); break; case 16: /* cell array */ @@ -488,7 +488,7 @@ static void interp(char *str, int segn) RESOLVE(f_arr_1, double, sizeof(double)); RESOLVE(f_arr_2, double, sizeof(double)); RESOLVE(len_c_arr, int, sizeof(int)); - RESOLVE(c_arr, char, 132); + RESOLVE(c_arr, char, GKS_K_TEXT_MAX_SIZE); break; case 16: /* cell array */ diff --git a/lib/gr3/gr3.c b/lib/gr3/gr3.c index a42bbf799..1b3ee45a2 100644 --- a/lib/gr3/gr3.c +++ b/lib/gr3/gr3.c @@ -71,14 +71,14 @@ const char *gr3_error_file_ = ""; { \ GR3_InitStruct_INITIALIZER, 0, 0, 0, NULL, 0, NULL, not_initialized_, NULL, NULL, 0, 0, {{0}}, 0, 0, 0, NAN, NAN, \ NAN, NAN, 0, 0, 0, 0, 0, {0, 0, 0, 1}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, 4, 0, {0}, {0}, {0}, \ - {0}, 0, 0, 0, 0, {0}, {0.2, 0.8, 128, 0.7}, NAN, NAN, NAN, NAN, NAN, NAN \ + {0}, 0, 0, 0, 0, {0}, {0.2, 0.8, 128, 0.7}, 1, NAN, NAN, NAN, NAN, NAN, NAN \ } #else #define GR3_ContextStruct_INITIALIZER \ { \ GR3_InitStruct_INITIALIZER, 0, 0, 0, NULL, 0, NULL, not_initialized_, NULL, NULL, 0, 0, {{0}}, 0, 0, 0, NAN, NAN, \ NAN, NAN, 0, 0, 0, 0, 0, {0, 0, 0, 1}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0, 0, 0, 0, -1, 0, {0}, {0}, {0}, \ - 0, 0, 0, {0}, {0.2, 0.8, 128, 0.7}, NAN, NAN, NAN, NAN, NAN, NAN \ + 0, 0, 0, {0}, {0.2, 0.8, 128, 0.7}, 1, NAN, NAN, NAN, NAN, NAN, NAN \ } #endif GR3_ContextStruct_t_ context_struct_ = GR3_ContextStruct_INITIALIZER; @@ -1801,6 +1801,10 @@ GR3API int gr3_drawimage(float xmin, float xmax, float ymin, float ymax, int wid switch (drawable_type) { case GR3_DRAWABLE_OPENGL: + if (context_struct_.use_software_renderer == 1) + { + RETURN_ERROR(GR3_ERROR_INVALID_VALUE); + } return gr3_drawimage_opengl_(xmin, xmax, ymin, ymax, width, height); case GR3_DRAWABLE_GKS: return gr3_drawimage_gks_(xmin, xmax, ymin, ymax, width, height); @@ -2896,6 +2900,7 @@ void gr3_setlightparameters(float ambient, float diffuse, float specular, float context_struct_.light_parameters.diffuse = diffuse; context_struct_.light_parameters.specular = specular; context_struct_.light_parameters.specular_exponent = specular_power; + context_struct_.use_default_light_parameters = 0; } void gr3_getlightparameters(float *ambient, float *diffuse, float *specular, float *specular_power) @@ -2926,6 +2931,7 @@ void gr3_setdefaultlightparameters() context_struct_.light_parameters.diffuse = 0.8; context_struct_.light_parameters.specular_exponent = 128; context_struct_.light_parameters.specular = 0.7; + context_struct_.use_default_light_parameters = 1; } GR3API void gr3_setclipping(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax) diff --git a/lib/gr3/gr3_gr.c b/lib/gr3/gr3_gr.c index f9d5beeed..231a50722 100644 --- a/lib/gr3/gr3_gr.c +++ b/lib/gr3/gr3_gr.c @@ -467,39 +467,48 @@ GR3API int gr3_createsurfacemesh(int *mesh, int nx, int ny, float *px, float *py int k = j * nx + i; float *v = vertices + 3 * k; float *n = normals + 3 * k; - float dx, dy; + float a[3]; + float b[3]; if (i == 0) { - dx = (v[dirx + 1] - v[1]) / (v[dirx + 0] - v[0]); + a[0] = v[dirx + 0] - v[0]; + a[1] = v[dirx + 1] - v[1]; + a[2] = v[dirx + 2] - v[2]; } else if (i == nx - 1) { - dx = (v[1] - v[-dirx + 1]) / (v[0] - v[-dirx + 0]); + a[0] = v[0] - v[0 - dirx]; + a[1] = v[1] - v[1 - dirx]; + a[2] = v[2] - v[2 - dirx]; } else { - dx = ((v[1] - v[-dirx + 1]) / (v[0] - v[-dirx + 0]) + (v[dirx + 1] - v[1]) / (v[dirx + 0] - v[0])) / - 2.0f; + a[0] = (v[dirx + 0] - v[0 - dirx]) * 0.5; + a[1] = (v[dirx + 1] - v[1 - dirx]) * 0.5; + a[2] = (v[dirx + 2] - v[2 - dirx]) * 0.5; } if (j == 0) { - dy = (v[diry + 1] - v[1]) / (v[diry + 2] - v[2]); + b[0] = v[diry + 0] - v[0]; + b[1] = v[diry + 1] - v[1]; + b[2] = v[diry + 2] - v[2]; } else if (j == ny - 1) { - dy = (v[1] - v[-diry + 1]) / (v[2] - v[-diry + 2]); + b[0] = v[0] - v[0 - diry]; + b[1] = v[1] - v[1 - diry]; + b[2] = v[2] - v[2 - diry]; } else { - dy = ((v[1] - v[-diry + 1]) / (v[2] - v[-diry + 2]) + (v[diry + 1] - v[1]) / (v[diry + 2] - v[2])) / - 2.0f; + b[0] = (v[diry + 0] - v[0 - diry]) * 0.5; + b[1] = (v[diry + 1] - v[1 - diry]) * 0.5; + b[2] = (v[diry + 2] - v[2 - diry]) * 0.5; } - n[0] = -dx; - n[1] = 1.0f; - n[2] = -dy; + gr3_crossprod_(n, a, b); gr3_normalize_(n); } } @@ -669,14 +678,12 @@ GR3API void gr3_drawmesh_grlike(int mesh, int n, const float *positions, const f int i, j; int projection_type; gr_inqprojectiontype(&projection_type); - if (projection_type == GR_PROJECTION_DEFAULT) { gr3_setprojectiontype(GR3_PROJECTION_PARALLEL); if (gr3_geterror(0, NULL, NULL)) return; gr3_setcameraprojectionparameters(90.0f, 1.0f, 200.0f); if (gr3_geterror(0, NULL, NULL)) return; - gr3_setlightdirection(0.0f, -1.0f, 0.0f); } else if (projection_type == GR_PROJECTION_PERSPECTIVE || projection_type == GR_PROJECTION_ORTHOGRAPHIC) { @@ -698,7 +705,6 @@ GR3API void gr3_drawmesh_grlike(int mesh, int n, const float *positions, const f (GLfloat)zfar); } if (gr3_geterror(0, NULL, NULL)) return; - gr3_setlightdirection(-ups[0], -ups[1], -ups[2]); } if (gr3_geterror(0, NULL, NULL)) return; @@ -823,6 +829,10 @@ GR3API void gr3_surface(int nx, int ny, float *px, float *py, float *pz, int opt int previous_option = context_struct_.option; context_struct_.option = option; surfaceoption = GR3_SURFACE_GRTRANSFORM; + if (option == OPTION_Z_SHADED_MESH || option == OPTION_COLORED_MESH) + { + surfaceoption |= GR3_SURFACE_NORMALS; + } if (option == OPTION_Z_SHADED_MESH) { surfaceoption |= GR3_SURFACE_GRZSHADED; @@ -864,6 +874,11 @@ GR3API void gr3_surface(int nx, int ny, float *px, float *py, float *pz, int opt height *= device_pixel_ratio; gr_inqviewport(&vpxmin, &vpxmax, &vpymin, &vpymax); aspect = fabs((vpxmax - vpxmin) / (vpymax - vpymin)); + if (context_struct_.use_default_light_parameters) + { + gr3_setlightparameters(0.8, 0.2, 0.1, 10.0); + context_struct_.use_default_light_parameters = 1; + } gr_inqprojectiontype(&projection_type); if (projection_type == GR_PROJECTION_DEFAULT) { @@ -885,6 +900,10 @@ GR3API void gr3_surface(int nx, int ny, float *px, float *py, float *pz, int opt } context_struct_.option = previous_option; context_struct_.aspect_override = 0; + if (context_struct_.use_default_light_parameters) + { + gr3_setdefaultlightparameters(); + } if (gr3_geterror(0, NULL, NULL)) return; } else @@ -1034,13 +1053,47 @@ GR3API int gr3_createsurface3dmesh(int *mesh, int ncols, int nrows, float *px, f vertices[offset + k * 3 + 1] = gr3_transform_(z, tz); vertices[offset + k * 3 + 2] = gr3_transform_(y, ty); } - normals[offset + k * 3 + 0] = 0; - normals[offset + k * 3 + 1] = 1; - normals[offset + k * 3 + 2] = 0; colors[offset + k * 3 + 0] = red; colors[offset + k * 3 + 1] = green; colors[offset + k * 3 + 2] = blue; } + { + float normal[3]; + int corner_indices[4][3] = {{0, 1, 2}, {2, 0, 5}, {1, 5, 0}, {5, 2, 1}}; + for (k = 0; k < 4; k++) + { + float corner_normal[3]; + float a[3]; + float b[3]; + a[0] = + vertices[offset + corner_indices[k][1] * 3 + 0] - vertices[offset + corner_indices[k][0] * 3 + 0]; + a[1] = + vertices[offset + corner_indices[k][1] * 3 + 1] - vertices[offset + corner_indices[k][0] * 3 + 1]; + a[2] = + vertices[offset + corner_indices[k][1] * 3 + 2] - vertices[offset + corner_indices[k][0] * 3 + 2]; + b[0] = + vertices[offset + corner_indices[k][2] * 3 + 0] - vertices[offset + corner_indices[k][0] * 3 + 0]; + b[1] = + vertices[offset + corner_indices[k][2] * 3 + 1] - vertices[offset + corner_indices[k][0] * 3 + 1]; + b[2] = + vertices[offset + corner_indices[k][2] * 3 + 2] - vertices[offset + corner_indices[k][0] * 3 + 2]; + gr3_normalize_(a); + gr3_normalize_(b); + gr3_crossprod_(corner_normal, a, b); + gr3_normalize_(corner_normal); + normal[0] += corner_normal[0]; + normal[1] += corner_normal[1]; + normal[2] += corner_normal[2]; + } + gr3_normalize_(normal); + for (k = 0; k < 6; k++) + { + + normals[offset + k * 3 + 0] = normal[0]; + normals[offset + k * 3 + 1] = normal[1]; + normals[offset + k * 3 + 2] = normal[2]; + } + } } } result = gr3_createmesh(mesh, num_vertices, vertices, normals, colors); @@ -1109,14 +1162,27 @@ GR3API void gr3_drawtrianglesurface(int n, const float *positions) assert(colors); for (i = 0; i < n; i++) { + float normal[3]; + float a[3]; + float b[3]; + a[0] = positions[(i * 3 + 1) * 3 + 0] - positions[(i * 3 + 0) * 3 + 0]; + a[1] = positions[(i * 3 + 1) * 3 + 1] - positions[(i * 3 + 0) * 3 + 1]; + a[2] = positions[(i * 3 + 1) * 3 + 2] - positions[(i * 3 + 0) * 3 + 2]; + b[0] = positions[(i * 3 + 2) * 3 + 0] - positions[(i * 3 + 0) * 3 + 0]; + b[1] = positions[(i * 3 + 2) * 3 + 1] - positions[(i * 3 + 0) * 3 + 1]; + b[2] = positions[(i * 3 + 2) * 3 + 2] - positions[(i * 3 + 0) * 3 + 2]; + gr3_normalize_(a); + gr3_normalize_(b); + gr3_crossprod_(normal, a, b); + gr3_normalize_(normal); for (j = 0; j < 3; j++) { int color; int rgb; /* light direction in gr3_drawmesh_grlike() is fixed to (0, 1, 0) */ - normals[(i * 3 + j) * 3 + 0] = 0; - normals[(i * 3 + j) * 3 + 1] = 1; - normals[(i * 3 + j) * 3 + 2] = 0; + normals[(i * 3 + j) * 3 + 0] = normal[0]; + normals[(i * 3 + j) * 3 + 1] = normal[1]; + normals[(i * 3 + j) * 3 + 2] = normal[2]; color = 1000 + 255 * (positions[(i * 3 + j) * 3 + 2] - z_min) / (z_max - z_min); gr_inqcolor(color, &rgb); colors[(i * 3 + j) * 3 + 0] = (float)(rgb & 0xff) / 255; @@ -1153,9 +1219,18 @@ GR3API void gr3_drawtrianglesurface(int n, const float *positions) gr_inqvpsize(&width, &height, &device_pixel_ratio); width *= device_pixel_ratio; height *= device_pixel_ratio; + if (context_struct_.use_default_light_parameters) + { + gr3_setlightparameters(0.8, 0.2, 0.1, 10.0); + context_struct_.use_default_light_parameters = 1; + } gr3_drawimage((float)window.x_min, (float)window.x_max, (float)window.y_min, (float)window.y_max, width, height, GR3_DRAWABLE_GKS); + if (context_struct_.use_default_light_parameters) + { + gr3_setdefaultlightparameters(); + } if (gr3_geterror(0, NULL, NULL)) return; } diff --git a/lib/gr3/gr3_internals.h b/lib/gr3/gr3_internals.h index 610411034..5c5bb44f9 100644 --- a/lib/gr3/gr3_internals.h +++ b/lib/gr3/gr3_internals.h @@ -295,6 +295,7 @@ typedef struct _GR3_ContextStruct_t_ int num_lights; GR3_LightSource_t_ light_sources[MAX_NUM_LIGHTS]; GR3_LightParameter_t_ light_parameters; + int use_default_light_parameters; float clip_xmin; float clip_xmax; float clip_ymin; diff --git a/lib/grm/plot.c b/lib/grm/plot.c index 80f71c6cb..d1681d432 100644 --- a/lib/grm/plot.c +++ b/lib/grm/plot.c @@ -1117,7 +1117,7 @@ static void legend_size(grm_args_t *subplot_args, double *w, double *h) for (current_label = labels; *current_label != NULL; ++current_label) { gr_inqtext(0, 0, *(char **)current_label, tbx, tby); - *w = max(*w, tbx[2]); + *w = max(*w, tbx[2] - tbx[0]); *h += max(tby[2] - tby[0], 0.03); } } @@ -2354,6 +2354,8 @@ error_t plot_barplot(grm_args_t *subplot_args) grm_args_t **inner_series; unsigned int inner_series_length; + gr_savestate(); + /* Default */ int bar_color = 989, edge_color = 1; double bar_color_rgb[3] = {-1}; @@ -2761,6 +2763,8 @@ error_t plot_barplot(grm_args_t *subplot_args) pos_vertical_change = 0; neg_vertical_change = 0; + double width, height, available_width, available_height, x_text, y_text; + double tbx[4], tby[4]; /* Draw ylabels */ if (ylabels != NULL) { @@ -2801,9 +2805,12 @@ error_t plot_barplot(grm_args_t *subplot_args) if (ylabels_left > 0) { - x1 = (x1 + x2) / 2; - x2 = (y1 + y2) / 2; - gr_wctondc(&x1, &x2); + gr_wctondc(&x1, &y1); + gr_wctondc(&x2, &y2); + available_width = x2 - x1; + available_height = y2 - y1; + x_text = (x1 + x2) / 2; + y_text = (y1 + y2) / 2; if (y_lightness[i] < 0.4) { gr_settextcolorind(0); @@ -2812,7 +2819,28 @@ error_t plot_barplot(grm_args_t *subplot_args) { gr_settextcolorind(1); } - gr_text(x1, x2, ylabels[i]); + gr_settextalign(2, 3); + gr_setcharup(0.0, 1.0); + gr_inqtextext(x_text, y_text, ylabels[i], tbx, tby); + logger((stderr, "ylabel: \"%s\", textext_x: (%lf, %lf, %lf, %lf), textext_y: (%lf, %lf, %lf, %lf)\n", + ylabels[i], tbx[0], tbx[1], tbx[2], tbx[3], tby[0], tby[1], tby[2], tby[3])); + gr_wctondc(&tbx[0], &tby[0]); + gr_wctondc(&tbx[2], &tby[2]); + width = tbx[2] - tbx[0]; + height = tby[2] - tby[0]; + logger((stderr, "width: %lf, available_width: %lf\n", width, available_width)); + logger((stderr, "height: %lf, available_height: %lf\n", height, available_height)); + if (width < available_width && height < available_height) + { + gr_setcharup(0.0, 1.0); + gr_text(x_text, y_text, ylabels[i]); + } + else if (height < available_width && width < available_height) + { + gr_setcharup(-1.0, 0.0); + gr_text(x_text, y_text, ylabels[i]); + gr_setcharup(0.0, 1.0); + } --ylabels_left; } } @@ -2975,8 +3003,12 @@ error_t plot_barplot(grm_args_t *subplot_args) if (ylabels_left > 0) { - x1 = (x1 + x2) / 2; - x2 = (y1 + y2) / 2; + gr_wctondc(&x1, &y1); + gr_wctondc(&x2, &y2); + available_width = x2 - x1; + available_height = y2 - y1; + x_text = (x1 + x2) / 2; + y_text = (y1 + y2) / 2; gr_wctondc(&x1, &x2); if (y_lightness[ylabels_length - ylabels_left] < 0.4) { @@ -2986,7 +3018,30 @@ error_t plot_barplot(grm_args_t *subplot_args) { gr_settextcolorind(1); } - gr_text(x1, x2, ylabels[ylabels_length - ylabels_left]); + gr_settextalign(2, 3); + gr_setcharup(0.0, 1.0); + gr_inqtextext(x_text, y_text, ylabels[ylabels_length - ylabels_left], tbx, tby); + logger((stderr, + "ylabel: \"%s\", textext_x: (%lf, %lf, %lf, %lf), textext_y: (%lf, %lf, %lf, %lf)\n", + ylabels[ylabels_length - ylabels_left], tbx[0], tbx[1], tbx[2], tbx[3], tby[0], tby[1], + tby[2], tby[3])); + gr_wctondc(&tbx[0], &tby[0]); + gr_wctondc(&tbx[2], &tby[2]); + width = tbx[2] - tbx[0]; + height = tby[2] - tby[0]; + logger((stderr, "width: %lf, available_width: %lf\n", width, available_width)); + logger((stderr, "height: %lf, available_height: %lf\n", height, available_height)); + if (width < available_width && height < available_height) + { + gr_setcharup(0.0, 1.0); + gr_text(x_text, y_text, ylabels[ylabels_length - ylabels_left]); + } + else if (height < available_width && width < available_height) + { + gr_setcharup(-1.0, 0.0); + gr_text(x_text, y_text, ylabels[ylabels_length - ylabels_left]); + gr_setcharup(0.0, 1.0); + } --ylabels_left; } } @@ -3030,7 +3085,7 @@ error_t plot_barplot(grm_args_t *subplot_args) { free(y_lightness); } - + gr_restorestate(); return error; } @@ -5673,8 +5728,8 @@ error_t plot_draw_pie_legend(grm_args_t *subplot_args) for (current_label = labels; *current_label != NULL; ++current_label) { gr_inqtext(0, 0, *(char **)current_label, tbx, tby); - w += tbx[2]; - h = max(h, tby[2]); + w += tbx[2] - tbx[0]; + h = max(h, tby[2] - tby[0]); } w += num_labels * 0.03 + (num_labels - 1) * 0.02; @@ -5698,7 +5753,7 @@ error_t plot_draw_pie_legend(grm_args_t *subplot_args) gr_drawrect(px, px + 0.02, py - 0.01, py + 0.01); gr_text(px + 0.03, py, (char *)*current_label); gr_inqtext(0, 0, *(char **)current_label, tbx, tby); - px += tbx[2] + 0.05; + px += tbx[2] - tbx[0] + 0.05; set_next_color(NULL, NULL, GR_COLOR_FILL); } set_next_color(NULL, NULL, GR_COLOR_RESET); @@ -7339,8 +7394,8 @@ void draw_xticklabel(double x1, double x2, const char *label, double available_w new_label[i] = '\0'; gr_inqtext(x1, x2, new_label + cur_start, tbx, tby); gr_wctondc(&tbx[0], &tby[0]); - gr_wctondc(&tbx[1], &tby[1]); - width = tbx[1] - tbx[0]; + gr_wctondc(&tbx[2], &tby[2]); + width = tbx[2] - tbx[0]; new_label[i] = ' '; /* add possible breakpoint */