source: rtems-graphics-toolkit/fltk-1.1.10/src/fl_draw_image_mac.cxx @ 513eea1

Last change on this file since 513eea1 was 513eea1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/09/10 at 22:43:24

2010-01-08 Joel Sherrill <joel.sherrill@…>

fltk 1.1.10. imported

  • ORIGIN: Updated.
  • Property mode set to 100644
File size: 8.2 KB
Line 
1//
2// "$Id$"
3//
4// MacOS image drawing code for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 1998-2005 by Bill Spitzak and others.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (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 GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25//     http://www.fltk.org/str.php
26//
27
28////////////////////////////////////////////////////////////////
29
30#include <config.h>
31#include <FL/Fl.H>
32#include <FL/fl_draw.H>
33#include <FL/x.H>
34
35#define MAXBUFFER 0x40000 // 256k
36
37/**
38 * draw an image based on the input parameters
39 *
40 * buf:       image source data
41 * X, Y:      position (in buffer?!)
42 * W, H:      size of picture (in pixel?)
43 * delta:     distance from pixel to pixel in buf in bytes
44 * linedelta: distance from line to line in buf in bytes
45 * mono:      if set, pixel is one byte - if zero, pixel is 3 byte
46 * cb:        callback to copy image data into (RGB?) buffer
47 *   buf:       pointer to first byte in image source
48 *   x, y:      position in buffer
49 *   w:         width (in bytes?)
50 *   dst:       destination buffer
51 * userdata:  ?
52 */
53static void innards(const uchar *buf, int X, int Y, int W, int H,
54                    int delta, int linedelta, int mono,
55                    Fl_Draw_Image_Cb cb, void* userdata)
56{
57  if (!linedelta) linedelta = W*delta;
58
59#ifdef __APPLE_QD__
60  // theoretically, if the current GPort permits, we could write
61  // directly into it, avoiding the temporary GWorld. For now I
62  // will go the safe way... .
63  char direct = 0;
64  GWorldPtr gw;
65  Rect bounds;
66  bounds.left=0; bounds.right=W; bounds.top=0; bounds.bottom=H;
67  QDErr err = NewGWorld( &gw, 32, &bounds, 0L, 0L, useTempMem );
68  if (err==noErr && gw) {
69    PixMapHandle pm = GetGWorldPixMap( gw );
70    if ( pm ) {
71      LockPixels( pm );
72      if ( *pm ) {
73        uchar *base = (uchar*)GetPixBaseAddr( pm );
74        if ( base ) {
75          PixMapPtr pmp = *pm;
76          // make absolutely sure that we can use a direct memory write to
77          // create the pixmap!
78          if ( pmp->pixelType == 16 || pmp->pixelSize == 32 || pmp->cmpCount == 3 || pmp->cmpSize == 8 ) {
79            int rowBytes = pmp->rowBytes & 0x3fff;
80            if ( cb )
81            {
82              uchar *tmpBuf = new uchar[ W*delta ];
83              if ( mono ) delta -= 1; else delta -= 3;
84              for ( int i=0; i<H; i++ )
85              {
86                uchar *src = tmpBuf;
87                uchar *dst = base + i*rowBytes;
88                cb( userdata, 0, i, W, tmpBuf );
89                if ( mono ) {
90                  for ( int j=0; j<W; j++ )
91                    { uchar c = *src++; *dst++ = 0; *dst++ = c; *dst++ = c; *dst++ = c; src += delta; }
92                } else {
93                  for ( int j=0; j<W; j++ )
94                    { *dst++ = 0; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; src += delta; }
95                }
96              }
97              delete[] tmpBuf;
98            }
99            else
100            {
101              if ( mono ) delta -= 1; else delta -= 3;
102              for ( int i=0; i<H; i++ )
103              {
104                const uchar *src = buf+i*linedelta;
105                uchar *dst = base + i*rowBytes;
106                if ( mono ) {
107                  for ( int j=0; j<W; j++ )
108                    { uchar c = *src++; *dst++ = 0; *dst++ = c; *dst++ = c; *dst++ = c; src += delta; }
109                } else {
110                  for ( int j=0; j<W; j++ )
111                    { *dst++ = 0; *dst++ = *src++; *dst++ = *src++; *dst++ = *src++; src += delta; }
112                }
113              }
114            }
115         
116            fl_copy_offscreen( X, Y, W, H, gw, 0, 0 );
117            direct = 1;
118          }
119        }
120      }
121
122      UnlockPixels( pm );
123    }
124
125    DisposeGWorld( gw );
126  }
127
128  // great. We were able to write the pixels directly into memory, so we can return now.
129  if ( direct )
130    return;
131
132  // following the very save (and very slow) way to write the image into the give port
133  if ( cb )
134  {
135    uchar *tmpBuf = new uchar[ W*3 ];
136    for ( int i=0; i<H; i++ )
137    {
138      uchar *src = tmpBuf;
139      cb( userdata, 0, i, W, tmpBuf );
140      for ( int j=0; j<W; j++ )
141      {
142        if ( mono )         
143          { fl_color( src[0], src[0], src[0] ); src++; }
144        else
145          { fl_color( src[0], src[1], src[2] ); src+=3; }
146        MoveTo( X+j, Y+i );
147        Line( 0, 0 );
148      }
149    }
150    delete[] tmpBuf;
151  }
152  else
153  {
154    for ( int i=0; i<H; i++ )
155    {
156      const uchar *src = buf+i*linedelta;
157      for ( int j=0; j<W; j++ )
158      {
159        if ( mono )         
160          fl_color( src[0], src[0], src[0] );
161        else
162          fl_color( src[0], src[1], src[2] );
163        MoveTo( X+j, Y+i );
164        Line( 0, 0 );
165        src += delta;
166      }
167    }
168  }
169#elif defined(__APPLE_QUARTZ__)
170  const void *array = buf;
171  uchar *tmpBuf = 0;
172  if (cb) {
173    tmpBuf = new uchar[ H*W*delta ];
174    for (int i=0; i<H; i++) {
175      cb(userdata, 0, i, W, tmpBuf+i*W*delta);
176    }
177    array = (void*)tmpBuf;
178    linedelta = W*delta;
179  }
180  // create an image context
181  CGColorSpaceRef   lut = 0;
182  if (delta<=2)
183    lut = CGColorSpaceCreateDeviceGray();
184  else
185    lut = CGColorSpaceCreateDeviceRGB();
186  CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, linedelta*H, 0L);
187  CGImageRef        img = CGImageCreate( W, H, 8, 8*delta, linedelta,
188                            lut, delta&1?kCGImageAlphaNone:kCGImageAlphaNoneSkipLast,
189                            src, 0L, false, kCGRenderingIntentDefault);
190  // draw the image into the destination context
191  if (img) {
192    CGRect rect = { { X, Y }, { W, H } };
193    Fl_X::q_begin_image(rect, 0, 0, W, H);
194    CGContextDrawImage(fl_gc, rect, img);
195    Fl_X::q_end_image();
196    // release all allocated resources
197    CGImageRelease(img);
198  }
199  CGColorSpaceRelease(lut);
200  CGDataProviderRelease(src);
201  if (cb) {
202    delete[] tmpBuf;
203  }
204  if (img) return; // else fall through to slow mode
205  // following the very save (and very slow) way to write the image into the give port
206  CGContextSetShouldAntialias(fl_gc, false);
207  if ( cb )
208  {
209    uchar *tmpBuf = new uchar[ W*4 ];
210    for ( int i=0; i<H; i++ )
211    {
212      uchar *src = tmpBuf;
213      cb( userdata, 0, i, W, tmpBuf );
214      for ( int j=0; j<W; j++ )
215      {
216        if ( mono )
217          { fl_color( src[0], src[0], src[0] ); }
218        else
219          { fl_color( src[0], src[1], src[2] ); }
220        CGContextMoveToPoint(fl_gc, X+j, Y+i);
221        CGContextAddLineToPoint(fl_gc, X+j, Y+i);
222        CGContextStrokePath(fl_gc);
223        src+=delta;
224      }
225    }
226    delete[] tmpBuf;
227  }
228  else
229  {
230    for ( int i=0; i<H; i++ )
231    {
232      const uchar *src = buf+i*linedelta;
233      for ( int j=0; j<W; j++ )
234      {
235        if ( mono )
236          fl_color( src[0], src[0], src[0] );
237        else
238          fl_color( src[0], src[1], src[2] );
239        CGContextMoveToPoint(fl_gc, X+j, Y+i);
240        CGContextAddLineToPoint(fl_gc, X+j, Y+i);
241        CGContextStrokePath(fl_gc);
242        src += delta;
243      }
244    }
245  }
246  CGContextSetShouldAntialias(fl_gc, true);
247#else
248# error : you must defined __APPLE_QD__ or __APPLE_QUARTZ__
249#endif
250}
251
252void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
253  innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
254}
255void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
256                   int x, int y, int w, int h,int d) {
257  innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
258}
259void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
260  innards(buf,x,y,w,h,d,l,1,0,0);
261}
262void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
263                   int x, int y, int w, int h,int d) {
264  innards(0,x,y,w,h,d,0,1,cb,data);
265}
266
267void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
268  fl_color(r,g,b);
269  fl_rectf(x,y,w,h);
270}
271
272//
273// End of "$Id$".
274//
Note: See TracBrowser for help on using the repository browser.