Fixed issues with rotating and fliping images + other bugs
This commit is contained in:
parent
5faefbdf8d
commit
9105bef5f5
|
|
@ -27,4 +27,7 @@ src/parselabel.h
|
|||
src/rawtovcd
|
||||
src/xschem
|
||||
|
||||
/build
|
||||
CMakeLists.txt
|
||||
.vscode
|
||||
|
||||
|
|
|
|||
20
src/draw.c
20
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);
|
||||
|
|
|
|||
186
src/psprint.c
186
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;i<xctx->rects[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;i<xctx->arcs[c];i++)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue