mirror of https://github.com/fltk/fltk
Fl_SVG_Image class: add support for compressed .svgz image files.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12477 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
7a9d5be6cb
commit
0b797d704c
|
@ -74,6 +74,7 @@ public:
|
|||
virtual void color_average(Fl_Color c, float i);
|
||||
virtual void draw(int X, int Y, int W, int H, int cx = 0, int cy = 0);
|
||||
void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); }
|
||||
static void* gzopen(const char *fname);
|
||||
};
|
||||
|
||||
#endif // FL_SVG_IMAGE_H
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#include <FL/Fl_Screen_Driver.H>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(HAVE_LIBZ)
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_LONG_LONG)
|
||||
static double strtoll(const char *str, char **endptr, int base) {
|
||||
|
@ -41,8 +44,8 @@ static double strtoll(const char *str, char **endptr, int base) {
|
|||
#include "../nanosvg/altsvgrast.h"
|
||||
|
||||
|
||||
/** The constructor loads the SVG image from the given .svg filename or in-memory data.
|
||||
\param filename A full path and name pointing to an SVG file, or NULL.
|
||||
/** The constructor loads the SVG image from the given .svg/.svgz filename or in-memory data.
|
||||
\param filename A full path and name pointing to a .svg or .svgz file, or NULL.
|
||||
\param filedata A pointer to the memory location of the SVG image data.
|
||||
This parameter allows to load an SVG image from in-memory data, and is used when \p filename is NULL.
|
||||
\note In-memory SVG data is modified by the object constructor and is no longer used after construction.
|
||||
|
@ -73,6 +76,55 @@ float Fl_SVG_Image::svg_scaling_(int W, int H) {
|
|||
return (f1 < f2) ? f1 : f2;
|
||||
}
|
||||
|
||||
/** Opens for reading a potentially gzip'ed file identified by a UTF-8 encoded filename. */
|
||||
void* Fl_SVG_Image::gzopen(const char *fname) {
|
||||
#if defined(HAVE_LIBZ)
|
||||
# ifdef _WIN32
|
||||
unsigned wl = fl_utf8towc(fname, strlen(fname), NULL, 0) + 1;
|
||||
wchar_t *wc = new wchar_t[wl];
|
||||
fl_utf8towc(fname, strlen(fname), wc, wl);
|
||||
gzFile gzf = gzopen_w(wc, "r");
|
||||
delete[] wc;
|
||||
return gzf;
|
||||
# else
|
||||
int fd = fl_open(fname, 0);
|
||||
if (fd < 0) return NULL;
|
||||
return gzdopen(fd, "r");
|
||||
# endif
|
||||
#else
|
||||
return NULL;
|
||||
#endif // HAVE_LIBZ
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBZ)
|
||||
|
||||
static char *svg_inflate(const char *fname) {
|
||||
struct stat b;
|
||||
fl_stat(fname, &b);
|
||||
long size = b.st_size;
|
||||
gzFile gzf = (gzFile)Fl_SVG_Image::gzopen(fname);
|
||||
int l;
|
||||
bool direct = gzdirect(gzf);
|
||||
long out_size = direct ? size + 1 : 3*size + 1;
|
||||
char *out = (char*)malloc(out_size);
|
||||
char *p = out;
|
||||
do {
|
||||
if ((!direct) && p + size > out + out_size) {
|
||||
out_size += size;
|
||||
char *tmp = (char*)realloc(out, out_size + 1);
|
||||
p = tmp + (p - out);
|
||||
out = tmp;
|
||||
}
|
||||
l = gzread(gzf, p, size);
|
||||
if (l > 0) {
|
||||
p += l; *p = 0;
|
||||
}
|
||||
} while ((!direct) && l >0);
|
||||
gzclose(gzf);
|
||||
if (!direct) out = (char*)realloc(out, (p-out)+1);
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Fl_SVG_Image::init_(const char *filename, char *filedata, Fl_SVG_Image *copy_source) {
|
||||
if (copy_source) {
|
||||
|
@ -88,22 +140,29 @@ void Fl_SVG_Image::init_(const char *filename, char *filedata, Fl_SVG_Image *cop
|
|||
average_weight_ = 1;
|
||||
proportional = true;
|
||||
if (filename) {
|
||||
#if defined(HAVE_LIBZ)
|
||||
filedata = svg_inflate(filename);
|
||||
#else
|
||||
filedata = NULL;
|
||||
FILE *fp = fl_fopen(filename, "rb");
|
||||
if (fp) {
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = ftell(fp);
|
||||
long size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
filedata = (char*)malloc(size+1);
|
||||
if (filedata) {
|
||||
if (fread(filedata, 1, size, fp) == size) filedata[size] = '\0';
|
||||
if (fread(filedata, 1, size, fp) == size) {
|
||||
filedata[size] = '\0';
|
||||
}
|
||||
else {
|
||||
free(filedata);
|
||||
filedata = NULL;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
} else ld(ERR_FILE_ACCESS);
|
||||
}
|
||||
#endif // HAVE_LIBZ
|
||||
if (!filedata) ld(ERR_FILE_ACCESS);
|
||||
}
|
||||
if (filedata) {
|
||||
counted_svg_image_->svg_image = nsvgParse(filedata, "px", 96);
|
||||
|
|
|
@ -35,7 +35,9 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "flstring.h"
|
||||
|
||||
#if defined(HAVE_LIBZ)
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// Define a simple global image registration function that registers
|
||||
|
@ -90,6 +92,15 @@ fl_check_images(const char *name, // I - Filename
|
|||
#endif // HAVE_LIBJPEG
|
||||
|
||||
#ifdef FLTK_USE_NANOSVG
|
||||
# if defined(HAVE_LIBZ)
|
||||
if (header[0] == 0x1f && header[1] == 0x8b) { // denotes gzip'ed data
|
||||
gzFile gzf = (gzFile)Fl_SVG_Image::gzopen(name);
|
||||
if (gzf) {
|
||||
gzread(gzf, header, headerlen);
|
||||
gzclose(gzf);
|
||||
}
|
||||
}
|
||||
# endif // HAVE_LIBZ
|
||||
if ( (headerlen > 5 && memcmp(header, "<?xml", 5) == 0) ||
|
||||
memcmp(header, "<svg", 4) == 0)
|
||||
return new Fl_SVG_Image(name);
|
||||
|
|
|
@ -79,6 +79,9 @@ void button_cb(Fl_Widget *,void *) {
|
|||
const char *fname = fl_file_chooser("Image file?","*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm"
|
||||
#ifdef FLTK_USE_NANOSVG
|
||||
",svg"
|
||||
#ifdef HAVE_LIBZ
|
||||
",svgz"
|
||||
#endif
|
||||
#endif
|
||||
"}", name);
|
||||
puts(fname ? fname : "(null)"); fflush(stdout);
|
||||
|
|
Loading…
Reference in New Issue