+bool
+wxLayoutLine::Wrap(CoordType wrapmargin, wxLayoutList *llist)
+{
+ wxLayoutObjectList::iterator nulled(NULL);
+ if(GetLength() < wrapmargin)
+ return false; // nothing to do
+
+ // find the object which covers the wrapmargin:
+ CoordType offset;
+ wxLOiterator i = FindObject(wrapmargin, &offset);
+ wxCHECK_MSG( i != nulled, false,
+ wxT("Cannot find object covering wrapmargin."));
+
+ // from this object on, the rest of the line must be copied to the
+ // next one:
+ wxLOiterator copyObject = nulled;
+ // if we split a text-object, we must pre-pend some text to the
+ // next line later on, remember it here:
+ wxString prependText = _T("");
+ // we might need to adjust the cursor position later, so remember it
+ size_t xpos = llist->GetCursorPos().x;
+ // by how much did we shorten the current line:
+ size_t shorter = 0;
+ // remember cursor location of object
+ size_t objectCursorPos = 0;
+
+ size_t breakpos = offset;
+
+ if( (**i).GetType() != WXLO_TYPE_TEXT )
+ {
+ // break before a non-text object
+ copyObject = i;
+ }
+ else
+ {
+ bool foundSpace = false;
+ do
+ {
+// while(i != nulled && (**i).GetType() != WXLO_TYPE_TEXT)
+// i--;
+ // try to find a suitable place to split the object:
+ wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
+ if((**i).GetType() == WXLO_TYPE_TEXT
+ && tobj->GetText().Length() >= breakpos)
+ {
+ do
+ {
+ foundSpace = isspace(tobj->GetText()[breakpos]) != 0;
+ if ( foundSpace )
+ break;
+ }
+ while ( breakpos-- > 0 );
+ }
+ else
+ {
+ breakpos = 0;
+ }
+
+ if(! foundSpace) // breakpos == 0!
+ {
+ if(i == m_ObjectList.begin())
+ return false; // could not break line
+ else
+ {
+ i--;
+ while(i != m_ObjectList.begin()
+ && (**i).GetType() != WXLO_TYPE_TEXT )
+ {
+ i--;
+ }
+ breakpos = (**i).GetLength();
+ }
+ }
+ }while(! foundSpace);
+ // before we actually break the object, we need to know at which
+ // cursorposition it starts, so we can restore the cursor if needed:
+ if( this == llist->GetCursorLine() && xpos >= breakpos )
+ {
+ for(wxLOiterator j = m_ObjectList.begin();
+ j != nulled && j != i; j++)
+ objectCursorPos += (**j).GetLength();
+ }
+ // now we know where to break it:
+ wxLayoutObjectText *tobj = (wxLayoutObjectText *)*i;
+ shorter = tobj->GetLength() - breakpos;
+ // remember text to copy from this object
+ prependText = tobj->GetText().Mid(breakpos+1);
+ tobj->SetText(tobj->GetText().Left(breakpos));
+ // copy every following object:
+ copyObject = i; copyObject ++;
+ }
+
+ // make sure there is an empty m_Next line:
+ (void) new wxLayoutLine(this, llist);
+ wxASSERT(m_Next);
+ // We need to move this and all following objects to the next
+ // line. Starting from the end of line, to keep the order right.
+ if(copyObject != nulled)
+ {
+ wxLOiterator j;
+ for(j = m_ObjectList.tail(); j != copyObject; j--)
+ m_Next->Prepend(*j);
+ m_Next->Prepend(*copyObject);
+ // and now remove them from this list:
+ while( copyObject != m_ObjectList.end() )
+ {
+ shorter += (**copyObject).GetLength();
+ m_ObjectList.remove(copyObject); // remove without deleting it
+ }
+ }
+ m_Length -= shorter;
+
+ if(prependText.Length() > 0)
+ m_Next->Insert(0, prependText);
+
+ // do we need to adjust the cursor position?
+ if( this == llist->GetCursorLine() && xpos >= breakpos)
+ {
+ xpos = objectCursorPos + (xpos - objectCursorPos - breakpos -
+ ((xpos > breakpos) ? 1 : 0 ));
+ #if 0
+ // this assert is useless when xpos has unsigned type
+ wxASSERT(xpos >= 0);
+ #endif
+ llist->MoveCursorTo( wxPoint( xpos, m_Next->GetLineNumber()) );
+ }
+ return true; // we wrapped the line
+}
+