OpState OpReversePath::GetState (String_256* Description, OpDescriptor*) { OpState OpSt; SelRange* Selected = GetApplication ()->FindSelection (); if ((Document::GetSelected () == NULL) || (Selected == NULL) ) { // There is no selected document or selrange is invalid OpSt.Greyed = TRUE; return (OpSt); } if (Selected->Count () == 0) // if there ain't no selection - return cause we ain't // going to be reversing anything { OpSt.Greyed = TRUE; return (OpSt); } Node* pNode = Selected->FindFirst (); // scan the selection and if even a single DoThisNode fails, then return that the op // is greyed immediately .... while (pNode != NULL) { // we're only interested in NodePaths which have selected points BOOL DoThisNode = pNode->IsNodePath (); //if (DoThisNode) // DoThisNode = (((NodePath*)pNode)->InkPath.IsSubSelection()); if (DoThisNode) DoThisNode = (((NodePath*)pNode)->IsPathAllowable ()); if (DoThisNode) { pNode = Selected->FindNext (pNode); } else { pNode = NULL; OpSt.Greyed = TRUE; } } return (OpSt); }
BOOL SelectionState::Record() { // Make sure that Record has not been called before ENSURE(((SelNdList == NULL) && (SelNdRngList == NULL)), "SelectionState::Record called twice"); // Find the current selections SelRange* pSel; pSel = GetApplication()->FindSelection(); Node* StartRange; UINT32 SelNdRngListIndex = 0; UINT32 SelNdListIndex = 0; UINT32 NumSelectedNodes = pSel->Count(); if (NumSelectedNodes != 0) { // At this point we don't know exactly how much memory to allocate for the SelNdRngList // and SelNdList. So we allocate two temporary arrays which are more than big enough to // store the selection state. When we have completed recording the selection state into // these temporary arrays, we know how big the SelNdRngList and SelNdList should // be. so we can allocate memory for these and then copy the data from the temporary // arrays into them. SelNdRng* SelNdRngListTmp = new SelNdRng[NumSelectedNodes]; if (SelNdRngListTmp == NULL) { return FALSE; } Node** SelNdListTmp = new Node*[NumSelectedNodes]; if (SelNdListTmp == NULL) { delete[] SelNdRngListTmp; // Tidy up return FALSE; } // Get the first selected node in the tree Node * Current = pSel->FindFirst(); Node* Last; BYTE NumAdjacentSel; // Number of contiguous selected nodes #ifdef _DEBUG UINT32 NumSel = 0; #endif // always use the selection object to determine next node to store... this fixes bug #10775 whereby // selected Bevel,Contour & Shadow objects were not being restored on Undo while (Current != NULL) { // At this point Current will always point to the next selected node which needs // recording. // Only NodeRenderableInk nodes should be selected ENSURE(Current->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk)), "A non NodeRenderableInk node is selected"); NumAdjacentSel = 1; #ifdef _DEBUG NumSel++; #endif StartRange = Current; Last = Current; Current = pSel->FindNext(Current); //next from selection // if we have at least two contiguous nodes, store as a range if (Current && AreContiguous(Last, Current) && !IS_A(Last, CaretNode) && !IS_A(Current, CaretNode)) { SelNdRngListTmp[SelNdRngListIndex].FirstNode = StartRange; do { if (IS_A(Current, CaretNode)) { // Give Caret it's own selection record but don't break the contiguous range SelNdListTmp[SelNdListIndex] = Current; SelNdListIndex++; #ifdef _DEBUG NumSel++; #endif } else { NumAdjacentSel++; #ifdef _DEBUG NumSel++; #endif } Last = Current; Current = pSel->FindNext(Current); if (Current == NULL) break; } while ((AreContiguous(Last,Current)) && (NumAdjacentSel < 255)); // Either there are no more contiguous selected nodes or // we have hit the maximum number of selected nodes that a SelNdRng can // represent. SelNdRngListTmp[SelNdRngListIndex].NumSelected = NumAdjacentSel; SelNdRngListIndex++; } else // Store node in the SelNdLst { ERROR3IF(StartRange==NULL, "Trying to add NULL pointer to SelNdList\n"); SelNdListTmp[SelNdListIndex] = StartRange; SelNdListIndex++; } } ERROR3IF(NumSel!=NumSelectedNodes,"Incorrect selection state stored!"); NumNd = SelNdListIndex; NumNdRng = SelNdRngListIndex; if (SelNdRngListIndex != 0) { // We have created at least one SelNdRange SelNdRngList = new SelNdRng[NumNdRng]; if (SelNdRngList == NULL) // Out of memory { // Delete the two temporary lists delete [] SelNdRngListTmp; delete [] SelNdListTmp; return FALSE; } // Copy the SelNdRngListTmp to the SelNdRngList memcpy(SelNdRngList, SelNdRngListTmp, sizeof(SelNdRng)*NumNdRng); } delete[] SelNdRngListTmp; // No longer required if (SelNdListIndex != 0) { SelNdList = new Node*[NumNd]; if (SelNdList == NULL) // Out of memory { delete [] SelNdListTmp; if (SelNdRngList != NULL) // We allocated the SelNdRng list { delete [] SelNdRngList; } return FALSE; } // copy the SelNdListTmp to the SelNdList memcpy(SelNdList, SelNdListTmp, sizeof(Node*)*NumNd); } delete[] SelNdListTmp; // No longer required #ifdef _DEBUG //if (IsUserName("Simon")) //TRACE( _T("Number of nodes selected = %lu\n"), NumSel); #endif } return (TRUE); }
/******************************************************************************************** > 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 }