Add new Fl_SVG_Image class to support scalable vector graphics images using the (modified) nanosvg software.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12413 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
da31ff4569
commit
1a28d85dc3
@ -148,6 +148,13 @@ else()
|
|||||||
set(FLTK_CAIRO_FOUND FALSE)
|
set(FLTK_CAIRO_FOUND FALSE)
|
||||||
endif(LIB_CAIRO AND OPTION_CAIROEXT AND PKG_CAIRO_FOUND)
|
endif(LIB_CAIRO AND OPTION_CAIROEXT AND PKG_CAIRO_FOUND)
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
option(OPTION_USE_NANOSVG "support SVG images" ON)
|
||||||
|
|
||||||
|
if(OPTION_USE_NANOSVG)
|
||||||
|
set(FLTK_USE_NANOSVG 1)
|
||||||
|
endif(OPTION_USE_NANOSVG)
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
set(HAVE_GL LIB_GL OR LIB_MesaGL)
|
set(HAVE_GL LIB_GL OR LIB_MesaGL)
|
||||||
|
|
||||||
|
82
FL/Fl_SVG_Image.H
Normal file
82
FL/Fl_SVG_Image.H
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// "$Id: Fl_SVG_Image.H 12239 2017-05-17 11:54:18Z manolo $"
|
||||||
|
//
|
||||||
|
// SVG Image header file for the Fast Light Tool Kit (FLTK).
|
||||||
|
//
|
||||||
|
// Copyright 2017 by Bill Spitzak and others.
|
||||||
|
//
|
||||||
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
|
// file is missing or damaged, see the license at:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/COPYING.php
|
||||||
|
//
|
||||||
|
// Please report all bugs and problems on the following page:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/str.php
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FL_SVG_IMAGE_H
|
||||||
|
#define FL_SVG_IMAGE_H
|
||||||
|
|
||||||
|
#include <FL/Fl_Image.H>
|
||||||
|
|
||||||
|
struct NSVGimage;
|
||||||
|
|
||||||
|
/** The Fl_SVG_Image class supports loading, caching and drawing of scalable vector graphics (SVG) images.
|
||||||
|
The FLTK library performs parsing and rasterization of SVG data using a modified version
|
||||||
|
of the \c nanosvg software (https://github.com/memononen/nanosvg) © 2013-14 Mikko Mononen
|
||||||
|
(memon@inside.org). The software modification allows the option to change the image ratio
|
||||||
|
while performing rasterization.
|
||||||
|
|
||||||
|
Use Fl_Image::fail() to check if the Fl_SVG_Image failed to load. fail() returns ERR_FILE_ACCESS
|
||||||
|
if the file could not be opened or read, and ERR_FORMAT if the SVG format could not be decoded.
|
||||||
|
If the image has loaded correctly, w(), h(), and d() should return values greater than zero.
|
||||||
|
|
||||||
|
Rasterization is not done until the image is first drawn or resize() is called. Therefore,
|
||||||
|
array() is NULL until then. The delayed rasterization ensures an Fl_Shared_Image based on
|
||||||
|
an SVG image and scaled to its display size by calling Fl_Shared_Image::scale() will be
|
||||||
|
always rasterized to the exact screen resolution.
|
||||||
|
|
||||||
|
The Fl_SVG_Image class draws images computed by \c nanosvg: one known limitation is that text
|
||||||
|
within \c <text\></text\> blocks is not rendered.
|
||||||
|
|
||||||
|
The FLTK library can optionally be built without SVG support; in that case,
|
||||||
|
class Fl_SVG_Image is unavailable.
|
||||||
|
*/
|
||||||
|
class FL_EXPORT Fl_SVG_Image : public Fl_RGB_Image {
|
||||||
|
private:
|
||||||
|
typedef struct {
|
||||||
|
NSVGimage* svg_image;
|
||||||
|
int ref_count;
|
||||||
|
} counted_NSVGimage;
|
||||||
|
counted_NSVGimage* counted_svg_image_;
|
||||||
|
bool rasterized_;
|
||||||
|
int raster_w_, raster_h_;
|
||||||
|
bool to_desaturate_;
|
||||||
|
Fl_Color average_color_;
|
||||||
|
float average_weight_;
|
||||||
|
float svg_scaling_(int W, int H);
|
||||||
|
void rasterize_(int W, int H);
|
||||||
|
void init_(const char *filename, char *filedata, Fl_SVG_Image *copy_source);
|
||||||
|
virtual int draw_scaled_(int X, int Y, int W, int H);
|
||||||
|
Fl_SVG_Image(Fl_SVG_Image *source);
|
||||||
|
public:
|
||||||
|
/** Set this to \c false to allow image re-scaling that alters the image aspect ratio.
|
||||||
|
Upon object creation, \c proportional is set to \c true, and the aspect ratio is kept constant.*/
|
||||||
|
bool proportional;
|
||||||
|
Fl_SVG_Image(const char *filename, char *filedata = NULL);
|
||||||
|
virtual ~Fl_SVG_Image();
|
||||||
|
virtual Fl_Image *copy(int W, int H);
|
||||||
|
void resize(int width, int height);
|
||||||
|
virtual void desaturate();
|
||||||
|
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); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FL_SVG_IMAGE_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of "$Id: Fl_SVG_Image.H 12239 2017-05-17 11:54:18Z manolo $".
|
||||||
|
//
|
@ -328,6 +328,14 @@
|
|||||||
#cmakedefine HAVE_PNG_GET_VALID 1
|
#cmakedefine HAVE_PNG_GET_VALID 1
|
||||||
#cmakedefine HAVE_PNG_SET_TRNS_TO_ALPHA 1
|
#cmakedefine HAVE_PNG_SET_TRNS_TO_ALPHA 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FLTK_USE_NANOSVG
|
||||||
|
*
|
||||||
|
* Do we want FLTK to support SVG images with nanosvg ?
|
||||||
|
*/
|
||||||
|
|
||||||
|
#cmakedefine FLTK_USE_NANOSVG 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do we have POSIX threading?
|
* Do we have POSIX threading?
|
||||||
*/
|
*/
|
||||||
|
@ -297,6 +297,7 @@
|
|||||||
#undef HAVE_LIBPNG
|
#undef HAVE_LIBPNG
|
||||||
#undef HAVE_LIBZ
|
#undef HAVE_LIBZ
|
||||||
#undef HAVE_LIBJPEG
|
#undef HAVE_LIBJPEG
|
||||||
|
#undef FLTK_USE_NANOSVG
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FLTK_USE_CAIRO
|
* FLTK_USE_CAIRO
|
||||||
|
@ -766,6 +766,12 @@ AC_SUBST(PNGINC)
|
|||||||
AC_SUBST(ZLIB)
|
AC_SUBST(ZLIB)
|
||||||
AC_SUBST(ZLIBINC)
|
AC_SUBST(ZLIBINC)
|
||||||
|
|
||||||
|
# Control the usage of the nanosvg lib
|
||||||
|
AC_ARG_ENABLE(nanosvg, [ --enable-nanosvg use nanosvg to support SVG images [[default=yes]]])
|
||||||
|
if test x$enable_nanosvg != xno; then
|
||||||
|
AC_DEFINE(FLTK_USE_NANOSVG)
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Restore original LIBS settings...
|
dnl Restore original LIBS settings...
|
||||||
LIBS="$SAVELIBS"
|
LIBS="$SAVELIBS"
|
||||||
|
|
||||||
|
136
nanosvg/altsvgrast.diff
Normal file
136
nanosvg/altsvgrast.diff
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
1,6d0
|
||||||
|
< //
|
||||||
|
< // "$Id: altsvgrast.h 12239 2017-05-17 11:54:18Z XX $"
|
||||||
|
< //
|
||||||
|
<
|
||||||
|
< /* Modified by FLTK from original sources to support non-square X,Y axes scaling */
|
||||||
|
<
|
||||||
|
31d24
|
||||||
|
<
|
||||||
|
51,53d43
|
||||||
|
<
|
||||||
|
< // For non-square X,Y scaling, use
|
||||||
|
< nsvgAltRasterize(rast, image, 0,0,1,1, img, w, h, w*4);
|
||||||
|
63c53
|
||||||
|
< // scale - image scale (assumes square aspect ratio)
|
||||||
|
---
|
||||||
|
> // scale - image scale
|
||||||
|
72,77d61
|
||||||
|
< // As above, but allow X and Y axes to scale independently for non-square aspects
|
||||||
|
< void nsvgAltRasterize(NSVGrasterizer* r,
|
||||||
|
< NSVGimage* image, float tx, float ty,
|
||||||
|
< float sx, float sy,
|
||||||
|
< unsigned char* dst, int w, int h, int stride);
|
||||||
|
<
|
||||||
|
382c366
|
||||||
|
< static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float sx, float sy)
|
||||||
|
---
|
||||||
|
> static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
|
||||||
|
390c374
|
||||||
|
< nsvg__addPathPoint(r, path->pts[0]*sx, path->pts[1]*sy, 0);
|
||||||
|
---
|
||||||
|
> nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
|
||||||
|
393c377
|
||||||
|
< nsvg__flattenCubicBez(r, p[0]*sx,p[1]*sy, p[2]*sx,p[3]*sy, p[4]*sx,p[5]*sy, p[6]*sx,p[7]*sy, 0, 0);
|
||||||
|
---
|
||||||
|
> nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0);
|
||||||
|
396c380
|
||||||
|
< nsvg__addPathPoint(r, path->pts[0]*sx, path->pts[1]*sy, 0);
|
||||||
|
---
|
||||||
|
> nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
|
||||||
|
746c730
|
||||||
|
< static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float sx, float sy)
|
||||||
|
---
|
||||||
|
> static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale)
|
||||||
|
754,755c738
|
||||||
|
< const float sw = (sx + sy) / 2; // average scaling factor
|
||||||
|
< const float lineWidth = shape->strokeWidth * sw; // FIXME (?)
|
||||||
|
---
|
||||||
|
> float lineWidth = shape->strokeWidth * scale;
|
||||||
|
760c743
|
||||||
|
< nsvg__addPathPoint(r, path->pts[0]*sx, path->pts[1]*sy, NSVG_PT_CORNER);
|
||||||
|
---
|
||||||
|
> nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER);
|
||||||
|
763c746
|
||||||
|
< nsvg__flattenCubicBez(r, p[0]*sx,p[1]*sy, p[2]*sx,p[3]*sy, p[4]*sx,p[5]*sy, p[6]*sx,p[7]*sy, 0, NSVG_PT_CORNER);
|
||||||
|
---
|
||||||
|
> nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER);
|
||||||
|
809c792
|
||||||
|
< dashLen = (shape->strokeDashArray[idash] - dashOffset) * sw;
|
||||||
|
---
|
||||||
|
> dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale;
|
||||||
|
831c814
|
||||||
|
< dashLen = shape->strokeDashArray[idash] * sw;
|
||||||
|
---
|
||||||
|
> dashLen = shape->strokeDashArray[idash] * scale;
|
||||||
|
1000c983
|
||||||
|
< float tx, float ty, float sx, float sy, NSVGcachedPaint* cache)
|
||||||
|
---
|
||||||
|
> float tx, float ty, float scale, NSVGcachedPaint* cache)
|
||||||
|
1041,1043c1024,1026
|
||||||
|
< fx = ((float)x - tx) / sx;
|
||||||
|
< fy = ((float)y - ty) / sy;
|
||||||
|
< dx = 1.0f / sx;
|
||||||
|
---
|
||||||
|
> fx = ((float)x - tx) / scale;
|
||||||
|
> fy = ((float)y - ty) / scale;
|
||||||
|
> dx = 1.0f / scale;
|
||||||
|
1086,1088c1069,1071
|
||||||
|
< fx = ((float)x - tx) / sx;
|
||||||
|
< fy = ((float)y - ty) / sy;
|
||||||
|
< dx = 1.0f / sx;
|
||||||
|
---
|
||||||
|
> fx = ((float)x - tx) / scale;
|
||||||
|
> fy = ((float)y - ty) / scale;
|
||||||
|
> dx = 1.0f / scale;
|
||||||
|
1127c1110
|
||||||
|
< static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float sx, float sy, NSVGcachedPaint* cache, char fillRule)
|
||||||
|
---
|
||||||
|
> static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule)
|
||||||
|
1209c1192
|
||||||
|
< nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, sx, sy, cache);
|
||||||
|
---
|
||||||
|
> nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache);
|
||||||
|
1377,1379c1360,1361
|
||||||
|
< void nsvgAltRasterize(NSVGrasterizer* r,
|
||||||
|
< NSVGimage* image, float tx, float ty,
|
||||||
|
< float sx, float sy,
|
||||||
|
---
|
||||||
|
> void nsvgRasterize(NSVGrasterizer* r,
|
||||||
|
> NSVGimage* image, float tx, float ty, float scale,
|
||||||
|
1410c1392
|
||||||
|
< nsvg__flattenShape(r, shape, sx, sy);
|
||||||
|
---
|
||||||
|
> nsvg__flattenShape(r, shape, scale);
|
||||||
|
1427c1409
|
||||||
|
< nsvg__rasterizeSortedEdges(r, tx,ty, sx, sy, &cache, shape->fillRule);
|
||||||
|
---
|
||||||
|
> nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule);
|
||||||
|
1429c1411
|
||||||
|
< if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * sx) > 0.01f) {
|
||||||
|
---
|
||||||
|
> if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) {
|
||||||
|
1434c1416
|
||||||
|
< nsvg__flattenShapeStroke(r, shape, sx, sy);
|
||||||
|
---
|
||||||
|
> nsvg__flattenShapeStroke(r, shape, scale);
|
||||||
|
1453c1435
|
||||||
|
< nsvg__rasterizeSortedEdges(r, tx,ty,sx, sy, &cache, NSVG_FILLRULE_NONZERO);
|
||||||
|
---
|
||||||
|
> nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO);
|
||||||
|
1465,1477c1447
|
||||||
|
< void nsvgRasterize(NSVGrasterizer* r,
|
||||||
|
< NSVGimage* image, float tx, float ty, float scale,
|
||||||
|
< unsigned char* dst, int w, int h, int stride)
|
||||||
|
< {
|
||||||
|
< nsvgAltRasterize(r,image, tx, ty, scale, scale, dst, w, h, stride);
|
||||||
|
< }
|
||||||
|
<
|
||||||
|
< #endif // NANOSVGRAST_IMPLEMENTATION
|
||||||
|
<
|
||||||
|
<
|
||||||
|
< //
|
||||||
|
< // End of "$Id: altsvgrast.h 12239 2017-05-17 11:54:18Z XX $".
|
||||||
|
< //
|
||||||
|
---
|
||||||
|
> #endif
|
1477
nanosvg/altsvgrast.h
Normal file
1477
nanosvg/altsvgrast.h
Normal file
File diff suppressed because it is too large
Load Diff
2925
nanosvg/nanosvg.h
Normal file
2925
nanosvg/nanosvg.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -367,6 +367,7 @@ set (IMGCPPFILES
|
|||||||
Fl_JPEG_Image.cxx
|
Fl_JPEG_Image.cxx
|
||||||
Fl_PNG_Image.cxx
|
Fl_PNG_Image.cxx
|
||||||
Fl_PNM_Image.cxx
|
Fl_PNM_Image.cxx
|
||||||
|
Fl_SVG_Image.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
set (CFILES
|
set (CFILES
|
||||||
|
206
src/Fl_SVG_Image.cxx
Normal file
206
src/Fl_SVG_Image.cxx
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
//
|
||||||
|
// "$Id: Fl_SVG_Image.cxx 12239 2017-05-17 11:54:18Z manolo $"
|
||||||
|
//
|
||||||
|
// SVG image code for the Fast Light Tool Kit (FLTK).
|
||||||
|
//
|
||||||
|
// Copyright 2017 by Bill Spitzak and others.
|
||||||
|
//
|
||||||
|
// This library is free software. Distribution and use rights are outlined in
|
||||||
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
|
// file is missing or damaged, see the license at:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/COPYING.php
|
||||||
|
//
|
||||||
|
// Please report all bugs and problems on the following page:
|
||||||
|
//
|
||||||
|
// http://www.fltk.org/str.php
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined(FLTK_USE_NANOSVG) || defined(FL_DOXYGEN)
|
||||||
|
|
||||||
|
#include <FL/Fl_SVG_Image.H>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define NANOSVG_ALL_COLOR_KEYWORDS // Include full list of color keywords.
|
||||||
|
#define NANOSVG_IMPLEMENTATION // Expands implementation
|
||||||
|
#include "../nanosvg/nanosvg.h"
|
||||||
|
|
||||||
|
#define NANOSVGRAST_IMPLEMENTATION // Expands implementation
|
||||||
|
#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.
|
||||||
|
\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 requires that \p filename is NULL.
|
||||||
|
\note In-memory SVG data is modified by the object constructor and is no longer used after construction.
|
||||||
|
*/
|
||||||
|
Fl_SVG_Image::Fl_SVG_Image(const char *filename, char *filedata) : Fl_RGB_Image(NULL, 0, 0, 4) {
|
||||||
|
init_(filename, filedata, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// private constructor
|
||||||
|
Fl_SVG_Image::Fl_SVG_Image(Fl_SVG_Image *source) : Fl_RGB_Image(NULL, 0, 0, 4) {
|
||||||
|
init_(NULL, NULL, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** The destructor frees all memory and server resources that are used by the SVG image. */
|
||||||
|
Fl_SVG_Image::~Fl_SVG_Image() {
|
||||||
|
if ( --counted_svg_image_->ref_count <= 0) {
|
||||||
|
nsvgDelete(counted_svg_image_->svg_image);
|
||||||
|
delete counted_svg_image_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Fl_SVG_Image::svg_scaling_(int W, int H) {
|
||||||
|
float f1 = float(W) / int(counted_svg_image_->svg_image->width+0.5);
|
||||||
|
float f2 = float(H) / int(counted_svg_image_->svg_image->height+0.5);
|
||||||
|
return (f1 < f2) ? f1 : f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_SVG_Image::init_(const char *filename, char *filedata, Fl_SVG_Image *copy_source) {
|
||||||
|
if (copy_source) {
|
||||||
|
filename = filedata = NULL;
|
||||||
|
counted_svg_image_ = copy_source->counted_svg_image_;
|
||||||
|
counted_svg_image_->ref_count++;
|
||||||
|
} else {
|
||||||
|
counted_svg_image_ = new counted_NSVGimage;
|
||||||
|
counted_svg_image_->svg_image = NULL;
|
||||||
|
counted_svg_image_->ref_count = 1;
|
||||||
|
}
|
||||||
|
to_desaturate_ = false;
|
||||||
|
average_weight_ = 1;
|
||||||
|
proportional = true;
|
||||||
|
if (filename) {
|
||||||
|
filedata = NULL;
|
||||||
|
FILE *fp = fopen(filename, "rb");
|
||||||
|
if (fp) {
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
size_t 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';
|
||||||
|
else {
|
||||||
|
free(filedata);
|
||||||
|
filedata = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
} else ld(ERR_FILE_ACCESS);
|
||||||
|
}
|
||||||
|
if (filedata) {
|
||||||
|
counted_svg_image_->svg_image = nsvgParse(filedata, "px", 96);
|
||||||
|
if (filename) free(filedata);
|
||||||
|
if (counted_svg_image_->svg_image->width == 0 || counted_svg_image_->svg_image->height == 0) {
|
||||||
|
d(-1);
|
||||||
|
ld(ERR_FORMAT);
|
||||||
|
} else {
|
||||||
|
w(counted_svg_image_->svg_image->width + 0.5);
|
||||||
|
h(counted_svg_image_->svg_image->height + 0.5);
|
||||||
|
}
|
||||||
|
} else if (copy_source) {
|
||||||
|
w(copy_source->w());
|
||||||
|
h(copy_source->h());
|
||||||
|
}
|
||||||
|
rasterized_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_SVG_Image::rasterize_(int W, int H) {
|
||||||
|
static NSVGrasterizer *rasterizer = nsvgCreateRasterizer();
|
||||||
|
double fx, fy;
|
||||||
|
if (proportional) {
|
||||||
|
fx = svg_scaling_(W, H);
|
||||||
|
fy = fx;
|
||||||
|
} else {
|
||||||
|
fx = (double)W / counted_svg_image_->svg_image->width;
|
||||||
|
fy = (double)H / counted_svg_image_->svg_image->height;
|
||||||
|
}
|
||||||
|
array = new uchar[W*H*4];
|
||||||
|
nsvgAltRasterize(rasterizer, counted_svg_image_->svg_image, 0, 0, fx, fy, (uchar* )array, W, H, W*4);
|
||||||
|
alloc_array = 1;
|
||||||
|
data((const char * const *)&array, 1);
|
||||||
|
d(4);
|
||||||
|
if (to_desaturate_) Fl_RGB_Image::desaturate();
|
||||||
|
if (average_weight_ < 1) Fl_RGB_Image::color_average(average_color_, average_weight_);
|
||||||
|
rasterized_ = true;
|
||||||
|
raster_w_ = W;
|
||||||
|
raster_h_ = H;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Fl_Image *Fl_SVG_Image::copy(int W, int H) {
|
||||||
|
Fl_SVG_Image *svg2 = new Fl_SVG_Image(this);
|
||||||
|
svg2->to_desaturate_ = to_desaturate_;
|
||||||
|
svg2->average_weight_ = average_weight_;
|
||||||
|
svg2->average_color_ = average_color_;
|
||||||
|
svg2->w(W); svg2->h(H);
|
||||||
|
return svg2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Have the svg data (re-)rasterized using the given width and height values.
|
||||||
|
By default, the resulting image width and height will preserve the width/height ratio
|
||||||
|
of the SVG data.
|
||||||
|
If \ref proportional was set to false, the image is rasterized to the given \c width
|
||||||
|
and \v height values.*/
|
||||||
|
void Fl_SVG_Image::resize(int width, int height) {
|
||||||
|
if (ld() < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int w1 = width, h1 = height;
|
||||||
|
if (proportional) {
|
||||||
|
float f = svg_scaling_(width, height);
|
||||||
|
w1 = int( int(counted_svg_image_->svg_image->width+0.5)*f + 0.5 );
|
||||||
|
h1 = int( int(counted_svg_image_->svg_image->height+0.5)*f + 0.5 );
|
||||||
|
}
|
||||||
|
w(w1); h(h1);
|
||||||
|
if (rasterized_ && w1 == raster_w_ && h1 == raster_h_) return;
|
||||||
|
if (array) {
|
||||||
|
delete[] array;
|
||||||
|
array = NULL;
|
||||||
|
}
|
||||||
|
uncache();
|
||||||
|
rasterize_(w1, h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_SVG_Image::draw(int X, int Y, int W, int H, int cx, int cy) {
|
||||||
|
resize(w(), h());
|
||||||
|
Fl_RGB_Image::draw(X, Y, W, H, cx, cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_SVG_Image::desaturate() {
|
||||||
|
to_desaturate_ = true;
|
||||||
|
Fl_RGB_Image::desaturate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fl_SVG_Image::color_average(Fl_Color c, float i) {
|
||||||
|
average_color_ = c;
|
||||||
|
average_weight_ = i;
|
||||||
|
Fl_RGB_Image::color_average(c, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Fl_SVG_Image::draw_scaled_(int X, int Y, int W, int H) {
|
||||||
|
w(W);
|
||||||
|
h(H);
|
||||||
|
draw(X, Y, W, H, 0, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FLTK_USE_NANOSVG
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of "$Id: Fl_SVG_Image.cxx 12239 2017-05-17 11:54:18Z manolo $".
|
||||||
|
//
|
@ -209,7 +209,8 @@ IMGCPPFILES = \
|
|||||||
Fl_Help_Dialog.cxx \
|
Fl_Help_Dialog.cxx \
|
||||||
Fl_JPEG_Image.cxx \
|
Fl_JPEG_Image.cxx \
|
||||||
Fl_PNG_Image.cxx \
|
Fl_PNG_Image.cxx \
|
||||||
Fl_PNM_Image.cxx
|
Fl_PNM_Image.cxx \
|
||||||
|
Fl_SVG_Image.cxx
|
||||||
|
|
||||||
|
|
||||||
CFILES = fl_call_main.c flstring.c numericsort.c vsnprintf.c
|
CFILES = fl_call_main.c flstring.c numericsort.c vsnprintf.c
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <FL/Fl_JPEG_Image.H>
|
#include <FL/Fl_JPEG_Image.H>
|
||||||
#include <FL/Fl_PNG_Image.H>
|
#include <FL/Fl_PNG_Image.H>
|
||||||
#include <FL/Fl_PNM_Image.H>
|
#include <FL/Fl_PNM_Image.H>
|
||||||
|
#include <FL/Fl_SVG_Image.H>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "flstring.h"
|
#include "flstring.h"
|
||||||
@ -63,7 +64,7 @@ void fl_register_images() {
|
|||||||
Fl_Image * // O - Image, if found
|
Fl_Image * // O - Image, if found
|
||||||
fl_check_images(const char *name, // I - Filename
|
fl_check_images(const char *name, // I - Filename
|
||||||
uchar *header, // I - Header data from file
|
uchar *header, // I - Header data from file
|
||||||
int) { // I - Amount of data (not used)
|
int headerlen) { // I - Amount of data
|
||||||
if (memcmp(header, "GIF87a", 6) == 0 ||
|
if (memcmp(header, "GIF87a", 6) == 0 ||
|
||||||
memcmp(header, "GIF89a", 6) == 0) // GIF file
|
memcmp(header, "GIF89a", 6) == 0) // GIF file
|
||||||
return new Fl_GIF_Image(name);
|
return new Fl_GIF_Image(name);
|
||||||
@ -88,6 +89,12 @@ fl_check_images(const char *name, // I - Filename
|
|||||||
return new Fl_JPEG_Image(name);
|
return new Fl_JPEG_Image(name);
|
||||||
#endif // HAVE_LIBJPEG
|
#endif // HAVE_LIBJPEG
|
||||||
|
|
||||||
|
#ifdef FLTK_USE_NANOSVG
|
||||||
|
if ( (headerlen > 5 && memcmp(header, "<?xml", 5) == 0) ||
|
||||||
|
memcmp(header, "<svg", 4) == 0)
|
||||||
|
return new Fl_SVG_Image(name);
|
||||||
|
#endif // FLTK_USE_NANOSVG
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
// http://www.fltk.org/str.php
|
// http://www.fltk.org/str.php
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
#include <FL/Fl.H>
|
#include <FL/Fl.H>
|
||||||
#include <FL/Fl_Box.H>
|
#include <FL/Fl_Box.H>
|
||||||
#include <FL/Fl_Double_Window.H>
|
#include <FL/Fl_Double_Window.H>
|
||||||
@ -75,7 +76,11 @@ void file_cb(const char *n) {
|
|||||||
|
|
||||||
void button_cb(Fl_Widget *,void *) {
|
void button_cb(Fl_Widget *,void *) {
|
||||||
fl_file_chooser_callback(file_cb);
|
fl_file_chooser_callback(file_cb);
|
||||||
const char *fname = fl_file_chooser("Image file?","*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm}", name);
|
const char *fname = fl_file_chooser("Image file?","*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm"
|
||||||
|
#ifdef FLTK_USE_NANOSVG
|
||||||
|
",svg"
|
||||||
|
#endif
|
||||||
|
"}", name);
|
||||||
puts(fname ? fname : "(null)"); fflush(stdout);
|
puts(fname ? fname : "(null)"); fflush(stdout);
|
||||||
fl_file_chooser_callback(0);
|
fl_file_chooser_callback(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user