|
fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation) ![]() |
00001 // 00002 // "$Id: fl_draw_image_mac.cxx 8128 2010-12-28 15:17:23Z manolo $" 00003 // 00004 // MacOS image drawing code for the Fast Light Tool Kit (FLTK). 00005 // 00006 // Copyright 1998-2010 by Bill Spitzak and others. 00007 // 00008 // This library is free software; you can redistribute it and/or 00009 // modify it under the terms of the GNU Library General Public 00010 // License as published by the Free Software Foundation; either 00011 // version 2 of the License, or (at your option) any later version. 00012 // 00013 // This library is distributed in the hope that it will be useful, 00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 // Library General Public License for more details. 00017 // 00018 // You should have received a copy of the GNU Library General Public 00019 // License along with this library; if not, write to the Free Software 00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 // USA. 00022 // 00023 // Please report all bugs and problems on the following page: 00024 // 00025 // http://www.fltk.org/str.php 00026 // 00027 00029 00030 #include <config.h> 00031 #include <FL/Fl.H> 00032 #include <FL/fl_draw.H> 00033 #include <FL/x.H> 00034 00035 #define MAXBUFFER 0x40000 // 256k 00036 00037 static void dataReleaseCB(void *info, const void *data, size_t size) 00038 { 00039 delete[] (uchar *)data; 00040 } 00041 00058 static void innards(const uchar *buf, int X, int Y, int W, int H, 00059 int delta, int linedelta, int mono, 00060 Fl_Draw_Image_Cb cb, void* userdata) 00061 { 00062 if (!linedelta) linedelta = W*delta; 00063 00064 const void *array = buf; 00065 uchar *tmpBuf = 0; 00066 if (cb) { 00067 tmpBuf = new uchar[ H*W*delta ]; 00068 for (int i=0; i<H; i++) { 00069 cb(userdata, 0, i, W, tmpBuf+i*W*delta); 00070 } 00071 array = (void*)tmpBuf; 00072 linedelta = W*delta; 00073 } 00074 // create an image context 00075 CGColorSpaceRef lut = 0; 00076 if (delta<=2) 00077 lut = CGColorSpaceCreateDeviceGray(); 00078 else 00079 lut = CGColorSpaceCreateDeviceRGB(); 00080 // a release callback is necessary when the fl_gc is a print context because the image data 00081 // must be kept until the page is closed. Thus tmpBuf can't be deleted here. It's too early. 00082 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 00083 typedef void (*CGDataProviderReleaseDataCallback) ( 00084 void *info, 00085 const void *data, 00086 size_t size 00087 ); 00088 #endif 00089 CGDataProviderReleaseDataCallback releaseCB = ( cb ? dataReleaseCB : NULL); 00090 CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, releaseCB); 00091 CGImageRef img = CGImageCreate( W, H, 8, 8*delta, linedelta, 00092 //lut, delta&1?kCGImageAlphaNone:kCGImageAlphaNoneSkipLast, 00093 lut, delta&1?kCGImageAlphaNone:kCGImageAlphaLast, 00094 src, 0L, false, kCGRenderingIntentDefault); 00095 // draw the image into the destination context 00096 if (img) { 00097 CGRect rect = { { X, Y }, { W, H } }; 00098 Fl_X::q_begin_image(rect, 0, 0, W, H); 00099 CGContextDrawImage(fl_gc, rect, img); 00100 Fl_X::q_end_image(); 00101 // release all allocated resources 00102 CGImageRelease(img); 00103 } 00104 CGColorSpaceRelease(lut); 00105 CGDataProviderRelease(src); 00106 if (img) return; // else fall through to slow mode 00107 // following the very save (and very slow) way to write the image into the give port 00108 CGContextSetShouldAntialias(fl_gc, false); 00109 if ( cb ) 00110 { 00111 uchar *tmpBuf = new uchar[ W*4 ]; 00112 for ( int i=0; i<H; i++ ) 00113 { 00114 uchar *src = tmpBuf; 00115 cb( userdata, 0, i, W, tmpBuf ); 00116 for ( int j=0; j<W; j++ ) 00117 { 00118 if ( mono ) 00119 { fl_color( src[0], src[0], src[0] ); } 00120 else 00121 { fl_color( src[0], src[1], src[2] ); } 00122 CGContextMoveToPoint(fl_gc, X+j, Y+i); 00123 CGContextAddLineToPoint(fl_gc, X+j, Y+i); 00124 CGContextStrokePath(fl_gc); 00125 src+=delta; 00126 } 00127 } 00128 delete[] tmpBuf; 00129 } 00130 else 00131 { 00132 for ( int i=0; i<H; i++ ) 00133 { 00134 const uchar *src = buf+i*linedelta; 00135 for ( int j=0; j<W; j++ ) 00136 { 00137 if ( mono ) 00138 fl_color( src[0], src[0], src[0] ); 00139 else 00140 fl_color( src[0], src[1], src[2] ); 00141 CGContextMoveToPoint(fl_gc, X+j, Y+i); 00142 CGContextAddLineToPoint(fl_gc, X+j, Y+i); 00143 CGContextStrokePath(fl_gc); 00144 src += delta; 00145 } 00146 } 00147 } 00148 CGContextSetShouldAntialias(fl_gc, true); 00149 } 00150 00151 void Fl_Quartz_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ 00152 innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0); 00153 } 00154 void Fl_Quartz_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, 00155 int x, int y, int w, int h,int d) { 00156 innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); 00157 } 00158 void Fl_Quartz_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ 00159 innards(buf,x,y,w,h,d,l,1,0,0); 00160 } 00161 void Fl_Quartz_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, 00162 int x, int y, int w, int h,int d) { 00163 innards(0,x,y,w,h,d,0,1,cb,data); 00164 } 00165 00166 void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { 00167 fl_color(r,g,b); 00168 fl_rectf(x,y,w,h); 00169 } 00170 00171 // 00172 // End of "$Id: fl_draw_image_mac.cxx 8128 2010-12-28 15:17:23Z manolo $". 00173 //