summaryrefslogtreecommitdiff
path: root/src/Fl_Image.cxx
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2018-03-19 17:43:18 +0000
committerManolo Gouy <Manolo>2018-03-19 17:43:18 +0000
commit916b44e361f275555c5f22b9d91c973ccc089037 (patch)
treea36b734804a82d3e5d4bd900bc9031b8fe60d35a /src/Fl_Image.cxx
parentc4f7c09b7bacbfe19d1dcea5a28eeb30b1136a95 (diff)
New member function Fl_Image::scale(int width, int height) to set the FLTK size of an image.
Each image has now two sizes implemented as follows: - the pixel size is stored in private members pixel_w_ and pixel_h_ with public accessors pixel_w() and pixel_h() - the FLTK size is stored in private members w_ and h_ and read by w() and h() - when the image is constructed, the two sizes have the same value - the protected w(int) and h(int) member functions set both FLTK and pixel sizes. - the public scale(int, int) member function is essentially nothing but set the FLTK size and don't change the pixel size. - when the image is drawn, its FLTK size determines how big it is drawn, its pixel size determines how much data are available to draw it. FLTK 1.3.4 with FL_ABI_VERSION=10304 contained an equivalent member function but only for the Fl_Shared_Image class. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12776 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/Fl_Image.cxx')
-rw-r--r--src/Fl_Image.cxx116
1 files changed, 82 insertions, 34 deletions
diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx
index 2a01f8558..1276b0513 100644
--- a/src/Fl_Image.cxx
+++ b/src/Fl_Image.cxx
@@ -33,6 +33,7 @@ void fl_restore_clip(); // from fl_rect.cxx
Fl_RGB_Scaling Fl_Image::RGB_scaling_ = FL_RGB_SCALING_NEAREST;
+Fl_RGB_Scaling Fl_Image::scaling_algorithm_ = FL_RGB_SCALING_BILINEAR;
/**
The constructor creates an empty image with the specified
@@ -42,6 +43,7 @@ Fl_RGB_Scaling Fl_Image::RGB_scaling_ = FL_RGB_SCALING_NEAREST;
*/
Fl_Image::Fl_Image(int W, int H, int D) :
w_(W), h_(H), d_(D), ld_(0), count_(0), data_(0L)
+, pixel_w_(W), pixel_h_(H)
{}
/**
@@ -232,6 +234,66 @@ Fl_RGB_Scaling Fl_Image::RGB_scaling() {
return RGB_scaling_;
}
+/** Sets the drawing size of the image.
+ This function gives the image its own drawing size, independently from its pixel size.
+ This can be useful to draw an image on a drawing surface with more than 1 pixel per
+ FLTK unit: all pixels of the original image become available to fill an area of the drawing surface
+ sized at <tt>width,height</tt> FLTK units.
+ Examples of such drawing surfaces: HiDPI displays, laser printers, PostScript files, PDF printers.
+
+ \param width,height maximum width and height (in FLTK units) to use when drawing the image
+ \param proportional if not null, keep the width and height of the image proportional to those of the original size
+ \param can_expand if null, the width and height of the image will not exceed those of the original size
+ \version 1.4 (1.3.4 and FL_ABI_VERSION for Fl_Shared_Image only)
+
+ Example code: scale an image to fit in a box
+ \code
+ Fl_Box *b = ... // a box
+ Fl_Image *img = Fl_Shared_Image::get("/path/to/picture.jpeg"); // read a picture file
+ img->scale(b->w(), b->h()); // set the drawing size of the image to the size of the box
+ b->image(img); // use the image as the box image
+ b->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER | FL_ALIGN_CLIP); // the image is to be drawn centered in the box
+ \endcode
+ */
+void Fl_Image::scale(int width, int height, int proportional, int can_expand)
+{
+ if ((width <= pixel_w() && height <= pixel_h()) || can_expand) {
+ w_ = width;
+ h_ = height;
+ }
+ if (fail()) return;
+ if (!proportional && can_expand) return;
+ if (!proportional && width <= pixel_w() && height <= pixel_h()) return;
+ float fw = pixel_w() / float(width);
+ float fh = pixel_h() / float(height);
+ if (proportional) {
+ if (fh > fw) fw = fh;
+ else fh = fw;
+ }
+ if (!can_expand) {
+ if (fw < 1) fw = 1;
+ if (fh < 1) fh = 1;
+ }
+ w_ = int(pixel_w() / fw);
+ h_ = int(pixel_h() / fh);
+}
+
+/** Draw the image to the current drawing surface rescaled to a given width and height.
+ Deprecated. Only for API compatibility with FLTK 1.3.4.
+ Intended for internal use by the FLTK library.
+ \param X,Y position of the image's top-left
+ \param W,H width and height for the drawn image
+ \return 1
+ */
+int Fl_Image::draw_scaled(int X, int Y, int W, int H) {
+ // transiently set image drawing size to WxH
+ int width = w(), height = h();
+ scale(W, H, 0, 1);
+ draw(X, Y, W, H, 0, 0);
+ scale(width, height, 0, 1);
+ return 1;
+}
+
//
// RGB image class...
@@ -334,29 +396,29 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
// Optimize the simple copy where the width and height are the same,
// or when we are copying an empty image...
- if ((W == w() && H == h()) ||
+ if ((W == pixel_w() && H == pixel_h()) ||
!w() || !h() || !d() || !array) {
if (array) {
// Make a copy of the image data and return a new Fl_RGB_Image...
- new_array = new uchar[w() * h() * d()];
- if (ld() && ld()!=w()*d()) {
+ new_array = new uchar[pixel_w() * pixel_h() * d()];
+ if (ld() && ld()!=pixel_w()*d()) {
const uchar *src = array;
uchar *dst = new_array;
- int dy, dh = h(), wd = w()*d(), wld = ld();
+ int dy, dh = h(), wd = pixel_w()*d(), wld = ld();
for (dy=0; dy<dh; dy++) {
memcpy(dst, src, wd);
src += wld;
dst += wd;
}
} else {
- memcpy(new_array, array, w() * h() * d());
+ memcpy(new_array, array, pixel_w() * pixel_h() * d());
}
- new_image = new Fl_RGB_Image(new_array, w(), h(), d());
+ new_image = new Fl_RGB_Image(new_array, pixel_w(), pixel_h(), d());
new_image->alloc_array = 1;
return new_image;
} else {
- return new Fl_RGB_Image(array, w(), h(), d(), ld());
+ return new Fl_RGB_Image(array, pixel_w(), pixel_h(), d(), ld());
}
}
if (W <= 0 || H <= 0) return 0;
@@ -372,7 +434,7 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
new_image = new Fl_RGB_Image(new_array, W, H, d());
new_image->alloc_array = 1;
- line_d = ld() ? ld() : w() * d();
+ line_d = ld() ? ld() : pixel_w() * d();
if (Fl_Image::RGB_scaling() == FL_RGB_SCALING_NEAREST) {
@@ -383,10 +445,10 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
xstep, ystep; // X & Y step increments
// Figure out Bresenham step/modulus values...
- xmod = w() % W;
- xstep = (w() / W) * d();
- ymod = h() % H;
- ystep = h() / H;
+ xmod = pixel_w() % W;
+ xstep = (pixel_w() / W) * d();
+ ymod = pixel_h() % H;
+ ystep = pixel_h() / H;
// Scale the image using a nearest-neighbor algorithm...
for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) {
@@ -411,28 +473,28 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
}
} else {
// Bilinear scaling (FL_RGB_SCALING_BILINEAR)
- const float xscale = (w() - 1) / (float) W;
- const float yscale = (h() - 1) / (float) H;
+ const float xscale = (pixel_w() - 1) / (float) W;
+ const float yscale = (pixel_h() - 1) / (float) H;
for (dy = 0; dy < H; dy++) {
float oldy = dy * yscale;
- if (oldy >= h())
- oldy = float(h() - 1);
+ if (oldy >= pixel_h())
+ oldy = float(pixel_h() - 1);
const float yfract = oldy - (unsigned) oldy;
for (dx = 0; dx < W; dx++) {
new_ptr = new_array + dy * W * d() + dx * d();
float oldx = dx * xscale;
- if (oldx >= w())
- oldx = float(w() - 1);
+ if (oldx >= pixel_w())
+ oldx = float(pixel_w() - 1);
const float xfract = oldx - (unsigned) oldx;
const unsigned leftx = (unsigned)oldx;
const unsigned lefty = (unsigned)oldy;
- const unsigned rightx = (unsigned)(oldx + 1 >= w() ? oldx : oldx + 1);
+ const unsigned rightx = (unsigned)(oldx + 1 >= pixel_w() ? oldx : oldx + 1);
const unsigned righty = (unsigned)oldy;
const unsigned dleftx = (unsigned)oldx;
- const unsigned dlefty = (unsigned)(oldy + 1 >= h() ? oldy : oldy + 1);
+ const unsigned dlefty = (unsigned)(oldy + 1 >= pixel_h() ? oldy : oldy + 1);
const unsigned drightx = (unsigned)rightx;
const unsigned drighty = (unsigned)dlefty;
@@ -586,20 +648,6 @@ void Fl_RGB_Image::label(Fl_Menu_Item* m) {
m->label(FL_IMAGE_LABEL, (const char*)this);
}
-int Fl_RGB_Image::draw_scaled(int X, int Y, int W, int H) {
- return fl_graphics_driver->draw_scaled(this, X, Y, W, H);
-}
-
-/** Attempts to draw the image to the current drawing surface rescaled to a given width and height.
- This virtual member function is mostly intended for use by the FLTK library.
- \param X,Y position of the image's top-left
- \param W,H width and height for the drawn image
- \return 0 if scaled drawing is not implemented for this image, non-zero if it is implemented.
- */
-int Fl_Image::draw_scaled(int X, int Y, int W, int H) {
- return 0;
-}
-
//
// End of "$Id$".
//