diff options
| -rw-r--r-- | FL/Fl_Graphics_Driver.H | 2 | ||||
| -rw-r--r-- | FL/Fl_SVG_Image.H | 2 | ||||
| -rw-r--r-- | src/Fl_Graphics_Driver.cxx | 13 | ||||
| -rw-r--r-- | src/Fl_SVG_Image.cxx | 17 | ||||
| -rw-r--r-- | src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx | 8 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx | 10 |
9 files changed, 38 insertions, 20 deletions
diff --git a/FL/Fl_Graphics_Driver.H b/FL/Fl_Graphics_Driver.H index 813613fbb..be5dbe433 100644 --- a/FL/Fl_Graphics_Driver.H +++ b/FL/Fl_Graphics_Driver.H @@ -236,7 +236,7 @@ protected: static void draw_empty(Fl_Image* img, int X, int Y) {img->draw_empty(X, Y);} Fl_Graphics_Driver(); - virtual void cache_size(int &width, int &height); + virtual void cache_size(Fl_Image *img, int &width, int &height); static unsigned need_pixmap_bg_color; public: virtual ~Fl_Graphics_Driver() {} ///< Destructor diff --git a/FL/Fl_SVG_Image.H b/FL/Fl_SVG_Image.H index 9a2504c02..7ced23cc0 100644 --- a/FL/Fl_SVG_Image.H +++ b/FL/Fl_SVG_Image.H @@ -133,6 +133,7 @@ struct NSVGimage; */ class FL_EXPORT Fl_SVG_Image : public Fl_RGB_Image { + friend class Fl_Graphics_Driver; private: typedef struct { NSVGimage* svg_image; @@ -146,6 +147,7 @@ private: float average_weight_; float svg_scaling_(int W, int H); void rasterize_(int W, int H); + void cache_size(int &width, int &height); void init_(const char *filename, const char *filedata, Fl_SVG_Image *copy_source); Fl_SVG_Image(Fl_SVG_Image *source); public: diff --git a/src/Fl_Graphics_Driver.cxx b/src/Fl_Graphics_Driver.cxx index 7b46d691e..c5cd9d6c5 100644 --- a/src/Fl_Graphics_Driver.cxx +++ b/src/Fl_Graphics_Driver.cxx @@ -29,6 +29,7 @@ #include <FL/Fl_Image_Surface.H> #include <FL/math.h> #include <FL/platform.H> +#include <FL/Fl_SVG_Image.H> FL_EXPORT Fl_Graphics_Driver *fl_graphics_driver; // the current driver of graphics operations @@ -201,7 +202,7 @@ unsigned Fl_Graphics_Driver::font_desc_size() { /** Converts \p width and \p height from FLTK units to drawing units. The conversion performed consists in multiplying \p width and \p height by scale() and in slightly modifying that to help support tiled images. */ -void Fl_Graphics_Driver::cache_size(int &width, int &height) +void Fl_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height) { if ( int(scale()) == scale() ) { width = width * scale(); @@ -210,6 +211,10 @@ void Fl_Graphics_Driver::cache_size(int &width, int &height) width = (width+1) * scale(); height = (height+1) * scale(); } + if (img->d() == 4 && ((Fl_RGB_Image*)img)->as_svg_image()) { // check for SVG image + Fl_SVG_Image *svg = (Fl_SVG_Image*)img; + svg->cache_size(width, height); + } } /** Draws an Fl_Pixmap object using this graphics driver. @@ -223,7 +228,7 @@ void Fl_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int } // to allow rescale at runtime int w2=pxm->w(), h2=pxm->h(); - cache_size(w2, h2); // after this, w2 x h2 is size of desired cached image + cache_size(pxm, w2, h2); // after this, w2 x h2 is size of desired cached image int *pw, *ph; cache_w_h(pxm, pw, ph); // after this, *pw x *ph is current size of cached form of bitmap if (*id(pxm) && (*pw != w2 || *ph != h2)) { @@ -256,7 +261,7 @@ void Fl_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int return; } int w2 = bm->w(), h2 = bm->h(); - cache_size(w2, h2); // after this, w2 x h2 is size of desired cached image + cache_size(bm, w2, h2); // after this, w2 x h2 is size of desired cached image int *pw, *ph; cache_w_h(bm, pw, ph); // after this, *pw x *ph is current size of cached form of bitmap if (*id(bm) && (*pw != w2 || *ph != h2)) { @@ -296,7 +301,7 @@ void Fl_Graphics_Driver::draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int int w2, h2, *pw, *ph; if (need_scaled_drawing) { w2 = img->w(); h2 = img->h(); - cache_size(w2, h2); + cache_size(img, w2, h2); } else { w2 = img->data_w(); h2 = img->data_h(); } // after this, w2 x h2 is desired cached image size diff --git a/src/Fl_SVG_Image.cxx b/src/Fl_SVG_Image.cxx index 93aaee28b..6b241f841 100644 --- a/src/Fl_SVG_Image.cxx +++ b/src/Fl_SVG_Image.cxx @@ -221,8 +221,8 @@ void Fl_SVG_Image::resize(int width, int height) { 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 ); + w1 = int( counted_svg_image_->svg_image->width*f + 0.5 ); + h1 = int( counted_svg_image_->svg_image->height*f + 0.5 ); } w(w1); h(h1); if (rasterized_ && w1 == raster_w_ && h1 == raster_h_) return; @@ -235,6 +235,17 @@ void Fl_SVG_Image::resize(int width, int height) { } +void Fl_SVG_Image::cache_size(int &width, int &height) { + if (proportional) { + // Keep the rasterized image proportional to its source-level width and height + // while maintaining it large enough to allow image tiling. + float f = counted_svg_image_->svg_image->width / counted_svg_image_->svg_image->height; + if (height * f >= width) width = height * f + 0.5; + else height = width/f + 0.5; + } +} + + void Fl_SVG_Image::draw(int X, int Y, int W, int H, int cx, int cy) { /* There may be several pixels per FLTK unit in an area of size w() x h() of the display. This occurs, e.g., with Apple retina displays @@ -246,7 +257,7 @@ void Fl_SVG_Image::draw(int X, int Y, int W, int H, int cx, int cy) { int w1 = w(), h1 = h(); int f = fl_graphics_driver->has_feature(Fl_Graphics_Driver::PRINTER) ? 2 : 1; int w2 = f*w(), h2 = f*h(); - fl_graphics_driver->cache_size(w2, h2); + fl_graphics_driver->cache_size(this, w2, h2); resize(w2, h2); scale(w1, h1, 0, 1); Fl_RGB_Image::draw(X, Y, W, H, cx, cy); diff --git a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx index 37507b435..6bc9ad82d 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx +++ b/src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx @@ -400,7 +400,7 @@ void Fl_GDI_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) { void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) { X = X*scale(); Y = Y*scale(); - cache_size(W, H); + cache_size(bm, W, H); cx *= scale(); cy *= scale(); HDC tempdc = CreateCompatibleDC(gc_); @@ -500,7 +500,7 @@ void Fl_GDI_Graphics_Driver::cache(Fl_RGB_Image *img) void Fl_GDI_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) { X = X*scale(); Y = Y*scale(); - cache_size(W, H); + cache_size(img, W, H); cx *= scale(); cy *= scale(); if (W + cx > img->data_w()) W = img->data_w() - cx; if (H + cy > img->data_h()) H = img->data_h() - cy; @@ -538,7 +538,7 @@ void Fl_GDI_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP, float scaleW = float(rgb->data_w())/rgb->w(); float scaleH = float(rgb->data_h())/rgb->h(); int W = WP, H = HP; - cache_size(W, H); + cache_size(rgb, W, H); HDC new_gc = CreateCompatibleDC(gc_); int save = SaveDC(new_gc); SelectObject(new_gc, (HBITMAP)*Fl_Graphics_Driver::id(rgb)); @@ -628,7 +628,7 @@ void Fl_GDI_Graphics_Driver::cache(Fl_Bitmap *bm) { void Fl_GDI_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) { X = X*scale(); Y = Y*scale(); - cache_size(W, H); + cache_size(pxm, W, H); cx *= scale(); cy *= scale(); Fl_Region r2 = scale_clip(scale()); if (*Fl_Graphics_Driver::mask(pxm)) { diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H index 67265c304..76edc4134 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H @@ -59,7 +59,7 @@ protected: CGLineJoin quartz_line_join_; CGFloat *quartz_line_pattern; int quartz_line_pattern_size; - virtual void cache_size(int &width, int &height); + virtual void cache_size(Fl_Image* img, int &width, int &height); public: Fl_Quartz_Graphics_Driver(); virtual ~Fl_Quartz_Graphics_Driver() { if (p) free(p); } diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx index f8fab114e..1c5c7e977 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx @@ -154,7 +154,7 @@ void Fl_Quartz_Graphics_Driver::XDestroyRegion(Fl_Region r) { } } -void Fl_Quartz_Graphics_Driver::cache_size(int &width, int &height) { +void Fl_Quartz_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height) { width *= 2 * scale(); height *= 2 * scale(); } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx index c98cb546f..15ea319bc 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx @@ -86,7 +86,7 @@ void Fl_Xlib_Graphics_Driver::scale(float f) { Setting line_delta_ to 1 and offsetting all line, rectangle, text and clip coordinates by line_delta_ achieves what is wanted until scale_ <= 3.5. */ - line_delta_ = (scale() > 1.75 ? 1 : 0); + line_delta_ = (scale() > 1.9/*1.75*/ ? 1 : 0); } #endif } diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx index 2e0b4af50..b20a84cfe 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx +++ b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver_image.cxx @@ -625,7 +625,7 @@ void Fl_Xlib_Graphics_Driver::delete_bitmask(Fl_Bitmask bm) { void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Bitmap *bm, int X, int Y, int W, int H, int cx, int cy) { X = (X+offset_x_)*scale(); Y = (Y+offset_y_)*scale(); - cache_size(W, H); + cache_size(bm, W, H); cx *= scale(); cy *= scale(); XSetStipple(fl_display, gc_, *Fl_Graphics_Driver::id(bm)); int ox = X-cx; if (ox < 0) ox += bm->w()*scale(); @@ -727,7 +727,7 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_RGB_Image *img) { void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) { X = (X+offset_x_)*scale(); Y = (Y+offset_y_)*scale(); - cache_size(W, H); + cache_size(img, W, H); cx *= scale(); cy *= scale(); if (img->d() == 1 || img->d() == 3) { XCopyArea(fl_display, *Fl_Graphics_Driver::id(img), fl_window, gc_, cx, cy, W, H, X, Y); @@ -764,9 +764,9 @@ void Fl_Xlib_Graphics_Driver::draw_rgb(Fl_RGB_Image *rgb, int XP, int YP, int WP if (!*Fl_Graphics_Driver::id(rgb)) { cache(rgb); } - cache_size(W, H); + cache_size(rgb, W, H); int Wfull = rgb->w(), Hfull = rgb->h(); - cache_size(Wfull, Hfull); + cache_size(rgb, Wfull, Hfull); scale_and_render_pixmap( *Fl_Graphics_Driver::id(rgb), rgb->d(), rgb->data_w() / double(Wfull), rgb->data_h() / double(Hfull), cx*scale(), cy*scale(), (X + offset_x_)*scale(), (Y + offset_y_)*scale(), W, H); @@ -829,7 +829,7 @@ void Fl_Xlib_Graphics_Driver::cache(Fl_Bitmap *bm) { void Fl_Xlib_Graphics_Driver::draw_fixed(Fl_Pixmap *pxm, int X, int Y, int W, int H, int cx, int cy) { X = (X+offset_x_)*scale(); Y = (Y+offset_y_)*scale(); - cache_size(W, H); + cache_size(pxm, W, H); cx *= scale(); cy *= scale(); Fl_Region r2 = scale_clip(scale()); if (*Fl_Graphics_Driver::mask(pxm)) { |
