Merge branch 'StefanSchippers:master' into master

This commit is contained in:
Rafmag Cabrera 2023-01-16 12:37:35 +00:00 committed by GitHub
commit 588fcb22ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 245 additions and 200 deletions

View File

@ -9,6 +9,44 @@
#define version "2.0.1" #define version "2.0.1"
int find_sul_pcre(const char *name, int logdepth, int fatal)
{
const char *test_c =
NL "#include <stdio.h>"
NL "#include <stdlib.h>"
NL "#include <pcre.h>"
NL "int main()"
NL "{"
NL " const char *err;"
NL " int erro, ret;"
NL " pcre *p = pcre_compile(\"fo+b\", 0, &err, &erro, NULL);"
NL " ret = pcre_exec(p, NULL, \"hi foobar\", 9, 0, 0, &erro, 1);"
NL " if (ret == 0)"
NL " puts(\"OK\");"
NL " return 0;"
NL "}"
NL;
const char *node = "libs/sul/pcre";
if (require("cc/cc", logdepth, fatal))
return 1;
report("Checking for pcre... ");
if (try_icl_pkg_config(logdepth, "libs/sul/pcre", test_c, NULL, "libpcre", NULL))
return 0;
if (try_icl(logdepth, node, test_c, NULL, "-I/usr/include/pcre", "-lpcre"))
return 0;
if (try_icl(logdepth, node, test_c, NULL, "-I/usr/include/pcre", "-lpcre3"))
return 0;
return try_fail(logdepth, node);
}
static void help(void) static void help(void)
{ {
printf("./configure: configure xschem.\n"); printf("./configure: configure xschem.\n");

View File

@ -5,7 +5,7 @@ put /local/src {
select.c font.c editprop.c save.c paste.c token.c psprint.c node_hash.c select.c font.c editprop.c save.c paste.c token.c psprint.c node_hash.c
hilight.c options.c vhdl_netlist.c svgdraw.c spice_netlist.c hilight.c options.c vhdl_netlist.c svgdraw.c spice_netlist.c
tedax_netlist.c verilog_netlist.c parselabel.c expandlabel.c tedax_netlist.c verilog_netlist.c parselabel.c expandlabel.c
in_memory_undo.c in_memory_undo.c cairo_jpg.c
} }
# list all files that need to be installed in "$(XSHAREDIR)" # list all files that need to be installed in "$(XSHAREDIR)"
@ -40,7 +40,7 @@ rawtovcd: rawtovcd.o
$(CC) -o rawtovcd rawtovcd.o -lm $(CC) -o rawtovcd rawtovcd.o -lm
xschem: $(OBJ) xschem: $(OBJ)
$(CC) -o xschem $(OBJ) $(LDFLAGS) $(CC) -o xschem $(OBJ) $(LDFLAGS) -ljpeg
parselabel.c: parselabel.l expandlabel.h parselabel.c: parselabel.l expandlabel.h
flex -l -oparselabel.c parselabel.l flex -l -oparselabel.c parselabel.l

View File

@ -57,8 +57,9 @@
/*! Macro to activate main() function. This is only used for testing. Comment /*! Macro to activate main() function. This is only used for testing. Comment
* it out (#undef) if you link this file to your own program. * it out (#undef) if you link this file to your own program.
*/ */
//#define CAIRO_JPEG_MAIN
// /* #define CAIRO_JPEG_MAIN */
/*! Define this to use an alternate implementation of /*! Define this to use an alternate implementation of
* cairo_image_surface_create_from_jpeg() which fstat(3)s the file before * cairo_image_surface_create_from_jpeg() which fstat(3)s the file before
* reading (see below). For huge files this /may/ be slightly faster. * reading (see below). For huge files this /may/ be slightly faster.
@ -107,7 +108,7 @@ static void pix_conv(unsigned char *dst, int dw, const unsigned char *src, int s
{ {
int si, di; int si, di;
// safety check /* safety check */
if (dw < 3 || sw < 3 || dst == NULL || src == NULL) if (dw < 3 || sw < 3 || dst == NULL || src == NULL)
return; return;
@ -119,7 +120,7 @@ static void pix_conv(unsigned char *dst, int dw, const unsigned char *src, int s
dst[di + 1] = src[si + 1]; dst[di + 1] = src[si + 1];
dst[di + 0] = src[si + 2]; dst[di + 0] = src[si + 2];
#else #else
// FIXME: This is untested, it may be wrong. /* FIXME: This is untested, it may be wrong. */
dst[di - 3] = src[si - 3]; dst[di - 3] = src[si - 3];
dst[di - 2] = src[si - 2]; dst[di - 2] = src[si - 2];
dst[di - 1] = src[si - 1]; dst[di - 1] = src[si - 1];
@ -157,49 +158,49 @@ cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsig
JSAMPROW row_pointer[1]; JSAMPROW row_pointer[1];
cairo_surface_t *other = NULL; cairo_surface_t *other = NULL;
// check valid input format (must be IMAGE_SURFACE && (ARGB32 || RGB24)) /* check valid input format (must be IMAGE_SURFACE && (ARGB32 || RGB24)) */
if (cairo_surface_get_type(sfc) != CAIRO_SURFACE_TYPE_IMAGE || if (cairo_surface_get_type(sfc) != CAIRO_SURFACE_TYPE_IMAGE ||
(cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_ARGB32 && (cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_ARGB32 &&
cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_RGB24)) cairo_image_surface_get_format(sfc) != CAIRO_FORMAT_RGB24))
{ {
// create a similar surface with a proper format if supplied input format /* create a similar surface with a proper format if supplied input format */
// does not fulfill the requirements /* does not fulfill the requirements */
double x1, y1, x2, y2; double x1, y1, x2, y2;
other = sfc; other = sfc;
cairo_t *ctx = cairo_create(other); cairo_t *ctx = cairo_create(other);
// get extents of original surface /* get extents of original surface */
cairo_clip_extents(ctx, &x1, &y1, &x2, &y2); cairo_clip_extents(ctx, &x1, &y1, &x2, &y2);
cairo_destroy(ctx); cairo_destroy(ctx);
// create new image surface /* create new image surface */
sfc = cairo_surface_create_similar_image(other, CAIRO_FORMAT_RGB24, x2 - x1, y2 - y1); sfc = cairo_surface_create_similar_image(other, CAIRO_FORMAT_RGB24, x2 - x1, y2 - y1);
if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS) if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
return CAIRO_STATUS_INVALID_FORMAT; return CAIRO_STATUS_INVALID_FORMAT;
// paint original surface to new surface /* paint original surface to new surface */
ctx = cairo_create(sfc); ctx = cairo_create(sfc);
cairo_set_source_surface(ctx, other, 0, 0); cairo_set_source_surface(ctx, other, 0, 0);
cairo_paint(ctx); cairo_paint(ctx);
cairo_destroy(ctx); cairo_destroy(ctx);
} }
// finish queued drawing operations /* finish queued drawing operations */
cairo_surface_flush(sfc); cairo_surface_flush(sfc);
// init jpeg compression structures /* init jpeg compression structures */
cinfo.err = jpeg_std_error(&jerr); cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo); jpeg_create_compress(&cinfo);
// set compression parameters /* set compression parameters */
jpeg_mem_dest(&cinfo, data, len); jpeg_mem_dest(&cinfo, data, len);
cinfo.image_width = cairo_image_surface_get_width(sfc); cinfo.image_width = cairo_image_surface_get_width(sfc);
cinfo.image_height = cairo_image_surface_get_height(sfc); cinfo.image_height = cairo_image_surface_get_height(sfc);
#ifdef LIBJPEG_TURBO_VERSION #ifdef LIBJPEG_TURBO_VERSION
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
//cinfo.in_color_space = JCS_EXT_BGRX; /* cinfo.in_color_space = JCS_EXT_BGRX; */
cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_BGRA : JCS_EXT_BGRX; cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_BGRA : JCS_EXT_BGRX;
#else #else
//cinfo.in_color_space = JCS_EXT_XRGB; /* cinfo.in_color_space = JCS_EXT_XRGB; */
cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_ARGB : JCS_EXT_XRGB; cinfo.in_color_space = cairo_image_surface_get_format(sfc) == CAIRO_FORMAT_ARGB32 ? JCS_EXT_ARGB : JCS_EXT_XRGB;
#endif #endif
cinfo.input_components = 4; cinfo.input_components = 4;
@ -210,10 +211,10 @@ cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsig
jpeg_set_defaults(&cinfo); jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE); jpeg_set_quality(&cinfo, quality, TRUE);
// start compressor /* start compressor */
jpeg_start_compress(&cinfo, TRUE); jpeg_start_compress(&cinfo, TRUE);
// loop over all lines and compress /* loop over all lines and compress */
while (cinfo.next_scanline < cinfo.image_height) while (cinfo.next_scanline < cinfo.image_height)
{ {
#ifdef LIBJPEG_TURBO_VERSION #ifdef LIBJPEG_TURBO_VERSION
@ -221,7 +222,7 @@ cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsig
* cairo_image_surface_get_stride(sfc)); * cairo_image_surface_get_stride(sfc));
#else #else
unsigned char* row_buf = malloc(3 * cinfo.image_width); unsigned char* row_buf = malloc(3 * cinfo.image_width);
//unsigned char row_buf[3 * cinfo.image_width]; /* unsigned char row_buf[3 * cinfo.image_width]; */
pix_conv(row_buf, 3, cairo_image_surface_get_data(sfc) + pix_conv(row_buf, 3, cairo_image_surface_get_data(sfc) +
(cinfo.next_scanline * cairo_image_surface_get_stride(sfc)), 4, cinfo.image_width); (cinfo.next_scanline * cairo_image_surface_get_stride(sfc)), 4, cinfo.image_width);
row_pointer[0] = row_buf; row_pointer[0] = row_buf;
@ -229,11 +230,11 @@ cairo_status_t cairo_image_surface_write_to_jpeg_mem(cairo_surface_t *sfc, unsig
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1); (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
} }
// finalize and close everything /* finalize and close everything */
jpeg_finish_compress(&cinfo); jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo); jpeg_destroy_compress(&cinfo);
// destroy temporary image surface (if available) /* destroy temporary image surface (if available) */
if (other != NULL) if (other != NULL)
cairo_surface_destroy(sfc); cairo_surface_destroy(sfc);
@ -270,14 +271,14 @@ cairo_status_t cairo_image_surface_write_to_jpeg_stream(cairo_surface_t *sfc, ca
unsigned char *data = NULL; unsigned char *data = NULL;
size_t len = 0; size_t len = 0;
// create JPEG data in memory from surface /* create JPEG data in memory from surface */
if ((e = cairo_image_surface_write_to_jpeg_mem(sfc, &data, &len, quality)) != CAIRO_STATUS_SUCCESS) if ((e = cairo_image_surface_write_to_jpeg_mem(sfc, &data, &len, quality)) != CAIRO_STATUS_SUCCESS)
return e; return e;
// write whole memory block with stream function /* write whole memory block with stream function */
e = write_func(closure, data, len); e = write_func(closure, data, len);
// free JPEG memory again and return the return value /* free JPEG memory again and return the return value */
free(data); free(data);
return e; return e;
@ -301,14 +302,14 @@ cairo_status_t cairo_image_surface_write_to_jpeg(cairo_surface_t *sfc, const cha
cairo_status_t e; cairo_status_t e;
int outfile; int outfile;
// Open/create new file /* Open/create new file */
if ((outfile = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) if ((outfile = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)
return CAIRO_STATUS_DEVICE_ERROR; return CAIRO_STATUS_DEVICE_ERROR;
// write surface to file /* write surface to file */
e = cairo_image_surface_write_to_jpeg_stream(sfc, cj_write, (void*)(intptr_t) outfile, quality); e = cairo_image_surface_write_to_jpeg_stream(sfc, cj_write, (void*)(intptr_t) outfile, quality);
// close file again and return /* close file again and return */
close(outfile); close(outfile);
return e; return e;
} }
@ -330,7 +331,7 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_mem(void *data, size_t len
JSAMPROW row_pointer[1]; JSAMPROW row_pointer[1];
cairo_surface_t *sfc; cairo_surface_t *sfc;
// initialize jpeg decompression structures /* initialize jpeg decompression structures */
cinfo.err = jpeg_std_error(&jerr); cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo); jpeg_create_decompress(&cinfo);
jpeg_mem_src(&cinfo, data, len); jpeg_mem_src(&cinfo, data, len);
@ -346,10 +347,10 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_mem(void *data, size_t len
cinfo.out_color_space = JCS_RGB; cinfo.out_color_space = JCS_RGB;
#endif #endif
// start decompressor /* start decompressor */
(void) jpeg_start_decompress(&cinfo); (void) jpeg_start_decompress(&cinfo);
// create Cairo image surface /* create Cairo image surface */
sfc = cairo_image_surface_create(CAIRO_FORMAT_RGB24, cinfo.output_width, cinfo.output_height); sfc = cairo_image_surface_create(CAIRO_FORMAT_RGB24, cinfo.output_width, cinfo.output_height);
if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS) if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
{ {
@ -357,7 +358,7 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_mem(void *data, size_t len
return sfc; return sfc;
} }
// loop over all scanlines and fill Cairo image surface /* loop over all scanlines and fill Cairo image surface */
while (cinfo.output_scanline < cinfo.output_height) while (cinfo.output_scanline < cinfo.output_height)
{ {
unsigned char *row_address = cairo_image_surface_get_data(sfc) + unsigned char *row_address = cairo_image_surface_get_data(sfc) +
@ -369,12 +370,12 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_mem(void *data, size_t len
#endif #endif
} }
// finish and close everything /* finish and close everything */
cairo_surface_mark_dirty(sfc); cairo_surface_mark_dirty(sfc);
(void) jpeg_finish_decompress(&cinfo); (void) jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo); jpeg_destroy_decompress(&cinfo);
// set jpeg mime data /* set jpeg mime data */
cairo_surface_set_mime_data(sfc, CAIRO_MIME_TYPE_JPEG, data, len, free, data); cairo_surface_set_mime_data(sfc, CAIRO_MIME_TYPE_JPEG, data, len, free, data);
return sfc; return sfc;
@ -403,39 +404,39 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_stream(cairo_read_func_t r
ssize_t len, rlen; ssize_t len, rlen;
int eof = 0; int eof = 0;
// read all data into memory buffer in blocks of CAIRO_JPEG_IO_BLOCK_SIZE /* read all data into memory buffer in blocks of CAIRO_JPEG_IO_BLOCK_SIZE */
for (len = 0, data = NULL; !eof; len += rlen) for (len = 0, data = NULL; !eof; len += rlen)
{ {
// grow memory buffer and check for error /* grow memory buffer and check for error */
if ((tmp = realloc(data, len + CAIRO_JPEG_IO_BLOCK_SIZE)) == NULL) if ((tmp = realloc(data, len + CAIRO_JPEG_IO_BLOCK_SIZE)) == NULL)
break; break;
data = tmp; data = tmp;
// read bytes into buffer and check for error /* read bytes into buffer and check for error */
rlen = read_func(closure, data + len, CAIRO_JPEG_IO_BLOCK_SIZE); rlen = read_func(closure, data + len, CAIRO_JPEG_IO_BLOCK_SIZE);
#ifdef USE_CAIRO_READ_FUNC_LEN_T #ifdef USE_CAIRO_READ_FUNC_LEN_T
// check for error /* check for error */
if (rlen == -1) if (rlen == -1)
break; break;
// check if EOF occured /* check if EOF occured */
if (rlen < CAIRO_JPEG_IO_BLOCK_SIZE) if (rlen < CAIRO_JPEG_IO_BLOCK_SIZE)
eof++; eof++;
#else #else
// check for error /* check for error */
if (rlen == CAIRO_STATUS_READ_ERROR) if (rlen == CAIRO_STATUS_READ_ERROR)
eof++; eof++;
#endif #endif
} }
// check for error in read loop /* check for error in read loop */
if (!eof) if (!eof)
{ {
free(data); free(data);
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0); return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0);
} }
// call jpeg decompression and return surface /* call jpeg decompression and return surface */
sfc = cairo_image_surface_create_from_jpeg_mem(data, len); sfc = cairo_image_surface_create_from_jpeg_mem(data, len);
if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS) if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
free(data); free(data);
@ -462,19 +463,19 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg(const char *filename)
int infile; int infile;
struct stat stat; struct stat stat;
// open input file /* open input file */
if ((infile = open(filename, O_RDONLY)) == -1) if ((infile = open(filename, O_RDONLY)) == -1)
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0); return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0);
// get stat structure for file size /* get stat structure for file size */
if (fstat(infile, &stat) == -1) if (fstat(infile, &stat) == -1)
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0); return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0);
// allocate memory /* allocate memory */
if ((data = malloc(stat.st_size)) == NULL) if ((data = malloc(stat.st_size)) == NULL)
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0); return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0);
// read data /* read data */
int s = read(infile, data, stat.st_size); int s = read(infile, data, stat.st_size);
if ( s < stat.st_size) if ( s < stat.st_size)
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0); return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0);
@ -520,11 +521,11 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg(const char *filename)
cairo_surface_t *sfc; cairo_surface_t *sfc;
int infile; int infile;
// open input file /* open input file */
if ((infile = open(filename, O_RDONLY)) == -1) if ((infile = open(filename, O_RDONLY)) == -1)
return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0); return cairo_image_surface_create(CAIRO_FORMAT_INVALID, 0, 0);
// call stream loading function /* call stream loading function */
sfc = cairo_image_surface_create_from_jpeg_stream(cj_read, (void*)(intptr_t) infile); sfc = cairo_image_surface_create_from_jpeg_stream(cj_read, (void*)(intptr_t) infile);
close(infile); close(infile);
@ -540,7 +541,7 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg(const char *filename)
int strrcasecmp(const char *s1, const char *s2) int strrcasecmp(const char *s1, const char *s2)
{ {
int off = (int) strlen(s1) - (int) strlen(s2); // typecast size_t to int because size_t typically is unsigned int off = (int) strlen(s1) - (int) strlen(s2); /* typecast size_t to int because size_t typically is unsigned */
return strcasecmp(s1 + (off < 0 ? 0 : off), s2); return strcasecmp(s1 + (off < 0 ? 0 : off), s2);
} }
@ -558,15 +559,15 @@ int main(int argc, char **argv)
return 1; return 1;
} }
// test input file type and read file /* test input file type and read file */
if (!strrcasecmp(argv[1], ".png")) if (!strrcasecmp(argv[1], ".png"))
{ {
// read PNG file /* read PNG file */
sfc = cairo_image_surface_create_from_png(argv[1]); sfc = cairo_image_surface_create_from_png(argv[1]);
} }
else if (!strrcasecmp(argv[1], ".jpg")) else if (!strrcasecmp(argv[1], ".jpg"))
{ {
// read JPEG file /* read JPEG file */
sfc = cairo_image_surface_create_from_jpeg(argv[1]); sfc = cairo_image_surface_create_from_jpeg(argv[1]);
} }
else else
@ -575,22 +576,22 @@ int main(int argc, char **argv)
return 1; return 1;
} }
// check surface status /* check surface status */
if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS) if (cairo_surface_status(sfc) != CAIRO_STATUS_SUCCESS)
{ {
fprintf(stderr, "error loading image: %s", cairo_status_to_string(cairo_surface_status(sfc))); fprintf(stderr, "error loading image: %s", cairo_status_to_string(cairo_surface_status(sfc)));
return 2; return 2;
} }
// test output file type and write file /* test output file type and write file */
if (!strrcasecmp(argv[2], ".png")) if (!strrcasecmp(argv[2], ".png"))
{ {
// write PNG file /* write PNG file */
cairo_surface_write_to_png(sfc, argv[2]); cairo_surface_write_to_png(sfc, argv[2]);
} }
else if (!strrcasecmp(argv[2], ".jpg")) else if (!strrcasecmp(argv[2], ".jpg"))
{ {
// write JPEG file /* write JPEG file */
cairo_image_surface_write_to_jpeg(sfc, argv[2], 90); cairo_image_surface_write_to_jpeg(sfc, argv[2], 90);
} }
else else

View File

@ -981,7 +981,7 @@ void drawline(int c, int what, double linex1, double liney1, double linex2, doub
if(xctx->draw_pixmap) if(xctx->draw_pixmap)
XDrawLine(display, xctx->save_pixmap, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2); XDrawLine(display, xctx->save_pixmap, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2);
if(dash) { if(dash) {
XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), LineSolid, CapRound, JoinRound); XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
} }
#if !defined(__unix__) && defined(HAS_CAIRO) #if !defined(__unix__) && defined(HAS_CAIRO)
check_cairo_drawline(ct, c, x1, y1, x2, y2, dash); check_cairo_drawline(ct, c, x1, y1, x2, y2, dash);
@ -1002,14 +1002,14 @@ void drawline(int c, int what, double linex1, double liney1, double linex2, doub
XSetDashes(display, xctx->gc[c], 0, dash_arr, 1); XSetDashes(display, xctx->gc[c], 0, dash_arr, 1);
XSetLineAttributes (display, xctx->gc[c], INT_BUS_WIDTH(xctx->lw), xDashType, xCap, xJoin); XSetLineAttributes (display, xctx->gc[c], INT_BUS_WIDTH(xctx->lw), xDashType, xCap, xJoin);
} else { } else {
XSetLineAttributes (display, xctx->gc[c], INT_BUS_WIDTH(xctx->lw), LineSolid, CapRound, JoinRound); XSetLineAttributes (display, xctx->gc[c], INT_BUS_WIDTH(xctx->lw), LineSolid, LINECAP, LINEJOIN);
} }
if(xctx->draw_window) XDrawLine(display, xctx->window, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2); if(xctx->draw_window) XDrawLine(display, xctx->window, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2);
if(xctx->draw_pixmap) XDrawLine(display, xctx->save_pixmap, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2); if(xctx->draw_pixmap) XDrawLine(display, xctx->save_pixmap, xctx->gc[c], (int)x1, (int)y1, (int)x2, (int)y2);
#if !defined(__unix__) && defined(HAS_CAIRO) #if !defined(__unix__) && defined(HAS_CAIRO)
check_cairo_drawline(ct, c, x1, y1, x2, y2, dash); check_cairo_drawline(ct, c, x1, y1, x2, y2, dash);
#endif #endif
XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound); XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN);
} }
} }
else if((what & END) && i) else if((what & END) && i)
@ -1087,10 +1087,10 @@ void drawtempline(GC gc, int what, double linex1,double liney1,double linex2,dou
y2=Y_TO_SCREEN(liney2); y2=Y_TO_SCREEN(liney2);
if( clip(&x1,&y1,&x2,&y2) ) if( clip(&x1,&y1,&x2,&y2) )
{ {
XSetLineAttributes (display, gc, INT_BUS_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound); XSetLineAttributes (display, gc, INT_BUS_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN);
XDrawLine(display, xctx->window, gc, (int)x1, (int)y1, (int)x2, (int)y2); XDrawLine(display, xctx->window, gc, (int)x1, (int)y1, (int)x2, (int)y2);
XSetLineAttributes (display, gc, INT_WIDTH(xctx->lw), LineSolid, CapRound , JoinRound); XSetLineAttributes (display, gc, INT_WIDTH(xctx->lw), LineSolid, LINECAP , LINEJOIN);
} }
} }
@ -1346,7 +1346,7 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b,
} }
} }
if(dash) { if(dash) {
XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, CapRound , JoinRound); XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
} }
} }
} }
@ -1534,7 +1534,7 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
} }
} }
if(dash) { if(dash) {
XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, CapRound , JoinRound); XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
} }
my_free(722, &p); my_free(722, &p);
} }
@ -1595,7 +1595,7 @@ void drawrect(int c, int what, double rectx1,double recty1,double rectx2,double
(unsigned int)y2 - (unsigned int)y1); (unsigned int)y2 - (unsigned int)y1);
} }
if(dash) { if(dash) {
XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, CapRound , JoinRound); XSetLineAttributes (display, xctx->gc[c], INT_WIDTH(xctx->lw) ,LineSolid, LINECAP, LINEJOIN);
} }
} }
} }
@ -1862,11 +1862,11 @@ static void set_thick_waves(int what, int wcnt, int wave_col, Graph_ctx *gr)
if(what) { if(what) {
if(gr->hilight_wave == wcnt) if(gr->hilight_wave == wcnt)
XSetLineAttributes (display, xctx->gc[wave_col], XSetLineAttributes (display, xctx->gc[wave_col],
3 * INT_WIDTH(xctx->lw) ,LineSolid, CapRound , JoinRound); 3 * INT_WIDTH(xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
} else { } else {
if(gr->hilight_wave == wcnt) if(gr->hilight_wave == wcnt)
XSetLineAttributes (display, xctx->gc[wave_col], XSetLineAttributes (display, xctx->gc[wave_col],
(int)(xctx->lw) ,LineSolid, CapRound , JoinRound); (int)(xctx->lw) ,LineSolid, LINECAP , LINEJOIN);
} }
} }

View File

@ -100,77 +100,78 @@ static char ps_font_family[80] = "Helvetica"; /* Courier Times Helvetica Symbol
typedef struct typedef struct
{ {
unsigned char* buffer; unsigned char* buffer;
size_t pos; size_t pos;
size_t size; size_t size;
} png_to_byte_closure_t; } png_to_byte_closure_t;
cairo_status_t png_reader(void* in_closure, unsigned char* out_data, unsigned int length) cairo_status_t png_reader(void* in_closure, unsigned char* out_data, unsigned int length)
{ {
png_to_byte_closure_t* closure = (png_to_byte_closure_t*)in_closure; png_to_byte_closure_t* closure = (png_to_byte_closure_t*)in_closure;
if (!closure->buffer) return CAIRO_STATUS_READ_ERROR; if (!closure->buffer) return CAIRO_STATUS_READ_ERROR;
memcpy(out_data, closure->buffer + closure->pos, length); memcpy(out_data, closure->buffer + closure->pos, length);
closure->pos += length; closure->pos += length;
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
char* bin2hex(const unsigned char* bin, size_t len) char* bin2hex(const unsigned char* bin, size_t len)
{ {
char* out; char* out;
size_t i; size_t i;
if (bin == NULL || len == 0) if (bin == NULL || len == 0)
return NULL; return NULL;
out = malloc(len * 2 + 1); out = malloc(len * 2 + 1);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
out[i * 2] = "0123456789abcdef"[bin[i] >> 4]; out[i * 2] = "0123456789abcdef"[bin[i] >> 4];
out[i * 2 + 1] = "0123456789abcdef"[bin[i] & 0x0F]; out[i * 2 + 1] = "0123456789abcdef"[bin[i] & 0x0F];
} }
out[len * 2] = '\0'; out[len * 2] = '\0';
return out; 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)
{ {
size_t data_size; int i;
png_to_byte_closure_t closure; size_t data_size;
char* filter = NULL; png_to_byte_closure_t closure;
my_strdup(1484, &filter, get_tok_value(r->prop_ptr, "filter", 0)); char* filter = NULL;
unsigned char* image_data64_ptr = get_tok_value(r->prop_ptr, "image_data", 0); 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) { if (filter) {
size_t filtersize = 0; size_t filtersize = 0;
char* filterdata = NULL; char* filterdata = NULL;
closure.buffer = NULL; closure.buffer = NULL;
filterdata = (char*)base64_decode(image_data64_ptr, strlen(image_data64_ptr), &filtersize); filterdata = (char*)base64_decode(image_data64_ptr, strlen(image_data64_ptr), &filtersize);
filter_data(filterdata, filtersize, (char**)&closure.buffer, &data_size, filter); filter_data(filterdata, filtersize, (char**)&closure.buffer, &data_size, filter);
my_free(1488, &filterdata); my_free(1488, &filterdata);
} }
else { else {
closure.buffer = base64_decode(image_data64_ptr, strlen(image_data64_ptr), &data_size); closure.buffer = base64_decode(image_data64_ptr, strlen(image_data64_ptr), &data_size);
} }
closure.pos = 0; closure.pos = 0;
closure.size = data_size; /* should not be necessary */ closure.size = data_size; /* should not be necessary */
cairo_surface_t* surface = cairo_image_surface_create_from_png_stream(png_reader, &closure); 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_x = cairo_image_surface_get_width(surface);
int png_size_y = cairo_image_surface_get_height(surface); int png_size_y = cairo_image_surface_get_height(surface);
cairo_surface_flush(surface); cairo_surface_flush(surface);
unsigned char* png_data = cairo_image_surface_get_data(surface); unsigned char* png_data = cairo_image_surface_get_data(surface);
unsigned char* invertImage = get_tok_value(r->prop_ptr, "InvertOnExport", 0); unsigned char* invertImage = get_tok_value(r->prop_ptr, "InvertOnExport", 0);
unsigned char BG_r = 0xFF, BG_g = 0xFF, BG_b = 0xFF; unsigned char BG_r = 0xFF, BG_g = 0xFF, BG_b = 0xFF;
for (int i = 0; i < (png_size_x * png_size_y * 4); i += 4) for (i = 0; i < (png_size_x * png_size_y * 4); i += 4)
{ {
unsigned char png_r = png_data[i + 0]; unsigned char png_r = png_data[i + 0];
unsigned char png_g = png_data[i + 1]; unsigned char png_g = png_data[i + 1];
unsigned char png_b = png_data[i + 2]; unsigned char png_b = png_data[i + 2];
unsigned char png_a = png_data[i + 3]; unsigned char png_a = png_data[i + 3];
if(invertImage[0]=='1') if(invertImage[0]=='1')
{ {
@ -186,42 +187,42 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2)
png_data[i + 3] = 0xFF; png_data[i + 3] = 0xFF;
} }
} }
cairo_surface_mark_dirty(surface); cairo_surface_mark_dirty(surface);
static char str[PATH_MAX]; static char str[PATH_MAX];
my_snprintf(str, S(str), "%s%s", tclgetvar("XSCHEM_TMP_DIR"), "/temp.jpg"); my_snprintf(str, S(str), "%s%s", tclgetvar("XSCHEM_TMP_DIR"), "/temp.jpg");
cairo_image_surface_write_to_jpeg(surface, str, 100); cairo_image_surface_write_to_jpeg(surface, str, 100);
unsigned char* jpgData; unsigned char* jpgData;
FILE* fp; FILE* fp;
fp = fopen(str, "rb"); /* Open the file for reading */ fp = fopen(str, "rb"); /* Open the file for reading */
fseek(fp, 0L, SEEK_END); fseek(fp, 0L, SEEK_END);
int fileSize = ftell(fp); int fileSize = ftell(fp);
rewind(fp); rewind(fp);
jpgData = malloc(fileSize); jpgData = malloc(fileSize);
fread(jpgData, sizeof(jpgData[0]), fileSize, fp); fread(jpgData, sizeof(jpgData[0]), fileSize, fp);
fclose(fp); fclose(fp);
unsigned char* hexEncodedJPG = bin2hex(jpgData, fileSize); unsigned char* hexEncodedJPG = bin2hex(jpgData, fileSize);
fprintf(fd, "gsave\n"); fprintf(fd, "gsave\n");
fprintf(fd, "%g %g translate\n", X_TO_PS(x1), Y_TO_PS(y1)); 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, "%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_x);
fprintf(fd, "%d\n", png_size_y); fprintf(fd, "%d\n", png_size_y);
fprintf(fd, "8\n"); fprintf(fd, "8\n");
fprintf(fd, "[%d 0 0 %d 0 0]\n", png_size_x, png_size_y); fprintf(fd, "[%d 0 0 %d 0 0]\n", png_size_x, png_size_y);
fprintf(fd, "(%s)\n", hexEncodedJPG); fprintf(fd, "(%s)\n", hexEncodedJPG);
fprintf(fd, "/ASCIIHexDecode\n"); fprintf(fd, "/ASCIIHexDecode\n");
fprintf(fd, "filter\n"); fprintf(fd, "filter\n");
fprintf(fd, "0 dict\n"); fprintf(fd, "0 dict\n");
fprintf(fd, "/DCTDecode\n"); fprintf(fd, "/DCTDecode\n");
fprintf(fd, "filter\n"); fprintf(fd, "filter\n");
fprintf(fd, "false\n"); fprintf(fd, "false\n");
fprintf(fd, "3\n"); fprintf(fd, "3\n");
fprintf(fd, "colorimage\n"); fprintf(fd, "colorimage\n");
fprintf(fd, "grestore\n"); fprintf(fd, "grestore\n");
free(hexEncodedJPG); free(jpgData); free(hexEncodedJPG); free(jpgData);
} }
@ -287,53 +288,53 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
closure.size = 0; closure.size = 0;
closure.pos = 0; closure.pos = 0;
static char str[PATH_MAX]; static char str[PATH_MAX];
my_snprintf(str, S(str), "%s%s", tclgetvar("XSCHEM_TMP_DIR"), "/temp.jpg"); my_snprintf(str, S(str), "%s%s", tclgetvar("XSCHEM_TMP_DIR"), "/temp.jpg");
cairo_image_surface_write_to_jpeg(png_sfc, str, 100); cairo_image_surface_write_to_jpeg(png_sfc, str, 100);
unsigned char* jpgData; unsigned char* jpgData;
FILE* fp; FILE* fp;
fp = fopen(str, "rb"); fp = fopen(str, "rb");
fseek(fp, 0L, SEEK_END); fseek(fp, 0L, SEEK_END);
int fileSize = ftell(fp); int fileSize = ftell(fp);
rewind(fp); rewind(fp);
jpgData = malloc(fileSize); jpgData = malloc(fileSize);
fread(jpgData, sizeof(jpgData[0]), fileSize, fp); fread(jpgData, sizeof(jpgData[0]), fileSize, fp);
fclose(fp); fclose(fp);
unsigned char* hexEncodedJPG = bin2hex(jpgData, fileSize); unsigned char* hexEncodedJPG = bin2hex(jpgData, fileSize);
cairo_surface_destroy(png_sfc); cairo_surface_destroy(png_sfc);
xctx->draw_pixmap = 1; xctx->draw_pixmap = 1;
xctx->draw_window = save_draw_window; xctx->draw_window = save_draw_window;
xctx->do_copy_area = 1; xctx->do_copy_area = 1;
tclsetboolvar("draw_grid", save_draw_grid); tclsetboolvar("draw_grid", save_draw_grid);
save_restore_zoom(0); save_restore_zoom(0);
resetwin(1, 1, 1, 0, 0); resetwin(1, 1, 1, 0, 0);
change_linewidth(-1.); change_linewidth(-1.);
tclsetboolvar("dark_colorscheme", d_c); tclsetboolvar("dark_colorscheme", d_c);
build_colors(0, 0); build_colors(0, 0);
draw(); draw();
fprintf(fd, "gsave\n"); fprintf(fd, "gsave\n");
fprintf(fd, "%f %f translate\n", X_TO_PS(rx1), Y_TO_PS(ry1)); fprintf(fd, "%f %f translate\n", X_TO_PS(rx1), Y_TO_PS(ry1));
fprintf(fd, "%f %f scale\n", X_TO_PS(rx2) - X_TO_PS(rx1), Y_TO_PS(ry2) - Y_TO_PS(ry1)); fprintf(fd, "%f %f scale\n", X_TO_PS(rx2) - X_TO_PS(rx1), Y_TO_PS(ry2) - Y_TO_PS(ry1));
fprintf(fd, "%d\n", rwi); fprintf(fd, "%d\n", rwi);
fprintf(fd, "%d\n", rhi); fprintf(fd, "%d\n", rhi);
fprintf(fd, "8\n"); fprintf(fd, "8\n");
fprintf(fd, "[%d 0 0 %d 0 0]\n", rwi, rhi); fprintf(fd, "[%d 0 0 %d 0 0]\n", rwi, rhi);
fprintf(fd, "(%s)\n", hexEncodedJPG); fprintf(fd, "(%s)\n", hexEncodedJPG);
fprintf(fd, "/ASCIIHexDecode\n"); fprintf(fd, "/ASCIIHexDecode\n");
fprintf(fd, "filter\n"); fprintf(fd, "filter\n");
fprintf(fd, "0 dict\n"); fprintf(fd, "0 dict\n");
fprintf(fd, "/DCTDecode\n"); fprintf(fd, "/DCTDecode\n");
fprintf(fd, "filter\n"); fprintf(fd, "filter\n");
fprintf(fd, "false\n"); fprintf(fd, "false\n");
fprintf(fd, "3\n"); fprintf(fd, "3\n");
fprintf(fd, "colorimage\n"); fprintf(fd, "colorimage\n");
fprintf(fd, "grestore\n"); fprintf(fd, "grestore\n");
free(hexEncodedJPG); free(jpgData); free(hexEncodedJPG); free(jpgData);
#endif #endif
} }
static void set_lw(void) static void set_lw(void)
@ -842,7 +843,7 @@ static void ps_draw_symbol(int n,int layer, int what, short tmp_flip, short rot,
ROTATION(rot, flip, 0.0,0.0,rect.x1,rect.y1,x1,y1); ROTATION(rot, flip, 0.0,0.0,rect.x1,rect.y1,x1,y1);
ROTATION(rot, flip, 0.0,0.0,rect.x2,rect.y2,x2,y2); ROTATION(rot, flip, 0.0,0.0,rect.x2,rect.y2,x2,y2);
RECTORDER(x1,y1,x2,y2); RECTORDER(x1,y1,x2,y2);
if (rect.flags & 1024)//image 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);
continue; continue;
@ -924,8 +925,7 @@ static void fill_ps_colors()
} }
#define A4
void create_ps(char **psfile, int what) void create_ps(char **psfile, int what)
{ {
double dx, dy, scale, scaley; double dx, dy, scale, scaley;
@ -933,9 +933,14 @@ void create_ps(char **psfile, int what)
static int numpages = 0; static int numpages = 0;
double margin=10; /* in postscript points, (1/72)". No need to add margin as xschem zoom full already has margins.*/ double margin=10; /* in postscript points, (1/72)". No need to add margin as xschem zoom full already has margins.*/
/* Legal: 612 792 */ /* Legal: 612 792, A4: 842 595 */
double pagex=792;/* a4, in postscript points, (1/72)" */ #ifdef A4
double pagey=612;/* a4, in postscript points, (1/72)" */ double pagex=842;/* a4, in postscript points, (1/72)" */
double pagey=595;/* a4, in postscript points, (1/72)" */
#else
double pagex=792;/* Legal, in postscript points, (1/72)" */
double pagey=612;/* Legal, in postscript points, (1/72)" */
#endif
xRect boundbox; xRect boundbox;
int c,i, textlayer; int c,i, textlayer;
int old_grid; int old_grid;
@ -1113,13 +1118,13 @@ void create_ps(char **psfile, int what)
} }
if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1024)) { /* image */ if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1024)) { /* image */
xRect* r = &xctx->rect[c][i]; xRect* r = &xctx->rect[c][i];
//PNG Code Here /* PNG Code Here */
ps_drawPNG(r, r->x1, r->y1, r->x2, r->y2); ps_drawPNG(r, r->x1, r->y1, r->x2, r->y2);
} }
if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */ if (c == GRIDLAYER && (xctx->rect[c][i].flags & 1)) { /* graph */
xRect* r = &xctx->rect[c][i]; xRect* r = &xctx->rect[c][i];
ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2); ps_embedded_graph(r, r->x1, r->y1, r->x2, r->y2);
} }
} }
for(i=0;i<xctx->arcs[c];i++) for(i=0;i<xctx->arcs[c];i++)
{ {

View File

@ -1726,9 +1726,9 @@ void change_linewidth(double w)
linew = INT_WIDTH(xctx->lw); linew = INT_WIDTH(xctx->lw);
dbg(1, "Line width = %d\n", linew); dbg(1, "Line width = %d\n", linew);
for(i=0;i<cadlayers;i++) { for(i=0;i<cadlayers;i++) {
XSetLineAttributes (display, xctx->gc[i], linew, LineSolid, CapRound , JoinRound); XSetLineAttributes (display, xctx->gc[i], linew, LineSolid, LINECAP , LINEJOIN);
} }
XSetLineAttributes (display, xctx->gctiled, linew, LineSolid, CapRound , JoinRound); XSetLineAttributes (display, xctx->gctiled, linew, LineSolid, LINECAP , LINEJOIN);
} }
if(!xctx->only_probes) { if(!xctx->only_probes) {
xctx->areax1 = -2*INT_WIDTH(xctx->lw); xctx->areax1 = -2*INT_WIDTH(xctx->lw);

View File

@ -378,7 +378,8 @@ do { \
#define DIG_NWAVES 0.1 /* inverse number: by default 10 digital traces per graph */ #define DIG_NWAVES 0.1 /* inverse number: by default 10 digital traces per graph */
#define DIG_SPACE 0.07 /* trace extends from 0 to DIG_SPACE, so we have DIG_WAVES-DIG_SPACE #define DIG_SPACE 0.07 /* trace extends from 0 to DIG_SPACE, so we have DIG_WAVES-DIG_SPACE
* spacing between traces */ * spacing between traces */
#define LINECAP CapRound /* CapNotLast, CapButt, CapRound, or CapProjecting */
#define LINEJOIN JoinRound /* JoinMiter, JoinRound, or JoinBevel */
typedef struct typedef struct
{ {
unsigned short type; unsigned short type;