Ejemplo n.º 1
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.º 2
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.º 3
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;
}