@@ -9759,10 +9759,16 @@ ldomXPointer ldomDocument::createXPointer( lvPoint pt, int direction, bool stric
97599759 return ldomXPointer(node, 0);
97609760 }
97619761 // It is a word
9762- if ( find_first ) // return xpointer to logical start of word
9762+ if ( find_first ) { // return xpointer to logical start of word
9763+ if ( node->isElement() ) // (see comment about <br/><br/> below)
9764+ return ldomXPointer(node, 0);
97639765 return ldomXPointer( node, src->t.offset + word->t.start );
9764- else // return xpointer to logical end of word
9766+ }
9767+ else { // return xpointer to logical end of word
9768+ if ( node->isElement() )
9769+ return ldomXPointer(node, 0);
97659770 return ldomXPointer( node, src->t.offset + word->t.start + word->t.len );
9771+ }
97669772 }
97679773
97689774 // Found line, searching for word (words are in visual order)
@@ -9841,24 +9847,36 @@ ldomXPointer ldomDocument::createXPointer( lvPoint pt, int direction, bool stric
98419847 font->measureText( str.c_str()+word->t.start, word->t.len, width, flg, word->width+50, '?',
98429848 src->lang_cfg, src->letter_spacing + word->added_letter_spacing, false, hints);
98439849
9850+ // In some special cases, node may be an element and not a text node (ie. on a blank
9851+ // line caused by <br/><br/> where our word is a space generated by lvrend): below,
9852+ // we must return node with an offset of 0 (to avoid getting xpointer like p[2]/br[3].1
9853+ // which may fail being resolved back to the br node).
98449854 bool word_is_rtl = word->flags & LTEXT_WORD_DIRECTION_IS_RTL;
98459855 if ( word_is_rtl ) {
98469856 for ( int i=word->t.len-1; i>=0; i-- ) {
98479857 int xx = ( i>0 ) ? (width[i-1] + width[i])/2 : width[i]/2;
98489858 xx = word->width - xx;
98499859 if ( x < word->x + xx ) {
9860+ if ( node->isElement() )
9861+ return ldomXPointer(node, 0);
98509862 return ldomXPointer( node, src->t.offset + word->t.start + i );
98519863 }
98529864 }
9865+ if ( node->isElement() )
9866+ return ldomXPointer(node, 0);
98539867 return ldomXPointer( node, src->t.offset + word->t.start );
98549868 }
98559869 else {
98569870 for ( int i=0; i<word->t.len; i++ ) {
98579871 int xx = ( i>0 ) ? (width[i-1] + width[i])/2 : width[i]/2;
98589872 if ( x < word->x + xx ) {
9873+ if ( node->isElement() )
9874+ return ldomXPointer(node, 0);
98599875 return ldomXPointer( node, src->t.offset + word->t.start + i );
98609876 }
98619877 }
9878+ if ( node->isElement() )
9879+ return ldomXPointer( node, 0 );
98629880 return ldomXPointer( node, src->t.offset + word->t.start + word->t.len );
98639881 }
98649882 }
@@ -10456,6 +10474,16 @@ bool ldomXPointer::getRect(lvRect & rect, bool extended, bool adjusted) const
1045610474 }
1045710475 }
1045810476 }
10477+ if ( frmline->word_count == 0 && l == txtform->GetLineCount() - 1 && frmline->height == 0 ) {
10478+ // Handle a special case: we may end up setting the last added line a height of
10479+ // zero when we realize no word would be added. We don't want to return the full
10480+ // final node.
10481+ rect.left = rc.left;
10482+ rect.top = rc.top + frmline->y;
10483+ rect.right = rect.left + 1; // not the right word: no char width
10484+ rect.bottom = rect.top + frmline->height + 1;
10485+ return true;
10486+ }
1045910487 }
1046010488 // return false;
1046110489 // Not found, which is possible with a final node with only empty
0 commit comments