#include <opdrbrsh.h>
Inheritance diagram for OpDrawBrush:
Public Member Functions | |
OpDrawBrush () | |
Constructor. | |
OpDrawBrush (FreeHandTool *pTool) | |
Constructor. This simply sets a few of the operation flags. | |
~OpDrawBrush () | |
destructor. | |
void | DoDrag (DocCoord Anchor, Spread *, INT32, BrushHandle Handle, FreeHandJoinInfo *pJoinInfo, Path *ToolPath, GRenderBrush *pGRndRgn, ClickModifiers ClickMods) |
Starts up the drag operation by storing all start positions and setting up a Path to store the mouse movement in. | |
virtual void | DragPointerMove (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL bSolidDrag) |
Handles the event of the mouse moving during a drag. | |
virtual void | DragPointerIdle (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL bSolidDrag) |
Handles the mouse idle events. | |
virtual void | DragFinished (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL Success, BOOL bSolidDrag) |
Handles the drag finishing by rubbing out an EOR on the screen and adding the path to the tree and building all the undo that will be needed. | |
void | RenderDragBlobs (DocRect, Spread *, BOOL bSolidDrag) |
EORs the whole path onto the screen a segment at a time. It needs to do it a segment at a time as that is how it is drawn as the path is created. This has to redraw it identically or there will be bits of EORed stuff left all over the place. | |
virtual BOOL | IsBrushOp () |
BOOL | SetTimeStamp (double TimeStamp) |
to set the timestamp member | |
Static Public Member Functions | |
static BOOL | Declare () |
Adds the operation to the list of all known operations. | |
static OpState | GetState (String_256 *Description, OpDescriptor *) |
Find out the state of the operation at the specific time. | |
static CDistanceSampler * | GeneratePressureData (AttrBrushType *pAttrBrush, MILLIPOINT StartDistance, MILLIPOINT EndDistance, MILLIPOINT NewPathLength) |
This function deals with the case when we wish to edit a brush with pressure data but we do not generate a pressure list during the edit for some reason. In this case we must create a new pressure list and fill it with values based upon the values in the existing brush pressure list. | |
static MILLIPOINT | GetCurrentLineWidthIfNotDefault () |
In order to determine whether we have to tell the brush to scale to a new line width or not. | |
Protected Member Functions | |
void | ResetMembers () |
Initialises all our member variables to something sensible. | |
void | AddPointsToPath (DocCoord Pos, Spread *pSpread) |
Adds a new point to the path of mouse moves. When the drag finishes the mouse moves will be smoothed. | |
virtual void | SetCursorAndStatus (CursorType CurType) |
Overridden version for the brush, basically we do not offer any of the keyboard options so we wish to keep the status line blank during brush operations. | |
virtual BOOL | ApplyAttributes (NodePath *NewPath, Document *pDocument) |
Applies the current attributes to the Node passed in. It has to find the current document to do this and will ENSURE if it fails to find one. This overridden version also finds the newly applied brush attribute and gives it the cache of points that we have been recording. | |
void | RenderStepsForTime (double TimeSlice, Spread *pSpread) |
Renders as many steps in the brush as possible in the time available. The reason for having the code here rather than in the processor is twofold: 1) I feel the property of rendering for a certain timeslice is a property of the Op rather than the PPB; 2) In order to make use of the caching ProcessPathDistance, which belongs to the Op rather than the PPB. | |
BOOL | InitialisePathProcessorBrush (BrushHandle Handle, MILLIPOINT Distance=0) |
To create a new pathprocessorbrush and copy all the data from the brush definitino found using BrushIndex. | |
BOOL | InitialiseProcessPathDistance () |
To create a new path processor object. | |
BOOL | InitialisePressureCache () |
To allocate the pressure array, if we need it. | |
AttrBrushType * | CreateNewAttribute () |
Adds the operation to the list of all known operations. | |
virtual BOOL | EditBrushLists (NodePath *pNewPath, INT32 FirstChangedIndex, INT32 NumElements) |
When we are editing a brush that contains either timestamping or pressure data and we are editing using a brush we will have generated our own list of TS or pressure info that we need to insert into the existing list. This fn. manages the insertion of these lists and any others that might arise. | |
BOOL | EditTimeStampList (NodePath *pNewPath, INT32 FirstChangedIndex, INT32 NumElements) |
When a path is edited that has a timestamping brush applied to it we those points are stored in a list that is generated when the path is drawn. If we subsequently want to edit that path we have to insert or remove points from that list. This function works out what points should be inserted or removed, and performs that action on the applied brush. This is made slightly easier. | |
BOOL | EditPressureList (NodePath *pNewPath, INT32 FirstChangedIndex, INT32 NumElements) |
virtual BOOL | SimpleJoinBrush (NodePath *pNewNodePath, Path *pNewPath) |
Joins a Simple path with the new freehand path and builds all the undo that is needed in the process. | |
virtual BOOL | ReverseBrushPressure () |
Calls the attribute function to reverse our pressure list. | |
BOOL | InitialiseTimeStampList () |
to create a new timestamp object list and assign it to our member | |
void | RenderTimeStamp () |
To be used in timestamp mode, obviously. This fn. determines whether or not enough time has elapsed for us to render a point. If so we render a point and cache it, updating the necessary members. | |
BOOL | InitialisePressureSampler () |
to create a new CSampleData object and assign it to our pointer for sampling pressure | |
BOOL | ApplyRetroSmoother (NodePath *pNodePath, double SmoothAmount) |
Initialises the RetroSmoother object and uses it to smooth the nodepath we have created. The reason for using this smoother rather than the FreeHand smoother is that it does not seem to change the shape of the path in a visible way. It is useful to apply this because otherwise the paths that we draw have too many control points which can obscure the brush objects. | |
BOOL | RetroSmoothBrush (NodePath *pNewNodePath) |
As above, the base class version does nothing. | |
Protected Attributes | |
MILLIPOINT | m_BrushSpacing |
MILLIPOINT | m_LastSpacing |
MILLIPOINT | m_DistanceSinceLastObject |
MILLIPOINT | m_LastDistanceRendered |
DocCoord | m_LastPoint |
DocCoord | m_StartPoint |
DocCoord | m_LastPointRendered |
INT32 | m_NumBrushObjects |
UINT32 | m_NumInkObjects |
UINT32 | m_LastInkObjectRendered |
double | m_BrushScaling |
GRenderBrush * | m_pGRenderBrush |
PathProcessorBrush * | m_pPathProcBrush |
BrushDefinition * | m_pBrushDefinition |
BOOL | mustClearStatusBar |
Application * | pApp |
ProcessPathDistance * | m_pProcPathDistance |
FreeHandTool * | m_pTool |
BOOL | m_bFirstPointRendered |
MILLIPOINT | m_FirstSpacing |
INT32 | m_LastPathIndexRendered |
PointsMap * | m_pPointsCache |
double | m_TimeStamp |
double | m_LastTimeStamp |
TimeStampList * | m_pTimeStampList |
MonotonicTime | m_Timer |
PressureList * | m_pPressureList |
CDistanceSampler * | m_pPressureSampler |
UINT32 | m_NumPressureVals |
Private Member Functions | |
CC_DECLARE_DYNCREATE (OpDrawBrush) |
Definition at line 139 of file opdrbrsh.h.
|
Constructor.
Definition at line 183 of file opdrbrsh.cpp. 00184 { 00185 ResetMembers(); 00186 }
|
|
Constructor. This simply sets a few of the operation flags.
Definition at line 198 of file opdrbrsh.cpp. 00199 { 00200 ResetMembers(); 00201 if (pTool != NULL) 00202 m_pTool = pTool; 00203 }
|
|
destructor.
Definition at line 216 of file opdrbrsh.cpp. 00217 { 00218 // if (m_pGRenderBrush != NULL) 00219 // delete m_pGRenderBrush; 00220 if (m_pProcPathDistance != NULL) 00221 delete m_pProcPathDistance; 00222 00223 00224 if (m_pPathProcBrush != NULL) 00225 delete m_pPathProcBrush; 00226 00227 if (m_pPressureList != NULL) 00228 delete m_pPressureList; 00229 00230 if (m_pPointsCache != NULL) 00231 delete m_pPointsCache; 00232 00233 if (m_pPressureSampler != NULL) 00234 delete m_pPressureSampler; 00235 }
|
|
Adds a new point to the path of mouse moves. When the drag finishes the mouse moves will be smoothed.
Reimplemented from OpFreeHand. Definition at line 1932 of file opdrbrsh.cpp. 01933 { 01934 // If this coord is the same as the last one, then do not bother adding to the track data 01935 if (PreviousPoint == PointerPos) 01936 return; 01937 01938 // Insert the move 01939 if (TrackData->InsertLineTo(PointerPos)) 01940 { 01941 // and add pressure info if needed 01942 if (AddPressureToPath) 01943 { 01944 TrackData->AddExtraInfo(CI_PRESSURE, FreeHandPressure); 01945 } 01946 } 01947 else 01948 { 01949 // Oh no, we ran out of mem in the middle of making a new path 01950 // Tidy up and report back to HQ 01951 EndDrag(); 01952 01953 // Tell the World that it all went horribly wrong 01954 InformError(); 01955 01956 // Remove it from the tree and delete it 01957 TrackData->ClearPath(); 01958 01959 // End this operation and return 01960 FailAndExecute(); 01961 End(); 01962 return; 01963 } 01964 01965 // RenderLine(m_pGRenderBrush, TrackData, TrackData->GetNumCoords()-1); 01966 01967 // Make a note of the coord, inc the line count and mark joining to the start as active. 01968 PreviousPoint = PointerPos; 01969 LineSegmentCount++; 01970 CanLineJoin = TRUE; 01971 }
|
|
Applies the current attributes to the Node passed in. It has to find the current document to do this and will ENSURE if it fails to find one. This overridden version also finds the newly applied brush attribute and gives it the cache of points that we have been recording.
Andy Hills, 18-09-00 Note - I have temporarily reverted this function to the 24-08-00 version. This fixes the problem where, if the above-mentioned option is disabled, an access violation occurs. Reimplemented from OpFreeHand. Definition at line 1084 of file opdrbrsh.cpp. 01085 { 01086 ERROR2IF(pNewPath == NULL, FALSE, "pNewNodePath is NULL in OpDrawBrush::ApplyAttributes"); 01087 ERROR2IF(pDocument == NULL, FALSE, "pDocument is NULL in OpDrawBrush::ApplyAttributes"); 01088 01089 //ApplyRetroSmoother(pNewPath, 50); 01090 01091 // Find the current document to get the current attributes from 01092 ENSURE(pDocument!=NULL, "Null Document while setting attributes for new NodePath"); 01093 if (pDocument!=NULL) 01094 { 01095 // we make out own attributes here 01096 AttrBrushType* pNewAttr = CreateNewAttribute(); 01097 if (pNewAttr == NULL) 01098 return FALSE; 01099 #ifdef NEWFASTBRUSHES 01100 BrushAttrValue* pAttrVal = (BrushAttrValue*) pNewAttr->GetAttributeValue(); 01101 pAttrVal->SetBoundsParent (pNewPath); 01102 #endif 01103 // now make the line the correct width, if someone has selected a line width then we will make it 01104 // that size, otherwise we will use the default provided by the brush 01105 MILLIPOINT LineWidth = GetCurrentLineWidthIfNotDefault(); 01106 if (LineWidth == -1) 01107 LineWidth = pNewAttr->GetDefaultLineWidth(!AddPressureToPath); 01108 01109 01110 // Apply the current attributes to the path, changing the line width if necessary 01111 if (!pDocument->GetAttributeMgr().ApplyCurrentAttribsToNode((NodeRenderableInk*)pNewPath)) 01112 ERROR3("Failed to apply current attributes in OpDrawBrush::ApplyAttributes"); 01113 01114 // change the line width value 01115 AttrLineWidth* pLineWidth = (AttrLineWidth*)pNewPath->FindFirstChild(CC_RUNTIME_CLASS(AttrLineWidth)); 01116 if (pLineWidth != NULL) 01117 pLineWidth->Value.LineWidth = LineWidth; 01118 else 01119 ERROR3("Unable to find line width in OpDrawBrush::ApplyAttributes"); 01120 01121 // if the document inserted a brush then get rid of it 01122 Node* pDocBrush = pNewPath->FindFirstChild(CC_RUNTIME_CLASS(AttrBrushType)); 01123 if (pDocBrush) 01124 { 01125 pDocBrush->CascadeDelete(); 01126 delete pDocBrush; 01127 pDocBrush = NULL; 01128 } 01129 01130 01131 // apply our brush attribute here, in case the document already applied a default 01132 pNewPath->ApplyAttributeToObject(pNewAttr, FALSE); 01133 01134 // tell it about the freehand tool 01135 pNewAttr->SetFreeHandTool(m_pTool); 01136 01137 if (pNewAttr->GetBrushHandle() != BrushHandle_NoBrush) 01138 { 01139 01140 #ifdef OPBRUSHPOINTSCACHE 01141 if (m_TimeStamp <= 0) 01142 pNewAttr->SetCache(m_pPointsCache); 01143 01144 // make sure we don't try to use the cache, the attribute is now responsible for 01145 // deleting it 01146 m_pPointsCache = NULL; 01147 #endif 01148 BrushAttrValue* pVal = (BrushAttrValue*)pNewAttr->GetAttributeValue(); 01149 // if we're timestamping then set the timestamp cache instead 01150 if (m_TimeStamp > 0) 01151 { 01152 if (pVal != NULL) 01153 { 01154 pVal->SetTimeStampList(m_pTimeStampList); 01155 pVal->CalculateProportionalDistances((MILLIPOINT)pNewPath->InkPath.GetPathLength()); 01156 } 01157 } 01158 // add the pressure cache, if we need to 01159 if (AddPressureToPath) 01160 { 01161 //m_pPressureVals->SetSize(m_NumPressureVals, 1); 01162 //m_pPressureVals->FreeExtra(); 01163 m_pPressureSampler->FinishSampling(); 01164 m_pPressureSampler->FreeExtra(); 01165 01166 pNewAttr->SetPressureCache(m_pPressureSampler); 01167 // set our pointer to null so we don't end up deleting it 01168 m_pPressureSampler = NULL; 01169 01170 // ask the attribute to calculate the proportional distances 01171 //if (pVal != NULL) 01172 // pVal->CalculatePressureArrayProportions((MILLIPOINT)pNewPath->InkPath.GetPathLength()); 01173 } 01174 } 01175 01176 return TRUE; 01177 } 01178 01179 // We failed to apply the attributes, so fail 01180 return FALSE; 01181 }
|
|
Initialises the RetroSmoother object and uses it to smooth the nodepath we have created. The reason for using this smoother rather than the FreeHand smoother is that it does not seem to change the shape of the path in a visible way. It is useful to apply this because otherwise the paths that we draw have too many control points which can obscure the brush objects.
Definition at line 1201 of file opdrbrsh.cpp. 01202 { 01203 ERROR2IF(pNodePath == NULL, FALSE, "NodePath is NULL in OpDrawBrush::ApplyRetroSmoother"); 01204 01205 // make a smoothing object 01206 RetroSmooth Smoother; 01207 01208 if (!Smoother.Initialise()) 01209 return FALSE; 01210 01211 // tell the smoother we don't want EOR rendering 01212 Smoother.SetRenderFlag(FALSE); 01213 01214 // we need to set all our path elements selected for the smoother 01215 pNodePath->InkPath.SetAllSubSelection(); 01216 01217 // we need the spread for the smoothing operation 01218 Spread* pSpread = Document::GetSelectedSpread(); 01219 if (pSpread == NULL) 01220 { 01221 ERROR3("Spread is NULL in OpDrawBrush::ApplyRetroSmoother"); 01222 return FALSE; 01223 } 01224 01225 Smoother.Changing(pNodePath, pSpread, SmoothAmount); 01226 Smoother.FinishedNoUndo(pNodePath); 01227 01228 // unselect our path elements 01229 pNodePath->InkPath.ClearSubSelection(); 01230 01231 return TRUE; 01232 }
|
|
|
|
Adds the operation to the list of all known operations.
Definition at line 1247 of file opdrbrsh.cpp. 01248 { 01249 01250 AttrBrushType* pNewAttr = new AttrBrushType; 01251 if (pNewAttr == NULL) 01252 { 01253 ERROR3("Couldn't make attribute node"); 01254 return NULL; 01255 } 01256 01257 BrushAttrValue* pVal = (BrushAttrValue*)pNewAttr->GetAttributeValue(); 01258 if (pVal == NULL) 01259 { 01260 ERROR3("No attribute value"); 01261 return NULL; 01262 } 01263 01264 if (m_pPathProcBrush == NULL) 01265 { 01266 ERROR3("Path Processor Brush is NULL already"); 01267 return NULL; 01268 } 01269 pVal->SetPathProcessor(m_pPathProcBrush); 01270 01271 m_pPathProcBrush->SetParentAttribute(pNewAttr); 01272 01273 // make sure our processor has all the correct data 01274 Document* pDoc = Document::GetCurrent(); 01275 ERROR2IF(pDoc == NULL, pNewAttr, "No document in OpDrawBrush::CreateNewAttribute"); 01276 BrushComponent* pBrushComp = (BrushComponent*)pDoc->GetDocComponent(CC_RUNTIME_CLASS(BrushComponent)); 01277 ERROR2IF(pBrushComp == NULL, pNewAttr, "No brush component in OpDrawBrush::CreateNewAttribute"); 01278 BrushDefinition* pBrushDef = pBrushComp->FindBrushDefinition(m_pPathProcBrush->GetBrushDefinitionHandle()); 01279 ERROR2IF(pBrushDef == NULL, pNewAttr, "Unable to retrieve brush definition, invalid handle"); 01280 01281 // copy the data from the definition 01282 pBrushDef->CopyDataToProcessor(m_pPathProcBrush); 01283 01284 // scale to the appropriate line width (or not) 01285 01286 MILLIPOINT LineWidth = GetCurrentLineWidthIfNotDefault(); 01287 if (LineWidth != -1) 01288 { 01289 m_pPathProcBrush->ScaleToValue(LineWidth, !AddPressureToPath); 01290 } 01291 else 01292 { 01293 MILLIPOINT Size = pBrushDef->GetDefaultLineWidth(!AddPressureToPath); 01294 m_pPathProcBrush->ScaleToValue(Size, !AddPressureToPath); 01295 } 01296 01297 // make sure we don't delete it now 01298 m_pPathProcBrush = NULL; 01299 return pNewAttr; 01300 }
|
|
Adds the operation to the list of all known operations.
Reimplemented from OpFreeHand. Definition at line 1882 of file opdrbrsh.cpp. 01883 { 01884 return (RegisterOpDescriptor( 01885 0, 01886 _R(IDS_FREE_HAND_TOOL), 01887 CC_RUNTIME_CLASS(OpDrawBrush), 01888 OPTOKEN_DRAWBRUSH, 01889 OpDrawBrush::GetState, 01890 0, /* help ID */ 01891 _R(IDBBL_FREEHANDTOOLOP), 01892 0 /* bitmap ID */)); 01893 }
|
|
Starts up the drag operation by storing all start positions and setting up a Path to store the mouse movement in.
Definition at line 329 of file opdrbrsh.cpp. 00332 { 00333 TRACEUSER( "Diccon", _T("Drag started\n")); 00334 if (pSpread == NULL) 00335 { 00336 ERROR3("No spread"); 00337 FailAndExecute(); 00338 End(); 00339 return; 00340 } 00341 if (ToolPath == NULL) 00342 { 00343 ERROR3("Tool path is NULL"); 00344 FailAndExecute(); 00345 End(); 00346 return; 00347 } 00348 // WEBSTER - markn 25/4/97 00349 // No pen stuff required in Webster 00350 // Taken out by vector stroking code Neville 2/10/97 00351 #ifdef VECTOR_STROKING 00352 // Tell the pressure pen that we're starting a new stroke 00353 CCPen *pPen = pApp->GetPressurePen(); 00354 if (pPen != NULL) 00355 pPen->StartStroke(); 00356 #endif // VECTOR_STROKING 00357 00358 // Snap the starting coord if we are not joining to something else 00359 if ((pFreeHandInfo==NULL) || (pFreeHandInfo->pJoinPath==NULL)) 00360 DocView::SnapCurrent(pSpread, &Anchor, FALSE, TRUE); 00361 00362 // Make a note of various starting conditions 00363 TrackData = ToolPath; 00364 Smoothness = Smooth; 00365 pJoinInfo = pFreeHandInfo; 00366 StartPath = pJoinInfo->pJoinPath; 00367 EndPath = NULL; 00368 00369 // Make a mental note of the start point 00370 StartPoint = Anchor; 00371 StartSpread = pSpread; 00372 PreviousSpread= pSpread; 00373 PreviousPoint = Anchor; 00374 LineSegmentCount = 0; 00375 IsStraightLineMode = FALSE; 00376 CanLineJoin = FALSE; 00377 00378 // Prepare the Track data path and add in the initial click point to the path 00379 if (!PrepareTrackDataPath()) 00380 { 00381 // We failed to get the memory to initialise the track data 00382 InformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK)); 00383 FailAndExecute(); 00384 End(); 00385 return; 00386 } 00387 00388 // Create some cursors that I might need 00389 if (!LoadCursors()) 00390 { 00391 // The cursors did not load, so fail? 00392 FailAndExecute(); 00393 End(); 00394 return; 00395 } 00396 00397 00398 // Push my new cursor onto the stack 00399 CurrentCursorID = CursorStack::GPush(pFreeHandCursor, TRUE); 00400 MyCurrentCursor = pFreeHandCursor; 00401 00402 // Diccon new brush stuff 00403 TRACEUSER( "Diccon", _T("DRAG STARTED\n")); 00404 if (pGRndRgn == NULL) 00405 { 00406 ERROR3("No GRenderBrush"); 00407 FailAndExecute(); 00408 End(); 00409 return; 00410 } 00411 else 00412 m_pGRenderBrush = pGRndRgn; 00413 00414 // if we are joining a brush then make sure we know that handle 00415 if (pFreeHandInfo->m_BrushHandle != BrushHandle_NoBrush) 00416 Handle = pFreeHandInfo->m_BrushHandle; 00417 00418 if (!InitialisePathProcessorBrush(Handle, pFreeHandInfo->BrushDistance)) 00419 { 00420 FailAndExecute(); 00421 End(); 00422 return; 00423 } 00424 00425 // if out freehand info indicates that we are joining to an existing brush then 00426 // copy out the data from that brush 00427 if (pFreeHandInfo->m_BrushHandle != BrushHandle_NoBrush && pFreeHandInfo->pAttrBrush != NULL) 00428 { 00429 // MILLIPOINT Spacing = 0; 00430 m_pPathProcBrush->GetSpacingAndScalingAtDistance(pFreeHandInfo->BrushDistance, &m_FirstSpacing, &m_BrushScaling); 00431 00432 m_pPathProcBrush->CopyDataFromObject(&(pFreeHandInfo->m_BrushData)); 00433 m_LastSpacing = m_pPathProcBrush->GetSpacing(); 00434 00435 // set the scaling, this can vary as we may be adding to a line 00436 // of any width 00437 m_BrushScaling = pFreeHandInfo->m_BrushData.m_BrushScaling; 00438 00439 m_pPathProcBrush->AdvanceBrushToDistance(pFreeHandInfo->BrushDistance); 00440 00441 m_LastInkObjectRendered = m_pPathProcBrush->GetLastObject(); 00442 00443 // if we're overriding colours then tell the ppb what colour to use 00444 m_pPathProcBrush->SetUseLocalFillColour(pFreeHandInfo->UseLocalColour); 00445 m_pPathProcBrush->SetUseNamedColours(pFreeHandInfo->UseNamedColour); 00446 if (pFreeHandInfo->UseLocalColour || !pFreeHandInfo->UseNamedColour) 00447 m_pPathProcBrush->SetStrokeColour(pFreeHandInfo->StrokeColour); 00448 00449 // m_FirstSpacing = m_pPathProcBrush->GetLastSpacing() - pFreeHandInfo->FirstBrushSpacing; 00450 00451 // TRACEUSER( "Diccon", _T("JOINING EXISTING BRUSH\n")); 00452 } 00453 00454 if (!InitialiseProcessPathDistance()) 00455 { 00456 FailAndExecute(); 00457 End(); 00458 return; 00459 } 00460 00461 if (!InitialisePressureSampler()) 00462 { 00463 FailAndExecute(); 00464 End(); 00465 return; 00466 } 00467 if (AddPressureToPath == TRUE) 00468 { 00469 // TRACEUSER( "Diccon", _T("Pressure = %d\n"), ClickMods.Pressure); 00470 // m_pPressureSampler->CollectData(Anchor, ClickMods.Pressure); //?? not sure this is right 00471 } 00472 00473 if (m_pPathProcBrush != NULL) 00474 { 00475 m_NumInkObjects = m_pPathProcBrush->GetNumBrushObjects(); 00476 m_BrushSpacing = m_pPathProcBrush->GetSpacing(); 00477 m_pPathProcBrush->SetParentAttribute(pFreeHandInfo->pAttrBrush); 00478 } 00479 else 00480 { 00481 FailAndExecute(); 00482 End(); 00483 return; 00484 } 00485 if (m_NumInkObjects < 1) 00486 { 00487 ERROR3("No brush ink objects"); 00488 FailAndExecute(); 00489 End(); 00490 return; 00491 } 00492 00493 // if we are not timestamping then we want a regular point-at-distance map to 00494 // use as a cache, so long as we are not joining an existing brush 00495 #ifdef OPBRUSHPOINTSCACHE 00496 if (m_TimeStamp <= 0 && pFreeHandInfo->m_BrushHandle == BrushHandle_NoBrush) 00497 { 00498 // allocate the map for caching 00499 m_pPointsCache = new PointsMap; 00500 00501 //m_pPointsList = new List; 00502 // not a disaster if we don't get it 00503 // if (m_pPointsCache != NULL) 00504 // m_pPointsCache->InitHashTable(1277); 00505 // else 00506 // ERROR3("Failed to allocate cache"); 00507 } 00508 #endif 00509 // if we are timestamping then we want a list 00510 if (m_TimeStamp > 0) 00511 { 00512 if (!InitialiseTimeStampList()) 00513 { 00514 // can't do anything if we don't get our cache 00515 FailAndExecute(); 00516 End(); 00517 return; 00518 } 00519 } 00520 00521 // initialise needs to have correct start point 00522 m_StartPoint = Anchor; 00523 00524 // set up the member variables 00525 m_LastPoint = Anchor; 00526 m_LastPointRendered = Anchor; 00527 m_LastDistanceRendered = 0; 00528 m_DistanceSinceLastObject = 0; 00529 m_LastSpacing = m_BrushSpacing; 00530 m_NumBrushObjects = 0; 00531 00532 AddPointsToPath(Anchor, pSpread); 00533 m_bFirstPointRendered = FALSE; 00534 00535 StartDrag( DRAGTYPE_NOSCROLL ); 00536 00537 // TRACEUSER( "Diccon", _T("Drag initialised")); 00538 00539 PORTNOTE("other", "Removed m_pRenderGBrush"); 00540 #ifndef EXCLUDE_FROM_XARALX 00541 //#ifdef NEWFASTBRUSHES 00542 View* pView = View::GetCurrent(); 00543 CCamView* pCCamView = pView->GetConnectionToOilView(); 00544 CDC* pDevContext = pCCamView->GetRenderDC(); 00545 HDC DeviceHdc = pDevContext->GetSafeHdc(); 00546 00547 m_pGRenderBrush->SetView (pView); 00548 m_pGRenderBrush->SetCamView (pView->GetConnectionToOilView()); 00549 m_pGRenderBrush->SetCDC (pCCamView->GetRenderDC()); 00550 m_pGRenderBrush->SetHDC (pDevContext->GetSafeHdc()); 00551 //#endif 00552 #endif 00553 }
|
|
Handles the drag finishing by rubbing out an EOR on the screen and adding the path to the tree and building all the undo that will be needed.
Reimplemented from OpFreeHand. Definition at line 966 of file opdrbrsh.cpp. 00968 { 00969 TRACEUSER( "Diccon", _T("Drag finished\n")); 00970 // Erase the whole EORed line 00971 DocRect ClipRect(0,0,0,0); 00972 RenderDragBlobs(ClipRect, StartSpread, bSolidDrag); 00973 00974 // Get rid of all the cursors 00975 RemoveCursors(); 00976 00977 // Put the hour glass up as we have to and end the drag 00978 //BeginSlowJob(); 00979 String_32 ProgString = _T("Calculating brush, please wait.."); 00980 Progress Hourglass(&ProgString, -1, FALSE); 00981 00982 EndDrag(); 00983 00984 00985 // Add the new path to the tree if it was valid 00986 BOOL Worked = FALSE; 00987 if (Success) 00988 { 00989 // were we in the middle of drawing a straight line 00990 if (IsStraightLineMode) 00991 { 00992 // we were so add it in to the track data 00993 AddStraightLine(); 00994 PreviousPoint = StraightLinePos; 00995 IsStraightLineMode = FALSE; 00996 } 00997 BeginSlowJob(-1, TRUE, NULL); 00998 00999 // invalidate the rect that we calculated (this may be different to the bounding 01000 // rect of the node due to smoothing) 01001 DocRect BRect = m_pPathProcBrush->GetCachedRect(); 01002 // Get rid of cached bitmaps here! 01003 Node* pANode = NULL; 01004 if (m_pPathProcBrush->GetParentAttribute()) 01005 { 01006 pANode = m_pPathProcBrush->GetParentAttribute()->FindParent(); 01007 if (pANode->IsBounded()) 01008 { 01009 ((NodeRenderableBounded*)pANode)->ReleaseCached(); 01010 } 01011 } 01012 DoInvalidateRegion(pSpread, BRect); 01013 01014 // clean up some memory we used 01015 m_pPathProcBrush->CleanUpAfterRender(); 01016 01017 BrushDefinition* pDef = BrushComponent::FindBrushDefinition(m_pPathProcBrush->GetBrushDefinitionHandle()); 01018 if (pDef) 01019 pDef->StopRender(); 01020 else 01021 ERROR3("Unable to get brush definition in OpDrawBrush::DragFinished"); 01022 01023 // try and smooth the path and insert it into the tree 01024 Worked = CompleteOperation(); 01025 EndSlowJob(); 01026 } 01027 // WEBSTER - markn 25/4/97 01028 // No pen stuff required in Webster 01029 // Taken out by vector stroking code Neville 2/10/97 01030 #ifdef VECTOR_STROKING 01031 // Inform the pressure pen that we've finished the stroke 01032 CCPen *pPen = pApp->GetPressurePen(); 01033 if (pPen != NULL) 01034 pPen->EndStroke(); 01035 #endif // VECTOR_STROKING 01036 01037 01038 if (m_pTool != NULL) 01039 m_pTool->BrushFinished(); 01040 01041 // point the pointer away from the render region (the tool still needs it so we don't delete) 01042 m_pGRenderBrush = NULL; 01043 01044 // If the operation failed, then tidy up 01045 if (Worked==FALSE) 01046 FailAndExecute(); 01047 else 01048 { 01049 // Update all the parents of the effected paths. 01050 ObjChangeFlags cFlags; 01051 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this); 01052 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this); 01053 UpdateChangedNodes(&ObjChange); 01054 } 01055 // End the operation properly 01056 End(); 01057 }
|
|
Handles the mouse idle events.
Reimplemented from OpFreeHand. Definition at line 678 of file opdrbrsh.cpp. 00679 { 00680 BOOL bAllowRender = TRUE; 00681 00682 // --- If the quality is set low enough, strokes are just rendered as centrelines 00683 // "low enough" is defined as the same point that Blends show their middle parts 00684 // BLOCK 00685 { 00686 PORTNOTE("other", "Removed m_pRenderGBrush"); 00687 #ifndef EXCLUDE_FROM_XARALX 00688 if(m_pGRenderBrush != NULL) 00689 { 00690 QualityAttribute *pQuality = (QualityAttribute *) m_pGRenderBrush->GetCurrentAttribute(ATTR_QUALITY); 00691 if (pQuality != NULL && pQuality->QualityValue.GetBlendQuality() != Quality::FullBlend) 00692 { 00693 bAllowRender = FALSE; 00694 // return; 00695 } 00696 } 00697 #endif 00698 } 00699 00700 // because we are throwing away the first few pressure values we want to make sure we have 00701 // got enough before we render here 00702 if (AddPressureToPath) 00703 { 00704 if (m_NumPressureVals > PressureValsThreshold && bAllowRender) 00705 RenderStepsForTime(75, pSpread); // 75 is the time to render for in ms, as determined by trial and error 00706 } 00707 else 00708 { 00709 if(bAllowRender) 00710 RenderStepsForTime(75, pSpread); 00711 } 00712 00713 //TRACEUSER( "Diccon", _T("Drag pointer idle\n")); 00714 }
|
|
Handles the event of the mouse moving during a drag.
Reimplemented from OpFreeHand. Definition at line 572 of file opdrbrsh.cpp. 00574 { 00575 // Lets whip out the current pressure value 00576 if (AddPressureToPath) 00577 FreeHandPressure = ClickMods.Pressure; 00578 00579 // If drag has moved onto a different spread, convert the coord to be relative to the 00580 // original spread. 00581 if (pSpread != StartSpread) 00582 #ifdef NEWFASTBRUSHES 00583 PointerPos = MakeRelativeToSpreadNoOverhead(StartSpread, pSpread, PointerPos); // min variable allocation overhead version 00584 #else 00585 PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos); // min variable allocation overhead version 00586 #endif 00587 00588 // I'm not allowing rubbing out or straightlines whilst drawing a brush 00589 ClickMods.Alternative1 = FALSE; 00590 ClickMods.Adjust = FALSE; 00591 00592 // Change the Cursor to display the appropriate thing. 00593 SetCursorOnMove(ClickMods, StartSpread, &PointerPos); 00594 00595 AddPointsToPath(PointerPos, StartSpread); 00596 // Set the last spread to something appropriate 00597 PreviousSpread = pSpread; 00598 00599 // brush specific code 00600 double Distance = (PointerPos.Distance(m_LastPoint)); 00601 m_DistanceSinceLastObject += (MILLIPOINT)Distance; 00602 // cache the point for this brush object 00603 m_LastPoint = PointerPos; 00604 // pass the data to our pressure sampler 00605 if (m_pPressureSampler != NULL) 00606 { 00607 m_NumPressureVals++; 00608 if (m_NumPressureVals > PressureValsThreshold) 00609 { 00610 TRACEUSER( "Diccon", _T("Pressure = %d\n"), ClickMods.Pressure); 00611 00612 if (!m_pPressureSampler->CollectData(PointerPos, FreeHandPressure)) 00613 { 00614 ERROR3("Error in Pressure sampler, aborting.."); 00615 FailAndExecute(); 00616 End(); 00617 return; 00618 } 00619 } 00620 else 00621 return; 00622 00623 } 00624 // --- If the quality is set low enough, strokes are just rendered as centrelines 00625 // "low enough" is defined as the same point that Blends show their middle parts 00626 // BLOCK 00627 { 00628 PORTNOTE("other", "Removed m_pRenderGBrush"); 00629 #ifndef EXCLUDE_FROM_XARALX 00630 if(m_pGRenderBrush != NULL) 00631 { 00632 QualityAttribute *pQuality = (QualityAttribute *) m_pGRenderBrush->GetCurrentAttribute(ATTR_QUALITY); 00633 if (pQuality != NULL && pQuality->QualityValue.GetBlendQuality() != Quality::FullBlend) 00634 { 00635 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, UnclippedEOR ); 00636 while ( pRegion ) 00637 { 00638 RenderLine(pRegion, TrackData, TrackData->GetNumCoords()-1, FALSE); 00639 // get the next region to draw in 00640 pRegion = DocView::GetNextOnTop(NULL); 00641 } 00642 return; 00643 } 00644 } 00645 #endif 00646 } 00647 00648 // if (pJoinInfo->BrushHandle != BrushHandle_NoBrush) 00649 // RenderLine(m_pGRenderBrush, TrackData, TrackData->GetNumCoords()-1); 00650 // Render brush objects for the specified period 00651 RenderStepsForTime(50, pSpread); 00652 00653 // if we are editing then render the path too 00654 /* if (pJoinInfo->BrushHandle != BrushHandle_NoBrush) 00655 { 00656 RenderLine(NULL, pSpread, TrackData, TrackData->GetNumCoords() - 1); 00657 RenderLine(m_pGRenderBrush, TrackData, TrackData->GetNumCoords()-1); 00658 }*/ 00659 }
|
|
When we are editing a brush that contains either timestamping or pressure data and we are editing using a brush we will have generated our own list of TS or pressure info that we need to insert into the existing list. This fn. manages the insertion of these lists and any others that might arise.
Reimplemented from OpFreeHand. Definition at line 1321 of file opdrbrsh.cpp. 01322 { 01323 ERROR2IF(pNewPath == NULL, FALSE, "pNewPath is NULL in OpDrawBrush::EditBrushLists"); 01324 01325 BOOL ok = TRUE; 01326 // if we have a timestamp list then attempt to insert it 01327 if (m_pTimeStampList != NULL) 01328 ok = EditTimeStampList(pNewPath, FirstChangedIndex, NumElements); 01329 // edit the pressure list (if there is one) 01330 if (ok) 01331 ok = EditPressureList(pNewPath, FirstChangedIndex, NumElements); 01332 01333 return ok; 01334 }
|
|
Definition at line 1455 of file opdrbrsh.cpp. 01456 { 01457 ERROR2IF(pNewPath == NULL, FALSE, "pNewPath is NULL in OpDrawBrush::EditPressureList"); 01458 01459 /* First up, find the nearest applied brush attribute. If there isn't one or 01460 it has no pressure list then we don't have to bother with all this */ 01461 AttrBrushType* pAttrBrush = NULL; 01462 01463 pAttrBrush = EndPath->GetAppliedBrushAttribute(); 01464 if (pAttrBrush == NULL) 01465 return TRUE; 01466 01467 // if we are attempting to edit an existing brush that does not have an existing pressure 01468 // cache then leave now 01469 if (!pAttrBrush->ContainsPressureCache()) 01470 return TRUE; 01471 01472 // most of the action takes place in the attribute value so get that also 01473 BrushAttrValue* pVal = (BrushAttrValue*)pAttrBrush->GetAttributeValue(); 01474 if (pVal == NULL) 01475 return TRUE; 01476 01477 /* next, record the following distances: 01478 - original path length; 01479 - distance to first changed point; 01480 - distance to last changed point; 01481 */ 01482 01483 // double OriginalLength = EndPath->InkPath.GetPathLength(); 01484 MILLIPOINT DistToFirstPoint = -1; 01485 MILLIPOINT DistToLastPoint = -1; 01486 DocCoord* pCoords = EndPath->InkPath.GetCoordArray(); 01487 01488 DocCoord FirstChangedPoint; 01489 DocCoord LastChangedPoint; 01490 01491 if (pCoords == NULL) 01492 return FALSE; 01493 if (FirstChangedIndex + NumElements > EndPath->InkPath.GetNumCoords()) 01494 { 01495 ERROR3("Illegal number of coordinates"); 01496 return FALSE; 01497 } 01498 01499 // get the coordinates from the array 01500 FirstChangedPoint = pCoords[FirstChangedIndex]; 01501 LastChangedPoint = pCoords[FirstChangedIndex + NumElements]; 01502 01503 EndPath->InkPath.GetDistanceToPoint(FirstChangedPoint, &DistToFirstPoint); 01504 EndPath->InkPath.GetDistanceToPoint(LastChangedPoint, &DistToLastPoint); 01505 01506 // Now find the indices into the pressure list that correspond to those distances 01507 INT32 StartPressureIndex = pVal->GetPressureListIndexAtDistance(DistToFirstPoint); 01508 if (StartPressureIndex == -1) 01509 { 01510 ERROR3("StartPressureIndex is -1 in OpDrawBrush::EditPressureList"); 01511 return FALSE; 01512 } 01513 01514 INT32 EndPressureIndex = pVal->GetPressureListIndexAtDistance(DistToLastPoint); 01515 if (EndPressureIndex == -1 || EndPressureIndex <= StartPressureIndex) 01516 { 01517 ERROR3("EndPressureIndex is invalid in OpDrawBrush::EditPressureList"); 01518 return FALSE; 01519 } 01520 UINT32 NumObjects = EndPressureIndex - StartPressureIndex; 01521 // MILLIPOINT Spacing = pAttrBrush->GetSpacing(); 01522 UINT32 NumIndexes = 0; //Spacing / MIN_BRUSH_SPACING; 01523 StartPressureIndex -= NumIndexes; 01524 if (StartPressureIndex < 0) 01525 StartPressureIndex = 0; 01526 01527 // if (m_pPressureList == NULL) 01528 // m_pPressureList = GeneratePressureList(pAttrBrush, StartPressureIndex, EndPressureIndex, 01529 // (MILLIPOINT)pNewPath->InkPath.GetPathLength()); 01530 01531 // if (m_pPressureList == NULL) // did it fail, of so we must quit 01532 // return FALSE; 01533 /* now get the pressure points list and ask the attribute to clear all the points 01534 between the edited distances*/ 01535 pAttrBrush->ClearCachedRect(); 01536 DocRect Rect = pAttrBrush->GetAttrBoundingRect(EndPath); 01537 Spread* pSpread = Document::GetSelectedSpread(); 01538 01539 if (!DoInvalidateRegion(pSpread, Rect)) 01540 return FALSE; 01541 // Invalidate it as it was 01542 if (!DoInvalidateNodeRegion(EndPath, TRUE)) 01543 return FALSE; 01544 01545 // now make a removepoints action 01546 RemovePressurePointsAction* pAction; 01547 01548 if (m_pPressureSampler) 01549 { 01550 // only remove items if m_pPressureSampler is non-NULL! 01551 if (RemovePressurePointsAction::Init(this, &UndoActions, pAttrBrush, (UINT32)StartPressureIndex, NumObjects, NULL, &pAction) == AC_FAIL) 01552 return FALSE; 01553 } 01554 01555 // now insert our new points into the attribute 01556 AddPressurePointsAction* pAddAction; 01557 01558 if (m_pPressureSampler) 01559 { 01560 // find out how many points we're inserting 01561 UINT32 NumAddPoints = m_pPressureSampler->GetNumItems(); 01562 01563 if (AddPressurePointsAction::Init(this, &UndoActions, pAttrBrush, m_pPressureSampler, (UINT32)StartPressureIndex, NumAddPoints, &pAddAction) == AC_FAIL) 01564 return FALSE; 01565 } 01566 else 01567 { 01568 // YUCK, this means that somebodies trying to 'glue' a non-pressure sensititive path in with the pressure 01569 // sensitive one .... 01570 01571 // I think the most sensible thing to do is just to leave current pressure data intact. Otherwise we get 01572 // bogged down in bodging default pressure values (which might not be what the user wants/go wrong), and trouble 01573 // with undo/redo by replacing these values on the fly. 01574 } 01575 01576 m_pPressureSampler = NULL; // otherwise we end up deleting it whilst we still need it 01577 // invalidate the whole thing 01578 pAttrBrush->ClearCachedRect(); 01579 Rect = pAttrBrush->GetAttrBoundingRect(EndPath); 01580 EndPath->ReleaseCached(); 01581 01582 if (!DoInvalidateRegion(pSpread, Rect)) 01583 return FALSE; 01584 01585 return TRUE; 01586 }
|
|
When a path is edited that has a timestamping brush applied to it we those points are stored in a list that is generated when the path is drawn. If we subsequently want to edit that path we have to insert or remove points from that list. This function works out what points should be inserted or removed, and performs that action on the applied brush. This is made slightly easier.
Definition at line 1356 of file opdrbrsh.cpp. 01357 { 01358 ERROR2IF(pNewPath == NULL, FALSE, "pNewPath is NULL in OpDrawBrush::EditTimeStampingBrush"); 01359 01360 // if we're not timestamping then just return now 01361 if (m_pTimeStampList == NULL) 01362 return TRUE; 01363 01364 /* First up, find the nearest applied brush attribute. If there isn't one or 01365 it is not timestamping then we don't have to bother with all this */ 01366 AttrBrushType* pAttrBrush = NULL; 01367 01368 pAttrBrush = EndPath->GetAppliedBrushAttribute(); 01369 if (pAttrBrush == NULL) 01370 return TRUE; 01371 01372 // if we are attempting to edit an existing brush that does not use the timestamping 01373 // system then also give up 01374 if (!pAttrBrush->IsTimeStamping()) 01375 return TRUE; 01376 01377 // most of the action takes place in the attribute value so get that also 01378 BrushAttrValue* pVal = (BrushAttrValue*)pAttrBrush->GetAttributeValue(); 01379 if (pVal == NULL) 01380 return TRUE; 01381 01382 /* next, record the following distances: 01383 - original path length; 01384 - distance to first changed point; 01385 - distance to last changed point; 01386 */ 01387 01388 // double OriginalLength = EndPath->InkPath.GetPathLength(); 01389 MILLIPOINT DistToFirstPoint = -1; 01390 MILLIPOINT DistToLastPoint = -1; 01391 DocCoord* pCoords = EndPath->InkPath.GetCoordArray(); 01392 01393 DocCoord FirstChangedPoint; 01394 DocCoord LastChangedPoint; 01395 01396 if (pCoords == NULL) 01397 return FALSE; 01398 if (FirstChangedIndex + NumElements > EndPath->InkPath.GetNumCoords()) 01399 { 01400 ERROR3("Illegal number of coordinates"); 01401 return FALSE; 01402 } 01403 01404 // get the coordinates from the array 01405 FirstChangedPoint = pCoords[FirstChangedIndex]; 01406 LastChangedPoint = pCoords[FirstChangedIndex + NumElements]; 01407 01408 EndPath->InkPath.GetDistanceToPoint(FirstChangedPoint, &DistToFirstPoint); 01409 EndPath->InkPath.GetDistanceToPoint(LastChangedPoint, &DistToLastPoint); 01410 01411 01412 /* now get the timestamping points list and ask the attribute to clear all the points 01413 between the edited distances*/ 01414 01415 // first make a removepoints action 01416 RemoveTimeStampPointsAction* pAction; 01417 01418 if (RemoveTimeStampPointsAction::Init(this, &UndoActions, pAttrBrush, DistToFirstPoint, DistToLastPoint, NULL, &pAction) == AC_FAIL) 01419 return FALSE; 01420 01421 // now insert our new points into the attribute 01422 AddTimeStampPointsAction* pAddAction; 01423 01424 // find out the distance of the new points to be inserted 01425 TimeStampBrushPoint StartPoint = m_pTimeStampList->front(); 01426 TimeStampBrushPoint EndPoint = m_pTimeStampList->back(); 01427 01428 INT32 NewPointsDistance = EndPoint.m_Distance - StartPoint.m_Distance; 01429 01430 if (AddTimeStampPointsAction::Init(this, &UndoActions, pAttrBrush, m_pTimeStampList, DistToFirstPoint, DistToFirstPoint + NewPointsDistance, 0, &pAddAction) == AC_FAIL) 01431 return FALSE; 01432 01433 // invalidate the whole thing3 01434 if (!DoInvalidateNodeRegion(EndPath, TRUE)) 01435 return FALSE; 01436 01437 return TRUE; 01438 }
|
|
This function deals with the case when we wish to edit a brush with pressure data but we do not generate a pressure list during the edit for some reason. In this case we must create a new pressure list and fill it with values based upon the values in the existing brush pressure list.
NewPathLength - the length of the path that we wish to insert
Definition at line 1777 of file opdrbrsh.cpp. 01779 { 01780 if (pAttrBrush == NULL) 01781 { 01782 ERROR3("Entry pointer is NULL in OpDrawBrush::GeneratePressureList"); 01783 return NULL; 01784 } 01785 if (NewPathLength < 0 ) 01786 { 01787 ERROR3("Negative path length in OpDrawBrush::GeneratePressureList"); 01788 return NULL; 01789 } 01790 01791 // just make sure we actually have a pressure list 01792 CDistanceSampler* pSampler = pAttrBrush->GetPressureCache(); 01793 if (pSampler == NULL) 01794 { 01795 ERROR3("Why are you trying to do a pressure edit when this brush doesn't use pressure!??"); 01796 return NULL; 01797 } 01798 01799 /* there are two possibilities here: 01800 1) we are inserting in the middle, in which case get the two insert values and interpolate, or 01801 2) we are inserting at the beginning or end, in which case just repeat the first/last value 01802 */ 01803 // get the pressure values at StartIndex and EndIndex 01804 INT32 StartIndex = -1; 01805 INT32 EndIndex = -1; 01806 01807 // case 1 01808 if (Start != -1 && End != -1) 01809 { 01810 StartIndex = pSampler->GetInternalIndexFromDistance(Start); 01811 EndIndex = pSampler->GetInternalIndexFromDistance(End); 01812 } 01813 01814 // case 2 01815 else if (Start == -1) 01816 StartIndex = EndIndex = 0; 01817 else if (End == -1) 01818 StartIndex = EndIndex = pSampler->GetInternalIndexFromDistance(Start); 01819 01820 // just make sure we got valid indexes 01821 if (StartIndex == -1 || EndIndex == -1) 01822 { 01823 ERROR3("Start or end index off the end of the array in OpDrawBrush::GeneratePressureData"); 01824 return NULL; 01825 } 01826 01827 // we are using internal indexes so set the sample rate to 1.0 01828 pSampler->SetRetrievalSampleRate(1.0); 01829 01830 // get the starting pressure, make it a double as we're going to be doing lots of fp ops. 01831 CSampleItem StartItem; 01832 BOOL ok = pSampler->GetAt(StartIndex, &StartItem); 01833 double StartNewValue = (double)StartItem.m_Pressure; 01834 01835 // same for the end 01836 CSampleItem EndItem; 01837 if (ok) ok = pSampler->GetAt(EndIndex, &EndItem); 01838 double EndNewValue = (double)EndItem.m_Pressure; 01839 01840 // now we have our start and end values, we also need to know how many items to make 01841 // Given that we sample at the rate of MIN_BRUSH_SPACING this is fairly straightforward 01842 UINT32 NumObjects = NewPathLength / MIN_BRUSH_SPACING; 01843 01844 // find out by how much we must increase/decrease by each time 01845 double Incr = (EndNewValue - StartNewValue)/NumObjects; 01846 01847 // lets make our new sampler here 01848 CDistanceSampler* pNewSampler = new CDistanceSampler; 01849 if (pNewSampler == NULL) 01850 return NULL; 01851 01852 if (!pNewSampler->InitialiseData(NumObjects)) 01853 { 01854 delete pNewSampler; 01855 return NULL; 01856 } 01857 01858 // now just loop through, adding items to the sampler 01859 CSampleItem NewItem; 01860 NewItem.m_Pressure = (UINT32)StartNewValue; 01861 ok = pNewSampler->SetAt(0, NewItem); 01862 while (NumObjects > 0 && ok) 01863 { 01864 NewItem.m_Pressure += (UINT32)Incr; 01865 ok = pNewSampler->SetNext(NewItem); 01866 NumObjects--; 01867 } 01868 return pNewSampler; 01869 }
|
|
In order to determine whether we have to tell the brush to scale to a new line width or not.
Definition at line 2329 of file opdrbrsh.cpp. 02330 { 02331 MILLIPOINT Retval = -1; 02332 02333 Document* pDoc = Document::GetCurrent(); 02334 if (pDoc == NULL) 02335 { 02336 ERROR3("No document"); 02337 return Retval; 02338 } 02339 02340 AttributeManager* pAttrMgr = &(pDoc->GetAttributeMgr()); 02341 if (pAttrMgr == NULL) 02342 { 02343 ERROR3("No attribute manager"); 02344 return Retval; 02345 } 02346 02347 AttrLineWidth* pAttr = (AttrLineWidth*)(pAttrMgr->GetCurrentAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), CC_RUNTIME_CLASS(AttrLineWidth))); 02348 02349 if (pAttr != NULL) 02350 { 02351 AttrLineWidth* pDefault = (AttrLineWidth*)(AttributeManager::GetDefaultAttribute(ATTR_LINEWIDTH)); 02352 if (pDefault == NULL) 02353 { 02354 ERROR3("Unable to get default line width, theres no way this can happen Jim!"); 02355 return Retval; 02356 } 02357 MILLIPOINT CurrentLineWidth = pAttr->Value.LineWidth; 02358 MILLIPOINT DefaultLineWidth = pDefault->Value.LineWidth; 02359 02360 if (CurrentLineWidth != DefaultLineWidth -1) // for some reason the default is 501 02361 Retval = CurrentLineWidth; 02362 02363 // it turns out that GetDefault returns a copy of the default, so we must delete it here 02364 delete pDefault; 02365 } 02366 return Retval; 02367 }
|
|
Find out the state of the operation at the specific time.
Reimplemented from OpFreeHand. Definition at line 1910 of file opdrbrsh.cpp. 01911 { 01912 OpState Blobby; 01913 01914 return Blobby; 01915 }
|
|
To create a new pathprocessorbrush and copy all the data from the brush definitino found using BrushIndex.
Definition at line 2095 of file opdrbrsh.cpp. 02096 { 02097 // find the brush definition corresponding to the Handle 02098 Document* pDoc = Document::GetCurrent(); 02099 ERROR2IF(pDoc == NULL, FALSE, "er, wheres the document gone"); 02100 BrushComponent* pBrushComp = (BrushComponent*)pDoc->GetDocComponent((CC_RUNTIME_CLASS(BrushComponent))); 02101 ERROR2IF(pBrushComp == NULL, FALSE, "No brush component"); 02102 BrushDefinition* pBrushDef = pBrushComp->FindBrushDefinition(Handle); 02103 ERROR2IF(pBrushDef == NULL, FALSE, "Couldn't find brush definition"); 02104 02105 // ask the definition to prepare for rendering 02106 if (!pBrushDef->StartRender()) 02107 return FALSE; 02108 02109 // check we haven't already allocated this member 02110 if (m_pPathProcBrush != NULL) 02111 { 02112 delete m_pPathProcBrush; 02113 m_pPathProcBrush = NULL; 02114 } 02115 // allocate the new path processor 02116 m_pPathProcBrush = new PathProcessorBrush; 02117 if (m_pPathProcBrush == NULL) 02118 { 02119 InformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK)); 02120 return FALSE; 02121 } 02122 02123 // everything is ok so far, so transfer the data 02124 m_pPathProcBrush->SetBrushDefinition(Handle); 02125 pBrushDef->CopyDataToProcessor(m_pPathProcBrush); 02126 02127 PORTNOTE("other", "Removed m_pGRenderBrush support") 02128 #ifndef EXCLUDE_FROM_XARALX 02129 // if our screen depth is < 24 BPP then we need to ensure that the scaling and offset 02130 // variations are turned off. 02131 if (m_pGRenderBrush->GetScreenDepth() < 24) 02132 { 02133 m_pPathProcBrush->SetBrushScalingIncr(1); 02134 m_pPathProcBrush->SetBrushScalingIncrConst(0); 02135 // m_pPathProcBrush->SetScalingMaxPressure(0); 02136 m_pPathProcBrush->SetPathOffsetIncrConst(0); 02137 m_pPathProcBrush->SetPathOffsetIncrProp(1); 02138 // m_pPathProcBrush->SetScalingMaxRand(0); 02139 } 02140 #endif 02141 02142 // if we're not using pressure then turn it off 02143 if (!AddPressureToPath) 02144 { 02145 m_pPathProcBrush->SetScalingMaxPressure(0); 02146 m_pPathProcBrush->SetTransparencyPressure(0); 02147 } 02148 02149 // do we need to scale to line width 02150 MILLIPOINT LineWidth = GetCurrentLineWidthIfNotDefault(); 02151 if (LineWidth != -1) 02152 { 02153 if (LineWidth < 501) // make sure we don't go too small 02154 LineWidth = 501; 02155 m_pPathProcBrush->ScaleToValue(LineWidth, !AddPressureToPath); 02156 } 02157 02158 m_BrushScaling = m_pPathProcBrush->GetBrushScaling(); 02159 02160 m_pPathProcBrush->Reset(); 02161 m_pPathProcBrush->SetCalculateBoundingBox(TRUE); // we want the bounding box 02162 02163 // set up the arrays to hold cached transformation data 02164 if (!m_pPathProcBrush->PrepareForRenderingLoop(m_pPathProcBrush->GetNumBrushObjects())) 02165 { 02166 delete m_pPathProcBrush; 02167 return FALSE; 02168 } 02169 02170 02171 // if we are starting at some point along the path then advance our data to what it should be 02172 if (Distance) 02173 m_pPathProcBrush->AdvanceBrushToDistance(Distance); 02174 02175 m_LastInkObjectRendered = m_pPathProcBrush->GetLastObject(); 02176 02177 // finally if this brush does not require pressure then turn it off 02178 if (!pBrushDef->UsesPressure()) 02179 AddPressureToPath = FALSE; 02180 02181 //#ifdef NEWFASTBRUSHES 02182 m_pBrushDefinition = m_pPathProcBrush->GetOurBrushDefinition (); // store this off here 02183 // old RenderBrushAtPoint would grab this for each iteration! 02184 //#endif 02185 02186 return TRUE; 02187 }
|
|
To allocate the pressure array, if we need it.
Definition at line 2202 of file opdrbrsh.cpp. 02203 { 02204 // do we actually need to do this? 02205 if (!AddPressureToPath) 02206 return TRUE; 02207 /* 02208 m_pPressureVals = new PressureArray; 02209 if (m_pPressureVals == NULL) 02210 return FALSE; 02211 02212 // make it pretty big so we don't have to keep reallocating 02213 m_pPressureVals->SetSize(200, 10); 02214 */ 02215 02216 m_pPressureList = new PressureList; 02217 if (m_pPressureList == NULL) 02218 return FALSE; 02219 02220 return TRUE; 02221 }
|
|
to create a new CSampleData object and assign it to our pointer for sampling pressure
Definition at line 2287 of file opdrbrsh.cpp. 02288 { 02289 if (m_pPressureSampler != NULL) 02290 { 02291 delete m_pPressureSampler; 02292 m_pPressureSampler = NULL; 02293 } 02294 if (!AddPressureToPath) 02295 return TRUE; 02296 02297 m_pPressureSampler = new CDistanceSampler; 02298 02299 if (m_pPressureSampler == NULL) 02300 return FALSE; 02301 02302 // set the max pressure value from our device 02303 CCPen *pPen = pApp->GetPressurePen(); 02304 UINT32 MaxPressure = MAXPRESSURE; 02305 if (pPen != NULL) 02306 MaxPressure = pPen->GetPressureMax(); 02307 02308 m_pPressureSampler->SetMaxPressure(MaxPressure); 02309 02310 return m_pPressureSampler->InitialiseData(5000); 02311 02312 }
|
|
To create a new path processor object.
Definition at line 2063 of file opdrbrsh.cpp. 02064 { 02065 if (m_pProcPathDistance != NULL) 02066 { 02067 delete m_pProcPathDistance; 02068 m_pProcPathDistance = NULL; 02069 } 02070 02071 m_pProcPathDistance = new ProcessPathDistance(750/2); 02072 if (m_pProcPathDistance == NULL) 02073 { 02074 InformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK)); 02075 return FALSE; 02076 } 02077 return TRUE; 02078 }
|
|
to create a new timestamp object list and assign it to our member
Definition at line 2235 of file opdrbrsh.cpp. 02236 { 02237 // if we've already got one then delete it 02238 if (m_pTimeStampList != NULL) 02239 { 02240 delete m_pTimeStampList; 02241 m_pTimeStampList = NULL; 02242 } 02243 m_pTimeStampList = new TimeStampList; 02244 if (m_pTimeStampList == NULL) 02245 return FALSE; 02246 02247 return TRUE; 02248 }
|
|
Reimplemented from OpFreeHand. Definition at line 174 of file opdrbrsh.h. 00174 { return TRUE;}
|
|
EORs the whole path onto the screen a segment at a time. It needs to do it a segment at a time as that is how it is drawn as the path is created. This has to redraw it identically or there will be bits of EORed stuff left all over the place.
Reimplemented from OpFreeHand. Definition at line 168 of file opdrbrsh.h.
|
|
Renders as many steps in the brush as possible in the time available. The reason for having the code here rather than in the processor is twofold: 1) I feel the property of rendering for a certain timeslice is a property of the Op rather than the PPB; 2) In order to make use of the caching ProcessPathDistance, which belongs to the Op rather than the PPB.
Definition at line 739 of file opdrbrsh.cpp. 00740 { 00741 if ( (m_pProcPathDistance == NULL) || (m_pPathProcBrush == NULL) 00742 || (m_pGRenderBrush == NULL) || (TrackData == NULL)) 00743 { 00744 ERROR3("One or more members are NULL"); 00745 return; 00746 } 00747 00748 MonotonicTime timer; 00749 00750 // declare locals outside the loop 00751 DocCoord Point; 00752 double Angle; 00753 UINT32 Pressure = 0; 00754 CSampleItem TheItem; 00755 BrushPointInfo PathPoint; 00756 00757 // records how far along the path we are 00758 MILLIPOINT DistanceToGetPoint = m_LastDistanceRendered; 00759 00760 // spacing records the spacing between objects (duh) 00761 // this little hack is here to make sure our first object is a few millipoints in from the 00762 // start of the path, otherwise we will always have a tangetial angle of zero 00763 00764 MILLIPOINT Spacing = m_LastSpacing; 00765 if (!m_bFirstPointRendered) 00766 { 00767 Spacing = m_FirstSpacing; 00768 if (m_pPressureSampler != NULL) 00769 { 00770 if (m_pPressureSampler->GetAt(0, &TheItem)) 00771 Pressure = TheItem.m_Pressure; 00772 else 00773 Pressure =127; 00774 m_pPathProcBrush->SetCurrentPressure(Pressure); 00775 } 00776 } 00777 00778 00779 BOOL Found; 00780 //m_BrushScaling = m_pPathProcBrush->GetLastScaling(); 00781 #ifdef SCALESPACING 00782 double ActualSpacing = (double)Spacing * m_BrushScaling; 00783 #else 00784 double ActualSpacing = (double)Spacing * m_pPathProcBrush->GetBrushScaling(); 00785 #endif 00786 // if (TrackData->GetNumCoords() > 2) 00787 // RenderLine(m_pGRenderBrush, TrackData, TrackData->GetNumCoords() - 1); 00788 UINT32 Dummy = 0; 00789 // render objects at m_BrushSpacing intervals starting at the last point rendered 00790 while (m_DistanceSinceLastObject >= (MILLIPOINT)ActualSpacing) 00791 { 00792 // the path processor needs to set up some variables to deal with offsets 00793 // before we come to actually render 00794 m_pPathProcBrush->SetNextOffsetType(); 00795 00796 //TRACEUSER( "Diccon", _T("Scaled Spacing = %f\n"), double(Spacing * m_BrushScaling)); 00797 DistanceToGetPoint += (MILLIPOINT)ActualSpacing; 00798 00799 // get the point from the nodebrushpath 00800 m_pProcPathDistance->GetCoordAndTangentWithCache(&Point, &Angle, &Found, 00801 DistanceToGetPoint, TrackData, &Dummy); 00802 if (Found) 00803 { 00804 00805 //TRACEUSER( "Diccon", _T("Point found at: %d, %d\n"), Point.x, Point.y); 00806 PathPoint.m_Point = Point; 00807 PathPoint.m_Tangent = Angle; 00808 PathPoint.m_Pressure = Dummy; 00809 00810 // pass to the pathprocessor which does the work of rendering, but not if our object is zero-sized 00811 PORTNOTE("other", "Removed m_pRenderGBrush"); 00812 #ifndef EXCLUDE_FROM_XARALX 00813 if (m_BrushScaling > 0) 00814 { 00815 m_pPathProcBrush->RenderBrushAtPoint(Point, Angle, m_LastInkObjectRendered, m_NumBrushObjects, 00816 m_pGRenderBrush, NULL, TRUE, m_pBrushDefinition); 00817 } 00818 #endif 00819 // get the next pressure value 00820 if (m_pPressureSampler != NULL && m_bFirstPointRendered) 00821 { 00822 m_pPressureSampler->SetSampleRateFromSpacing((MILLIPOINT)ActualSpacing); 00823 00824 if (m_pPressureSampler->GetNext(&TheItem)) 00825 Pressure = TheItem.m_Pressure; 00826 else 00827 Pressure = 127; 00828 m_pPathProcBrush->SetCurrentPressure(Pressure); 00829 //TRACEUSER( "Diccon", _T("SETTING PRESSURE %d = %d\n"), m_NumBrushObjects, Pressure); 00830 } 00831 00832 PORTNOTE("other", "Removed m_pRenderGBrush"); 00833 #ifndef EXCLUDE_FROM_XARALX 00834 // get it to the screen ASAP 00835 m_pGRenderBrush->DrawToScreenNow(); 00836 #endif 00837 00838 m_DistanceSinceLastObject -= (MILLIPOINT)(ActualSpacing); //m_BrushSpacing; 00839 m_LastDistanceRendered = DistanceToGetPoint; 00840 00841 // get the next spacing (spacing only changes once we have drawn an object) 00842 Spacing = m_pPathProcBrush->GetNextSpacing(); 00843 m_BrushScaling = m_pPathProcBrush->GetLastScaling(); 00844 #ifdef SCALESPACING 00845 ActualSpacing = Spacing * m_BrushScaling; 00846 #else 00847 ActualSpacing = (double)Spacing * m_pPathProcBrush->GetBrushScaling(); //m_BrushSpacing; //Spacing * m_BrushScaling; 00848 #endif 00849 // switch our alternating offset 00850 m_pPathProcBrush->SwitchAlternateValue(); 00851 00852 #ifdef OPBRUSHPOINTSCACHE 00853 // stash this point in the cache 00854 if (m_pPointsCache != NULL) 00855 (*m_pPointsCache)[DistanceToGetPoint]=PathPoint; 00856 #endif 00857 00858 // get the next object in the sequence 00859 m_LastInkObjectRendered = m_pPathProcBrush->GetNextInkObject(m_LastInkObjectRendered, 00860 m_NumInkObjects); 00861 00862 m_pPathProcBrush->DecideWhetherToUseActualScaling(m_LastInkObjectRendered); 00863 // increment our counter 00864 m_NumBrushObjects++; 00865 m_bFirstPointRendered = TRUE; 00866 // TRACEUSER( "Diccon", _T("Pressure at end of loop = %d\n"), Pressure); 00867 } 00868 00869 // if we hit the time constraint then just get out now 00870 if (timer.Elapsed(UINT32(TimeSlice * 1000.0))) 00871 break; 00872 } 00873 // TRACEUSER( "Diccon", _T("Exit RenderStepsForTime\n")); 00874 // remember the spacing for next time 00875 m_LastSpacing = Spacing; 00876 }
|
|
To be used in timestamp mode, obviously. This fn. determines whether or not enough time has elapsed for us to render a point. If so we render a point and cache it, updating the necessary members.
Definition at line 892 of file opdrbrsh.cpp. 00893 { 00894 if (m_TimeStamp <=0) 00895 { 00896 ERROR3("Invalid timestamp value"); 00897 return; 00898 } 00899 00900 if (m_Timer.Elapsed((UINT32)(m_TimeStamp * 1000.0))) 00901 { 00902 m_Timer.Sample(); 00903 00904 // find out how far along the path we are 00905 MILLIPOINT DistanceAlongPath = m_LastDistanceRendered + m_DistanceSinceLastObject; 00906 00907 DocCoord Point; 00908 double Angle = 0; 00909 BOOL Found = FALSE; 00910 // get the point from the path 00911 m_pProcPathDistance->GetCoordAndTangentWithCache(&Point, &Angle, &Found, 00912 DistanceAlongPath, TrackData); 00913 00914 if (Found) 00915 { 00916 TimeStampBrushPoint TSP(Point, Angle, DistanceAlongPath); 00917 00918 // get the next object in the sequence 00919 m_LastInkObjectRendered = m_pPathProcBrush->GetNextInkObject(m_LastInkObjectRendered, 00920 m_NumInkObjects); 00921 00922 PORTNOTE("other", "Removed m_pRenderGBrush"); 00923 #ifndef EXCLUDE_FROM_XARALX 00924 // pass to the pathprocessor which does the work of rendering 00925 if (m_pGRenderBrush != NULL) 00926 { 00927 m_pPathProcBrush->RenderBrushAtPoint(Point, Angle, m_LastInkObjectRendered++, 1, 00928 m_pGRenderBrush, NULL, TRUE); 00929 // get it to the screen ASAP 00930 m_pGRenderBrush->DrawToScreenNow(); 00931 TRACEUSER( "Diccon", _T("OpDrawBrush Rendered TimeStamp")); 00932 } 00933 #endif 00934 // update our member variables 00935 m_DistanceSinceLastObject = 0; 00936 m_LastDistanceRendered = DistanceAlongPath; 00937 00938 // cache the point 00939 if (m_pTimeStampList != NULL) 00940 m_pTimeStampList->push_back(TSP); 00941 } 00942 } 00943 }
|
|
Initialises all our member variables to something sensible.
Definition at line 248 of file opdrbrsh.cpp. 00249 { 00250 // Set all our cursors to NULL to start with 00251 pFreeHandCursor = NULL; 00252 pJoinCursor = NULL; 00253 pStraightCursor = NULL; 00254 pRubOutCursor = NULL; 00255 pModifyCursor = NULL; 00256 00257 // Set other default values 00258 TrackData = NULL; 00259 StartSpread = NULL; 00260 PreviousSpread = NULL; 00261 Smoothness = 512; 00262 LineSegmentCount = 0; 00263 CanLineJoin = FALSE; 00264 IsStraightLineMode = FALSE; 00265 AddPressureToPath = FALSE; 00266 FreeHandPressure = 0; 00267 00268 // The paths that we are joined to, or NULL if we are joined to none 00269 pJoinInfo = NULL; 00270 StartPath = NULL; 00271 EndPath = NULL; 00272 CloseTo = 0; 00273 Mu = 0.0; 00274 IsEndNearEndpoint = FALSE; 00275 CurrentCursorID = 0; 00276 00277 m_pGRenderBrush = NULL; 00278 m_pPathProcBrush = NULL; 00279 //#ifdef NEWFASTBRUSHES 00280 m_pBrushDefinition = NULL; 00281 mustClearStatusBar = TRUE; 00282 pApp = GetApplication (); 00283 ERROR3IF (!pApp, "Could not find the application!"); 00284 //#endif 00285 m_pProcPathDistance = NULL; 00286 m_BrushScaling = 1.0; 00287 00288 #ifdef OPBRUSHPOINTSCACHE 00289 m_pPointsCache = NULL; 00290 #endif 00291 00292 m_pTimeStampList = NULL; 00293 m_TimeStamp = 0; 00294 m_LastTimeStamp = -1; 00295 00296 m_pPressureList = NULL; 00297 00298 m_LastPathIndexRendered = 1; 00299 00300 m_FirstSpacing = 25; 00301 00302 m_pPressureSampler = NULL; 00303 m_NumPressureVals = 0; 00304 00305 00306 }
|
|
As above, the base class version does nothing.
Reimplemented from OpFreeHand. Definition at line 1726 of file opdrbrsh.cpp. 01727 { 01728 return ApplyRetroSmoother(pNewNodePath, 85); 01729 }
|
|
Calls the attribute function to reverse our pressure list.
Reimplemented from OpFreeHand. Definition at line 1744 of file opdrbrsh.cpp. 01745 { 01746 if (m_pPressureSampler == NULL) 01747 return FALSE; 01748 01749 return m_pPressureSampler->ReverseData(); 01750 }
|
|
Overridden version for the brush, basically we do not offer any of the keyboard options so we wish to keep the status line blank during brush operations.
Reimplemented from OpFreeHand. Definition at line 1986 of file opdrbrsh.cpp. 01987 { 01988 // Now, if FlipCursor = TRUE, we flip it! 01989 static Cursor* WhichCursor; 01990 WhichCursor = NULL; 01991 01992 switch (CurType) 01993 { 01994 case NORMAL_CURSOR: 01995 WhichCursor = pFreeHandCursor; 01996 break; 01997 01998 case JOIN_CURSOR: 01999 WhichCursor = pJoinCursor; 02000 break; 02001 02002 case MODIFY_CURSOR: 02003 WhichCursor = pModifyCursor; 02004 break; 02005 02006 default: 02007 break; 02008 } 02009 02010 if (mustClearStatusBar) // got to execute the following at least once so that we clear the status bar .... 02011 { 02012 String_256 StatusMsg(""); 02013 // Change Status bar message and the cursor 02014 pApp->UpdateStatusBarText(&StatusMsg); 02015 mustClearStatusBar = FALSE; 02016 } 02017 02018 if (WhichCursor != MyCurrentCursor) 02019 { 02020 String_256 StatusMsg(_T("")); 02021 02022 switch (CurType) 02023 { 02024 case NORMAL_CURSOR: 02025 break; 02026 02027 case JOIN_CURSOR: 02028 StatusMsg.Load(_R(IDS_FREEHANDDRAGJOIN)); 02029 break; 02030 02031 case MODIFY_CURSOR: 02032 StatusMsg.Load(_R(IDS_FREEHANDMODIFY)); 02033 break; 02034 02035 default: 02036 break; 02037 02038 } 02039 02040 // Change Status bar message and the cursor 02041 pApp->UpdateStatusBarText(&StatusMsg); 02042 02043 // set this cursor as the current cursor and immediately display it 02044 CursorStack::GSetTop(WhichCursor, CurrentCursorID); 02045 02046 // remember this is our current cursor 02047 MyCurrentCursor = WhichCursor; 02048 } 02049 }
|
|
to set the timestamp member
Definition at line 2264 of file opdrbrsh.cpp. 02265 { 02266 if (TimeStamp < MIN_TIMESTAMP || TimeStamp > MAX_TIMESTAMP) 02267 return FALSE; 02268 02269 m_TimeStamp = TimeStamp; 02270 return TRUE; 02271 }
|
|
Joins a Simple path with the new freehand path and builds all the undo that is needed in the process.
Reimplemented from OpFreeHand. Definition at line 1605 of file opdrbrsh.cpp. 01606 { 01607 if (pInsertedNode == NULL || pNewPath == NULL) 01608 { 01609 ERROR3("Null inputs to OpDrawBrush::SimpleJoinBrush"); 01610 return FALSE; 01611 } 01612 01613 // first check to see if the edited path has a brush applied to it, 01614 // if it doesn't then we'll leave 01615 NodeAttribute* pAttr; 01616 AttrBrushType* pAttrBrush; 01617 pInsertedNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType), &pAttr); 01618 if (pAttr == NULL) 01619 return TRUE; 01620 01621 pAttrBrush = (AttrBrushType*)pAttr; 01622 // if our brush has a 'no brush' handle then likewise 01623 if (pAttrBrush->GetBrushHandle() == BrushHandle_NoBrush) 01624 return TRUE; 01625 01626 // if our brush is not either timestamping or has a pressure list then we will leave aswell 01627 CDistanceSampler* pPressData = pAttrBrush->GetPressureCache(); 01628 if (pPressData == NULL) 01629 return TRUE; 01630 01631 // Do we have a pressure cache?? 01632 if (m_pPressureSampler == NULL) 01633 return TRUE; 01634 01635 // find out what type of join we have 01636 SimpleJoinType JoinType = GetSimpleJoinType(pNewPath, &(pInsertedNode->InkPath)); 01637 if (JoinType == JOINTYPE_NONE) 01638 { 01639 ERROR3("No join type in OpDrawBrush::SimpleJoinBrush"); 01640 return TRUE; 01641 } 01642 01643 // we need to know the distance along the original path where we want to insert the 01644 // new points. As this is a simple join it will either be at the beginning or the end. 01645 // we also need to know the distance to the end of the new points, as this is required 01646 // for the undo. 01647 MILLIPOINT NewPathLength = (MILLIPOINT)pNewPath->GetPathLength(); 01648 MILLIPOINT OldPathLength = -1; 01649 if (StartPath != NULL) 01650 { 01651 OldPathLength = (MILLIPOINT)StartPath->InkPath.GetPathLength(); 01652 } 01653 else 01654 { 01655 if (EndPath != NULL) 01656 OldPathLength = (MILLIPOINT)EndPath->InkPath.GetPathLength(); 01657 } 01658 01659 MILLIPOINT InsertDistance = -1; 01660 MILLIPOINT EndInsertDistance = -1; 01661 INT32 StartIndex = 0; //where we will begin our insert 01662 01663 // according to the type of join we will want to insert our new data at the beginning or the 01664 // end, we may also want to reverse it 01665 switch (JoinType) 01666 { 01667 case JOINTYPE_NEWSTART_TO_OLDSTART: 01668 InsertDistance = 0; 01669 EndInsertDistance = NewPathLength; 01670 StartIndex = 0; 01671 // in this instance we reversed the new path section so also reverse the pressure data 01672 m_pPressureSampler->ReverseData(); 01673 break; 01674 case JOINTYPE_NEWSTART_TO_OLDEND: 01675 InsertDistance = OldPathLength; 01676 EndInsertDistance = OldPathLength + NewPathLength; 01677 StartIndex = pPressData->GetInternalIndexFromDistance(OldPathLength); 01678 if (StartIndex==-1) StartIndex = pPressData->GetNumItems(); 01679 break; 01680 case JOINTYPE_NEWEND_TO_OLDSTART: 01681 InsertDistance = 0; 01682 EndInsertDistance = NewPathLength; 01683 StartIndex = 0; 01684 break; 01685 case JOINTYPE_NEWEND_TO_OLDEND: 01686 InsertDistance = OldPathLength; 01687 EndInsertDistance = OldPathLength + NewPathLength; 01688 StartIndex = pPressData->GetInternalIndexFromDistance(OldPathLength); 01689 if (StartIndex==-1) StartIndex = pPressData->GetNumItems(); 01690 m_pPressureSampler->ReverseData(); 01691 break; 01692 default: 01693 ERROR3("Unknown join type in OpDrawBrush::SimpleJoinBrush"); 01694 return FALSE; 01695 } 01696 01697 // make the action to insert the pressure list 01698 if (m_pPressureSampler != NULL) 01699 { 01700 AddPressurePointsAction* pAction; 01701 UINT32 NumPoints = m_pPressureSampler->GetNumItems(); 01702 01703 if (AddPressurePointsAction::Init(this, &UndoActions, pAttrBrush, m_pPressureSampler, 01704 StartIndex, NumPoints, &pAction) == AC_FAIL) 01705 return FALSE; 01706 m_pPressureSampler = NULL; // so we don't delete it 01707 } 01708 01709 return TRUE; 01710 }
|
|
Definition at line 257 of file opdrbrsh.h. |
|
Definition at line 242 of file opdrbrsh.h. |
|
Definition at line 230 of file opdrbrsh.h. |
|
Definition at line 232 of file opdrbrsh.h. |
|
Definition at line 259 of file opdrbrsh.h. |
|
Definition at line 233 of file opdrbrsh.h. |
|
Definition at line 240 of file opdrbrsh.h. |
|
Definition at line 261 of file opdrbrsh.h. |
|
Definition at line 234 of file opdrbrsh.h. |
|
Definition at line 236 of file opdrbrsh.h. |
|
Definition at line 231 of file opdrbrsh.h. |
|
Definition at line 270 of file opdrbrsh.h. |
|
Definition at line 237 of file opdrbrsh.h. |
|
Definition at line 239 of file opdrbrsh.h. |
|
Definition at line 282 of file opdrbrsh.h. |
|
Definition at line 248 of file opdrbrsh.h. |
|
Definition at line 244 of file opdrbrsh.h. |
|
Definition at line 245 of file opdrbrsh.h. |
|
Definition at line 264 of file opdrbrsh.h. |
|
Definition at line 277 of file opdrbrsh.h. |
|
Definition at line 280 of file opdrbrsh.h. |
|
Definition at line 254 of file opdrbrsh.h. |
|
Definition at line 271 of file opdrbrsh.h. |
|
Definition at line 255 of file opdrbrsh.h. |
|
Definition at line 235 of file opdrbrsh.h. |
|
Definition at line 272 of file opdrbrsh.h. |
|
Definition at line 269 of file opdrbrsh.h. |
|
Definition at line 250 of file opdrbrsh.h. |
|
Definition at line 251 of file opdrbrsh.h. |