//---Include---
#include "Bild.h"
#include "Farbe.h"
#include "Text.h"
#include "Punkt.h"
#include "DateiSystem.h"
#include "Rahmen.h"
#include "MausEreignis.h"

using namespace Framework;

// Inhalt der Bild Klasse aus Bild.h
// Konstruktor 
Bild::Bild()
{
	fc = 0;
	größe = new Punkt( 0, 0 );
	pfad = new Text();
	dPosA = new TArray< Punkt >();
	dGrößeA = new TArray< Punkt >();
	ref = 1;
	InitializeCriticalSection( &threadSave );
}

// Destruktor 
Bild::~Bild()
{
	if( fc )
	{
		delete []fc;
		fc = 0;
	}
	größe->release();
	dPosA->release();
	dGrößeA->release();
	if( pfad )
		pfad->release();
	DeleteCriticalSection( &threadSave );
}

// nicht constant 
void Bild::lock()
{
	EnterCriticalSection( &threadSave );
}

void Bild::unlock()
{
	LeaveCriticalSection( &threadSave );
}

void Bild::neuBild( Punkt *größe, Farbe *füllFarbe ) // erzeugt ein neues Bild mit der Größe größe und der Hintergrundfarbe füllFarbe
{
	lock();
	if( fc )
	{
		delete []fc;
	}
	this->größe->setX( größe->getX() );
	this->größe->setY( größe->getY() );
	fc = new int[ größe->getX() * größe->getY() ];
	for( int i = 0; i < größe->getX() * größe->getY(); i++ )
	{
		fc[ i ] = füllFarbe->getFarbe();
	}
	dPosA->deleteAll();
	dGrößeA->deleteAll();
	größe->release();
	füllFarbe->release();
	unlock();
}

void Bild::füllRegion( Punkt *p, Punkt *gr, Farbe *f ) // setzt die Farbe einer bestimmten Region
{
	lock();
	int x1 = p->getX(), xx = größe->getX(), b = gr->getX();
	int fc2 = f->getFarbe();
	if( *p >= Punkt( 0, 0 ) && *p <= *größe && *gr > Punkt( 0, 0 ) && Punkt( p->getX() + gr->getX(), p->getY() + gr->getY() ) <= *größe )
	{
		for( int x = x1; x < x1 + b; x++ )
			for( int y = p->getY(); y < p->getY() + gr->getY(); y++ )
				fc[ x + y * xx ] = fc2;
	}
	f->release();
	p->release();
	gr->release();
	unlock();
}

void Bild::füllRegion( int x, int y, int b, int h, int ff )
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( x < dpx )
	{
		b -= dpx - x;
		x = dpx;
	}
	if( y < dpy )
	{
		h -= dpy - y;
		y = dpy;
	}
	b = ( x + b ) >= dgx ? ( dgx - x ) : b;
	h = ( y + h ) >= dgy ? ( dgy - y ) : h;
	for( int xx = x; xx < x + b; xx++ )
		for( int yy = y; yy < y + h; yy++ )
			fc[ xx + yy * größe->x ] = ff;
	unlock();
}

void Bild::alphaRegion(  int x, int y, int b, int h, int ff )
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( x < dpx )
	{
		b -= dpx - x;
		x = dpx;
	}
	if( y < dpy )
	{
		h -= dpy - y;
		y = dpy;
	}
	b = ( x + b ) >= dgx ? ( dgx - x ) : b;
	h = ( y + h ) >= dgy ? ( dgy - y ) : h;
	for( int xx = x; xx < x + b; xx++ )
		for( int yy = y; yy < y + h; yy++ )
			alphaPixel( xx, yy, ff );
	unlock();
}

void Bild::setPixel( Punkt *p, Farbe *f )
{
	fc[ p->getX() + p->getY() * größe->getX() ] = f->getFarbe();
	f->release();
	p->release();
}

void Bild::alphaPixel( Punkt *pos, Farbe *f )
{
	int fc1 = fc[ pos->getX() + pos->getY() * größe->getX() ];
	int fc2 = f->getFarbe();
	unsigned char r1, r2, g1, g2, b1, b2, a1, a2;
	a1 = (fc1 & 0xFF000000) >> 24;
	r1 = (fc1 & 0x00FF0000) >> 16;
	g1 = (fc1 & 0x0000FF00) >>  8;
	b1 = (fc1 & 0x000000FF);
	a2 = (fc2 & 0xFF000000) >> 24;
	r2 = (fc2 & 0x00FF0000) >> 16;
	g2 = (fc2 & 0x0000FF00) >> 8;
	b2 = (fc2 & 0x000000FF);
	r2 = ( r1 * a2 + r2 * ( 255 - a2 ) ) / 255;
	g2 = ( g1 * a2 + g2 * ( 255 - a2 ) ) / 255;
	b2 = ( b1 * a2 + b2 * ( 255 - a2 ) ) / 255;
	fc[ pos->getX() + pos->getY() * größe->getX() ] = (int)( ( a2 << 24 ) | ( r2 << 16 ) | ( g2 << 8 ) | b2 );
	pos->release();
	f->release();
}

void Bild::alphaPixel( int i, int f )
{
	int fc1 = fc[ i ];
	unsigned char r1, r2, g1, g2, b1, b2, a1, a2;
	a1 = (fc1 & 0xFF000000) >> 24;
	r1 = (fc1 & 0x00FF0000) >> 16;
	g1 = (fc1 & 0x0000FF00) >>  8;
	b1 = (fc1 & 0x000000FF);
	a2 = (f & 0xFF000000) >> 24;
	r2 = (f & 0x00FF0000) >> 16;
	g2 = (f & 0x0000FF00) >> 8;
	b2 = (f & 0x000000FF);
	r2 = ( r2 * a2 + r1 * ( 255 - a2 ) ) / 255;
	g2 = ( g2 * a2 + g1 * ( 255 - a2 ) ) / 255;
	b2 = ( b2 * a2 + b1 * ( 255 - a2 ) ) / 255;
	fc[ i ] = (int)( ( a2 << 24 ) | ( r2 << 16 ) | ( g2 << 8 ) | b2 );
}

void Bild::alphaPixel( int x, int y, int f )
{
	int fc1 = fc[ x + y *größe->x ];
	unsigned char r1, r2, g1, g2, b1, b2, a1, a2;
	a1 = (fc1 & 0xFF000000) >> 24;
	r1 = (fc1 & 0x00FF0000) >> 16;
	g1 = (fc1 & 0x0000FF00) >>  8;
	b1 = (fc1 & 0x000000FF);
	a2 = (f & 0xFF000000) >> 24;
	r2 = (f & 0x00FF0000) >> 16;
	g2 = (f & 0x0000FF00) >> 8;
	b2 = (f & 0x000000FF);
	r2 = ( r2 * a2 + r1 * ( 255 - a2 ) ) / 255;
	g2 = ( g2 * a2 + g1 * ( 255 - a2 ) ) / 255;
	b2 = ( b2 * a2 + b1 * ( 255 - a2 ) ) / 255;
	fc[ x + y *größe->x ] = (int)( ( a2 << 24 ) | ( r2 << 16 ) | ( g2 << 8 ) | b2 );
}

void Bild::drawLinie( Punkt *pos, Punkt *pos2, Farbe *f )
{
	lock();
	int x1 = pos->getX(), x2 = pos2->getX(), y1 = pos->getY(), y2 = pos2->getY();
	int dx = x2 - x1;
	int dy = y2 - y1;
	int füllfarbe = f->getFarbe();
	int bildBreite = größe->getX();

	if( dy == 0 && dx == 0 )
	{
		fc[ x1 + y1 * bildBreite ] = füllfarbe;
	}
	else if( abs( dy ) > abs( dx ) )
	{
		if( dy < 0 )
		{
			int temp = x1;
			x1 = x2;
			x2 = temp;
			temp = y1;
			y1 = y2;
			y2 = temp;
		}
		float m = (float)dx / (float)dy;
		float b = x1 - m*y1;
		for( int y = y1; y <= y2; y++ )
		{
			int x = (int)(m*y + b + 0.5f);
			fc[ x + y * bildBreite ] = füllfarbe;
		}
	}
	else
	{
		if( dx < 0 )
		{
			int temp = x1;
			x1 = x2;
			x2 = temp;
			temp = y1;
			y1 = y2;
			y2 = temp;
		}
		float m = (float)dy / (float)dx;
		float b = y1 - m*x1;
		for( int x = x1; x <= x2; x++ )
		{
			int y = (int)(m*x + b + 0.5f);
			fc[ x + y * bildBreite ] = füllfarbe;
		}
	}
	pos->release();
	pos2->release();
	f->release();
	unlock();
}

void Bild::drawLinieAlpha( Punkt *pos, Punkt *pos2, Farbe *f )
{
	lock();
	int x1 = pos->getX(), x2 = pos2->getX(), y1 = pos->getY(), y2 = pos2->getY();
	int dx = x2 - x1;
	int dy = y2 - y1;

	if( dy == 0 && dx == 0 )
	{
		alphaPixel( pos->getThis(), f->getThis() );
	}
	else if( abs( dy ) > abs( dx ) )
	{
		if( dy < 0 )
		{
			int temp = x1;
			x1 = x2;
			x2 = temp;
			temp = y1;
			y1 = y2;
			y2 = temp;
		}
		float m = (float)dx / (float)dy;
		float b = x1 - m*y1;
		for( int y = y1; y <= y2; y++ )
		{
			int x = (int)(m*y + b + 0.5f);
			alphaPixel( new Punkt( x, y ), f->getThis() );
		}
	}
	else
	{
		if( dx < 0 )
		{
			int temp = x1;
			x1 = x2;
			x2 = temp;
			temp = y1;
			y1 = y2;
			y2 = temp;
		}
		float m = (float)dy / (float)dx;
		float b = y1 - m*x1;
		for( int x = x1; x <= x2; x++ )
		{
			int y = (int)(m*x + b + 0.5f);
			alphaPixel( new Punkt( x, y ), f->getThis() );
		}
	}
	pos->release();
	pos2->release();
	f->release();
	unlock();
}

void Bild::drawLinieH( Punkt *pos, int län, Farbe *f ) // zeichnet eine horizontale Linie
{
	lock();
	int xp = pos->getX(), yp = pos->getY();
	pos->release();
	int farbe = f->getFarbe();
	f->release();
	if( län < 0 )
	{
		xp -= län;
		län = -län;
	}
	int br = größe->getX();
	for( int i = 0; i < län; i++ )
		fc[ ( xp + i ) + yp * br ] = farbe;
	unlock();
}

void Bild::drawLinieV( Punkt *pos, int län, Farbe *f ) // zeichnet eine vertikale Linie
{
	lock();
	int xp = pos->getX(), yp = pos->getY();
	pos->release();
	int farbe = f->getFarbe();
	f->release();
	if( län < 0 )
	{
		yp -= län;
		län = -län;
	}
	int br = größe->getX();
	for( int i = 0; i < län; i++ )
		fc[ xp + ( yp + i ) * br ] = farbe;
	unlock();
}

void Bild::drawLinieH( int x, int y, int län, int f ) // zeichnet eine horizontale Linie
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( y < dpy || y >= dgy )
	{
		unlock();
		return;
	}
	if( x < dpx )
	{
		län -= dpx - x;
		if( län <= 0 )
		{
			unlock();
			return;
		}
		x = dpx;
	}
	if( x + län >= dgx )
	{
		län -= x - dgx + län;
		if( län <= 0 )
		{
			unlock();
			return;
		}
	}
	int br   = größe->x;
	int *fc  = this->fc + x + y * br;
	int pval = län < 0 ? -1  : 1;
	län      = län > 0 ? län : -län;
	for( int i = 0; i < län; i++, fc += pval )
		*fc = f;
	unlock();
}

void Bild::drawLinieV( int x, int y, int län, int f ) // zeichnet eine vertikale Linie
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( x < dpx || x >= dgx )
	{
		unlock();
		return;
	}
	if( y < dpy )
	{
		län -= dpy - y;
		if( län <= 0 )
		{
			unlock();
			return;
		}
		y = dpy;
	}
	if( y + län >= dgy )
	{
		län -= y - dgy + län;
		if( län < 0 )
		{
			unlock();
			return;
		}
	}
	int br = größe->x;
	int *fc = this->fc + x + y * br;
	int pval = län < 0 ? -br : br;
	län      = län > 0 ? län : -län;
	for( int i = 0; i < län; i++, fc += pval )
		*fc = f;
	unlock();
}

void Bild::drawLinieHAlpha( Punkt *pos, int län, Farbe *f ) // zeichnet eine horizontale Linie
{
	lock();
	int xp = pos->x, yp = pos->y;
	pos->release();
	if( län < 0 )
	{
		xp -= län;
		län = -län;
	}
	int ff = f->getFarbe();
	int x = xp + yp * größe->x;
	for( int i = 0; i < län; i++ )
		alphaPixel( i + x, ff );
	f->release();
	unlock();
}

void Bild::drawLinieVAlpha( Punkt *pos, int län, Farbe *f ) // zeichnet eine vertikale Linie
{
	lock();
	int xp = pos->getX(), yp = pos->getY();
	pos->release();
	if( län < 0 )
	{
		yp -= län;
		län = -län;
	}
	int br = größe->getX();
	int ff = f->getFarbe();
	for( int i = 0; i < län; i++ )
		alphaPixel( xp + ( yp + i ) * br, ff );
	f->release();
	unlock();
}

void Bild::drawLinieHAlpha( int x, int y, int län, int f ) // zeichnet eine horizontale Linie
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( y < dpy || y >= dgy )
	{
		unlock();
		return;
	}
	if( x < dpx )
	{
		län -= dpx - x;
		if( län <= 0 )
		{
			unlock();
			return;
		}
		x = dpx;
	}
	if( x + län >= dgx )
	{
		län -= x - dgx + län;
		if( län <= 0 )
		{
			unlock();
			return;
		}
	}
	int br   = größe->x;
	int pval = län < 0 ? -1  : 1;
	län      = län > 0 ? län : -län;
	int end  = 0;
	for( int i = x + y * br; end < län; end++, i += pval )
		alphaPixel( i, f );
	unlock();
}

void Bild::drawLinieVAlpha( int x, int y, int län, int f ) // zeichnet eine vertikale Linie
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( x < dpx || x >= dgx )
	{
		unlock();
		return;
	}
	if( y < dpy )
	{
		län -= dpy - y;
		if( län <= 0 )
		{
			unlock();
			return;
		}
		y = dpy;
	}
	if( y + län >= dgy )
	{
		län -= y - dgy + län;
		if( län < 0 )
		{
			unlock();
			return;
		}
	}
	int br   = größe->x;
	int pval = län < 0 ? -br : br;
	län      = län > 0 ? län : -län;
	int end  = 0;
	for( int i = x + y * br; end < län; end++, i += pval )
		alphaPixel( i, f );
	unlock();
}

void Bild::drawLinie( Punkt *pos, Punkt *pos2, int län, Farbe *f )
{
	lock();
	int x1 = pos->getX(), x2 = pos2->getX(), y1 = pos->getY(), y2 = pos2->getY();
	int dx = x2 - x1;
	int dy = y2 - y1;
	bool tausch = 0;

	if( dy == 0 && dx == 0 )
	{
		fc[ x1 + y1 * größe->getX() ] = f->getFarbe();
	}
	else if( abs( dy ) > abs( dx ) )
	{
		if( dy < 0 )
		{
			tausch = 1;
			int temp = x1;
			x1 = x2;
			x2 = temp;
			temp = y1;
			y1 = y2;
			y2 = temp;
		}
		float m = (float)dx / (float)dy;
		float b = x1 - m*y1;
		if( !tausch )
		{
			for( int y = y1; y <= y1 + län; y++ )
			{
				int x = (int)(m*y + b + 0.5f);
				fc[ x + y * größe->getX() ] = f->getFarbe();
			}
		}
		else
		{
			for( int y = y2 - län; y <= y2; y++ )
			{
				int x = (int)(m*y + b + 0.5f);
				fc[ x + y * größe->getX() ] = f->getFarbe();
			}
		}
	}
	else
	{
		if( dx < 0 )
		{
			tausch = 1;
			int temp = x1;
			x1 = x2;
			x2 = temp;
			temp = y1;
			y1 = y2;
			y2 = temp;
		}
		float m = (float)dy / (float)dx;
		float b = y1 - m*x1;
		if( !tausch )
		{
			for( int x = x1; x <= x1 + län; x++ )
			{
				int y = (int)(m*x + b + 0.5f);
				fc[ x + y * größe->getX() ] = f->getFarbe();
			}
		}
		else
		{
			for( int x = x2 - län; x <= x2; x++ )
			{
				int y = (int)(m*x + b + 0.5f);
				fc[ x + y * größe->getX() ] = f->getFarbe();
			}
		}
	}
	unlock();
}

void Bild::drawLinie( int x1, int y1, int x2, int y2, int fc ) // zeichnet eine Linie von Punkt( x1, y1 ) nach Punke( x2, y2 )
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( ( x1 < dpx && x2 < dpx ) || ( x1 >= dgx && x2 >= dgx ) || ( y1 < dpy && y2 < dpy ) || ( y1 >= dgy && y2 >= dgy ) )
	{
		unlock();
		return;
	}
	int xlän = x2 - x1, axlän = abs( xlän );
	int ylän = y2 - y1, aylän = abs( ylän );
	double xf = (double)xlän / ( aylän ? aylän : 1 );
	double yf = (double)ylän / ( axlän ? axlän : 1 );
	if( axlän > aylän )
		xf = xf < 0 ? -1 : 1;
	else
		yf = yf < 0 ? -1 : 1;
	double x = (double)x1, y = (double)y1;
	while( !( (int)( x + 0.5 ) == x2 && (int)( y + 0.5 ) == y2 ) )
	{
		if( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy )
		{
			x += xf, y += yf;
			continue;
		}
		this->fc[ (int)( (int)( x + 0.5 ) + (int)( y + 0.5 ) * größe->x ) ] = fc;
		x += xf, y += yf;
	}
	unlock();
}

void Bild::drawLinieAlpha( int x1, int y1, int x2, int y2, int fc )
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	if( x1 < dpx || x1 >= dgx || x2 < dpx || x2 >= dgx || y1 < dpy || y1 >= dgy || y2 < dpy || y2 >= dgy )
	{
		if( ( x1 < dpx && x2 < dpx ) || ( x1 >= dgx && x2 >= dgx ) || ( y1 < dpy && y2 < dpy ) || ( y1 >= dgy && y2 >= dgy ) )
		{
			unlock();
			return;
		}
	}
	int xlän = x2 - x1, axlän = abs( xlän );
	int ylän = y2 - y1, aylän = abs( ylän );
	double xf = (double)xlän / ( aylän ? aylän : 1 );
	double yf = (double)ylän / ( axlän ? axlän : 1 );
	if( axlän > aylän )
		xf = xf < 0 ? -1 : 1;
	else
		yf = yf < 0 ? -1 : 1;
	double x = (double)x1, y = (double)y1;
	while( !( (int)( x + 0.5 ) == x2 && (int)( y + 0.5 ) == y2 ) )
	{
		if( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy )
		{
			x += xf, y += yf;
			continue;
		}
		alphaPixel( (int)( (int)( x + 0.5 ) + (int)( y + 0.5 ) * größe->x ), fc );
		x += xf, y += yf;
	}
	unlock();
}

void Bild::setDrawOptions( int x, int y, int xb, int yh )
{
	lock();
	if( x > größe->x || xb < 0 || y > größe->y || yh < 0 )
	{
		dPosA->lösche( 0, 0 );
		dGrößeA->lösche( 0, 0 );
		unlock();
		return;
	}
	dPosA->add( new Punkt( x >= 0 ? x : 0, y >= 0 ? y : 0 ), 0, 0 );
	dGrößeA->add( new Punkt( xb < größe->x ? xb : größe->x, yh < größe->y ? yh : größe->y ), 0, 0 );
	unlock();
}

void Bild::drawBild( int x, int y, int br, int hö, Bild *zBild ) // zeichet zBild
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	br = br > zBild->getBreite() ? zBild->getBreite()    : br;
	hö = hö > zBild->getHöhe()   ? zBild->getHöhe()      : hö;
	int xst = x < dpx            ? ( dpx - x )           : 0;
	int yst = y < dpy            ? ( dpy - y )           : 0;
	int xst2 = x > dpx           ? x                     : dpx;
	int yst2 = y > dpy           ? y                     : dpy;
	dgx = ( xst2 + br ) > dgx    ? dgx                   : ( xst2 + br );
	dgy = ( yst2 + hö ) > dgy    ? dgy                   : ( yst2 + hö );
	int bb = zBild->getBreite();
	int *ff = zBild->getBuffer();
	for( int xx = xst2; xx < dgx; xx++ )
		for( int yy = yst2; yy < dgy; yy++ )
			fc[ xx + yy * größe->x ] = ff[ ( xx - xst2 + xst ) + ( yy - yst2 + yst ) * bb ];
	unlock();
}

void Bild::alphaBild( int x, int y, int br, int hö, Bild *zBild )
{
	lock();
	int dpx = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->x   : 0;
	int dpy = dPosA->z( 0, 0 )   ? dPosA->z( 0, 0 )->y   : 0;
	int dgx = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->x : größe->x;
	int dgy = dGrößeA->z( 0, 0 ) ? dGrößeA->z( 0, 0 )->y : größe->y;
	br = br > zBild->getBreite() ? zBild->getBreite()    : br;
	hö = hö > zBild->getHöhe()   ? zBild->getHöhe()      : hö;
	int xst = x < dpx            ? ( dpx - x )           : 0;
	int yst = y < dpy            ? ( dpy - y )           : 0;
	int xst2 = x > dpx           ? x                     : dpx;
	int yst2 = y > dpy           ? y                     : dpy;
	dgx = ( xst2 + br ) > dgx    ? dgx                   : ( xst2 + br );
	dgy = ( yst2 + hö ) > dgy    ? dgy                   : ( yst2 + hö );
	int bb = zBild->getBreite();
	int *ff = zBild->getBuffer();
	for( int xx = xst2; xx < dgx; xx++ )
		for( int yy = yst2; yy < dgy; yy++ )
			alphaPixel( xx, yy, ff[ ( xx - xst2 + xst ) + ( yy - yst2 + yst ) * bb ] );
	unlock();
}

// constant 
int *Bild::getBuffer()const // gibt buffer zurück
{
	return fc;
}

Farbe *Bild::getPixel( Punkt *p ) const // gibt die Farbe des Pixels(x, y) zurück
{
	Farbe *ret = new Farbe();
	ret->setFarbe( fc[ p->getX() + p->getY() * größe->getX() ] );
	p->release();
	return ret;
}

Punkt *Bild::getGröße() const // gibt die Größe zurück
{
	return größe->getThis();
}

int Bild::getBreite() const // gibt die Breite zurück
{
	return größe->getX();
}

int Bild::getHöhe() const // gibt die Höhe zurück
{
	return größe->getY();
}

int Bild::getDOX() const
{
	if( dPosA->z( 0, 0 ) )
		return dPosA->z( 0, 0 )->x;
	return 0;
}

int Bild::getDOY() const
{
	if( dPosA->z( 0, 0 ) )
		return dPosA->z( 0, 0 )->y;
	return 0;
}

int Bild::getDOBX() const
{
	if( dGrößeA->z( 0, 0 ) )
		return dGrößeA->z( 0, 0 )->x;
	return größe->x;
}

int Bild::getDOHY() const
{
	if( dGrößeA->z( 0, 0 ) )
		return dGrößeA->z( 0, 0 )->y;
	return größe->y;
}

// Reference Counting 
Bild *Bild::getThis()
{
	ref++;
	return this;
}

Bild *Bild::release()
{
	ref--;
	if( ref < 1 )
		delete this;
	return 0;
}