/******************************************************************************************** > 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; }
/******************************************************************************************** > BOOL AIBitmapProcessor::DecodeXI( AI5EPSFilter& filter ) Author: Colin_Barfoot (Xara Group Ltd) <*****@*****.**> Created: 23/03/00 Returns: TRUE if the definition was processed, FALSE if not used by this filter.. Purpose: Decodes the EPS XI, bitmap definition in an Illustrator 5 file The format of the operator is: [ a b c d tx ty ] llx lly urx ury h w bits ImageType AlphaChannelCount reserved bin-ascii ImageMask XI ********************************************************************************************/ BOOL AIBitmapProcessor::DecodeXI( AI5EPSFilter& filter ) { // Graeme (18/4/00) - This code isn't very pretty, but it's necessary because of the way // in which the bitmap is stored. If I try a GetCoordPair () to get the bitmap positions, // the image will be misrendered because the transformation should take place due to the // tx and ty components of the matrix. Note also that the bitmap's position in Adobe // Illustrator is taken from the top left corner, whilst we use the bottom left. ///////////////// // Get the page origin. ///////////////// // Graeme (18/4/00) - Declare variables to get the origin of the page within Camelot's // co-ordinate space. Document *pDocument = filter.GetDocument (); Spread *pSpread = pDocument->FindFirstSpread (); Page *pPage = pSpread->FindFirstPageInSpread (); DocCoord Origin = pPage->GetPageRect ().lo; ///////////////// // decode the bitmap parameters ///////////////// Matrix ImageMatrix; DocCoord Translation; INT32 h, w, bits, ImageType, AlphaChannelCount, reserved, bin_ascii, ImageMask; INT32 llx, lly, urx, ury; INT32 nLength = 0; INT32 nLineLength = 0; INT32 nMaxLineOffset = 0; INT32 nChannels = 0; NodeBitmap* pNodeBitmap = NULL; DocCoord p; // Graeme (18/4/00) - I've replaced the Pop with PopCoordPair for extracting the // bounding co-ordinates of the bitmap. This means that they will be scaled up // into the Xara co-ordinate space. I've also reversed the popping of h and w // from the stack - their order is incorrect in the AI documentation. if ( !filter.GetStack().Pop(&ImageMask) || !filter.GetStack().Pop(&bin_ascii) || !filter.GetStack().Pop(&reserved) || !filter.GetStack().Pop(&AlphaChannelCount) || !filter.GetStack().Pop(&ImageType) || !filter.GetStack().Pop(&bits) || !filter.GetStack().Pop(&h) || !filter.GetStack().Pop(&w) || !filter.GetStack().PopCoord(&ury) || !filter.GetStack().PopCoord(&urx) || !filter.GetStack().PopCoord(&lly) || !filter.GetStack().PopCoord(&llx) || !filter.GetStack().Pop( &ImageMatrix, TRUE ) ) goto EPSError; ///////////////// // create space for the tentative bitmap ///////////////// /////////////////// // ImageType gives the number of channels per pixel // bits is the bits per channel // However we will convert CMYK bitmaps to RGB /////////////////// switch ( ImageType ) { case 1: // greyscale nChannels = 1; break; case 3: // rgb nChannels = 3; break; case 4: // CMYK nChannels = 3; break; default: // unknown goto EPSError; } mpNewBitmap = new KernelBitmap( w, h, bits * nChannels, 96 ); if ( !mpNewBitmap ) goto EPSError; /////////////////// // We can import greyscale bitmaps as well /////////////////// if ( ImageType == 1 ) mpNewBitmap->SetAsGreyscale(); ///////////////// // get the binary data ///////////////// nLength = mpNewBitmap->GetActualBitmap()->GetBitmapSize(); nLineLength = mpNewBitmap->GetActualBitmap()->GetScanlineSize(); nMaxLineOffset = (( w * mpNewBitmap->GetActualBitmap()->GetBPP() ) / 8) - 1; if ( !ReadImageData( filter, ImageType, mpNewBitmap->GetBitmapBits(), nLength, nLineLength, nMaxLineOffset ) ) goto EPSError; ///////////////////// // insert the image into the document ///////////////////// // Get a new NodeBitmap object to import into. Don't know what the 12,12 bit does pNodeBitmap = new NodeBitmap; if ( !pNodeBitmap || !pNodeBitmap->SetUpPath(12,12) ) goto EPSError; pNodeBitmap->GetBitmapRef()->Attach( mpNewBitmap, filter.GetDocument() ); ///////////////// // set up the bounds of the shape containing the bitmap ///////////////// // Graeme (18/4/00) - Adjust the values of lly and ury before they're transformed. lly -= h * EPSScaleFactor; ury -= h * EPSScaleFactor; // Graeme (18/4/00) - Modify the matrix to place the bitmap in the correct place. ImageMatrix.GetTranslation ( Translation ); // Extract the translation component. Translation += Origin; // Add the page origin to it. ImageMatrix.SetTranslation ( Translation ); // And reset the value in the matrix. // Graeme (17/4/00) - Colin overlooked setting up the bounding parallelogram when he // wrote this code, and I've just added this. p.x = llx; p.y = ury; ImageMatrix.transform( &p ); pNodeBitmap->InkPath.InsertMoveTo( p ); pNodeBitmap->Parallel [0] = p; p.x = urx; p.y = ury; ImageMatrix.transform( &p ); pNodeBitmap->InkPath.InsertLineTo( p ); pNodeBitmap->Parallel [1] = p; p.x = urx; p.y = lly; ImageMatrix.transform( &p ); pNodeBitmap->InkPath.InsertLineTo( p ); pNodeBitmap->Parallel [2] = p; p.x = llx; p.y = lly; ImageMatrix.transform( &p ); pNodeBitmap->InkPath.InsertLineTo( p ); pNodeBitmap->Parallel [3] = p; p.x = llx; p.y = ury; ImageMatrix.transform( &p ); pNodeBitmap->InkPath.InsertLineTo( p ); pNodeBitmap->InkPath.CloseSubPath(); // Graeme (18/4/00) - It is necessary to set the default attributes up for a // new node bitmap before inserting it into the tree. Otherwise it's rendered // as a greyscale image, even if it is colour, because there's a start colour // value set. pNodeBitmap->ApplyDefaultBitmapAttrs ( NULL ); filter.AddNewNode( pNodeBitmap ); return TRUE; EPSError: if ( mpNewBitmap ) { delete mpNewBitmap; mpNewBitmap = 0; } return FALSE; }
void BitmapEffectAtom::Test2(UndoableOperation * Op) { BOOL CarryOn=TRUE; Range Sel(*(GetApplication()->FindSelection())); Node* FirstSelectedNode = Sel.FindFirst(); if (FirstSelectedNode != NULL) // No nodes selected so End { Node* CurrentNode = FirstSelectedNode; Node* NextCurrent; // Do all bitmaps while ((CurrentNode != NULL) && CarryOn) { NextCurrent = Sel.FindNext(CurrentNode); if ( (CurrentNode->IsSelected()) && (CurrentNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeBitmap)) ) { KernelBitmap * pBitmap = ((NodeBitmap *)(CurrentNode))->GetBitmap(); BitmapInfo BMInfo; UINT32 bpp; pBitmap->ActualBitmap->GetInfo(&BMInfo); bpp=BMInfo.PixelDepth; TRACEUSER( "Alex", _T("Bitmap found %d bpp\n"),bpp); if ((bpp==32) || TRUE) { CarryOn = FALSE; NodeBitmap *pNodeBitmap = new NodeBitmap; if ((pNodeBitmap == NULL) || (!pNodeBitmap->SetUpPath(12,12))) return; Spread *pSpread; DocCoord Origin; // For now, position Draw objects on 1st page of spread 1 Node *pNode = (Document::GetSelected())->GetFirstNode()->FindNext()->FindFirstChild(); while ((pNode != NULL) && (!pNode->IsKindOf(CC_RUNTIME_CLASS(Chapter)))) pNode = pNode->FindNext(); ENSURE(pNode->IsKindOf(CC_RUNTIME_CLASS(Chapter)), "Filter::GetFirstSpread(): Could not find Chapter"); Chapter *pChapter = (Chapter *) pNode; // pSpread is a child of pChapter pSpread = (Spread *) pChapter->FindFirstChild(); ENSURE(pSpread->IsKindOf(CC_RUNTIME_CLASS(Spread)), "Filter::GetFirstSpread(): Could not find Spread"); Page *pPage = (Page *) pSpread->FindFirstPageInSpread(); ENSURE(pPage->IsKindOf(CC_RUNTIME_CLASS(Page)), "BaseBitmapFilter::DoImport(): Could not find first Page"); // Use bottom left of page as origin DocRect PageRect = pPage->GetPageRect(); Origin = PageRect.lo; KernelBitmap* kb = new KernelBitmap(BMInfo.PixelWidth,BMInfo.PixelHeight,32,100); // Get a new bitmap object for this node. pNodeBitmap->GetBitmapRef()->Attach(kb); if (pNodeBitmap->GetBitmap() != kb) { // It didn't use the bitmap we gave it, so we can delete it delete kb; } ENSURE(pNodeBitmap->GetBitmap()->ActualBitmap != NULL, "No bitmap object found!"); // 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); // Apply some default attrs for the bitmap // This Must be done before the NodeBitmap is inserted into the tree if (!pNodeBitmap->ApplyDefaultBitmapAttrs(Op)) { return; } // Insert the node, but don't invalidate its region if (!Op->DoInsertNewNode(pNodeBitmap, pSpread, FALSE)) { // It didn't work - delete the sub-tree we just created, and report error. delete pNodeBitmap; return; } // Invalidate the region Op->DoInvalidateNodeRegion(pNodeBitmap, TRUE, FALSE); // Right, now we're going to do some processing... BitmapEffectBase * pEffect; pEffect=new /*TestBitmapEffect*/ BitmapEffectSILT; pEffect->SetParameters(); pEffect->SetSourceImage(pBitmap); pEffect->UseDestinationBitmap(pNodeBitmap->GetBitmap()); pEffect->Run(); pEffect->UseDestinationBitmap(NULL); delete(pEffect); } } CurrentNode = NextCurrent; } } // if (CarryOn) BitmapEffectSILT::RunA(); return; }