BOOL BitmapExportDocument::Init(KernelBitmap* pBitmap, const DocRect& RectToExport) { // Don't attach any CCamDoc. if (!Document::Init(0)) return(FALSE); Node *pSpread = FindFirstSpread(); ERROR3IF(pSpread == NULL, "No Spread in document!"); Node *pLayer = pSpread->FindFirstChild(); ERROR3IF(pLayer == NULL, "No Spread-child in document!"); // Store away the rectangle ExportRect = RectToExport; // Now scan the children of the first spread until we find a layer, or run out of nodes while (pLayer != NULL && !pLayer->IsLayer()) pLayer = pLayer->FindNext(); if (pLayer == NULL) // No Layer, so we'd better add one for ourselves { String_256 LayerID = String_256(_R(IDS_K_CLIPINT_LAYERNAME)); pLayer = new Layer(pSpread, LASTCHILD, LayerID); if (pLayer == NULL) return(InitFailed()); } // Create a new NodeRect NodeRect* pRectNode = new NodeRect(pLayer, FIRSTCHILD); // Failed so cleanup and exit if (pRectNode == NULL) return(InitFailed()); // Initilaise the node if (!pRectNode->SetUpPath(6,6)) return(InitFailed()); // Create the rectangle pRectNode->CreateShape(ExportRect); // Give the rectangle a line colour #if 0 // This memory leaks a StrokeColourAttribute StrokeColourAttribute* pAttrValue = new StrokeColourAttribute(DocColour(COLOUR_TRANS)); if (pAttrValue == NULL) return(InitFailed()); NodeAttribute* pAttr = pAttrValue->MakeNode(); if (pAttr == NULL) return(InitFailed()); // Attach the attribute to the rectangle pAttr->AttachNode(pRectNode, FIRSTCHILD); #else // Do what ApplyDefaultBitmapAttrs does Node* pLineColAttr = new AttrStrokeColour(); if (pLineColAttr == NULL) return(InitFailed()); DocColour none(COLOUR_NONE); ((AttrFillGeometry*)pLineColAttr)->SetStartColour(&none); pLineColAttr->AttachNode(pRectNode, FIRSTCHILD); #endif // Create a NodeBitmap (don't attach it to the tree straight away 'cos we // have to put the attributes on it first) pBitmapNode = new NodeBitmap(); if (pBitmapNode == NULL) return(InitFailed()); if (!pBitmapNode->SetUpPath(6,6)) return(InitFailed()); pBitmapNode->CreateShape(ExportRect); if (!SetBitmap(pBitmap)) return(InitFailed()); // Set the bitmap's attributes // This must be done before the NodeBitmap is inserted into the tree if (!pBitmapNode->ApplyDefaultBitmapAttrs(NULL)) return(InitFailed()); // Attach it to the tree as the next sibling of the rectangle pBitmapNode->AttachNode(pRectNode, NEXT); // Success... return(TRUE); }
void OpBreakAtPoints::Do(OpDescriptor*) { // Obtain the current selections SelRange* Selected = GetApplication()->FindSelection(); NodePath* pSplitNode; // Now, because we're going to be doing mad things to the selection, we have to make a list // of all the selected nodes, so that adding nodes into the tree won't confuse us List* NodeList = Selected->MakeListOfNodes(); NodeListItem* CurItem = (NodeListItem*)(NodeList->GetHead()); if (!CurItem) goto FailAndDeleteList; if (!DoStartSelOp(TRUE,TRUE)) goto FailAndDeleteList; while (CurItem) { // get a pointer to the NodePath NodePath* pThisNode = (NodePath*)(CurItem->pNode); // Only interested in NodePaths that have a sub selection, and that will allow the op to happen if ((IS_A(pThisNode,NodePath) || IS_A(pThisNode,NodeBlendPath)) && pThisNode->InkPath.IsSubSelection()) { // Find out how many nodes this op will reproduce INT32 NumSplinters = pThisNode->InkPath.NumSplinters(); BOOL DoThisNode = FALSE; if (NumSplinters > 0) { // We need to ask the effected nodes if they (and their parents) can handle this node being replaced ObjChangeFlags cFlags; if (NumSplinters > 1) cFlags.MultiReplaceNode = TRUE; // Node will be replaced with more than one node. else cFlags.ReplaceNode = TRUE; // Node will be replaced with one node only. ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this); DoThisNode = pThisNode->AllowOp(&ObjChange); } if (DoThisNode) { BOOL ok; Node* pnode; // Copy the nodepath and all its children, without placing the copy in the tree CALL_WITH_FAIL(pThisNode->NodeCopy(&pnode), this, ok); if (!ok) goto DeleteList; pSplitNode = (NodePath*)pnode; // remove the fill from this path as we're about to open it pSplitNode->InkPath.IsFilled = FALSE; // Now stick the new path into the tree CALL_WITH_FAIL ( DoInsertNewNode(pSplitNode, pThisNode, NEXT, TRUE, FALSE), this,ok ); if (!ok) goto DeleteListAndPath; // Now breakup this copy of the path where necessary Path* pChildPath; INT32 split; do { // Create a new path, ready for split ALLOC_WITH_FAIL(pChildPath, new Path, this); if (!pChildPath) goto DeleteList; // Now split the path, possibly into two pieces. split = pSplitNode->InkPath.BreakInTwo(pChildPath); if (split==-1) { InformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK)); delete pChildPath; goto FailAndDeleteList; } /* Karim 05/12/2000 No longer required - see code addition at the bottom of this loop. if (split==1) { delete pChildPath; continue; } */ if (split>1) { // update the split paths bounding rectangle pSplitNode->InvalidateBoundingRect(); // Create a new nodepath. NodePath* pChildNode; ALLOC_WITH_FAIL(pChildNode, new NodePath(), this); if (!pChildNode) { delete pChildPath; goto DeleteList; } // make room for the new path in the node path. CALL_WITH_FAIL ( pChildNode->SetUpPath(pChildPath->GetNumCoords(),12), this,ok ); if (!ok) { delete pChildNode; delete pChildPath; goto DeleteList; } // now copy the path data in there. pChildNode->InkPath.CopyPathDataFrom(pChildPath); delete pChildPath; // Clear the selection flag from the first element in both the split // and child paths. All others apart from the last will be unselected // by definition. Also select the last element in the child (pSplitNode->InkPath.GetFlagArray())[0].IsSelected = FALSE; (pChildNode->InkPath.GetFlagArray())[0].IsSelected = FALSE; (pChildNode->InkPath.GetFlagArray())[(pChildNode->InkPath.GetNumCoords()-1)].IsSelected = TRUE; pChildNode->InkPath.IsFilled = FALSE; // now, copy all attributes from the parent split to the child split Node* pAttr = pSplitNode->FindFirstChild(); while (pAttr != NULL) { if (pAttr->IsKindOf(CC_RUNTIME_CLASS(NodeAttribute))) { Node* pAttrCopy; CALL_WITH_FAIL(pAttr->NodeCopy(&pAttrCopy), this,ok); if (!ok) { pChildNode->CascadeDelete(); delete pChildNode; goto DeleteList; } pAttrCopy->AttachNode(pChildNode, FIRSTCHILD); } pAttr = pAttr->FindNext(); } for (INT32 loop = 0; loop < pChildNode->InkPath.GetNumCoords(); loop ++) { pChildNode->InkPath.GetVerbArray()[loop] = pChildNode->InkPath.GetVerbArray()[loop] & ~PT_CLOSEFIGURE; } // Now stick the new path into the tree CALL_WITH_FAIL ( DoInsertNewNode(pChildNode, pSplitNode, NEXT, TRUE, FALSE), this,ok ); if (!ok) { pChildNode->CascadeDelete(); delete pChildNode; goto DeleteList; } pSplitNode = pChildNode; } // Karim 05/12/2000 // Fix for memory leak. else { delete pChildPath; } } while (split); // Clear out any remaining closefigures on the last bit of the path for (INT32 loop = 0; loop < pSplitNode->InkPath.GetNumCoords(); loop ++) { pSplitNode->InkPath.GetVerbArray()[loop] = pSplitNode->InkPath.GetVerbArray()[loop] & ~PT_CLOSEFIGURE; } // Now we've broken up this path, let's hide it CALL_WITH_FAIL(DoHideNode(pThisNode,TRUE), this, ok) if (!ok) goto DeleteList; } } CurItem = (NodeListItem*)(NodeList->GetNext(CurItem)); }