From 9105bef5f52f98d224ea008a0523ffa8b0ccdc12 Mon Sep 17 00:00:00 2001 From: rafmag Date: Mon, 16 Jan 2023 11:33:59 -0700 Subject: [PATCH] Fixed issues with rotating and fliping images + other bugs --- .gitignore | 3 + src/draw.c | 20 ++++-- src/psprint.c | 186 ++++++++++++++++++++++++++++---------------------- 3 files changed, 121 insertions(+), 88 deletions(-) diff --git a/.gitignore b/.gitignore index f7542e7e..abe9bf02 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,7 @@ src/parselabel.h src/rawtovcd src/xschem +/build +CMakeLists.txt +.vscode diff --git a/src/draw.c b/src/draw.c index 8b2ba0fc..9b93252f 100644 --- a/src/draw.c +++ b/src/draw.c @@ -3215,15 +3215,23 @@ void draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2 } else { /* resize image to fit in rectangle */ rw = abs((int)(*x2 - *x1)); rh = abs((int)(*y2 - *y1)); - scalex = rw/w * xctx->mooz; - scaley = rh/h * xctx->mooz; + if (rot == 1 || rot == 3) + { + scalex = rh/w * xctx->mooz; + scaley = rw/h * xctx->mooz; + }else + { + scalex = rw/w * xctx->mooz; + scaley = rh/h * xctx->mooz; + } } if(dr && xctx->draw_pixmap) { cairo_translate(xctx->cairo_save_ctx, x, y); - if(flip && (rot == 0 || rot == 2)) cairo_scale(xctx->cairo_save_ctx, -scalex, scaley); - else if(flip && (rot == 1 || rot == 3)) cairo_scale(xctx->cairo_save_ctx, scalex, -scaley); - else cairo_scale(xctx->cairo_save_ctx, scalex, scaley); cairo_rotate(xctx->cairo_save_ctx, rot * XSCH_PI * 0.5); + if(flip && (rot == 0 || rot == 2)) cairo_scale(xctx->cairo_save_ctx, -scalex, scaley); + else if(flip && (rot == 1 || rot == 3)) cairo_scale(xctx->cairo_save_ctx, -scalex, scaley); + else cairo_scale(xctx->cairo_save_ctx, scalex, scaley); + cairo_set_source_surface(xctx->cairo_save_ctx, emb_ptr->image, 0. , 0.); cairo_rectangle(xctx->cairo_save_ctx, 0, 0, w , h ); /* cairo_fill(xctx->cairo_save_ctx); @@ -3233,10 +3241,10 @@ void draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2 } if(dr && xctx->draw_window) { cairo_translate(xctx->cairo_ctx, x, y); + cairo_rotate(xctx->cairo_ctx, rot * XSCH_PI * 0.5); if(flip && (rot == 0 || rot == 2)) cairo_scale(xctx->cairo_ctx, -scalex, scaley); else if(flip && (rot == 1 || rot == 3)) cairo_scale(xctx->cairo_ctx, scalex, -scaley); else cairo_scale(xctx->cairo_ctx, scalex, scaley); - cairo_rotate(xctx->cairo_ctx, rot * XSCH_PI * 0.5); cairo_set_source_surface(xctx->cairo_ctx, emb_ptr->image, 0. , 0.); cairo_rectangle(xctx->cairo_ctx, 0, 0, w , h ); /* cairo_fill(xctx->cairo_ctx); diff --git a/src/psprint.c b/src/psprint.c index 4e8e5259..a296f3b7 100644 --- a/src/psprint.c +++ b/src/psprint.c @@ -132,97 +132,117 @@ char* bin2hex(const unsigned char* bin, size_t len) return out; } -void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2) +void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, int flip) { - int i; - size_t data_size; - png_to_byte_closure_t closure; - char* filter = NULL; - my_strdup(1484, &filter, get_tok_value(r->prop_ptr, "filter", 0)); - unsigned char* image_data64_ptr = get_tok_value(r->prop_ptr, "image_data", 0); - + int i; + size_t data_size; + png_to_byte_closure_t closure; + char* filter = NULL; + my_strdup(1484, &filter, get_tok_value(r->prop_ptr, "filter", 0)); + unsigned char* image_data64_ptr = get_tok_value(r->prop_ptr, "image_data", 0); - if (filter) { - size_t filtersize = 0; - char* filterdata = NULL; - closure.buffer = NULL; - filterdata = (char*)base64_decode(image_data64_ptr, strlen(image_data64_ptr), &filtersize); - filter_data(filterdata, filtersize, (char**)&closure.buffer, &data_size, filter); - my_free(1488, &filterdata); - } - else { - closure.buffer = base64_decode(image_data64_ptr, strlen(image_data64_ptr), &data_size); - } - closure.pos = 0; - closure.size = data_size; /* should not be necessary */ - cairo_surface_t* surface = cairo_image_surface_create_from_png_stream(png_reader, &closure); - int png_size_x = cairo_image_surface_get_width(surface); - int png_size_y = cairo_image_surface_get_height(surface); + if (filter) { + size_t filtersize = 0; + char* filterdata = NULL; + closure.buffer = NULL; + filterdata = (char*)base64_decode(image_data64_ptr, strlen(image_data64_ptr), &filtersize); + filter_data(filterdata, filtersize, (char**)&closure.buffer, &data_size, filter); + my_free(1488, &filterdata); + } + else { + closure.buffer = base64_decode(image_data64_ptr, strlen(image_data64_ptr), &data_size); + } + closure.pos = 0; + closure.size = data_size; /* should not be necessary */ + cairo_surface_t* surface = cairo_image_surface_create_from_png_stream(png_reader, &closure); - cairo_surface_flush(surface); - unsigned char* png_data = cairo_image_surface_get_data(surface); + int png_size_x = cairo_image_surface_get_width(surface); + int png_size_y = cairo_image_surface_get_height(surface); - unsigned char* invertImage = get_tok_value(r->prop_ptr, "InvertOnExport", 0); - unsigned char BG_r = 0xFF, BG_g = 0xFF, BG_b = 0xFF; - for (i = 0; i < (png_size_x * png_size_y * 4); i += 4) - { + cairo_surface_flush(surface); + unsigned char* png_data = cairo_image_surface_get_data(surface); - unsigned char png_r = png_data[i + 0]; - unsigned char png_g = png_data[i + 1]; - unsigned char png_b = png_data[i + 2]; - unsigned char png_a = png_data[i + 3]; + unsigned char* invertImage = get_tok_value(r->prop_ptr, "InvertOnExport", 0); + unsigned char BG_r = 0xFF, BG_g = 0xFF, BG_b = 0xFF; + for (i = 0; i < (png_size_x * png_size_y * 4); i += 4) + { + unsigned char png_r = png_data[i + 0]; + unsigned char png_g = png_data[i + 1]; + unsigned char png_b = png_data[i + 2]; + unsigned char png_a = png_data[i + 3]; + double ainv=((double)(0xFF - png_a)) / ((double)(0xFF)); if(invertImage[0]=='1') { - png_data[i + 0] = (0xFF-png_r) + (unsigned char)((double)BG_r * ((double)(0xFF - png_a)) / ((double)(0xFF))); - png_data[i + 1] = (0xFF-png_g) + (unsigned char)((double)BG_g * ((double)(0xFF - png_a)) / ((double)(0xFF))); - png_data[i + 2] = (0xFF-png_b) + (unsigned char)((double)BG_b * ((double)(0xFF - png_a)) / ((double)(0xFF))); + png_data[i + 0] = (0xFF-png_r) + (unsigned char)((double)BG_r * ainv); + png_data[i + 1] = (0xFF-png_g) + (unsigned char)((double)BG_g * ainv); + png_data[i + 2] = (0xFF-png_b) + (unsigned char)((double)BG_b * ainv); png_data[i + 3] = 0xFF; }else { - png_data[i + 0] = png_r + (unsigned char)((double)BG_r * ((double)(0xFF - png_a)) / ((double)(0xFF))); - png_data[i + 1] = png_g + (unsigned char)((double)BG_g * ((double)(0xFF - png_a)) / ((double)(0xFF))); - png_data[i + 2] = png_b + (unsigned char)((double)BG_b * ((double)(0xFF - png_a)) / ((double)(0xFF))); + png_data[i + 0] = png_r + (unsigned char)((double)BG_r * ainv); + png_data[i + 1] = png_g + (unsigned char)((double)BG_g * ainv); + png_data[i + 2] = png_b + (unsigned char)((double)BG_b * ainv); png_data[i + 3] = 0xFF; } - - } - cairo_surface_mark_dirty(surface); + + } + cairo_surface_mark_dirty(surface); static char str[PATH_MAX]; my_snprintf(str, S(str), "%s%s", tclgetvar("XSCHEM_TMP_DIR"), "/temp.jpg"); - cairo_image_surface_write_to_jpeg(surface, str, 100); - unsigned char* jpgData; - FILE* fp; - fp = fopen(str, "rb"); /* Open the file for reading */ - fseek(fp, 0L, SEEK_END); - int fileSize = ftell(fp); - rewind(fp); - jpgData = malloc(fileSize); - fread(jpgData, sizeof(jpgData[0]), fileSize, fp); - fclose(fp); + cairo_image_surface_write_to_jpeg(surface, str, 100); + unsigned char* jpgData; + FILE* fp; + fp = fopen(str, "rb"); /* Open the file for reading */ + fseek(fp, 0L, SEEK_END); + int fileSize = ftell(fp); + rewind(fp); + jpgData = malloc(fileSize); + fread(jpgData, sizeof(jpgData[0]), fileSize, fp); + fclose(fp); - unsigned char* hexEncodedJPG = bin2hex(jpgData, fileSize); + unsigned char* hexEncodedJPG = bin2hex(jpgData, fileSize); - fprintf(fd, "gsave\n"); - fprintf(fd, "%g %g translate\n", X_TO_PS(x1), Y_TO_PS(y1)); - fprintf(fd, "%g %g scale\n", X_TO_PS(x2) - X_TO_PS(x1), Y_TO_PS(y2) - Y_TO_PS(y1)); - fprintf(fd, "%d\n", png_size_x); - fprintf(fd, "%d\n", png_size_y); - fprintf(fd, "8\n"); - fprintf(fd, "[%d 0 0 %d 0 0]\n", png_size_x, png_size_y); - fprintf(fd, "(%s)\n", hexEncodedJPG); - fprintf(fd, "/ASCIIHexDecode\n"); - fprintf(fd, "filter\n"); - fprintf(fd, "0 dict\n"); - fprintf(fd, "/DCTDecode\n"); - fprintf(fd, "filter\n"); - fprintf(fd, "false\n"); - fprintf(fd, "3\n"); - fprintf(fd, "colorimage\n"); - fprintf(fd, "grestore\n"); + fprintf(fd, "gsave\n"); + fprintf(fd, "%g %g translate\n", X_TO_PS(x1), Y_TO_PS(y1)); + if(rot==1) fprintf(fd, "90 rotate\n"); + if(rot==2) fprintf(fd, "180 rotate\n"); + if(rot==3) fprintf(fd, "270 rotate\n"); + fprintf(fd, "%g %g scale\n", (X_TO_PS(x2) - X_TO_PS(x1))*0.97, (Y_TO_PS(y2) - Y_TO_PS(y1))*0.97); + + fprintf(fd, "%g\n", (double)png_size_x); + fprintf(fd, "%g\n", (double)png_size_y); + fprintf(fd, "8\n"); + if(!flip) + { + if(rot==1) fprintf(fd, "[%g 0 0 %g 0 %g]\n", (double)png_size_y, (double)png_size_x, (double)png_size_y); + else if(rot==2) fprintf(fd, "[%g 0 0 %g %g %g]\n", (double)png_size_x, (double)png_size_y, (double)png_size_x, (double)png_size_y); + else if(rot==3) fprintf(fd, "[%g 0 0 %g %g 0]\n", (double)png_size_y, (double)png_size_x, (double)png_size_x); + else fprintf(fd, "[%g 0 0 %g 0 0]\n", (double)png_size_x, (double)png_size_y); + } + else + { + if(rot==1) fprintf(fd, "[%g 0 0 %g %g %g]\n", -(double)png_size_y, (double)png_size_x, (double)png_size_x, (double)png_size_y); + else if(rot==2) fprintf(fd, "[%g 0 0 %g 0 %g]\n", -(double)png_size_x, (double)png_size_y, (double)png_size_y); + else if(rot==3) fprintf(fd, "[%g 0 0 %g 0 0]\n", -(double)png_size_y, (double)png_size_x); + else fprintf(fd, "[%g 0 0 %g %g 0]\n", -(double)png_size_x, (double)png_size_y, (double)png_size_x); + } + + + fprintf(fd, "(%s)\n", hexEncodedJPG); + fprintf(fd, "/ASCIIHexDecode\n"); + fprintf(fd, "filter\n"); + fprintf(fd, "0 dict\n"); + fprintf(fd, "/DCTDecode\n"); + fprintf(fd, "filter\n"); + fprintf(fd, "false\n"); + fprintf(fd, "3\n"); + fprintf(fd, "colorimage\n"); + fprintf(fd, "grestore\n"); + fflush(fd); - free(hexEncodedJPG); free(jpgData); + free(hexEncodedJPG); free(jpgData); } @@ -845,7 +865,7 @@ static void ps_draw_symbol(int n,int layer, int what, short tmp_flip, short rot, RECTORDER(x1,y1,x2,y2); if (rect.flags & 1024) /* image */ { - ps_drawPNG(&rect, x0 + x1, y0 + y1, x0 + x2, y0 + y2); + ps_drawPNG(&rect, x0 + x1, y0 + y1, x0 + x2, y0 + y2, rot, flip); continue; } ps_filledrect(layer, x0+x1, y0+y1, x0+x2, y0+y2, rect.dash, rect.fill); @@ -1112,19 +1132,21 @@ void create_ps(char **psfile, int what) xctx->line[c][i].x2, xctx->line[c][i].y2, xctx->line[c][i].dash); for(i=0;irects[c];i++) { + + if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1024)) { /* image */ + xRect* r = &xctx->rect[c][i]; + /* PNG Code Here */ + ps_drawPNG(r, r->x1, r->y1, r->x2, r->y2,0 ,0); + continue; + } + if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */ + xRect* r = &xctx->rect[c][i]; + ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2); + } if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) { ps_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1, xctx->rect[c][i].x2, xctx->rect[c][i].y2, xctx->rect[c][i].dash, xctx->rect[c][i].fill); } - if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1024)) { /* image */ - xRect* r = &xctx->rect[c][i]; - /* PNG Code Here */ - ps_drawPNG(r, r->x1, r->y1, r->x2, r->y2); - } - if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */ - xRect* r = &xctx->rect[c][i]; - ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2); - } } for(i=0;iarcs[c];i++) {