#include <nodetxtl.h>
Inheritance diagram for TextLine:

Public Member Functions | |
| TextLine () | |
| Simple TextLine constructor, it is required so that SimpleCopy will work. | |
| ~TextLine () | |
| Destructor. | |
| TextLine (Node *ContextNode, AttachNodeDirection Direction) | |
| The main TextLine constructor. | |
| void | Init () |
| common init function for constructors | |
| virtual Node * | SimpleCopy () |
| This method returns a shallow copy of the node with all Node pointers NULL. The function is virtual, and must be defined for all derived classes of Node. | |
| void | CopyNodeContents (TextLine *NodeCopy) |
| This method copies the node's contents to the node pointed to by NodeCopy. | |
| virtual void | PolyCopyNodeContents (NodeRenderable *pNodeCopy) |
| Polymorphically copies the contents of this node to another. | |
| virtual CopyType | GetCopyType () |
| This function returns a type describing how this object is to be copied. The fuction is called from the low level copy operation CopyObjects. There are two options at present, these being SIMPLECOPY and COMPLEXCOPY. SIMPLECOPY indicates that the node can be copied by a call to its virtual function SimpleCopy(). COMPLEXCOPY however indicates that the node needs to do its own thing when copying and must be called via the ComplexCopy() virtual function. This virtual will likely return a tree of copied objects rather than just a copy of itself. | |
| virtual INT32 | ComplexCopy (CopyStage Stage, Range &RangeToCopy, Node **pOutput) |
| If the copystage is COPYOBJECT, The node has been called to copy itself and do what ever it needs to to make a sensible copy of other items such as attributes. The caller (CopyObjects) will not deep copy this node (as this is a complex copy and it expects the handler to know what its doing). In this case the TextLine object cannot exist on its own. It needs a TextStory as a parent and however many text characters that live inside it. Hence this is what is returned. SeeAlso Node::ComplexCopy(), CopyObjects(). | |
| virtual INT32 | ComplexHide (UndoableOperation *pOp, Node *pNextNode) |
| Override the node level virtual function ComplexHide. This gives us a chance to get in and hide the various selected members of a text story sensibly. We hide all necessary nodes when the last member of the text story is called to complex hide itself, otherwise we may corrupt the range being scanned. | |
| virtual BOOL | IsSetCandidate () const |
| Indicates that NodeRenderableInks are candidates for membership of Attribute gallery set. | |
| virtual BOOL | IsCompound () const |
| virtual UINT32 | GetNodeSize () const |
| For finding the size of the node. | |
| virtual void | GetDebugDetails (StringBase *Str) |
| For obtaining debug information about the Node. This fn can be deleted before we ship. | |
| virtual String | Describe (BOOL Plural, BOOL Verbose) |
| Gives a description of the TextLine node for the status line etc. | |
| DocRect | GetBlobBoundingRect () |
| This function returns the blob bounding rectangle of this TextLine. There is a tiny blob on the top left of the first character on the line. | |
| void | RenderObjectBlobs (RenderRegion *pRRegion) |
| Renders the TextLines object blobs. | |
| void | RenderTinyBlobs (RenderRegion *pRRegion) |
| Renders the TextLines tiny blobs. | |
| DocCoord | GetTinyBlobPos () |
| This function returns the location of the tiny blob on this TextLine. It is either on the top-left of the first character on the line, or if there isn't a char, on the top-left of the line bounding rect. | |
| BOOL | CreateNodeGroup (NodeGroup **ppNodeGroup, FormatRegion *pFormatRegion, BecomeA *pBecomeA) |
| Creates a NodeGroup containing all chars converted to NodePaths. | |
| virtual BOOL | ReCacheMetrics (FormatRegion *pFormmatRegion) |
| Recache metrics in text line. | |
| BOOL | Format (TextStoryInfo *pStoryInfo) |
| perform line level formatting Note: on entry pStoryInfo->DescentLine hold the DescentLine of the last line (pStoryInfo->DescentLineValid indicating if there was none (eg first line) and on exit, it holds the DescentLine for this line and DescentLineValid is TRUE | |
| BOOL | EnsureNextLineOfParagraphHasSameLineLevelAttrs (UndoableOperation *pUndoOp) |
| Ensure the next line of a paragraph has the same line level attibutes. | |
| BOOL | ReCalcLineInfo (TextLineInfo *pLineInfo) |
| Recalculate line level info (absorbing space at end of line) Note: Also updates line level info in node itself. | |
| BOOL | PositionCharsInLine (TextLineInfo *pLineInfo) |
| set the position of each char on the line accounting for justification ALSO, flag any chars that have moved as 'affected' | |
| BOOL | CalcBaseAndDescentLine (MILLIPOINT *pBaseLine, MILLIPOINT *pDescentLine, MILLIPOINT LastDescentLine, BOOL FirstLine) |
| Calculate BaseLine and DescentLine for this line given the last line's DescentLine if this is the first line in the story, the baseline is 0 and the DescentLine has to be back calculated. | |
| BOOL | SetCharMatrices (MILLIPOINT LinePos) |
| set matrices in all VTN on a line | |
| BOOL | FitTextToPath (TextStoryInfo *pPathInfo, MILLIPOINT LinePos) |
| set matrices in all VTN on a line so as to fit text to the path, accounting for any transform which was applied before the text was fitted to the path | |
| BOOL | Wrap (UndoableOperation *pUndoOp, MILLIPOINT WrapWidth, MILLIPOINT Indent) |
| Word wrap the line. | |
| VisibleTextNode * | FindBreakChar (MILLIPOINT FitWidth, BOOL SetCharPositions, MILLIPOINT Indent, MILLIPOINT CharPosOffset=0, MILLIPOINT ExtraOnChars=0, MILLIPOINT ExtraOnSpaces=0) |
| Find words to fit given width, absorbing spaces, optionally formats line. | |
| TextLine * | FindFirstLineOfParagraph () |
| BOOL | AddChildLineLevelAttrsToSet (AttrTypeSet *pAttrSet) |
| VisibleTextNode * | FindCharAtDistAlongLine (MILLIPOINT Distance, BOOL *LeftHandSide) |
| Call this function to get the character at a certian distance along this TextLine. If the distance is off the right end of the line then a pointer to the EOLNode is returned. | |
| VisibleTextNode * | FindFirstVTN () const |
| For getting a pointer to the first Visible Text Node in this TextLine. | |
| VisibleTextNode * | FindLastVTN () const |
| For getting a pointer to the last Visible Text Node in this TextLine. | |
| EOLNode * | FindEOLNode () const |
| CaretNode * | FindCaret () const |
| TextLine * | FindNextLine () const |
| TextLine * | FindPrevLine () const |
| MILLIPOINT | GetLastCharTracking () |
| BOOL | WholeLineSelected () |
| BOOL | WillLineWrapOnPath (FIXED16 xscale, MILLIPOINT PLength) |
| Calculates whether the formatter will wrap this line of text around the path It calculates this by checking the position of the last character (or VTN in the line). If this wraps it is assumed the whole line will wrap. | |
| virtual BOOL | WritePreChildrenWeb (BaseCamelotFilter *pFilter) |
| Saves a text line record to the new file format filter. | |
| virtual BOOL | WritePreChildrenNative (BaseCamelotFilter *pFilter) |
| virtual BOOL | WriteBeginChildRecordsWeb (BaseCamelotFilter *pFilter) |
| Begin to write out you child records, in the web format. | |
| virtual BOOL | WriteBeginChildRecordsNative (BaseCamelotFilter *pFilter) |
| Begin to write out you child records, in the native format. | |
| virtual BOOL | WriteEndChildRecordsWeb (BaseCamelotFilter *pFilter) |
| Finished writing out you child records, in the web format. | |
| virtual BOOL | WriteEndChildRecordsNative (BaseCamelotFilter *pFilter) |
| Finished writing out you child records, in the native format. | |
| MILLIPOINT | GetLineDescent () |
| MILLIPOINT | GetLineAscent () |
| MILLIPOINT | GetLineSize () |
| void | SetLineDescent (MILLIPOINT Descent) |
| void | SetLineAscent (MILLIPOINT Ascent) |
| void | SetLineSize (MILLIPOINT Size) |
| void | UpdateLineDescent (MILLIPOINT Descent) |
| void | UpdateLineAscent (MILLIPOINT Ascent) |
| void | UpdateLineSize (MILLIPOINT Size) |
| Justification | GetJustification () |
| MILLIPOINT | GetLineSpacing () |
| FIXED16 | GetLineSpaceRatio () |
| MILLIPOINT | GetParaLeftMargin () |
| MILLIPOINT | GetParaFirstIndent () |
| MILLIPOINT | GetParaRightMargin () |
| const TxtRuler * | GetRuler () |
| void | SetJustification (Justification justification) |
| void | SetLineSpacing (MILLIPOINT Spacing) |
| void | SetLineSpaceRatio (FIXED16 SpaceRatio) |
| void | SetParaLeftMargin (MILLIPOINT Margin) |
| void | SetParaFirstIndent (MILLIPOINT Indent) |
| void | SetParaRightMargin (MILLIPOINT Margin) |
| void | SetRuler (const TxtRuler *pRuler) |
| MILLIPOINT | GetPosInStory () |
| void | SetPosInStory (MILLIPOINT pos) |
Static Public Member Functions | |
| static TextLine * | CreateEmptyTextLine (Node *pContextNode=NULL, AttachNodeDirection Direction=FIRSTCHILD) |
| Create a TextLine with EOL and attach it to another node if required. | |
| static BOOL | IsAttrTypeLineLevel (CCRuntimeClass *pAttrType) |
Protected Member Functions | |
| MILLIPOINT | GetEffectiveLeftMargin () |
| Select the left margin or first indent value depending on whether this is the first line in the paragraph. | |
Private Attributes | |
| MILLIPOINT | mLineDescent |
| MILLIPOINT | mLineAscent |
| MILLIPOINT | mLineSize |
| Justification | mJustification |
| MILLIPOINT | mLineSpacing |
| FIXED16 | mLineSpaceRatio |
| MILLIPOINT | mLeftMargin |
| MILLIPOINT | mFirstIndent |
| MILLIPOINT | mRightMargin |
| TxtRuler * | mpRuler |
| MILLIPOINT | mPosInStory |
Definition at line 287 of file nodetxtl.h.
|
|
Simple TextLine constructor, it is required so that SimpleCopy will work.
Definition at line 196 of file nodetxtl.cpp. 00196 : BaseTextClass() // Call the base class 00197 { 00198 Init(); 00199 }
|
|
|
Destructor.
Definition at line 210 of file nodetxtl.cpp. 00211 { 00212 delete mpRuler; 00213 }
|
|
||||||||||||
|
The main TextLine constructor.
Specifies the direction in which the node is to be attached to the ContextNode. The values this variable can take are as follows: PREV : Attach node as a previous sibling of the context node NEXT : Attach node as a next sibling of the context node FIRSTCHILD: Attach node as the first child of the context node LASTCHILD : Attach node as a last child of the context node Definition at line 235 of file nodetxtl.cpp. 00236 :BaseTextClass(ContextNode, Direction) 00237 { 00238 Init(); 00239 }
|
|
|
Definition at line 1056 of file nodetxtl.cpp. 01057 { 01058 Node* pNode = FindFirstChild(); 01059 while (pNode!=NULL) 01060 { 01061 if (pNode->IsAnAttribute() && ((NodeAttribute*)pNode)->IsALineLevelAttrib()) 01062 if (!pAttrTypeSet->AddToSet(((NodeAttribute*)pNode)->GetAttributeType())) 01063 return FALSE; 01064 pNode = pNode->FindNext(); 01065 } 01066 return TRUE; 01067 }
|
|
||||||||||||||||||||
|
Calculate BaseLine and DescentLine for this line given the last line's DescentLine if this is the first line in the story, the baseline is 0 and the DescentLine has to be back calculated.
Definition at line 1600 of file nodetxtl.cpp. 01602 { 01603 // get some info about the line ... 01604 MILLIPOINT LineAscent = GetLineAscent(); 01605 MILLIPOINT LineDescent = GetLineDescent(); 01606 MILLIPOINT LineHeight = LineAscent-LineDescent; 01607 MILLIPOINT LineSpacing = GetLineSpacing(); 01608 01609 MILLIPOINT BaseLine = 0; 01610 MILLIPOINT DescentLine = 0; 01611 if (LineSpacing!=0) 01612 { 01613 MILLIPOINT OffsetFromDescentLineToBaseLine = MulDiv(LineSpacing, -LineDescent, LineHeight); 01614 if (LastDescentLineValid) 01615 { 01616 DescentLine = LastDescentLine - LineSpacing; 01617 BaseLine = DescentLine + OffsetFromDescentLineToBaseLine; 01618 } 01619 else 01620 DescentLine = BaseLine - OffsetFromDescentLineToBaseLine; 01621 } 01622 else 01623 { 01624 FIXED16 LineSpaceRatio = GetLineSpaceRatio(); 01625 MILLIPOINT AbsolutLineSpacing = MILLIPOINT( XLONG(LineHeight) * LineSpaceRatio ); 01626 MILLIPOINT OffsetFromLastDescentLineToBaseLine = LineAscent; 01627 if (LineSpaceRatio<1) 01628 OffsetFromLastDescentLineToBaseLine = XLONG(LineAscent) * LineSpaceRatio; 01629 01630 if (LastDescentLineValid) 01631 { 01632 BaseLine = LastDescentLine - OffsetFromLastDescentLineToBaseLine; 01633 DescentLine = LastDescentLine - AbsolutLineSpacing; 01634 } 01635 else 01636 DescentLine = BaseLine + OffsetFromLastDescentLineToBaseLine - AbsolutLineSpacing; 01637 } 01638 01639 // set outputs 01640 *pDescentLine = DescentLine; 01641 *pBaseLine = BaseLine; 01642 01643 return TRUE; 01644 }
|
|
||||||||||||||||
|
If the copystage is COPYOBJECT, The node has been called to copy itself and do what ever it needs to to make a sensible copy of other items such as attributes. The caller (CopyObjects) will not deep copy this node (as this is a complex copy and it expects the handler to know what its doing). In this case the TextLine object cannot exist on its own. It needs a TextStory as a parent and however many text characters that live inside it. Hence this is what is returned. SeeAlso Node::ComplexCopy(), CopyObjects().
Reimplemented from Node. Definition at line 315 of file nodetxtl.cpp. 00316 { 00317 TextStory* pTextStory = FindParentStory(); 00318 ERROR2IF(pTextStory==NULL,FALSE,"TextLine::ComplexCopy() - pTextStory==NULL"); 00319 return pTextStory->BaseComplexCopy(Stage, RangeToCopy, pOutput); 00320 }
|
|
||||||||||||
|
Override the node level virtual function ComplexHide. This gives us a chance to get in and hide the various selected members of a text story sensibly. We hide all necessary nodes when the last member of the text story is called to complex hide itself, otherwise we may corrupt the range being scanned.
Reimplemented from Node. Definition at line 340 of file nodetxtl.cpp. 00341 { 00342 // if there is no next node in the range then we need to hide all nodes 00343 BOOL CallComplexHide = TRUE; 00344 TextStory* pThisStory = FindParentStory(); 00345 ERROR2IF(pThisStory==NULL,FALSE,"VisibleTextNode::ComplexHide() - pThisStory==NULL"); 00346 00347 if (pNextNode) 00348 { 00349 if ( (pNextNode->IsAVisibleTextNode()) || 00350 (IS_A(pNextNode,TextLine)) 00351 ) 00352 { 00353 TextStory* pTextStory = FindParentStory(); 00354 ERROR2IF(pTextStory==NULL,FALSE,"VisibleTextNode::ComplexHide() - pTextStory==NULL"); 00355 00356 if (pThisStory==pTextStory) 00357 CallComplexHide=FALSE; 00358 } 00359 } 00360 00361 if (CallComplexHide) 00362 return pThisStory->BaseComplexHide(pOp); 00363 else 00364 return 1; 00365 }
|
|
|
This method copies the node's contents to the node pointed to by NodeCopy.
Definition at line 379 of file nodetxtl.cpp. 00380 { 00381 // Ask the base class to do its bit 00382 NodeRenderableBounded::CopyNodeContents(NodeCopy); 00383 00384 // Copy specifics 00385 NodeCopy->mLineAscent = mLineAscent; 00386 NodeCopy->mLineDescent = mLineDescent; 00387 NodeCopy->mLineSize = mLineSize; 00388 00389 NodeCopy->mJustification = mJustification; 00390 NodeCopy->mLineSpacing = mLineSpacing; 00391 NodeCopy->mLineSpaceRatio = mLineSpaceRatio; 00392 NodeCopy->mLeftMargin = mLeftMargin; 00393 NodeCopy->mFirstIndent = mFirstIndent; 00394 NodeCopy->mRightMargin = mRightMargin; 00395 *NodeCopy->mpRuler = *mpRuler; 00396 00397 NodeCopy->mPosInStory = mPosInStory; 00398 }
|
|
||||||||||||
|
Create a TextLine with EOL and attach it to another node if required.
Definition at line 538 of file nodetxtl.cpp. 00539 { 00540 TextLine* pTextLine = new TextLine(); 00541 if (pTextLine==NULL) 00542 return NULL; 00543 00544 EOLNode* pEOL = new EOLNode(pTextLine,FIRSTCHILD); 00545 if (pEOL==NULL) 00546 { 00547 pTextLine->CascadeDelete(); 00548 delete pTextLine; 00549 return NULL; 00550 } 00551 00552 if (pContextNode!=NULL) 00553 pTextLine->AttachNode(pContextNode,Direction); 00554 00555 return pTextLine; 00556 }
|
|
||||||||||||||||
|
Creates a NodeGroup containing all chars converted to NodePaths.
Definition at line 437 of file nodetxtl.cpp. 00438 { 00439 #ifndef DISABLE_TEXT_RENDERING 00440 ERROR2IF(pFormatRegion==NULL,FALSE,"TextChar::CreateNodeGroup() - pFormatRegion==NULL"); 00441 ERROR2IF( pBecomeA==NULL,FALSE,"TextChar::CreateNodeGroup() - pBecomeA==NULL"); 00442 ERROR2IF( ppNodeGroup==NULL,FALSE,"TextChar::CreateNodeGroup() - ppNodeGroup==NULL"); 00443 00444 pFormatRegion->SaveContext(); 00445 00446 // here to overcome scope problem 00447 Node* pNode=NULL; 00448 TextChar* pTextChar=NULL; 00449 00450 // if not passing back, create a NodeGroup to encompass the line, and copy non-text line attributes 00451 // BODGE - should use ALLOC_WITH_FAIL 00452 NodeGroup* pLineNodeGroup=NULL; 00453 if (pBecomeA->GetReason()!=BECOMEA_PASSBACK) 00454 { 00455 pLineNodeGroup=new NodeGroup; 00456 if (pLineNodeGroup==NULL) 00457 goto Fail; 00458 } 00459 00460 pNode=FindFirstChild(); 00461 while (pNode!=NULL) 00462 { 00463 if (pNode->IsAnAttribute()) 00464 { 00465 pNode->Render(pFormatRegion); // render attributes 00466 if (pBecomeA->GetReason()!=BECOMEA_PASSBACK) 00467 if (!pNode->IsKindOfTextAttribute()) 00468 if (pNode->CopyNode(pLineNodeGroup, LASTCHILD)==FALSE) 00469 goto Fail; 00470 } 00471 pNode=pNode->FindNext(); 00472 } 00473 00474 // For each child TextChar convert it to a NodePath 00475 // then EITHER pass it back OR attach it to the line group with non-text char attributes 00476 pTextChar=(TextChar*)FindFirstChild(CC_RUNTIME_CLASS(TextChar)); 00477 while (pTextChar) 00478 { 00479 pFormatRegion->SaveContext(); 00480 pTextChar->RenderChildAttrs(pFormatRegion); 00481 NodePath* pCharNodePath=NULL; 00482 if (pTextChar->CreateNodePath(&pCharNodePath,pFormatRegion)==FALSE) 00483 goto Fail; 00484 if (pCharNodePath) 00485 { 00486 if (pBecomeA->GetReason()==BECOMEA_PASSBACK) 00487 { 00488 if (pBecomeA->PassBack(pCharNodePath,pTextChar)==FALSE) 00489 goto Fail; 00490 } 00491 else 00492 { 00493 pCharNodePath->AttachNode(pLineNodeGroup,LASTCHILD); 00494 Node* pNode=pTextChar->FindFirstChild(); 00495 while (pNode) 00496 { 00497 if (pNode->IsAnAttribute() && !pNode->IsKindOfTextAttribute()) 00498 if (pNode->CopyNode(pCharNodePath, LASTCHILD)==FALSE) 00499 goto Fail; 00500 pNode=pNode->FindNext(); 00501 } 00502 00503 pBecomeA->PassBack(pCharNodePath, pTextChar); 00504 } 00505 } 00506 pFormatRegion->RestoreContext(); 00507 pTextChar=(TextChar*)(pTextChar->FindNext(CC_RUNTIME_CLASS(TextChar))); 00508 } 00509 00510 *ppNodeGroup=pLineNodeGroup; 00511 pFormatRegion->RestoreContext(); 00512 return TRUE; 00513 00514 Fail: 00515 if (pLineNodeGroup) 00516 { 00517 pLineNodeGroup->CascadeDelete(); 00518 delete pLineNodeGroup; 00519 } 00520 pFormatRegion->RestoreContext(); 00521 #endif 00522 return FALSE; 00523 }
|
|
||||||||||||
|
Gives a description of the TextLine node for the status line etc.
Reimplemented from Node. Definition at line 569 of file nodetxtl.cpp. 00570 { 00571 if (Plural) 00572 return(String(_R(IDS_DESCRIBE_TEXTLINEP))); 00573 else 00574 return(String(_R(IDS_DESCRIBE_TEXTLINES))); 00575 }
|
|
|
Ensure the next line of a paragraph has the same line level attibutes.
Definition at line 891 of file nodetxtl.cpp. 00892 { 00893 TRACEUSER("wuerthne", _T("EnsureNextLineOfParagraphHasSameLineLevelAttrs")); 00894 00895 ERROR2IF(FindEOLNode()!=NULL,FALSE,"TextLine::EnsureNextOfParagraphLineHasSameLineLevelAttrs() - there is no next line in the paragraph!"); 00896 TextStory* pStory = this->FindParentStory(); 00897 ERROR2IF(pStory==NULL,FALSE,"TextLine::EnsureNextOfParagraphLineHasSameLineLevelAttrs() - line has no parent story!"); 00898 TextLine* pNextLine = this->FindNextLine(); 00899 ERROR2IF(pNextLine==NULL,FALSE,"TextLine::EnsureNextOfParagraphLineHasSameLineLevelAttrs() - last line of story has no EOL!"); 00900 00901 // flag story not localised, and get the set of line level attrs to localise 00902 BOOL StoryLocalised = FALSE; 00903 AttrTypeSet LLASet; 00904 BOOL ok = this->AddChildLineLevelAttrsToSet(&LLASet); 00905 if (ok) ok = pNextLine->AddChildLineLevelAttrsToSet(&LLASet); 00906 if (!ok) return FALSE; 00907 00908 // hide any Line Level Attributes found on the next line 00909 // which are different to those on this line or do not exist on this line 00910 Node* pNextLineNode = pNextLine->FindFirstChild(); 00911 while (pNextLineNode!=NULL) 00912 { 00913 if (pNextLineNode->IsAnAttribute() && ((NodeAttribute*)pNextLineNode)->IsALineLevelAttrib()) 00914 { 00915 NodeAttribute* pNextLineLLA = (NodeAttribute*)pNextLineNode; 00916 NodeAttribute* pThisLineLLA = (NodeAttribute*)(this->FindFirstChild(pNextLineLLA->GetAttributeType())); 00917 if (pThisLineLLA==NULL || !((*pNextLineLLA)==(*pThisLineLLA)) ) 00918 { 00919 if (!StoryLocalised) 00920 if (!pStory->DoLocaliseCommonAttributes(pUndoOp,FALSE,TRUE,&LLASet)) 00921 return FALSE; 00922 StoryLocalised = TRUE; 00923 if (pUndoOp!=NULL) 00924 { 00925 if (!pUndoOp->DoHideNode(pNextLineLLA,FALSE)) 00926 return FALSE; 00927 } 00928 else 00929 { 00930 pNextLineLLA->CascadeDelete(); 00931 delete pNextLineLLA; 00932 } 00933 } 00934 } 00935 pNextLineNode = pNextLineNode->FindNext(); 00936 } 00937 00938 // hide any Line Level Attributes on next line which are different to those found on this line 00939 // then copy any Line Level Attributes from this line to the next 00940 // which don't exist (or have just been hiden) on the next line 00941 Node* pThisLineNode = this->FindFirstChild(); 00942 while (pThisLineNode!=NULL) 00943 { 00944 if (pThisLineNode->IsAnAttribute() && ((NodeAttribute*)pThisLineNode)->IsALineLevelAttrib()) 00945 { 00946 NodeAttribute* pThisLineLLA = (NodeAttribute*)pThisLineNode; 00947 NodeAttribute* pNextLineLLA = (NodeAttribute*)(pNextLine->FindFirstChild(pThisLineLLA->GetAttributeType())); 00948 00949 if (pNextLineLLA!=NULL && !((*pNextLineLLA)==(*pThisLineLLA)) ) 00950 { 00951 if (!StoryLocalised) 00952 if (!pStory->DoLocaliseCommonAttributes(pUndoOp,FALSE,TRUE,&LLASet)) 00953 return FALSE; 00954 StoryLocalised = TRUE; 00955 if (pUndoOp!=NULL) 00956 { 00957 if (!pUndoOp->DoHideNode(pNextLineLLA,FALSE)) 00958 return FALSE; 00959 } 00960 else 00961 { 00962 pNextLineLLA->CascadeDelete(); 00963 delete pNextLineLLA; 00964 } 00965 pNextLineLLA = NULL; // flag its been hidden 00966 } 00967 00968 if (pNextLineLLA==NULL) 00969 { 00970 if (!StoryLocalised) 00971 if (!pStory->DoLocaliseCommonAttributes(pUndoOp,FALSE,TRUE,&LLASet)) 00972 return FALSE; 00973 StoryLocalised = TRUE; 00974 TRACEUSER("wuerthne", _T("calling SimpleCopy for att %d %d"), IS_A(pThisLineLLA, AttrTxtLineSpace), IS_A(pThisLineLLA, AttrTxtRuler)); 00975 NodeAttribute* pNewLLA = (NodeAttribute*)pThisLineLLA->SimpleCopy(); 00976 TRACEUSER("wuerthne", _T("node copied %d %d"), IS_A(pNewLLA, AttrTxtLineSpace), IS_A(pNewLLA, AttrTxtRuler)); 00977 if (pNewLLA==NULL) 00978 return FALSE; 00979 pNewLLA->AttachNode(pNextLine,FIRSTCHILD,TRUE,FALSE); 00980 if (pUndoOp!=NULL) 00981 { 00982 Action* UndoHideAttrAction; 00983 if (HideNodeAction::Init(pUndoOp,pUndoOp->GetUndoActionList(),pNewLLA,TRUE,&UndoHideAttrAction)==AC_FAIL) 00984 return FALSE; 00985 } 00986 } 00987 } 00988 pThisLineNode = pThisLineNode->FindNext(); 00989 } 00990 00991 // if attrs localised on next line, factor out (globally) and flag line affected 00992 if (StoryLocalised) 00993 { 00994 if (!pStory->DoFactorOutCommonChildAttributes(pUndoOp,TRUE,&LLASet)) 00995 return FALSE; 00996 pNextLine->FlagNodeAndDescendantsModifiedByOpAndParentsHaveDescendantModifiedByOp(); 00997 } 00998 00999 return TRUE; 01000 }
|
|
||||||||||||||||||||||||||||
|
Find words to fit given width, absorbing spaces, optionally formats line.
Definition at line 1236 of file nodetxtl.cpp. 01239 { 01240 // This routine does not just find the break char (SetCharPositions = FALSE), it 01241 // also formats lines by setting the character positions (SetCharPositions = TRUE). 01242 // With the introduction of Tabs, formatting has become more complex, so it makes 01243 // a lot of sense to have 01244 // depending on whether 01245 // Finding the break char is straightforward when no tabs are involved. 01246 // You just add up the widths and remember the last space character and 01247 // return that when the available width has been exceeded. 01248 // 01249 // With tabs, things become a bit more complex. Left tabs are easy: A left tab 01250 // is treated like a character with the width of the remaining space up to the 01251 // tab stop. When dealing with centre or right tabs we need to remember how much 01252 // space we had left to the left of the tab stop. Half (for centre tabs) or all 01253 // (for right tabs) of the width of all subsequent text goes to the left until 01254 // that space is filled up, all remaining space goes to the right only. 01255 // Decimal tabs behave like centre tabs except that distributing half the width 01256 // to the left stops as soon as the decimal point has been seen. 01257 // 01258 // The formatting algorithm below divides the line into sections delimited by 01259 // tabs or end of line. When a section is finished (i.e., when seeing a tab or 01260 // end of line), then the complete section is formatted (using FinishTabSection()). 01261 01262 TRACEUSER("wuerthne", _T("FindBreakChar, SetCharPositions = %d"), SetCharPositions); 01263 VisibleTextNode* pBreakChar = NULL; 01264 BOOL CharOnLine = FALSE; 01265 VisibleTextNode* pPrevVTN = NULL; 01266 VisibleTextNode* pVTN = this->FindFirstVTN(); 01267 01268 // create a FormatState object that takes care of the formatting 01269 FormatState State(FitWidth, SetCharPositions, pVTN, Indent, CharPosOffset, ExtraOnChars, ExtraOnSpaces); 01270 01271 while(pVTN!=NULL) 01272 { 01273 BOOL IsATab = IS_A(pVTN, HorizontalTab); 01274 BOOL IsADecimalPoint = FALSE; 01275 if (State.ActiveTabType == DecimalTab && pVTN->IsATextChar()) 01276 { 01277 // if the currently active tab is a decimal tab check whether we have hit a decimal point 01278 // NB. - the decimal point character is stored in the tab stop 01279 IsADecimalPoint = (((TextChar*)pVTN)->GetUnicodeValue() == State.DecimalPointChar); 01280 } 01281 if (IsATab) 01282 { 01283 TxtTabType ThisTabType; 01284 MILLIPOINT ThisTabPos; 01285 MILLIPOINT TabWidth; 01286 01287 // finish the previous tab 01288 State.FinishTabSection(pVTN, FALSE); 01289 01290 // find the next tab stop (always returns usable values - if there are no more 01291 // tab stops on the ruler the routine assumes left tabs at equidistant positions) 01292 WCHAR DecimalPointChar; 01293 TxtRulerAttribute::FindTabStopInRuler(mpRuler, State.Width, &ThisTabType, &ThisTabPos, 01294 &DecimalPointChar); 01295 TabWidth = ThisTabPos - State.Width; 01296 ((HorizontalTab*)pVTN)->SetCharAdvance(TabWidth); 01297 ((HorizontalTab*)pVTN)->SetCharWidth(TabWidth); 01298 State.AnchorPos = State.Width; 01299 if (ThisTabType != LeftTab) 01300 { 01301 // Space between the tab character and the stop it aligns to 01302 State.RemainingSpace = TabWidth; 01303 } 01304 if (ThisTabType == DecimalTab) 01305 { 01306 State.DecimalPointChar = DecimalPointChar; 01307 State.DecimalPointFound = FALSE; 01308 } 01309 State.pLastTabVTN = pVTN; 01310 State.ActiveTabType = ThisTabType; 01311 State.ActiveTabPos = ThisTabPos; 01312 // we allow line breaks at tabs 01313 pBreakChar = pPrevVTN; 01314 } 01315 if (!pVTN->IsACaret()) 01316 { 01317 if (pVTN->IsAnEOLNode()) 01318 { 01319 State.FinishTabSection(pVTN, TRUE); 01320 return pVTN; 01321 } 01322 else if (pVTN->IsASpace()) 01323 { 01324 State.AdvanceBy(pVTN->GetCharAdvance(), IsADecimalPoint); 01325 pBreakChar = pVTN; 01326 } 01327 else if (!CharOnLine || State.IsAvailable(pVTN->GetCharWidth(), IsATab, IsADecimalPoint)) 01328 { 01329 if (IsATab) State.Width += pVTN->GetCharAdvance(); 01330 else State.AdvanceBy(pVTN->GetCharAdvance(), IsADecimalPoint); 01331 if (pVTN->IsAHyphen()) 01332 pBreakChar = pVTN; 01333 if (State.ActiveTabType == DecimalTab && !State.DecimalPointFound && IsADecimalPoint) 01334 State.DecimalPointFound = TRUE; 01335 } 01336 else 01337 { 01338 // did not fit 01339 if (pBreakChar==NULL) 01340 pBreakChar = pPrevVTN; 01341 if (pBreakChar) State.FinishTabSection(pBreakChar, TRUE); 01342 return pBreakChar; 01343 } 01344 CharOnLine = TRUE; 01345 } 01346 pPrevVTN = pVTN; 01347 if (SetCharPositions) 01348 { 01349 // formatting run - we stay within our line and finish when we run past the end 01350 pVTN = pVTN->FindNextVTNInLine(); 01351 if (!pVTN) 01352 { 01353 State.FinishTabSection(pPrevVTN, TRUE); 01354 return NULL; 01355 } 01356 } 01357 else 01358 { 01359 pVTN = pVTN->FindNextVTNInStory(); 01360 } 01361 } 01362 ERROR2(FALSE,"FindBreakChar() - story has no final EOL!"); 01363 }
|
|
|
Definition at line 1818 of file nodetxtl.cpp. 01819 { 01820 return (CaretNode*)FindFirstChild(CC_RUNTIME_CLASS(CaretNode)); 01821 }
|
|
||||||||||||
|
Call this function to get the character at a certian distance along this TextLine. If the distance is off the right end of the line then a pointer to the EOLNode is returned.
Definition at line 1771 of file nodetxtl.cpp. 01772 { 01773 ERROR2IF(LeftHandSide==NULL,NULL,"TextLine::FindCharAtDistAlongLine() - NULL side pointer"); 01774 01775 VisibleTextNode* pVTN = FindFirstVTN(); 01776 ERROR2IF(pVTN==NULL,NULL,"TextLine::FindCharAtDistAlongLine() - has no VTN"); 01777 while (1) 01778 { 01779 const MILLIPOINT Left = pVTN->GetPosInLine(); 01780 const MILLIPOINT Centre = Left+pVTN->GetCharWidth()/2; 01781 const MILLIPOINT Next = Left+pVTN->GetCharAdvance(); 01782 01783 // if to left of centre of this char (and to right of previous if any) 01784 // or at end of line, return char and 'to left' 01785 if (Distance<=Centre || pVTN->IsAnEOLNode()) 01786 { 01787 *LeftHandSide = TRUE; 01788 return pVTN; 01789 } 01790 01791 // if to left of next char (and right of centre of this char), 01792 // return char and 'to right' 01793 if (Distance<=Next) 01794 { 01795 *LeftHandSide = FALSE; 01796 return pVTN; 01797 } 01798 01799 // if no next VTN, return this char and 'to right' 01800 VisibleTextNode* pNextVTN = pVTN->FindNextVTNInLine(); 01801 if (pNextVTN==NULL) 01802 { 01803 *LeftHandSide = FALSE; 01804 return pVTN; 01805 } 01806 pVTN = pNextVTN; 01807 } 01808 }
|
|
|
Definition at line 1912 of file nodetxtl.cpp. 01913 { 01914 EOLNode* pEOL = (EOLNode*)FindFirstChild(CC_RUNTIME_CLASS(EOLNode)); 01915 ERROR3IF(pEOL!=NULL && pEOL->FindNext(CC_RUNTIME_CLASS(EOLNode))!=NULL, 01916 "TextLine::FindEOLNode() - more than one EOLNode on a line!"); 01917 return pEOL; 01918 }
|
|
|
Definition at line 1012 of file nodetxtl.cpp. 01013 { 01014 TextLine* pLine = this; 01015 while (1) 01016 { 01017 TextLine* pPrevLine = pLine->FindPrevLine(); 01018 if (pPrevLine==NULL || pPrevLine->FindEOLNode()!=NULL) 01019 break; 01020 pLine = pPrevLine; 01021 } 01022 return pLine; 01023 }
|
|