Ejemplo n.º 1
0
NodeRegularShape * OpBackground::DoCreateRectangle(Spread * pSpread)
{
	ERROR2IF(pSpread == NULL,FALSE,"OpBackground::DoCreateRectangle Bad params error!");

	if (pSpread == NULL)
		return NULL;

	// This assumes that we have already checked to see if there is a page covering rectangle
	// already present on this layer.

	// Create a new rectangle node on the layer
	NodeRegularShape *pShape = new NodeRegularShape;
	if (pShape != NULL)
	{
		BOOL ok = pShape->SetUpShape();

		if (!ok)
		{
			// Do something sensible in here
			delete pShape;
			return NULL;
		}

		// We want to make the rectangle the same size as the current union of
		// all the pages on the current spread
		DocRect Rect;
		pSpread->GetPagesRect(&Rect);

		/* // We must expand the rectangle by a single pixel as the page redraw
		// draws a single pixel line around the outside.
		const MILLIPOINT pixel = (MILLIPOINT)(72000.0/96.0);
		Rect.Inflate(pixel); */

		const INT32 CornerRadius = 0; // No curvature
		
		if (pShape->MakeRectangle(Rect.Width(), Rect.Height(), CornerRadius))
		{
			// Translate centre from 0,0 to required position relative to page
			INT32 XTrans = Rect.lo.x + (Rect.Width()/2);
			INT32 YTrans = Rect.lo.y + (Rect.Height()/2);
			Trans2DMatrix Trans(XTrans, YTrans);

			pShape->Transform(Trans);

			// finish off the shape
			pShape->InvalidateBoundingRect();
		}
	}

	return pShape;
}
Ejemplo n.º 2
0
Chapter* DocCoord::FindEnclosingChapter(Document *pDocument, 
										DocCoord* ChapterPos, 
										XLONG* ChapterDepth,
										View *pView)
{
	Chapter* CurrentChapter = Node::FindFirstChapter(pDocument);
	// Search all chapters
	*ChapterDepth = 0;
	DocRect CurrentChaptersPasteboardRect;

	while (CurrentChapter != NULL)
	{
		CurrentChaptersPasteboardRect = CurrentChapter->GetPasteboardRect(TRUE, pView);

		if (CurrentChaptersPasteboardRect.ContainsRectCoord(*this))
		{
			// Chapter position is the top left hand corner of the chapters pasteboard
			ChapterPos->x = CurrentChaptersPasteboardRect.LowCorner().x;
			ChapterPos->y = CurrentChaptersPasteboardRect.HighCorner().y;
			return (CurrentChapter);
		}

        (*ChapterDepth) += CurrentChaptersPasteboardRect.Height();
		CurrentChapter = CurrentChapter->FindNextChapter();
    }

	// The DocCoord was not found in any chapter
	ERROR3("DocCoord::FindEnclosingChapter: Coord wasn't in any chapter. See the function help for debugging tips");
	return(NULL);
}
Ejemplo n.º 3
0
XLONG Chapter::GetChapterDepth()
{
	XLONG Depth	= 0;

	// Loop through document tree calculating the logical coordinate offset for the
	// current chapter 	

//	Chapter *pChapter = Node::FindFirstChapter(FindOwnerDoc());
	Node* pNode = FindParent();
	ERROR2IF(!(pNode->IsNodeDocument()), 0, "Parent of Chapter is not NodeDocument");
	Chapter *pChapter = (Chapter*)pNode->FindFirstChild(CC_RUNTIME_CLASS(Chapter));

	ENSURE(pChapter != NULL, "Couldn't find first chapter in Chapter::GetChapterDepth");
	
	while ((pChapter != NULL) && (pChapter != this))
	{		
                                         				
		ENSURE(pChapter->IsKindOf(CC_RUNTIME_CLASS(Chapter)), 
				"Chapter's sibling is not a Chapter");

		const DocRect ChapRect = pChapter->GetPasteboardRect();
            
        // Accumulate logical offset
		Depth += ChapRect.Height();						
			
		pChapter = (Chapter *) pChapter->FindNext();
	}

	return Depth;
}
Ejemplo n.º 4
0
/********************************************************************************************

>	BOOL MakeBitmapFilter::FindCentreInsertionPosition(Spread** Spread, DocCoord* Position)

	Author:		Will_Cowling (Xara Group Ltd) <*****@*****.**> (from Simon)
	Created:	12/6/96
	Inputs:		-
	Outputs:	Spread:  The spread to place the clipboard objects on
				Position:The centre of the view (Spread coords)
	Purpose:	Finds the centre insertion position for clipboard objects

********************************************************************************************/
BOOL MakeBitmapFilter::FindCentreInsertionPosition(Spread** Spread, DocCoord* Position)
{
	// ---------------------------------------------------------------------------------
	// Find out which spread is in the centre of the view 
	// this is the spread that the pasted objects will be placed on

	// Obtain the current DocView
	DocView* CurDocView = DocView::GetCurrent();

	ENSURE(CurDocView != NULL, "The current DocView is NULL"); 
	if (CurDocView == NULL)
		return FALSE; // No DocView

	// Get the view rect
	WorkRect WrkViewRect = CurDocView->GetViewRect();

	if (WrkViewRect.IsEmpty() || (!WrkViewRect.IsValid()) )
		return FALSE; // Defensive
	
	// Determine the centre of the view
	WorkCoord WrkCentreOfView; 
	WrkCentreOfView.x = WrkViewRect.lox	+ (WrkViewRect.Width()/2); 
	WrkCentreOfView.y = WrkViewRect.loy	+ (WrkViewRect.Height()/2);
	
	// FindEnclosing spread requires an OilCoord
	OilCoord OilCentreOfView = WrkCentreOfView.ToOil(CurDocView->GetScrollOffsets()); 

	// Find out which spread to insert the pasteboard objects onto
	(*Spread) = CurDocView->FindEnclosingSpread(OilCentreOfView);
	if ((*Spread) == NULL)
		return FALSE; // There is no spread

	// Phew
	// ---------------------------------------------------------------------------------
	// Now lets find the spread coordinate of the centre of the view
	DocRect DocViewRect = CurDocView->GetDocViewRect(*Spread);
	
	if ( DocViewRect.IsEmpty() || (!DocViewRect.IsValid()) )
	{
		ERROR3("DocViewRect is invalid");
		return FALSE; // Defensive
	}

	// Find the centre of the DocViewRect
   	DocCoord DocCentreOfView; 
	DocCentreOfView.x = DocViewRect.lox	+ (DocViewRect.Width()/2); 
	DocCentreOfView.y = DocViewRect.loy	+ (DocViewRect.Height()/2);

	// --------------------------------------------------------------------------------
	// Now convert from DocCoords to spread coords

	DocRect PhysSpreadRect = (*Spread)->GetPasteboardRect();
	
	(*Position).x = DocCentreOfView.x - PhysSpreadRect.lo.x; 
	(*Position).y = DocCentreOfView.y - PhysSpreadRect.lo.y;
	
	return TRUE;  
}
Ejemplo n.º 5
0
/********************************************************************************************

>	BOOL TipsDlg::DrawBitmap(ResourceID BitmapID, DocRect& RedrawRect)

	Author:		Colin_Barfoot (Xara Group Ltd) <*****@*****.**>
	Created:	08/08/96
	Inputs:		BitmapID : the resource id of the bitmap to draw
				RedrawRect : the rectangle in which to draw it
	Returns:	TRUE if drawn OK
				FALSE otherwise
	Purpose:	Renders the given bitmap in the given rectangle

********************************************************************************************/
BOOL TipsDlg::DrawBitmap(ResourceID BitmapID, DocRect& RedrawRect)
{
	OILBitmap *pOILBitmap = OILBitmap::Create();
	if (pOILBitmap == NULL)
	{
		return FALSE;
	}

	if (!pOILBitmap->LoadBitmap(BitmapID))
	{
		return FALSE;
	}

	// Centre the bitmap within the RedrawRect
	UINT32 bitmapWidth = pOILBitmap->GetRecommendedWidth();
	UINT32 bitmapHeight = pOILBitmap->GetRecommendedHeight();

	UINT32 xOffset = RedrawRect.lo.x + (RedrawRect.Width() - bitmapWidth) / 2;
	UINT32 yOffset = RedrawRect.lo.y + (RedrawRect.Height() - bitmapHeight) / 2;

	DocCoord lowCorner(xOffset, yOffset);
	DocRect bitmapRect(lowCorner, bitmapWidth, bitmapHeight);

	KernelBitmap bitmap(pOILBitmap, TRUE);
	
	// Now we need to create a temporary NodeBitmap, which we will
	// use to render the bitmap preview.
	NodeBitmap* dummyNode = new NodeBitmap();
	if (dummyNode == NULL)
	{
		return FALSE;
	}

	// Set the NodeBitmap path to be our RedrawRect and attach the Bitmap to it.
	dummyNode->SetUpPath();
	dummyNode->CreateShape(bitmapRect);
	dummyNode->GetBitmapRef()->SetBitmap(&bitmap);

	// Now render the bitmap preview
  	dummyNode->Render(m_pRenderer);
	delete dummyNode;

	// All OK
	return TRUE;
}
Ejemplo n.º 6
0
double CamelotWebFilter::GetSimilarPathTolerance(NodePath* pPath)
{
	double Tolerance = 0.0;

	if (pPath != NULL)
	{
		// Don't get attribute-related bounds because the path might not be in the tree
		// (e.g. it may be generated by the 'convert text to outlines' system which keeps
		// all paths created from text stories in out-of-line groups)
		// The TRUE parameter means don't bother with attributes
		DocRect Rect = pPath->GetBoundingRect(TRUE);
		INT32 MaxDist = min(Rect.Width(),Rect.Height());

		Tolerance = double(MaxDist)*0.01;
		if (Tolerance > GetWebSimilarPathTolerence())
			Tolerance = GetWebSimilarPathTolerence(); 
	}

	return Tolerance;
}
Ejemplo n.º 7
0
BOOL BitmapExportDocument::SetBitmap(KernelBitmap* pBitmap)
{
	TRACEUSER( "Gerry", _T("BitmapExportDocument::SetBitmap()\n"));

	ERROR2IF(pBitmap == NULL, FALSE, "NULL bitmap passed to SetBitmap()\n");
	ERROR2IF(pBitmapNode == NULL, FALSE, "pBitmapNode is NULL in SetBitmap()\n");

	// Attach the bitmap to our node
	//
	// Note: Neville 18/9/97 
	// If the bitmap is a lone bitmap i.e. not attached to any document, then we
	// must attach it properly to this document so that it gets cleaned out
	// rather than memory leaking. If not, then we are just temporarily using
	// the bitmap and so everything should be ok. We need to work in the following
	// situations:-
	// - Selecting multiple bitmaps in the bitmap gallery and saving as animated GIF.
	//	 Here we are passed a list of bitmaps which are already in use in the source
	//   document.
	// - Making a new clipart index for bitmaps. Here we are passed a brand spanking
	//   new bitmap which is not on any lists. This used to memory leak.
	BitmapList* pBmpList = pBitmap->GetParentBitmapList();
	if (pBmpList != NULL)
	{
		// This will memory leak a kernel bitmap each time if it is not on a parent
		// document list. You will also end up with a KernelBitmap which contains
		// a deleted ActualBitmap pointer, which is very bad!
		pBitmapNode->GetBitmapRef()->SetBitmap(pBitmap);
	}
	else
	{
		// This is the same technique that the BaseBitmapFilter uses and so must be correct!
		pBitmapNode->GetBitmapRef()->Attach(pBitmap, this);
		if (pBitmapNode->GetBitmap() != pBitmap)
		{
			// It didn't use the bitmap we gave it, so we can delete it
			delete pBitmap;
		}
	}
	
	BitmapInfo Info;
	pBitmapNode->GetBitmap()->ActualBitmap->GetInfo(&Info);

	// Calculate the rectangle for this bitmap
	// We make it as large as possible (within the ExportRect)
	// without changing the aspect ration

	INT32 RectWidth = ExportRect.Width();
	INT32 RectHeight = ExportRect.Height();

	double xScale = (double) RectWidth / (double) Info.RecommendedWidth;
	double yScale = (double) RectHeight / (double) Info.RecommendedHeight;

	DocRect BitmapRect;

	BitmapRect.lo.x = 0;
	BitmapRect.lo.y = 0;

	if (xScale < yScale)
	{
		// Bitmap will be full width
		BitmapRect.hi.x = RectWidth;
		BitmapRect.hi.y = (INT32) ((double) Info.RecommendedHeight * xScale);

		// Center the bitmap vertically in the rectangle
		BitmapRect.Translate(0, (RectHeight - BitmapRect.Height()) / 2);
	}
	else
	{
		// Bitmap will be full height
		BitmapRect.hi.x = (INT32) ((double) Info.RecommendedWidth * yScale);
		BitmapRect.hi.y = RectHeight;

		// Center the bitmap horizontally in the rectangle
		BitmapRect.Translate((RectWidth - BitmapRect.Width()) / 2, 0);
	}

	// Delete the node's path
	// Because CreateShape inserts a rectangle at the beginning of the path
	pBitmapNode->InkPath.DeleteFromElement(0);

	// And create the shape
	pBitmapNode->CreateShape(BitmapRect);

	return(TRUE);
}
Ejemplo n.º 8
0
/********************************************************************************************

>	BOOL MakeBitmapFilter::InsertBitmapIntoDocument(UndoableOperation *pOp, KernelBitmap* KernelBmp, Document* DestDoc)

	Author:		Will_Cowling (Xara Group Ltd) <*****@*****.**>
	Created:	11/6/96
	Purpose:	Exports the current selection as a bitmap, via the virtual fns of the
				inherited class.
	Returns:	TRUE if worked, FALSE if failed.
	SeeAlso:	GetExportOptions; PrepareToExport; ExportRenderNodes; CleanUpAfterExport;

********************************************************************************************/
BOOL MakeBitmapFilter::InsertBitmapIntoDocument(UndoableOperation *pOp, KernelBitmap* KernelBmp, Document* DestDoc)
{
	Spread *pSpread;
	DocCoord Origin;

	// Remember the selection rect, before we change it
	DocRect SelRect = GetApplication()->FindSelection()->GetBoundingRect();

	// For now, position Draw objects on 1st page of spread 1
PORTNOTE("spread", "Multi-spread warning!")
	pSpread = GetFirstSpread(DestDoc);
	Page *pPage = (Page *) pSpread->FindFirstPageInSpread();
	ERROR3IF(!pPage->IsKindOf(CC_RUNTIME_CLASS(Page)),
		   "MakeBitmapFilter::InsertBitmapIntoDocument: Could not find first Page");

	// Use bottom left of page as origin
	DocRect PageRect = pPage->GetPageRect();
	Origin.x = PageRect.lo.x;
	Origin.y = PageRect.hi.y;

	// Get a new NodeBitmap object to import into.
	NodeBitmap *pNodeBitmap = new NodeBitmap;
	if ((pNodeBitmap == NULL) || (!pNodeBitmap->SetUpPath(12,12)))
		return FALSE;

	// Attach the Imported Bitmap to our Node
	pNodeBitmap->GetBitmapRef()->Attach(KernelBmp, DestDoc); //GetDocument());
	if (pNodeBitmap->GetBitmap() != KernelBmp)
		delete KernelBmp; // It didn't use the bitmap we gave it, so we can delete it

	// Import worked - try to add the bitmap object into the tree.
	// First, set the rectangle to the right size for the bitmap...
	BitmapInfo Info;
	pNodeBitmap->GetBitmap()->ActualBitmap->GetInfo(&Info);

	DocRect BoundsRect;
	BoundsRect.lo = Origin;
	BoundsRect.hi.x = BoundsRect.lo.x + Info.RecommendedWidth;
	BoundsRect.hi.y = BoundsRect.lo.y + Info.RecommendedHeight;

	// And set this in our bitmap node
	pNodeBitmap->CreateShape(BoundsRect);

	// Make sure that there is a layer to put the bitmap onto
	if (!MakeSureLayerExists(DestDoc))
	{
		// There is no layer and one could not be made, so we will have to fail
		delete pNodeBitmap;
		return FALSE;
	}

	// Set the default attrs
	// This MUST be done before the NodeBitmap is Inserted into the tree
	if (!pNodeBitmap->ApplyDefaultBitmapAttrs(pOp))
		return FALSE;

	// Insert the node, but don't invalidate its region
	if (!pOp->DoInsertNewNode(pNodeBitmap, pSpread, FALSE))
	{
		// It didn't work - delete the sub-tree we just created, and report error.
		delete pNodeBitmap;
		return FALSE;
	}

	// bitmap is currently positioned so its bottom left hand
	// corner is at the top left of the page

	// By default we'll move it down so the top-left of the bitmap is on the top-left of the page
	INT32 XTranslate = 0;
	INT32 YTranslate = -Info.RecommendedHeight;

	ClickModifiers ClickMods = ClickModifiers::GetClickModifiers();

	if (ClickMods.Adjust && !SelRect.IsEmpty())
	{
		// If shift is down, then we'll try and place the bitmap exactly on top of the selection
		DocCoord SelectionCentre(SelRect.lo.x + (SelRect.Width()/2), SelRect.lo.y + (SelRect.Height()/2));

		XTranslate = SelectionCentre.x - Origin.x - (Info.RecommendedWidth/2);
		YTranslate = SelectionCentre.y - Origin.y - (Info.RecommendedHeight/2);
	}
	else
	{
		// Otherwise we'll try and centre it within the current view
		Spread* pCurrentSpread;
		DocCoord ViewCentre;

		if (FindCentreInsertionPosition(&pCurrentSpread, &ViewCentre))
		{
/*	Karim 19/01/2000
 *	Ensure that the bmp is pixel-aligned as close to the centre as possible.
 *
			XTranslate = ViewCentre.x - Origin.x - (Info.RecommendedWidth/2);
			YTranslate = ViewCentre.y - Origin.y - (Info.RecommendedHeight/2);
/**/
			DocCoord PixAlignBmpOrigin(	ViewCentre.x - Info.RecommendedWidth/2,
										ViewCentre.y - Info.RecommendedHeight/2 );
			INT32			FullDPI		= GRenderRegion::GetDefaultDPI();
			MILLIPOINT	PixWidth	= (INT32)((IN_MP_VAL / (double)FullDPI) + 0.5);
			PixAlignBmpOrigin.x -= PixAlignBmpOrigin.x % PixWidth;
			PixAlignBmpOrigin.y -= PixAlignBmpOrigin.y % PixWidth;
			XTranslate = PixAlignBmpOrigin.x - Origin.x;
			YTranslate = PixAlignBmpOrigin.y - Origin.y;
		}
	}

	Trans2DMatrix Xlate(XTranslate, YTranslate);
	pNodeBitmap->Transform(Xlate);

	// Ensure Sel Bounds are correct after translation
	GetApplication()->UpdateSelection();

	return TRUE;
}
Ejemplo n.º 9
0
/********************************************************************************************

>	BOOL MakeBitmapFilter::DoCreateBitmap(Operation *pOp, Document *pDoc, KernelBitmap** ppBitmap)

	Author:		Will_Cowling (Xara Group Ltd) <*****@*****.**>
	Created:	11/6/96
	Purpose:	Exports the current selection as a bitmap, via the virtual fns of the
				inherited class.
	Returns:	TRUE if worked, FALSE if failed.
	SeeAlso:	GetExportOptions; PrepareToExport; ExportRenderNodes; CleanUpAfterExport;

********************************************************************************************/
BOOL MakeBitmapFilter::DoCreateBitmap(Operation *pOp, Document *pDoc, KernelBitmap** ppBitmap)
{
	ERROR3IF(ppBitmap == NULL, "NULL bitmap pointer passed to MakeBitmapFilter::DoCreateBitmap");
	if (ppBitmap == NULL)
		return FALSE;

	pTheBitmap = NULL;
	*ppBitmap = NULL;

	// Set the bitmap pointer to null just in case, usually only used by DoExportBitmap
	pExportBitmap = NULL;

	// Get pointer to the spread to export.
PORTNOTE("spread", "Multi-spread warning!")
	pSpread = GetFirstSpread(pDoc);

	// remember the document in the class variable
	TheDocument = pDoc;

	// We must now check if there is a selection present so that we can set up whether the
	// user gets the choice of exporting the selection, drawing or spread if there is a 
	// selection present OR just a choice between the spread or drawing if no selection is
	// present.
	// If have a caret selected in a text story then the selection will be almost zero so trap
	// this case as well. 
	RangeControl rg = GetApplication()->FindSelection()->GetRangeControlFlags();
	rg.PromoteToParent = TRUE;
	GetApplication()->FindSelection()->Range::SetRangeControl(rg);
	SelRange Rng(*(GetApplication()->FindSelection()));

	// now, run through the selection selecting all nodes under all compound nodes
	// if we don't do this then all compound nodes aren't rendered correctly with transparent
	// bitmaps
	Node * pNode = Rng.FindFirst(FALSE);

	while (pNode)
	{
		pNode->SetSelected(FALSE);
		pNode->SetSelected(TRUE);
		pNode = Rng.FindNext(pNode, FALSE);
	}

	rg.PromoteToParent = FALSE;
	GetApplication()->FindSelection()->Range::SetRangeControl(rg);
	GetApplication()->UpdateSelection();

	DocRect ClipRect = GetApplication()->FindSelection()->GetBoundingRect();
	SelectionType Selection = DRAWING;
 	if ( ClipRect.IsEmpty() || ClipRect.Width() < MinExportSize ||
		 ClipRect.Height() < MinExportSize)
		Selection = DRAWING;		// no selection present, so choose drawing by default
	else
		Selection = SELECTION;		// selection present, so choose this by default

	if (Selection != SELECTION)
	{
		BOOL UseDrawingBounds = TRUE;
		
		SelRange* pSel = GetApplication()->FindSelection();
		if (pSel && pSel->Count()==1)
		{
			// Only one thing selected ... Is it the Text Caret per chance ?
			Node* pSelNode = pSel->FindFirst();
			if (pSelNode && pSelNode->IsAVisibleTextNode())
			{
				VisibleTextNode* pTextNode = (VisibleTextNode*)pSelNode;
				if (pTextNode->IsACaret())
				{
				 	// Aha! It's the Caret that's selected.
					// We'll use the bounds of the parent text line instead then ...
					Node* pTextLine = pTextNode->FindParent();
					ERROR3IF(!IS_A(pTextLine, TextLine), "Caret doesn't have a parent text line in DoCreateBitmap");
					
					// Get the bounds of the text line
					ClipRect = ((TextLine*)pTextLine)->GetBoundingRect();				

					Selection = SELECTION;
					UseDrawingBounds = FALSE;
				}		 		
			}
		}

		if (UseDrawingBounds)
		{
			// Work out the size of the rectangle encompassing the drawing (visible layers only)
			ClipRect = GetSizeOfDrawing(pSpread);
		}
	}

	// Create somewhere to put the user options and fill them up
	MakeBitmapExportOptions* pMakeBmpExportOptions = (MakeBitmapExportOptions*)CreateExportOptions();
	if (pMakeBmpExportOptions == NULL)
	{
		Error::SetError(_R(IDS_OUT_OF_MEMORY));
		return FALSE;
	}

	pMakeBmpExportOptions->RetrieveDefaults();
	pMakeBmpExportOptions->SetDepth(32); // create bmp copies shoulda always default to being 32 bit
	pMakeBmpExportOptions->SetSelectionType(Selection);

	// Set the BaseBitmapFilter member so we can use base class functionality - blurghh
	SetExportOptions(pMakeBmpExportOptions);

	BOOL ok = GetExportOptions( (BitmapExportOptions*)pMakeBmpExportOptions );

	BOOL IsAnimation = BmapPrevDlg::m_pExportOptions == NULL;
	BaseBitmapFilter * pNewFilter = this;
	BitmapExportOptions * pExportOptions = BmapPrevDlg::m_pExportOptions;
	if (!IsAnimation)
	{
		pNewFilter = pExportOptions->FindBitmapFilterForTheseExportOptions();
		// from the exporting point of view we should always have been using png options
		// set them to the png options for the export part
		if (pNewFilter)
			pNewFilter->SetExportOptions(pExportOptions);
		// gets the real export options that the prevdlg has set up for us
		BmapPrevDlg::m_pExportOptions = NULL; // take responsibility for this data
	}
	else
	{
		// the animation export didn't bring up the dlg so never set BmapPrevDlg::m_pExportOptions
		// so continue with these options
		pExportOptions = (BitmapExportOptions*)pMakeBmpExportOptions;
	}

	SetExportOptions(pExportOptions);
	

	if (!ok)
	{
		SetExportOptions(NULL); // deletes the filter ptr and nulls it
		delete pExportOptions;
		return FALSE;									// if cancelled
	}


//////////////// SMFIX

	pExportOptions->MarkValid();
	SetDepthToRender(pExportOptions->GetDepth());

	// Set up device context and render region for this export.
	// This will show a progress hourglass for the objects being rendered
	// THis will now also write the data out to file via our ExportRenderNodes function
	if (!PrepareToExport(pSpread, pExportOptions->GetDepth(), pExportOptions->GetDPI(), 
							pExportOptions->GetSelectionType(), pExportOptions->GetDither()))
	{
		pNewFilter->SetExportOptions(NULL);
		SetExportOptions(NULL);
		delete pExportOptions;
		CleanUpAfterExport();
		return FALSE;
	}

	RenderInStrips = FALSE;
	
	if (!ExportRender(ExportRegion))
	{
		pNewFilter->SetExportOptions(NULL); // deletes the filter ptr and nulls it
		SetExportOptions(NULL);
		delete pExportOptions;
		CleanUpAfterExport();
		return FALSE;
	}

	// Now get the converted 32Bit BMP
	pTheBitmap = GetTheBitmap(pExportOptions);

	// if we`ve got a transparency index AND we`ve got a 32 Bit Render region with alpha channel info
	// then we can quickly do
	if(pExportOptions->GetDepth() <= 8 && pExportOptions->GetTransparencyIndex() != -1 && pTheBitmap)
	{
		// What we do now is to go throught the bitmap setting the relavent pixels to transparent
		// depending on the alpha channel info held in the 32 bit version.
		if(!ApplyTransparentColoursToBitmap(pTheBitmap,pExportOptions))
		{
			pNewFilter->SetExportOptions(NULL); // deletes the filter ptr and nulls it
			return FALSE;
		}

		// Now make sure the bitmap knows that it has a transparent colour!
		pTheBitmap->SetTransparencyIndex(pExportOptions->GetTransparencyIndex());
	}

	// Set pointer to the bitmap we have created
	*ppBitmap = pTheBitmap;

	pNewFilter->SetExportOptions(NULL); // deletes the filter ptr and nulls it
	SetExportOptions(NULL);
	delete pExportOptions;
	CleanUpAfterExport();

	return *ppBitmap != NULL;

//////////////// SMFIX
}
Ejemplo n.º 10
0
BOOL FreeHandEPSFilter::ProcessToken()
{
	// Decode the command, and execute it...
	switch (Token)
	{
		// state saving
		case EPSC_vms:
			if(!Import_gsave())
				return FALSE;
			break;

		case EPSC_vmr:
			if(!Import_grestore())
				return FALSE;
			break;

		case EPSC_vmrs:
			if(!Import_grestore())
				return FALSE;
			if(!Import_gsave())
				return FALSE;
			break;

		// tokens to ignore
		case EPSC_FREEHAND_IGNOREDTOKEN:
			break;

		// tokens which should be ignored and one entry discarded
		case EPSC_load:			// the load part of a fill - discard the /clipper before it
		case EPSC_fhsetspreadallow:
			if(!Stack.Discard(1))
				goto EPSError;
			break;

		case EPSC_concat:
			if(!Stack.DiscardArray())
				goto EPSError;
			break;
		
		// complex paths...
		case EPSC_eomode:
			{
				INT32 ComplexStart;

				if(!Stack.Pop(&ComplexStart))
					goto EPSError;

				// is this a start of a complex path?
				if(ComplexStart != TRUE)
				{
					ComplexPathMode = FALSE;
				}
				else
				{
					HadFirstOfComplexPath = FALSE;
					ComplexPathMode = TRUE;
				}
			}
			break;

		case EPSC_true:
			Stack.Push((INT32)TRUE);
			break;

		case EPSC_false:
			Stack.Push((INT32)FALSE);
			break;

		case EPSC_u:
			HadFirstOfComplexPath = FALSE;
			return EPSFilter::ProcessToken();
			break;

		// colours
		case EPSC_Ka:
		case EPSC_ka:
			{
				DocColour Colour;

				if(PopColour(&Colour))
				{
					// Remember this colour for future objects
					if (Token == EPSC_ka)
					{
				    	if (!SetFillColour(Colour))
							goto NoMemory;
					}
					else
					{
						if (!SetLineColour(Colour))
							goto NoMemory;
					}
				}
			    else	
			    	// Invalid colour operands
					goto EPSError;
			}
			break;

		case EPSC_Xa:
		case EPSC_xa:
			{
				DocColour Colour;

				if(PopNamedColour(&Colour))
				{
					// Remember this colour for future objects
					if (Token == EPSC_xa)
					{
				    	if (!SetFillColour(Colour))
							goto NoMemory;
					}
					else
					{
						if (!SetLineColour(Colour))
							goto NoMemory;
					}
				}
			    else	
			    	// Invalid colour operands
					goto EPSError;
			}
			break;

		case EPSC_H:
			if(ComplexPathMode)
			{
				// in complex path mode - make this a filled one, not a discarded one
				Token = EPSC_S; 
			}
			return EPSFilter::ProcessToken();
			break;
		
		case EPSC_h:
			if(ComplexPathMode)
			{
				// in complex path mode - modify and process
				Token = EPSC_s;
				return EPSFilter::ProcessToken();
				break;
			}
			// the hidden path closing operator - a grad fill thingy will follow shortly maybe...
			// this will prevent it being processed now, although it may get processed later on.
			HadhToken = TRUE;
			break;

		// for clipping masks, do some funky stuff
		case EPSC_q:
			// if there's a pending grad fill...
			if(DoingGradFill)
			{
				if(pPath != 0)
				{
					// right then, make a copy of the path...
					NodePath *pPathClone;

					if(!pPath->NodeCopy((Node **)&pPathClone))
					{
						goto NoMemory;
					}

					// copy the flags
					EPSFlagsDefn EPSFlagsClone = EPSFlags;
				
					// send a token to finish and fill the path...
					Token = (pInkPath->IsFilled)?EPSC_f:EPSC_s;
					if(!EPSFilter::ProcessToken())
						return FALSE;

					// restore the old fill
					if(!RestoreCurrentFill())
						goto NoMemory;

					// restore the copy of the path
					pPath = pPathClone;
					pInkPath = &pPath->InkPath;

					// restore the flags
					EPSFlags = EPSFlagsClone;

					// definately want to send an h
					HadhToken = TRUE;
				}

				// done the grad fill
				DoingGradFill = FALSE;

				// restore the old token
				Token = EPSC_q;
			}

			// clipping started - have we got an h token to send?
			if(HadhToken)
				FHEF_SENDh

			// process this
			return EPSFilter::ProcessToken();
			break;

		// for now, if there's no path, don't return a W
		case EPSC_W:
			if(pPath == 0)
			{
				// OK, now we want to get the last path we created, make a copy of it and then install it as the current one
				if(pLastPathSeen == 0)
					goto EPSError;

				// make a copy of it
				NodePath *pClone;
				
				if(!pLastPathSeen->NodeCopy((Node **)&pClone))
					goto NoMemory;

				// delete it's attributes
				pClone->DeleteChildren(pClone->FindFirstChild());

				// make it the current path
				pPath = pClone;
				pInkPath = &pPath->InkPath;
				ThePathType = PATH_NORMAL;
				EPSFlags.NoAttributes = TRUE;
			}
			if(pPath != 0)
				return EPSFilter::ProcessToken();
			break;

		// we may need to modify path closing things if we're doing a grad fill
		case EPSC_s:
		case EPSC_S:
			if(Token == EPSC_S)
			{
				// if we've had an h token but no grad fill, send the h now
				if(HadhToken)
					FHEF_SENDh

				// if we've got a grad fill, modify the token we got
				if(DoingGradFill)
					Token = EPSC_b;
			}
			
			// process the possily modified token normally
			HadhToken = FALSE;
			return EPSFilter::ProcessToken();
			break;

		// modify path closing for grad fills.
		case EPSC_n:
			if(DoingGradFill)
			{
				Token = EPSC_f;			// we want to fill the thing
				HadhToken = FALSE;
				return EPSFilter::ProcessToken();
				break;
			}
   			HadhToken = FALSE;			// ignore h's as this is another end path thingy...

			if(pPath != 0)
				return EPSFilter::ProcessToken();
			break;

		// unset the had h token for other path closing things
		case EPSC_N:
		case EPSC_F:
		case EPSC_f:
		case EPSC_B:
		case EPSC_b:
			HadhToken = FALSE;
			return EPSFilter::ProcessToken();
			break;
		
		// interested in path element things to switch off grad fills
		case EPSC_m:
			if(InText)
			{
				// if we're doing some text, discard the moveto command
				if(!Stack.Discard(2))
					goto EPSError;

				break;
			}
		case EPSC_l:
		case EPSC_L:
		case EPSC_c:
		case EPSC_C:
		case EPSC_v:
		case EPSC_V:
		case EPSC_y:
		case EPSC_Y:
			// maybe we need an h token to be sent
			if(HadhToken)
				FHEF_SENDh
			
			// stop grad fill
			if(DoingGradFill)
			{
				// turn the grad fill state off
				DoingGradFill = FALSE;

				// restore the old fill type
				RestoreCurrentFill();
			}
			return EPSFilter::ProcessToken();
			break;

		
		case EPSC_recfill:
			{
				// get the colours
				DocColour StartColour, EndColour;

				if(!PopColour(&EndColour) ||
						!PopColour(&StartColour))
					goto EPSError;

				// discard the fill type thingy - we can only do colours
				if(!DiscardFillSubType())
					goto EPSError;

				// OK, now a few coords
				DocCoord Centre;
				double Angle;
				DocRect BBox;
				if(!Stack.PopCoordPair(&BBox.hi) ||
						!Stack.PopCoordPair(&BBox.lo) ||
						!Stack.Pop(&Angle) ||
						!Stack.PopCoordPair(&Centre))
					goto EPSError;

				// munge the angle a little and get it into radians
				Angle += 225;
				Angle = (Angle * (2 * PI)) / 360;

				// see if we can get a more accurate BBox
				if(pPath != 0)
				{
					BBox = pPath->GetBoundingRect();
					Centre.x = BBox.lo.x + (BBox.Width() / 2);
					Centre.y = BBox.lo.y + (BBox.Height() / 2);
				}

				// OK, we've got all the stuff we need to do some niceness on it
				BBox.Translate(0 - Centre.x, 0 - Centre.y);
				DocCoord StartPoint, EndPoint;

				StartPoint.x = Centre.x + (INT32)(((double)BBox.lo.x * cos(Angle)) - ((double)BBox.lo.y * sin(Angle)));
				StartPoint.y = Centre.y + (INT32)(((double)BBox.lo.x * sin(Angle)) + ((double)BBox.lo.y * cos(Angle)));
				EndPoint.x = Centre.x + (INT32)(((double)BBox.hi.x * cos(Angle)) - ((double)BBox.hi.y * sin(Angle)));
				EndPoint.y = Centre.y + (INT32)(((double)BBox.hi.x * sin(Angle)) + ((double)BBox.hi.y * cos(Angle)));
		
				// store current fill attribute
				SaveCurrentFill();

				// set the fill
				if(!SetLinearFill(StartColour, EndColour, StartPoint, EndPoint))
					goto NoMemory;

				// say we're doing a grad fill
				DoingGradFill = TRUE;
				HadhToken = FALSE;			// absorb this
			}
			break;

		case EPSC_radfill:
			{
				// get the colours
				DocColour StartColour, EndColour;

				if(!PopColour(&StartColour) ||
						!PopColour(&EndColour))
					goto EPSError;

				// get the radius and centre coordinate
				DocCoord Centre;
				INT32 Radius;
				if(!Stack.PopCoord(&Radius) ||
						!Stack.PopCoordPair(&Centre))
					goto EPSError;

				// store current fill attribute
				SaveCurrentFill();

				// set the fill
				DocCoord EndPoint(Centre.x + Radius, Centre.y);
				if(!SetRadialFill(StartColour, EndColour, Centre, EndPoint))
					goto NoMemory;

				// say we're doing a grad fill
				DoingGradFill = TRUE;
				HadhToken = FALSE;
			}
			break;

		case EPSC_BeginSetup:
			// there's probably a colour list or something in that there setup thingy - search for the spots token
			{
				BOOL Found = FALSE;
				
				while(Found == FALSE)
				{
					if(!EPSFile->GetToken())
						return FALSE;

			 		if(EPSFile->GetTokenType() == TOKEN_NORMAL)
			 		{
			 			if(camStrcmp(TokenBuf, _T("spots")) == 0)
						{
							// check to see if the array is about to start
							if(!EPSFile->GetToken())
								return FALSE;

							if(TokenBuf[0] == '[')
							{
								TRACEUSER( "Ben", _T("Found spots\n"));
								Found = TRUE;
							}
						}
					}
				
					if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0)
					{
						TRACEUSER( "Ben", _T("Met end of setup without finding spots\n"));
						break;
					}

					if(EPSFile->eof())
						goto EPSError;
			 	}

				if(Found == TRUE)
				{
					InColours = TRUE;
				}
			}
			break;

		case EPSC_def:
			if(InColours)
			{
				// finished the colours...
				TRACEUSER( "Ben", _T("Finished spot colours\n"));			
				// scan for the end of the setup section
				BOOL Found = FALSE;
				
				while(Found == FALSE)
				{
					if(!EPSFile->GetToken())
						return FALSE;

			 		if(EPSFile->GetTokenType() == TOKEN_COMMENT)
			 		{
						if(camStrncmp(TokenBuf, _T("%%EndSetup"), 10) == 0)
						{
							TRACEUSER( "Ben", _T("Found end of setup\n"));
							Found = TRUE;
						}
					}

					if(EPSFile->eof())
						goto EPSError;
			 	}
				
				// get the ] off the stack
				EPSCommand Ignored;
				Stack.PopCmd(&Ignored);

				// empty it...
				Stack.DeleteAll ();
				InColours = FALSE;
			}
			else
			{
				// probably a font type thingy - empty the stack including commands
				Stack.DeleteAll ();
			}
			break;

		case EPSC_newcmykcustomcolor:
			// OK, here's a named colour... add it to those known
			{
				// discard some random thingy
				if(!Stack.Discard())
					goto EPSError;
			
				// get the name
				String_64 ColourName;
				if(!Stack.Pop(&ColourName))
					goto EPSError;

				// get the components
				double C, M, Y, K;
				if(!Stack.Pop(&K) ||
						!Stack.Pop(&Y) ||
						!Stack.Pop(&M) ||
						!Stack.Pop(&C))
					goto EPSError;

				// make the new colour
				ColourCMYK Colour;
				Colour.Cyan = C;
				Colour.Magenta = M;
				Colour.Yellow = Y;
				Colour.Key = K;

				// add it
				if(!pNewColours->AddColour(&ColourName, &Colour))
					goto NoMemory;

				// add it to the list of colours
				// this is a bit of a bodge, but never mind. Shouldn't be that bad.
				IndexedColour *TheNewColour = pNewColours->GetColour(ColourName);

				if(TheNewColour == 0)
					goto NoMemory;

				// add it to the list of colours
				// enough space?
				if((ColourArrayEntries + 1) >= ColourArraySize)
				{
					TRACEUSER( "Ben", _T("Extening colour array\n"));
					IndexedColour **NewPtr = (IndexedColour **)CCRealloc(ColourArray, (ColourArraySize + FHEF_COLOURARRAY_CHUNK) * sizeof(IndexedColour *));

					if(NewPtr == 0)
						goto NoMemory;

					ColourArray = NewPtr;
					ColourArraySize += FHEF_COLOURARRAY_CHUNK;
				}

				// add
				ColourArray[ColourArrayEntries] = TheNewColour;
				ColourArrayEntries++;
			}
			break;

		// ignore text stuff
		case EPSC_makesetfont:
			if(!Stack.DiscardArray())
				goto EPSError;
			if(!Stack.Discard(1))
				goto EPSError;
			InText = TRUE;
			break;

		case EPSC_ts:
			if(!Stack.Discard(6))
				goto EPSError;
			break;

		case EPSC_stob:
		case EPSC_sts:
			Stack.DeleteAll ();
			InText = FALSE;
			break;
				
		default:
			// Token not understood - pass on to base class
			return EPSFilter::ProcessToken();
	}


	// No errors encountered while parsing this token and its operands.
	return TRUE;
	
	
	// Error handlers:
EPSError:
	HandleEPSError();
	return FALSE;

NoMemory:
	HandleNoMemory();
	return FALSE;
}
Ejemplo n.º 11
0
BOOL OpBackground::FixBackgroundLayer(Layer * pBackgroundLayer, const DocRect& NewPagesRect,
									  const DocRect& OldPagesRect)
{
	ERROR2IF(pBackgroundLayer == NULL,FALSE,"OpBackground::FixBackgroundLayer Bad params!");
	
	//BOOL ok = TRUE;

	// There should be a rectangle on the page encompassing the old position of the pages
	// so go and try and find it
	NodeRegularShape * pShape = FindPageRectangle(pBackgroundLayer, OldPagesRect);
	// If no rectangle is found then something might be slightly wrong. Should we error?
	if (pShape)
	{
		const INT32 CornerRadius = 0; // No curvature
		if (pShape->MakeRectangle(NewPagesRect.Width(), NewPagesRect.Height(), CornerRadius))
		{
			// Translate centre from 0,0 to required position relative to page
			INT32 XTrans = NewPagesRect.lo.x + (NewPagesRect.Width()/2);
			INT32 YTrans = NewPagesRect.lo.y + (NewPagesRect.Height()/2);
			Trans2DMatrix Trans(XTrans, YTrans);

			pShape->Transform(Trans);

			// finish off the shape
			pShape->InvalidateBoundingRect();
		}
	
		// Find any bitmap fills and fix up the fill origin etc.
		Node * pNode = pShape->FindFirstChild();
		while (pNode != NULL)
		{
			// Only check and fix bitmap colour fill attributes of the regular shape nodes 
			if (pNode->IS_KIND_OF(AttrBitmapColourFill))
			{
				// Convert the pointer to the correct type
				AttrBitmapColourFill * pBitmapFillAttr = (AttrBitmapColourFill*)pNode;

				// Set the coordinates of the fill end points
				// We want to start the fill at the top left of the regular shape
				// The bounding rect should be roughly what we want
				DocRect Rect = pShape->GetBoundingRect(TRUE, FALSE);
							
				KernelBitmap * pBitmap = ((AttrFillGeometry*)pBitmapFillAttr)->GetBitmap();				
				// Get the size of the bitmap taking into account its DPI
				INT32 Width = pBitmap->GetRecommendedWidth();
				INT32 Height = pBitmap->GetRecommendedHeight();
				// You would think that the handles on the fill correspond to where you place them
				// but oh now the displayed handles are shown at different points. So instead of
				// positioning the start in the centre of the bitmap, you need to position it bottom left
				// The End should be centre and right but needs to be bottom right.
				// The End2 should be centre and top but needs to be top left.

				// We want the start point to be half the height of the bitmap below this
				//DocCoord Start(Rect.lo.x + Width/2, Rect.hi.y - Height/2);
				DocCoord Start(Rect.lo.x, Rect.hi.y - Height);
				// We want the other end point to be same height as the centre point
				// but on the far right of the rectangle i.e the full width across
				//DocCoord End(Rect.lo.x + Width, Rect.hi.y - Height/2);
				DocCoord End(Rect.lo.x + Width, Rect.hi.y - Height);
				// We want the end point to be middle and top of the rectangle
				//DocCoord End2(Rect.lo.x + Width/2, Rect.hi.y);
				DocCoord End2(Rect.lo.x, Rect.hi.y);

				((AttrFillGeometry*)pBitmapFillAttr)->SetStartPoint(&Start);
				((AttrFillGeometry*)pBitmapFillAttr)->SetEndPoint(&End);
				((AttrFillGeometry*)pBitmapFillAttr)->SetEndPoint2(&End2);
			}
		
			pNode = pNode->FindNext();
		}		
	}

	return TRUE;
}