Ejemplo n.º 1
0
/*==================================
	PatternToOffscreen
===================================*/
SUOffscreen *PTPatternView::BWPatternToOffscreen( const Pattern &inPattern )
{
	StSaveGWorld	save1;
	CTabHandle		theTable = nil;
	SUOffscreen		*theBuffer = nil;
	
	try
	{
		theTable = SUColorUtils::GetColorTable( 1 );
		
		theBuffer = SUOffscreen::CreateBuffer( DefaultPatternWidth, DefaultPatternHeight, 1, theTable );
		//theBuffer->AssignPalette( theTable );		
		
		theBuffer->BeginDrawing();
			Rect		r;
			::SetRect( &r, 0, 0, DefaultPatternWidth, DefaultPatternHeight );
			::PenPat( &inPattern );
			::PaintRect( &r );
			::PenNormal();
		theBuffer->EndDrawing();
	}
	catch( ... )
	{
		if ( theBuffer ) delete( theBuffer );
		if ( theTable ) ::DisposeCTable( theTable );
		throw;
	}
	
	if ( theTable ) ::DisposeCTable( theTable );
	return( theBuffer );
}
Ejemplo n.º 2
0
/*================================
	SetSelection
=================================*/
void PTPaintSelection::SetSelection( PTPaintSelection *inSource )
{
	if ( inSource->IsEmpty() )
	{
		this->SelectNone();
		return;
	}
	
	try
	{
		this->DisposeBuffer();
		
		SUOffscreen 		*sourceBuffer = inSource->mSelectionBuffer;
		
		mSelectionBuffer = sourceBuffer->CreateSimilarOffscreen( false );
		mSelectionBuffer->CopyFrom( sourceBuffer );
		
		this->SetRawSelection( inSource->GetRegion() );
	}
	catch( ... )
	{
		this->SelectNone();		// if an error occurs, force no selection or things get weird
		throw;
	}
}
Ejemplo n.º 3
0
/*===============================================
	ParseBWCursor
================================================*/
void PTCursorView::ParseBWCursor( RFMap *inMap, ResIDT inResID,
						SUOffscreen **outBW, SUOffscreen **outMask, 
						Point *outHotSpot )
{
	CursHandle		h = nil;
	SUOffscreen		*bw = nil, *mask = nil;
	
	try
	{
		/**************************************************
			get the raw resource handle
		**************************************************/
		RFResource *theRes = inMap->FindResource( ImageType_Cursor, inResID, false );
		ThrowIfNil_( theRes );
		h = (CursHandle) theRes->GetResData();
		ThrowIfNil_( h );
		::HLock( (Handle) h );

			// 2 rowBytes x 16 rows x 2 images + sizeof(Point)
		if ( ::GetHandleSize( (Handle) h ) != BWCursor_Bytes )
			LException::Throw( err_CorruptedResource );
		
		/**************************************************
			create the bw bitmap
		**************************************************/
		bw = SUOffscreen::CreateBuffer( Cursor_Width, Cursor_Height, 1 );
		ThrowIfMemFail_( bw );
		//bw->AssignPalette( oneBitTable );
		bw->CopyFromRawData( (UInt8*) &(**h).data, BWCursor_RowBytes );

		/**************************************************
			create the mask bitmap
		**************************************************/
		mask = SUOffscreen::CreateBuffer( Cursor_Width, Cursor_Height, 1 );
		ThrowIfMemFail_( bw );
		mask->CopyFromRawData( (UInt8*) &(**h).mask, BWCursor_RowBytes );

		/**************************************************
			and return stuff to the caller
		**************************************************/
		*outBW = bw;
		*outMask = mask;
		*outHotSpot = (**h).hotSpot;
	}
	catch( ... )
	{
		SUMiscUtils::DisposeHandle( h );
		if ( bw ) delete ( bw );
		if ( mask ) delete( mask );
		throw;
	}
	
	SUMiscUtils::DisposeHandle( h );
}
Ejemplo n.º 4
0
void PTRecolorAction::DoIt()
{
	if ( mTable )
	{
		SUOffscreen		*currentBuffer = mSettings.currentBuffer;
		
		mSettings.thePaintView->CopyToUndo();
		mSettings.thePaintView->SelectNone();
	
		/*
			create a new buffer the same size as the image but with
			a depth of 8-bits. use the specified color table as the
			color table.
		*/
		SInt32	width = currentBuffer->GetWidth();
		SInt32	height = currentBuffer->GetHeight();
		
		SUOffscreen *newBuffer = SUOffscreen::CreateBuffer( width, height, kRecolorDepth, mTable );

		/*
			increase the inverse table size from 4 to 5 bits.
			this gives substantially better color matching.
		*/
		newBuffer->IncreaseInverseTableSize();
		
		/*
			Copy the image to the 8-bit buffer to downsample the colors 
			and then back to the original 32-bit one
		*/
		newBuffer->CopyFrom( currentBuffer );		
		currentBuffer->CopyFrom( newBuffer );
		delete newBuffer;
		
			// update the canvas
		mSettings.theCanvas->DrawFrom( currentBuffer );
	}

	this->PostAsAction();
}
Ejemplo n.º 5
0
/*===============================================
	ChangeImageSize
	
	Note:
	Affects only the pixpat, _not_ the black & white pattern.
================================================*/
void PTPatternView::ChangeImageSize( SInt32 inWidth, SInt32 inHeight, Boolean inStretch )
{
	ThrowIf_( (inWidth < mMinImageWidth) || (inHeight < mMinImageHeight) );
	ThrowIf_( (inWidth > mMaxImageWidth) || (inHeight > mMaxImageHeight) );
	ThrowIf_( mResourceType != ImageType_PixPat );
	ThrowIfNil_( mColorSample );
	ThrowIfNil_( mCurrentImage );
	
	SInt32			savedWidth = mPixPatWidth;		// in case of error...
	SInt32			savedHeight = mPixPatHeight;
	Boolean			changedSize = true;
	SUOffscreen		*newBuffer = nil;
	Rect			destR;
	
	try
	{
		/*****************************************
			create a new buffer -- same depth as current one, but new size
		*****************************************/
		newBuffer = mCurrentImage->CreateSimilarOffscreen( false, inWidth, inHeight );
		
		/*****************************************
			copy the image from the old buffer into the new one
		*****************************************/
		if ( inStretch )
			::SetRect( &destR, 0, 0, inWidth, inHeight );
		else
			::SetRect( &destR, 0, 0, mCurrentImage->GetWidth(), mCurrentImage->GetHeight() );
		
		newBuffer->CopyFrom( mCurrentImage, &destR );
		
		/*****************************************
			resize the pixpat sample pane
		*****************************************/
		this->ResizeSampleWell( inWidth, inHeight );
		changedSize = true;
		
		/*****************************************
			keep track of the changed size. do this before SetImage() because it
			may call GetZoomFactor.
		*****************************************/
		mPixPatWidth = inWidth;
		mPixPatHeight = inHeight;

		/*****************************************
			set the current buffer
			 -- this can trigger all sorts of things (canvas resize, etc)
		*****************************************/
		this->SetImage( newBuffer, PTResize_All, redraw_Later );
		
		/*****************************************
			change the sample pane's buffer.
			Notes:
			 (1) The sample pane will own the buffer after this call (don't delete it)
			 (2) The previous sample pane buffer will be saved away by the PTResizer object
		*****************************************/
		mColorSample->SetRawBuffer( newBuffer );
	}
	catch( ... )
	{
		/*
			restore things to the way they were before we were called
		*/
		mPixPatWidth = savedWidth;
		mPixPatHeight = savedHeight;

		if ( changedSize )
			this->ResizeSampleWell( mPixPatWidth, mPixPatHeight );
	
		delete newBuffer;
		throw;
	}
}
Ejemplo n.º 6
0
/*==================================
	ParseColorPattern
===================================*/
void PTPatternView::ParseColorPattern( Handle inPattern, SUOffscreen **outColor,
												SUOffscreen **outBW )
{
	// See IM V-79 for details

	StSaveGWorld		save1;
	StHandleLocker		save2( inPattern );
	PixPatPtr			p = (PixPatPtr) *inPattern;
	CTabHandle			theTable = nil;
	SUOffscreen			*tempColorBuffer = nil, *colorBuffer = nil, *bwBuffer = nil;

	try
	{	
		if ( p->patType != 1 )
			LException::Throw( err_InvalidImageFormat );
			
		/*******************************************
			first handle the b&w pattern
		********************************************/
		bwBuffer = this->BWPatternToOffscreen( p->pat1Data );

		/*******************************************
			now the color pattern
		********************************************/
		PixMapPtr			theMap = (PixMapPtr)( *inPattern + (SInt32) p->patMap );
		UInt8 *				theData = (UInt8*)( *inPattern + (SInt32) p->patData );
		
		SInt32				depth = theMap->pixelSize;
		SInt32				width = theMap->bounds.right - theMap->bounds.left;
		SInt32				height = theMap->bounds.bottom - theMap->bounds.top;
		SInt32				rowBytes = theMap->rowBytes & 0x3FFF;		// clear flags
		
		if ( (depth != 1) && (depth != 2) && (depth != 4) && (depth != 8) )
			LException::Throw( err_InvalidImageDepth );
		
		if ( (width <= 3) || (width > 64) || (height <= 3) || (height > 64) )
			LException::Throw( err_InvalidImageSize );
		
		theTable = SUColorUtils::NewColorTableFromPtr( depth, (UInt8*)( *inPattern + (SInt32)theMap->pmTable) );
		tempColorBuffer = SUOffscreen::CreateBuffer( width, height, depth, theTable );
		tempColorBuffer->CopyFromRawData( theData, rowBytes );

		// now switch to a 32-bit buffer
		colorBuffer = SUOffscreen::CreateBuffer( width, height, 32 );
		colorBuffer->CopyFrom( tempColorBuffer );
	}
	catch( ... )
	{
		delete colorBuffer;
		delete bwBuffer;
		delete tempColorBuffer;
		if ( theTable )
			::DisposeCTable( theTable );
		throw;
	}
	
	*outColor = colorBuffer;
	*outBW = bwBuffer;

	if ( theTable )
		::DisposeCTable( theTable );
	delete tempColorBuffer;
}
Ejemplo n.º 7
0
/*===============================================
	InitializeFromResource
================================================*/
void PTPatternView::InitializeFromResource( RFMap *inMap, ResType inResType, ResIDT inResID )
{
	StSaveGWorld		aSaver;
	StSaveResFile		aSaver2;

	SUOffscreen			*colorImage = nil, *bwImage = nil;
	Handle				h = nil;
	
	try
	{
		mResourceType = inResType;
	
		/**************************************************
			get the raw resource handle
		**************************************************/
		RFResource *theRes = inMap->FindResource( inResType, inResID, false );
		ThrowIfNil_( theRes );
		h = theRes->GetResData();
		ThrowIfNil_( h );
		
		/**************************************************
			draw the pattern(s) into bitmaps
		**************************************************/
		switch( inResType )
		{
			case ImageType_PixPat:
				this->ParseColorPattern( h, &colorImage, &bwImage );
				mAllowImageResizing = true;
				break;
			case ImageType_Pattern:
				this->ParseBWPattern( h, &bwImage );
				break;
			default:
				LException::Throw( err_UnknownDataType );
		}
		
		/**************************************************
			resize the sample well if the color pattern is bigger than 8x8
		**************************************************/
		if ( colorImage )
		{
			SInt32	width = colorImage->GetWidth();
			SInt32	height = colorImage->GetHeight();
			
				// save these _now_ because SetImage() will trigger a call to
				// GetZoomFactor()
			mPixPatWidth = width;
			mPixPatHeight = height;
			
			this->ResizeSampleWell( width, height );
			
			this->SetImage( colorImage, PTResize_All, redraw_Later );

			mColorSample->SetBuffer( colorImage, redraw_Dont );
			colorImage = nil;		// because it belongs to the sample pane now
			mColorSample->SetTarget( true, redraw_Dont );
			
			mCurrentSamplePane = mColorSample;
		}
		else
		{
			this->SetImage( bwImage, PTResize_All, redraw_Later );
			mCurrentSamplePane = mBWSample;	
			mBWSample->SetTarget( true, redraw_Dont );
		}
		
		mBWSample->SetBuffer( bwImage, redraw_Dont );
		bwImage = nil;			// because it belongs to the sample pane now
	}
	catch( ... )
	{
		delete( colorImage );
		delete( bwImage );
		SUMiscUtils::DisposeHandle( h );
		throw;
	}
	
	SUMiscUtils::DisposeHandle( h );
}
Ejemplo n.º 8
0
/*====================================
	InitializeOneMember
=====================================*/
Boolean PTFamilyView::InitializeOneMember( RFMap *inMap, ResType inResType, ResIDT inResID,
											SInt32 inWidth, SInt32 inHeight, SInt32 inDepth,
											SInt32 inOffset, SInt32 inRowBytes,
											PaneIDT inSamplePaneID, Boolean /* inIsMask */ )
{
	StSaveResFile 	aSaver;
	SUOffscreen		*theBuffer = nil;
	Boolean			isUsed = false;
	
	/*
		icon families use the standard color table for their depth
	*/
	CTabHandle		theTable = SUColorUtils::GetColorTable( inDepth );

	try
	{
		/******************************************
			create the offscreen buffer
		*******************************************/
		theBuffer = SUOffscreen::CreateBuffer( inWidth, inHeight, inDepth, theTable );
		
		/******************************************
			if we have a resource, load the data into the offscreen buffer
		*******************************************/
		RFResource *theResource = inMap->FindResource( inResType, inResID, false );
		if ( theResource )
		{
			Handle h = theResource->GetResData();
			if ( h )
			{
				::HLock( h );
				theBuffer->CopyFromRawData( (UInt8*) *h + inOffset, inRowBytes );
				SUMiscUtils::DisposeHandle( h );
				isUsed = true;
			}
		}

		/******************************************
			initialize the sample pane
		*******************************************/
		PTDraggableTargetBox *thePane = (PTDraggableTargetBox*) this->FindPaneByID( inSamplePaneID );
		ThrowIfNil_( thePane );
		
		mSamplePaneList[ mNumSamplePanes++ ] = thePane;		
		thePane->SetUsedFlag( isUsed, redraw_Dont );		// true if the resource exists
		thePane->SetBuffer( theBuffer, redraw_Dont );
		theBuffer = nil;									// so we don't delete it below
	}
	catch( ... )
	{
		if ( theBuffer )
			delete theBuffer;
		if ( theTable )
			::DisposeCTable( theTable );
		throw;
	}
	
	if ( theTable )
		::DisposeCTable( theTable );
		
	return( isUsed );
}
Ejemplo n.º 9
0
/*===============================================
	ParseColorCursor

	Note:
	See description of CCrsr structure above.
================================================*/
void PTCursorView::ParseColorCursor( RFMap *inMap, ResIDT inResID,
						SUOffscreen **outColor, SUOffscreen **outBW, 
						SUOffscreen **outMask, Point *outHotSpot )
{
	PixMapPtr		cMap;
	SInt32			depth, width, height;
	CTabHandle		theTable = nil;
	SUOffscreen		*cBuffer = nil, *bwBuffer = nil, *maskBuffer = nil, *tempBuffer = nil;
	CCrsrHandle		h = nil;
	UInt8			*p;
	
	try
	{
		/**************************************************
			get the raw resource handle
			 -- this isn't the usual way of loading color cursors, so the fields
			 -- will be raw and not filled in (as when GetCCursor is used)
		**************************************************/
		RFResource *theRes = inMap->FindResource( ImageType_ColorCursor, inResID, false );
		ThrowIfNil_( theRes );
		h = (CCrsrHandle) theRes->GetResData();
		ThrowIfNil_( h );
		::HLock( (Handle) h );
		p = (UInt8*) *h;
		
		/**************************************************
			validate the handle a little bit
		**************************************************/
		if ( (UInt16) (**h).crsrType != (UInt16) 0x8001 )	// cast *is* needed - crsrType is signed
			LException::Throw( err_InvalidImageFormat );
		
		if ( ::GetHandleSize( (Handle) h ) < static_cast<Size>(sizeof(CCrsr)) )
			LException::Throw( err_CorruptedResource );
	
		/**************************************************
			get some info about the cursor
		**************************************************/
		cMap = (PixMapPtr) (p + (SInt32) (**h).crsrMap);

		if ( cMap->pixelType != 0 )
			LException::Throw( err_InvalidImageFormat );

		width = cMap->bounds.right - cMap->bounds.left;
		height = cMap->bounds.bottom - cMap->bounds.top;
		depth = cMap->pixelSize;
		
		if ( (width != Cursor_Width) || (height != Cursor_Height) )
			LException::Throw( err_InvalidImageSize );
		
		if ( (depth != 1) && (depth != 2) && (depth != 4) && (depth != 8) )
			LException::Throw( err_InvalidImageDepth );
		
		/**************************************************
			create the bwBuffer and maskBuffer
		**************************************************/
		bwBuffer = SUOffscreen::CreateBuffer( Cursor_Width, Cursor_Height, 1 );
		ThrowIfMemFail_( bwBuffer );
		bwBuffer->CopyFromRawData( (UInt8*) &(**h).crsr1Data, BWCursor_RowBytes );

		maskBuffer = SUOffscreen::CreateBuffer( Cursor_Width, Cursor_Height, 1 );
		ThrowIfMemFail_( maskBuffer );
		maskBuffer->CopyFromRawData( (UInt8*) &(**h).crsrMask, BWCursor_RowBytes );

		/**************************************************
			allocate the color table. note that the resource may have a minimal
			color table and QuickDraw doesn't work with anything but a full-sized one.
		**************************************************/
		if ( cMap->pmTable == 0 )			// probably won't happen, but can't hurt to check
			theTable = SUColorUtils::NewColorTableByDepth( depth );
		else
			theTable = SUColorUtils::NewColorTableFromPtr( depth, p + (SInt32) cMap->pmTable );
				
		/**************************************************
			allocate the color bitmap
		**************************************************/
		tempBuffer = SUOffscreen::CreateBuffer( width, height, depth, theTable );
		SInt32	rowBytes = cMap->rowBytes & 0x3FFF;			// clear flag bits
		if ( rowBytes != 0 )
			tempBuffer->CopyFromRawData( p + (SInt32) (**h).crsrData, rowBytes );

		/**************************************************
			now switch it to a 32-bit offscreen
		**************************************************/
		cBuffer = SUOffscreen::CreateBuffer( width, height, 32 );
		cBuffer->CopyFrom( tempBuffer );
	}
	catch( ... )
	{
		delete maskBuffer;
		delete bwBuffer;
		delete cBuffer;
		delete tempBuffer;
		if ( theTable ) ::DisposeCTable( theTable );
		SUMiscUtils::DisposeHandle( h );
	}
	
		// return buffers and info to the caller
	*outColor = cBuffer;
	*outBW = bwBuffer;
	*outMask = maskBuffer;
	*outHotSpot = (**h).crsrHotSpot;

		// don't need the color table because the offscreen makes a copy of it
	if ( theTable ) ::DisposeCTable( theTable );
	SUMiscUtils::DisposeHandle( h );
	delete tempBuffer;
}