SVG support: draw images at full screen resolution also when there are several pixels per graphical unit, as with Apple retina displays.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12456 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy 2017-09-13 16:15:34 +00:00
parent be7e7f0ee8
commit 435d135825
5 changed files with 27 additions and 4 deletions

View File

@ -167,7 +167,6 @@ protected:
*/
virtual void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {}
virtual void draw(Fl_Shared_Image *shared, int X, int Y);
virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H);
virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy);
/** Support function for image drawing */
@ -389,6 +388,8 @@ public:
virtual const char *font_name(int num) {return NULL;}
/** Support for Fl::set_font() */
virtual void font_name(int num, const char *name) {}
/** Support function for Fl_Shared_Image drawing */
virtual int draw_scaled(Fl_Image *img, int X, int Y, int W, int H);
};
#ifndef FL_DOXYGEN

View File

@ -176,6 +176,9 @@ public:
/** Returns the platform's support for rescaling the application with ctrl-/+/-/0/ keys.
*/
virtual APP_SCALING_CAPABILITY rescalable() { return NO_APP_SCALING; }
/* Number of pixels per drawing unit for the display.
The default implementation may be enough. */
virtual float retina_factor() { return 1; }
};

View File

@ -22,6 +22,8 @@
#include <FL/Fl_SVG_Image.H>
#include <FL/fl_utf8.h>
#include <FL/fl_draw.H>
#include <FL/Fl_Screen_Driver.H>
#include <stdio.h>
#include <stdlib.h>
@ -182,8 +184,23 @@ void Fl_SVG_Image::resize(int width, int height) {
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);
static float f = Fl::screen_driver()->retina_factor();
int w1 = w(), h1 = h();
/* When f > 1, there may be several pixels per drawing unit in an area
of size w() x h() of the display. This occurs, e.g., with Apple retina displays.
The SVG is rasterized to the area dimension in pixels. The image is then drawn
scaled to its size expressed in drawing units. With this procedure,
the SVG image is drawn using the full resolution of the display.
*/
resize(f*w(), f*h());
if (f == 1) {
Fl_RGB_Image::draw(X, Y, W, H, cx, cy);
} else {
bool need_clip = (cx || cy || W != w1 || H != h1);
if (need_clip) fl_push_clip(X, Y, W, H);
fl_graphics_driver->draw_scaled(this, X-cx, Y-cy, w1, h1);
if (need_clip) fl_pop_clip();
}
}

View File

@ -96,6 +96,7 @@ public:
virtual void open_display_platform();
// --- compute dimensions of an Fl_Offscreen
virtual void offscreen_size(Fl_Offscreen o, int &width, int &height);
virtual float retina_factor() { return 2; }
};

View File

@ -202,7 +202,8 @@ int Fl_Quartz_Graphics_Driver::draw_scaled(Fl_Image *img, int XP, int YP, int WP
CGContextClipToRect(gc_, CGRectMake(X, Y, W, H)); // this clip path will be rescaled & translated
CGContextTranslateCTM(gc_, XP, YP);
CGContextScaleCTM(gc_, float(WP)/img->w(), float(HP)/img->h());
img->draw(0, 0, img->w(), img->h(), 0, 0);
if (img->as_rgb_image()) draw(img->as_rgb_image(), 0, 0, img->w(), img->h(), 0, 0);
else img->draw(0, 0, img->w(), img->h(), 0, 0);
CGContextRestoreGState(gc_);
fl_pop_clip(); // restore FLTK's clip
return 1;