1 /******************************************************************************** 2 * * 3 * I m a g e O b j e c t * 4 * * 5 ********************************************************************************* 6 * Copyright (C) 1997,2020 by Jeroen van der Zijp. All Rights Reserved. * 7 ********************************************************************************* 8 * This library is free software; you can redistribute it and/or modify * 9 * it under the terms of the GNU Lesser General Public License as published by * 10 * the Free Software Foundation; either version 3 of the License, or * 11 * (at your option) any later version. * 12 * * 13 * This library is distributed in the hope that it will be useful, * 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 * GNU Lesser General Public License for more details. * 17 * * 18 * You should have received a copy of the GNU Lesser General Public License * 19 * along with this program. If not, see <http://www.gnu.org/licenses/> * 20 ********************************************************************************/ 21 #ifndef FXIMAGE_H 22 #define FXIMAGE_H 23 24 #ifndef FXDRAWABLE_H 25 #include "FXDrawable.h" 26 #endif 27 28 namespace FX { 29 30 31 /// Image rendering hints 32 enum { 33 IMAGE_KEEP = 0x00000001, /// Keep pixel data in client 34 IMAGE_OWNED = 0x00000002, /// Pixel data is owned by image 35 IMAGE_DITHER = 0, /// Dither image to look better 36 IMAGE_NEAREST = 0x00000004, /// Turn off dithering and map to nearest color 37 IMAGE_OPAQUE = 0x00000008, /// Force opaque background 38 IMAGE_ALPHACOLOR = 0x00000010, /// Override transparancy color 39 IMAGE_SHMI = 0x00000020, /// Using shared memory image 40 IMAGE_SHMP = 0x00000040, /// Using shared memory pixmap 41 IMAGE_ALPHAGUESS = 0x00000080, /// Guess transparency color from corners 42 IMAGE_THRESGUESS = 0x00000100 /// Guess threshold for etch mask 43 }; 44 45 46 class FXDC; 47 class FXDCWindow; 48 49 50 /** 51 * An Image is a rectangular array of pixels. It supports two representations 52 * of these pixels: a client-side pixel buffer which is stored as an array of 53 * FXColor, and a server-side pixmap which is stored in an organization directly 54 * compatible with the screen, for fast drawing onto the device. 55 * The server-side representation is not directly accessible from the current 56 * process as it lives in the process of the X Server or GDI. 57 * Before the image can be used in drawing operations, the server-side representation 58 * of the image must be realized by calling create(); until this is done, only the 59 * client-side pixel buffer exists. 60 * Usually the client-side pixel buffer is released when the server-side representation 61 * is generated [thus saving substantial amounts of memory when only the server-resident 62 * part of the image is of interest]. But if further manipulation of the client-side 63 * pixel buffer is needed, the IMAGE_KEEP option can be passed. In that case, the 64 * client-side buffer can be modified, and the server-side pixmap can be updated by 65 * calling render(). 66 */ 67 class FXAPI FXImage : public FXDrawable { 68 FXDECLARE(FXImage) 69 friend class FXDC; 70 friend class FXDCWindow; 71 protected: 72 FXColor *data; // Pixel data 73 FXuint options; // Options 74 private: 75 #ifdef WIN32 76 virtual FXID GetDC() const; 77 virtual int ReleaseDC(FXID) const; 78 #else 79 void render_true_32(void *xim,FXuchar *img); 80 void render_true_24(void *xim,FXuchar *img); 81 void render_true_16_fast(void *xim,FXuchar *img); 82 void render_true_16_dither(void *xim,FXuchar *img); 83 void render_true_8_fast(void *xim,FXuchar *img); 84 void render_true_8_dither(void *xim,FXuchar *img); 85 void render_true_N_fast(void *xim,FXuchar *img); 86 void render_true_N_dither(void *xim,FXuchar *img); 87 void render_index_4_fast(void *xim,FXuchar *img); 88 void render_index_4_dither(void *xim,FXuchar *img); 89 void render_index_8_fast(void *xim,FXuchar *img); 90 void render_index_8_dither(void *xim,FXuchar *img); 91 void render_index_N_fast(void *xim,FXuchar *img); 92 void render_index_N_dither(void *xim,FXuchar *img); 93 void render_gray_8_fast(void *xim,FXuchar *img); 94 void render_gray_8_dither(void *xim,FXuchar *img); 95 void render_gray_N_fast(void *xim,FXuchar *img); 96 void render_gray_N_dither(void *xim,FXuchar *img); 97 void render_mono_1_fast(void *xim,FXuchar *img); 98 void render_mono_1_dither(void *xim,FXuchar *img); 99 #endif 100 protected: 101 FXImage(); 102 private: 103 FXImage(const FXImage&); 104 FXImage &operator=(const FXImage&); 105 public: 106 107 /** 108 * Create an image. If a client-side pixel buffer has been specified, 109 * the image does not own the pixel buffer unless the IMAGE_OWNED flag is 110 * set. If the IMAGE_OWNED flag is set but a NULL pixel buffer is 111 * passed, a pixel buffer will be automatically created and will be owned 112 * by the image. The flags IMAGE_SHMI and IMAGE_SHMP may be specified for 113 * large images to instruct render() to use shared memory to communicate 114 * with the server. 115 */ 116 FXImage(FXApp* a,const FXColor *pix=NULL,FXuint opts=0,FXint w=1,FXint h=1); 117 118 /// Change options 119 void setOptions(FXuint opts); 120 121 /// To get to the option flags getOptions()122 FXuint getOptions() const { return options; } 123 124 /// Set pixel data ownership flag 125 void setOwned(FXbool owned); 126 127 /// Get pixel data ownership flag 128 FXbool isOwned() const; 129 130 /** 131 * Populate the image with new pixel data of the same size; it will assume 132 * ownership of the pixel data if image IMAGE_OWNED option is passed. 133 * The server-side representation of the image, if it exists, is not updated. 134 * This can be done by calling render(). 135 */ 136 virtual void setData(FXColor *pix,FXuint opts=0); 137 138 /** 139 * Populate the image with new pixel data of a new size; it will assume ownership 140 * of the pixel data if image IMAGE_OWNED option is passed. The size of the server- 141 * side representation of the image, if it exists, is adjusted but the contents are 142 * not updated yet. This can be done by calling render(). 143 */ 144 virtual void setData(FXColor *pix,FXuint opts,FXint w,FXint h); 145 146 /// Return pointer to the pixel data of the image getData()147 FXColor* getData() const { return data; } 148 149 /// Get pixel at x,y getPixel(FXint x,FXint y)150 FXColor getPixel(FXint x,FXint y) const { return data[y*width+x]; } 151 152 /// Change pixel at x,y setPixel(FXint x,FXint y,FXColor color)153 void setPixel(FXint x,FXint y,FXColor color){ data[y*width+x]=color; } 154 155 /// Scan the image and return false if fully opaque 156 FXbool hasAlpha() const; 157 158 /** 159 * Create the server side pixmap, then call render() to fill it with the 160 * pixel data from the client-side buffer. After the server-side image has 161 * been created, the client-side pixel buffer will be deleted unless 162 * IMAGE_KEEP has been specified. If the pixel buffer is not owned, i.e. 163 * the flag IMAGE_OWNED is not set, the pixel buffer will not be deleted, 164 * however the pixel buffer will be set to NULL. 165 */ 166 virtual void create(); 167 168 /** 169 * Detach the server side pixmap from the Image. 170 * Afterwards, the Image is left as if it never had a server-side resources. 171 */ 172 virtual void detach(); 173 174 /** 175 * Destroy the server-side pixmap. 176 * The client-side pixel buffer is not affected. 177 */ 178 virtual void destroy(); 179 180 /** 181 * Retrieves pixels from the server-side image. For example, to make 182 * screen snapshots, or to retrieve an image after it has been drawn 183 * into by various means. 184 */ 185 virtual void restore(); 186 187 /** 188 * Render the server-side representation of the image from client-side 189 * pixels. Normally, IMAGE_DITHER is used which causes the server-side 190 * representation to be rendered using a 16x16 ordered dither if necessary; 191 * however if IMAGE_NEAREST is used a faster (but uglier-looking), nearest 192 * neighbor algorithm is used. 193 */ 194 virtual void render(); 195 196 /** 197 * Release the client-side pixels buffer, free it if it was owned. 198 * If it is not owned, the image just forgets about the buffer. 199 */ 200 virtual void release(); 201 202 /** 203 * Resize both client-side and server-side representations (if any) to the 204 * given width and height. The new representations typically contain garbage 205 * after this operation and need to be re-filled. 206 */ 207 virtual void resize(FXint w,FXint h); 208 209 /** 210 * Rescale pixels image to the specified width and height; this calls 211 * resize() to adjust the client and server side representations. 212 */ 213 virtual void scale(FXint w,FXint h,FXint quality=0); 214 215 /// Mirror image horizontally and/or vertically 216 virtual void mirror(FXbool horizontal,FXbool vertical); 217 218 /** 219 * Rotate image by degrees ccw; this calls resize() to adjust the client 220 * and server side representations if necessary. 221 */ 222 virtual void rotate(FXint degrees); 223 224 /** 225 * Crop image to given rectangle; this calls resize() to adjust the client 226 * and server side representations. The new image may be smaller or larger 227 * than the old one; blank areas are filled with color. There must be at 228 * least one pixel of overlap between the old and the new image. 229 */ 230 virtual void crop(FXint x,FXint y,FXint w,FXint h,FXColor color=0); 231 232 /// Fill image with uniform color 233 virtual void fill(FXColor color); 234 235 /// Fade image to uniform color 236 virtual void fade(FXColor color,FXint factor=255); 237 238 /** 239 * Shear image horizontally; the number of pixels is equal to the 240 * shear parameter times 256. The area outside the image is filled 241 * with transparent black, unless another color is specified. 242 */ 243 virtual void xshear(FXint shear,FXColor clr=0); 244 245 /** 246 * Shear image vertically; the number of pixels is equal to the 247 * shear parameter times 256. The area outside the image is filled 248 * with transparent black, unless another color is specified. 249 */ 250 virtual void yshear(FXint shear,FXColor clr=0); 251 252 /// Fill horizontal gradient 253 virtual void hgradient(FXColor left,FXColor right); 254 255 /// Fill vertical gradient 256 virtual void vgradient(FXColor top,FXColor bottom); 257 258 /// Fill with gradient 259 virtual void gradient(FXColor topleft,FXColor topright,FXColor bottomleft,FXColor bottomright); 260 261 /// Blend image over uniform color 262 virtual void blend(FXColor color); 263 264 /// Invert colors of an image 265 virtual void invert(); 266 267 /// Colorize image based on luminance 268 virtual void colorize(FXColor color); 269 270 /// Save pixel data only 271 virtual FXbool savePixels(FXStream& store) const; 272 273 /// Load pixel data only 274 virtual FXbool loadPixels(FXStream& store); 275 276 /// Save object to stream 277 virtual void save(FXStream& store) const; 278 279 /// Load object from stream 280 virtual void load(FXStream& store); 281 282 /// Destructor 283 virtual ~FXImage(); 284 }; 285 286 } 287 288 #endif 289