diff options
| author | Manolo Gouy <Manolo> | 2018-03-19 17:43:18 +0000 |
|---|---|---|
| committer | Manolo Gouy <Manolo> | 2018-03-19 17:43:18 +0000 |
| commit | 916b44e361f275555c5f22b9d91c973ccc089037 (patch) | |
| tree | a36b734804a82d3e5d4bd900bc9031b8fe60d35a /src/Fl_Image.cxx | |
| parent | c4f7c09b7bacbfe19d1dcea5a28eeb30b1136a95 (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.cxx | 116 |
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$". // |
