1 /* ========================================================================
4 ** $Id: surface.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
6 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
8 ** This software and associated documentation
9 ** are CONFIDENTIAL and PROPRIETARY property of
10 ** the above-mentioned copyright holder.
12 ** You may not copy, print, publish, or in any
13 ** other way distribute this software without
14 ** a prior written agreement with
15 ** the copyright holder.
17 ** === N O T E S ===========================================================
19 ** ========================================================================= */
21 /* === H E A D E R S ======================================================= */
23 #define SYNFIG_NO_ANGLE
34 #include "target_scanline.h"
38 #include <Accelerate/Accelerate.h>
43 using namespace synfig;
47 /* === M A C R O S ========================================================= */
49 /* === G L O B A L S ======================================================= */
51 class target2surface : public synfig::Target_Scanline
57 target2surface(Surface *surface);
58 virtual ~target2surface();
60 virtual bool set_rend_desc(synfig::RendDesc *newdesc);
62 virtual bool start_frame(synfig::ProgressCallback *cb);
64 virtual void end_frame();
66 virtual Color * start_scanline(int scanline);
68 virtual bool end_scanline();
71 target2surface::target2surface(Surface *surface):surface(surface)
75 target2surface::~target2surface()
80 target2surface::set_rend_desc(synfig::RendDesc *newdesc)
85 return synfig::Target_Scanline::set_rend_desc(newdesc);
89 target2surface::start_frame(synfig::ProgressCallback *cb)
91 if(surface->get_w() != desc.get_w() || surface->get_h() != desc.get_h())
93 surface->set_wh(desc.get_w(),desc.get_h());
99 target2surface::end_frame()
105 target2surface::start_scanline(int scanline)
107 return (*surface)[scanline];
111 target2surface::end_scanline()
116 /* === P R O C E D U R E S ================================================= */
118 /* === M E T H O D S ======================================================= */
120 Target_Scanline::Handle
121 synfig::surface_target(Surface *surface)
123 return Target_Scanline::Handle(new target2surface(surface));
127 synfig::Surface::clear()
130 fill(Color(0.5,0.5,0.5,0.0000001));
132 etl::surface<Color, ColorAccumulator, ColorPrep>::clear();
137 synfig::Surface::blit_to(alpha_pen& pen, int x, int y, int w, int h)
139 static const float epsilon(0.00001);
140 const float alpha(pen.get_alpha());
141 if( pen.get_blend_method()==Color::BLEND_STRAIGHT && fabs(alpha-1.0f)<epsilon )
143 if(x>=get_w() || y>=get_w())
159 //clip width against dest width
160 w = min(w,pen.end_x()-pen.x());
161 h = min(h,pen.end_y()-pen.y());
163 //clip width against src width
164 w = min(w,get_w()-x);
165 h = min(h,get_h()-y);
172 char* src(static_cast<char*>(static_cast<void*>(operator[](y)+x))+i*get_w()*sizeof(Color));
173 char* dest(static_cast<char*>(static_cast<void*>(pen.x()))+i*pen.get_width()*sizeof(Color));
174 memcpy(dest,src,w*sizeof(Color));
180 if( pen.get_blend_method()==Color::BLEND_COMPOSITE && fabs(alpha-1.0f)<epsilon )
182 if(x>=get_w() || y>=get_w())
200 //clip width against dest width
201 w = min(w,pen.end_x()-pen.x());
202 h = min(h,pen.end_y()-pen.y());
204 //clip width against src width
205 w = min(w,get_w()-x);
206 h = min(h,get_h()-y);
213 vImage_Buffer top,bottom;
214 vImage_Buffer& dest(bottom);
216 top.data=static_cast<void*>(operator[](y)+x);
219 //top.rowBytes=get_w()*sizeof(Color); //! \fixme this should get the pitch!!
220 top.rowBytes=get_pitch();
222 bottom.data=static_cast<void*>(pen.x());
225 //bottom.rowBytes=pen.get_width()*sizeof(Color); //! \fixme this should get the pitch!!
226 bottom.rowBytes=pen.get_pitch(); //! \fixme this should get the pitch!!
229 ret=vImageAlphaBlend_ARGBFFFF(&top,&bottom,&dest,kvImageNoFlags);
231 assert(ret!=kvImageNoError);
236 etl::surface<Color, ColorAccumulator, ColorPrep>::blit_to(pen,x,y,w,h);