Merge branch 'StefanSchippers:master' into master

This commit is contained in:
Rafmag Cabrera 2023-01-18 05:43:11 +00:00 committed by GitHub
commit f50d8ec153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 135 additions and 76 deletions

View File

@ -1,5 +1,6 @@
put /local/xschem/cflags [@ put /local/xschem/cflags [@
@cc/cflags@ @cc/cflags@
@?libs/sul/libjpeg/cflags@
@?libs/gui/cairo/cflags@ @?libs/gui/cairo/cflags@
@?libs/gui/xrender/cflags@ @?libs/gui/xrender/cflags@
@?libs/gui/xcb/cflags@ @?libs/gui/xcb/cflags@
@ -13,6 +14,7 @@ put /local/xschem/cflags [@
put /local/xschem/ldflags [@ put /local/xschem/ldflags [@
@cc/ldflags@ @cc/ldflags@
-lm -lm
@?libs/sul/libjpeg/ldflags@
@?libs/gui/cairo/ldflags@ @?libs/gui/cairo/ldflags@
@?libs/gui/xrender/ldflags@ @?libs/gui/xrender/ldflags@
@?libs/gui/xcb/ldflags@ @?libs/gui/xcb/ldflags@

View File

@ -20,6 +20,9 @@ print [@/*************************************************************/
/* Source: config.h.in; to regenerate run ./configure */ /* Source: config.h.in; to regenerate run ./configure */
/*************************************************************/@] /*************************************************************/@]
print {\n\n/* Define this var if libjpeg is available and is to be used */\n}
print_ternary ?libs/sul/libjpeg/presents {#define HAS_LIBJPEG 1} {/*#undef HAS_LIBJPEG */}
print {\n\n/* Define this var if cairo is available and is to be used */\n} print {\n\n/* Define this var if cairo is available and is to be used */\n}
print_ternary ?libs/gui/cairo/presents {#define HAS_CAIRO 1} {/*#undef HAS_CAIRO */} print_ternary ?libs/gui/cairo/presents {#define HAS_CAIRO 1} {/*#undef HAS_CAIRO */}

View File

@ -9,38 +9,38 @@
#define version "2.0.1" #define version "2.0.1"
int find_sul_pcre(const char *name, int logdepth, int fatal) int find_sul_libjpeg(const char *name, int logdepth, int fatal)
{ {
const char *test_c = const char *test_c =
NL "#include <stdio.h>" NL "#include <stdio.h>"
NL "#include <stdlib.h>" NL "#include <stdlib.h>"
NL "#include <pcre.h>" NL "#include <jpeglib.h>"
NL ""
NL "int main()" NL "int main()"
NL "{" NL "{"
NL " const char *err;" NL " struct jpeg_compress_struct cinfo;"
NL " int erro, ret;" NL " struct jpeg_error_mgr jerr;"
NL " pcre *p = pcre_compile(\"fo+b\", 0, &err, &erro, NULL);" NL " jerr.error_exit = NULL;"
NL " ret = pcre_exec(p, NULL, \"hi foobar\", 9, 0, 0, &erro, 1);" NL " cinfo.err = jpeg_std_error(&jerr);"
NL " if (ret == 0)" NL " jpeg_create_compress(&cinfo);"
NL " jpeg_destroy_compress(&cinfo);"
NL " if(jerr.error_exit)"
NL " puts(\"OK\");" NL " puts(\"OK\");"
NL " return 0;" NL " return 0;"
NL "}" NL "}"
NL; NL;
const char *node = "libs/sul/pcre"; const char *node = "libs/sul/libjpeg";
if (require("cc/cc", logdepth, fatal)) if (require("cc/cc", logdepth, fatal))
return 1; return 1;
report("Checking for pcre... "); report("Checking for libjpeg... ");
if (try_icl_pkg_config(logdepth, "libs/sul/pcre", test_c, NULL, "libpcre", NULL)) if (try_icl_pkg_config(logdepth, node, test_c, NULL, "libjpeg", NULL))
return 0; return 0;
if (try_icl(logdepth, node, test_c, NULL, "-I/usr/include/pcre", "-lpcre")) if (try_icl(logdepth, node, test_c, NULL, NULL, "-ljpeg"))
return 0;
if (try_icl(logdepth, node, test_c, NULL, "-I/usr/include/pcre", "-lpcre3"))
return 0; return 0;
return try_fail(logdepth, node); return try_fail(logdepth, node);
@ -123,6 +123,9 @@ int hook_preinit()
/* Runs after initialization */ /* Runs after initialization */
int hook_postinit() int hook_postinit()
{ {
/* libjpeg detection */
dep_add("libs/sul/libjpeg/*", find_sul_libjpeg);
db_mkdir("/local"); db_mkdir("/local");
db_mkdir("/local/xschem"); db_mkdir("/local/xschem");
@ -289,6 +292,7 @@ int hook_detect_target()
require("fstools/awk", 0, 1); require("fstools/awk", 0, 1);
require("libs/gui/xpm/*", 0, 1); require("libs/gui/xpm/*", 0, 1);
require("libs/gui/cairo/*", 0, 0); require("libs/gui/cairo/*", 0, 0);
require("libs/sul/libjpeg/*", 0, 0);
if (require("libs/gui/cairo-xcb/*", 0, 0) != 0) { if (require("libs/gui/cairo-xcb/*", 0, 0) != 0) {
put("libs/gui/xcb/presents", sfalse); put("libs/gui/xcb/presents", sfalse);
@ -357,6 +361,7 @@ int hook_generate()
printf(" tcl: %s\n", get("/target/libs/script/tcl/ldflags")); printf(" tcl: %s\n", get("/target/libs/script/tcl/ldflags"));
printf(" tk: %s\n", get("/target/libs/script/tk/ldflags")); printf(" tk: %s\n", get("/target/libs/script/tk/ldflags"));
printf(" cairo: %s\n", istrue(get("/target/libs/gui/cairo/presents")) ? "yes" : "no"); printf(" cairo: %s\n", istrue(get("/target/libs/gui/cairo/presents")) ? "yes" : "no");
printf(" libjpeg: %s\n", istrue(get("/target/libs/sul/libjpeg/presents")) ? "yes" : "no");
printf(" xcb: %s\n", istrue(get("/target/libs/gui/xcb/presents")) ? "yes" : "no"); printf(" xcb: %s\n", istrue(get("/target/libs/gui/xcb/presents")) ? "yes" : "no");
printf("\nConfiguration complete, ready to compile.\n\n"); printf("\nConfiguration complete, ready to compile.\n\n");

View File

@ -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) -ljpeg $(CC) -o xschem $(OBJ) $(LDFLAGS)
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

@ -39,6 +39,8 @@
* @license LGPL3. * @license LGPL3.
*/ */
#include "../config.h"
#if defined(HAS_LIBJPEG) && defined(HAS_CAIRO)
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -625,4 +627,5 @@ int main(int argc, char **argv)
} }
#endif #endif
#endif /* HAS_LIBJPEG && HAS_CAIRO */
typedef int make_iso_compilers_happy; /* to avoid empty translation unit */

View File

@ -24,9 +24,6 @@
#define X_TO_PS(x) ( (x+xctx->xorigin)* xctx->mooz ) #define X_TO_PS(x) ( (x+xctx->xorigin)* xctx->mooz )
#define Y_TO_PS(y) ( (y+xctx->yorigin)* xctx->mooz ) #define Y_TO_PS(y) ( (y+xctx->yorigin)* xctx->mooz )
/* FIXME This must be investigated, without some fflushes the ps file is corrupted */
#define FFLUSH_PS
#if 0 #if 0
* /* FIXME: overflow check. Not used, BTW */ * /* FIXME: overflow check. Not used, BTW */
* static char *strreplace(char s[], char token[], char replace[]) * static char *strreplace(char s[], char token[], char replace[])
@ -125,28 +122,32 @@ unsigned char* bin2hex(const unsigned char* bin, size_t len)
return out; return out;
} }
void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, int flip) void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, int flip)
{ {
#if defined(HAS_LIBJPEG) && defined(HAS_CAIRO)
int i; int i;
size_t data_size; size_t data_size = 0;
png_to_byte_closure_t closure; png_to_byte_closure_t closure = {NULL, 0, 0};
char* filter = NULL; char* filter = NULL;
int png_size_x, png_size_y; int png_size_x, png_size_y;
unsigned char *png_data, BG_r, BG_g, BG_b; unsigned char *png_data = NULL, BG_r, BG_g, BG_b;
int invertImage; int invertImage;
/* static char str[PATH_MAX]; /* static char str[PATH_MAX];
* FILE* fp; * FILE* fp;
*/ */
unsigned char* hexEncodedJPG; unsigned char* hexEncodedJPG = NULL;
char* image_data64_ptr = NULL; char* image_data64_ptr = NULL;
cairo_surface_t* surface; cairo_surface_t* surface = NULL;
unsigned char* jpgData = NULL; unsigned char* jpgData = NULL;
size_t fileSize = 0; size_t fileSize = 0;
int quality=100;
const char *quality_attr;
quality_attr = get_tok_value(r->prop_ptr, "jpeg_quality", 0);
if(quality_attr[0]) quality = atoi(quality_attr);
my_strdup(59, &filter, get_tok_value(r->prop_ptr, "filter", 0)); my_strdup(59, &filter, get_tok_value(r->prop_ptr, "filter", 0));
my_strdup2(1183, &image_data64_ptr, get_tok_value(r->prop_ptr, "image_data", 0)); my_strdup2(1183, &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;
@ -163,6 +164,7 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
closure.pos = 0; closure.pos = 0;
closure.size = data_size; /* should not be necessary */ closure.size = data_size; /* should not be necessary */
surface = cairo_image_surface_create_from_png_stream(png_reader, &closure); surface = cairo_image_surface_create_from_png_stream(png_reader, &closure);
png_size_x = cairo_image_surface_get_width(surface); png_size_x = cairo_image_surface_get_width(surface);
png_size_y = cairo_image_surface_get_height(surface); png_size_y = cairo_image_surface_get_height(surface);
@ -171,6 +173,8 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
png_data = cairo_image_surface_get_data(surface); png_data = cairo_image_surface_get_data(surface);
invertImage = !strcmp(get_tok_value(r->prop_ptr, "InvertOnExport", 0), "true"); invertImage = !strcmp(get_tok_value(r->prop_ptr, "InvertOnExport", 0), "true");
if(!invertImage)
invertImage = !strcmp(get_tok_value(r->prop_ptr, "ps_invert", 0), "true");
BG_r = 0xFF; BG_g = 0xFF; BG_b = 0xFF; BG_r = 0xFF; BG_g = 0xFF; BG_b = 0xFF;
for (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)
{ {
@ -196,7 +200,7 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
} }
} }
cairo_surface_mark_dirty(surface); cairo_surface_mark_dirty(surface);
cairo_image_surface_write_to_jpeg_mem(surface, &jpgData, &fileSize, 100); cairo_image_surface_write_to_jpeg_mem(surface, &jpgData, &fileSize, quality);
/* /*
* 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);
@ -246,17 +250,14 @@ void ps_drawPNG(xRect* r, double x1, double y1, double x2, double y2, int rot, i
fprintf(fd, "3\n"); fprintf(fd, "3\n");
fprintf(fd, "colorimage\n"); fprintf(fd, "colorimage\n");
fprintf(fd, "grestore\n"); fprintf(fd, "grestore\n");
#ifdef FFLUSH_PS /* FIXME: why is this needed? */
fflush(fd);
#endif
cairo_surface_destroy(surface); cairo_surface_destroy(surface);
my_free(1663, &hexEncodedJPG); my_free(1663, &hexEncodedJPG);
#endif
} }
void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2) void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
{ {
#if defined(HAS_CAIRO) #if defined(HAS_LIBJPEG) && defined(HAS_CAIRO)
double rw, rh, scale; double rw, rh, scale;
cairo_surface_t* png_sfc; cairo_surface_t* png_sfc;
int save_draw_window, save_draw_grid, rwi, rhi; int save_draw_window, save_draw_grid, rwi, rhi;
@ -269,6 +270,11 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
* static char str[PATH_MAX]; * static char str[PATH_MAX];
*/ */
unsigned char *hexEncodedJPG; unsigned char *hexEncodedJPG;
int quality=100;
const char *quality_attr;
quality_attr = get_tok_value(r->prop_ptr, "jpeg_quality", 0);
if(quality_attr[0]) quality = atoi(quality_attr);
if (!has_x) return; if (!has_x) return;
rw = fabs(rx2 - rx1); rw = fabs(rx2 - rx1);
rh = fabs(ry2 - ry1); rh = fabs(ry2 - ry1);
@ -315,7 +321,7 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
} }
} }
#endif #endif
cairo_image_surface_write_to_jpeg_mem(png_sfc, &jpgData, &fileSize, 100); cairo_image_surface_write_to_jpeg_mem(png_sfc, &jpgData, &fileSize, quality);
/* /*
* 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);
@ -359,12 +365,8 @@ void ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, double ry2)
fprintf(fd, "3\n"); fprintf(fd, "3\n");
fprintf(fd, "colorimage\n"); fprintf(fd, "colorimage\n");
fprintf(fd, "grestore\n"); fprintf(fd, "grestore\n");
#ifdef FFLUSH_PS /* FIXME: why is this needed? */
fflush(fd);
#endif
my_free(1666, &hexEncodedJPG); my_free(1666, &hexEncodedJPG);
#endif #endif
} }
static void set_lw(void) static void set_lw(void)
{ {
@ -380,9 +382,6 @@ static void set_ps_colors(unsigned int pixel)
if(color_ps) fprintf(fd, "%g %g %g RGB\n", if(color_ps) fprintf(fd, "%g %g %g RGB\n",
(double)ps_colors[pixel].red/256.0, (double)ps_colors[pixel].green/256.0, (double)ps_colors[pixel].red/256.0, (double)ps_colors[pixel].green/256.0,
(double)ps_colors[pixel].blue/256.0); (double)ps_colors[pixel].blue/256.0);
#ifdef FFLUSH_PS /* FIXME: why is this needed? */
fflush(fd);
#endif
} }

View File

@ -25,6 +25,34 @@
#include <sys/wait.h> /* waitpid */ #include <sys/wait.h> /* waitpid */
#endif #endif
/* splits a command string into argv-like arguments
* return # of args in *argc
* argv[*argc] is always set to NULL
* parse_cmd_string(NULL, NULL) to clear static allocated data */
#define PARSE_SIZE 128
char **parse_cmd_string(const char *cmd, int *argc)
{
static char *cmd_copy = NULL;
static char *argv[PARSE_SIZE];
char *cmd_ptr, *cmd_save;
if(!cmd || !cmd[0]) {
if(cmd_copy) my_free(1670, &cmd_copy);
return NULL;
}
*argc = 0;
my_strdup2(1669, &cmd_copy, cmd);
cmd_ptr = cmd_copy;
while( (argv[*argc] = my_strtok_r(cmd_ptr, " \t", "'\"", &cmd_save)) ) {
cmd_ptr = NULL;
dbg(1, "--> %s\n", argv[*argc]);
(*argc)++;
if(*argc >= PARSE_SIZE) break;
}
argv[*argc] = NULL; /*terminating pointer needed by execvp() */
return argv;
}
/* get an input databuffer (din[ilen]), and a shell command (cmd) that reads stdin /* get an input databuffer (din[ilen]), and a shell command (cmd) that reads stdin
* and writes stdout, return the result in dout[olen]. * and writes stdout, return the result in dout[olen].
* Caller must free the returned buffer. * Caller must free the returned buffer.
@ -50,29 +78,32 @@ int filter_data(const char *din, const size_t ilen,
pipe(p1); pipe(p1);
pipe(p2); pipe(p2);
signal(SIGPIPE, SIG_IGN); /* so attempting write/read a broken pipe won't kill program */ signal(SIGPIPE, SIG_IGN); /* so attempting write/read a broken pipe won't kill program */
/*
* p2
* ------------------- p2[0] <--------- p2[1] -------------------
* | Parent program | | Child filter |
* ------------------- p1[1] ---------> p1[0] -------------------
* p1
*/
if( (pid = fork()) == 0) { if( (pid = fork()) == 0) {
char **av;
int ac;
/* child */ /* child */
close(p1[1]); /* only read from p1 */ close(p1[1]); /* only read from p1 */
close(p2[0]); /* only write to p2 */ close(p2[0]); /* only write to p2 */
#if 0
dup2(p1[0],0); /* some systems lack this function */
#else
close(0); /* dup2(p1[0],0); */ /* connect read side of read pipe to stdin */ close(0); /* dup2(p1[0],0); */ /* connect read side of read pipe to stdin */
dup(p1[0]); dup(p1[0]);
#endif
#if 0
dup2(p2[1],1); /* some systems lack this function */
#else
close(1); /* dup2(p2[1],1); */ /* connect write side of write pipe to stdout */ close(1); /* dup2(p2[1],1); */ /* connect write side of write pipe to stdout */
dup(p2[1]); dup(p2[1]);
#endif
/* execlp("gm", "gm", "convert", "-", "-quality", "50", "jpg:-", NULL); */
if(system(cmd)) { av = parse_cmd_string(cmd, &ac);
if(execvp(av[0], av) == -1) {
fprintf(stderr, "error: conversion failed\n"); fprintf(stderr, "error: conversion failed\n");
ret = 1;
}
close(p1[0]); close(p1[0]);
close(p2[1]); close(p2[1]);
ret = 1;
}
exit(ret); exit(ret);
} }
/* parent */ /* parent */
@ -100,7 +131,6 @@ int filter_data(const char *din, const size_t ilen,
} }
if(*olen) (*dout)[*olen] = '\0'; /* so (if ascii) it can be used as a string */ if(*olen) (*dout)[*olen] = '\0'; /* so (if ascii) it can be used as a string */
} }
close(p2[0]);
if(n < 0 || !*olen) { if(n < 0 || !*olen) {
if(oalloc) { if(oalloc) {
my_free(1483, dout); my_free(1483, dout);
@ -110,10 +140,11 @@ int filter_data(const char *din, const size_t ilen,
ret = 1; ret = 1;
} }
waitpid(pid, NULL, 0); /* write for child process to finish and unzombie it */ waitpid(pid, NULL, 0); /* write for child process to finish and unzombie it */
close(p2[0]);
signal(SIGPIPE, SIG_DFL); /* restore default SIGPIPE signal action */ signal(SIGPIPE, SIG_DFL); /* restore default SIGPIPE signal action */
return ret; return ret;
} }
#else #else /* anyone wanting to write a similar function for windows Welcome! */
int filter_data(const char* din, const size_t ilen, int filter_data(const char* din, const size_t ilen,
char** dout, size_t* olen, char** dout, size_t* olen,
const char* cmd) const char* cmd)

View File

@ -1875,7 +1875,19 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else { cmd_found = 0;} else { cmd_found = 0;}
break; break;
case 'p': /*----------------------------------------------*/ case 'p': /*----------------------------------------------*/
if(!strcmp(argv[1], "parselabel")) if(!strcmp(argv[1], "parse_cmd"))
{
if(argc > 2) {
int c, i;
char **av;
av = parse_cmd_string(argv[2], &c);
for(i = 0; i < c; i++) {
dbg(0, "--> %s\n", av[i]);
}
}
}
else if(!strcmp(argv[1], "parselabel"))
{ {
if(argc > 2) { if(argc > 2) {
parse(argv[2]); parse(argv[2]);

View File

@ -1361,6 +1361,7 @@ extern void my_strndup(int id, char **dest, const char *src, size_t n);
extern size_t my_strdup2(int id, char **dest, const char *src); extern size_t my_strdup2(int id, char **dest, const char *src);
extern char *my_fgets(FILE *fd); extern char *my_fgets(FILE *fd);
extern char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr); extern char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr);
extern char **parse_cmd_string(const char *cmd, int *argc);
extern int my_strncpy(char *d, const char *s, size_t n); extern int my_strncpy(char *d, const char *s, size_t n);
extern int my_strcasecmp(const char *s1, const char *s2); extern int my_strcasecmp(const char *s1, const char *s2);
extern double mylog10(double x); extern double mylog10(double x);

File diff suppressed because one or more lines are too long