Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/riched20/caret.c | 135 +++++++++++++++-------------------------- dlls/riched20/editor.h | 3 + dlls/riched20/row.c | 26 ++++++++ 3 files changed, 78 insertions(+), 86 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 2fa6842da13..f36c00458b8 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -1272,105 +1272,68 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL row_cursor( editor, &pItem->member.row, x, pCursor ); }
-static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowPageUp( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *p = ME_FindItemFwd(editor->pBuffer->pFirst, diStartRow); + ME_Row *row = para_first_row( editor_first_para( editor ) ), *last_row; + int x, yd, old_scroll_pos = editor->vert_si.nPos;
- if (editor->vert_si.nPos < p->member.row.nHeight) - { - ME_SetCursorToStart(editor, pCursor); - /* Native clears seems to clear this x value on page up at the top - * of the text, but not on page down at the end of the text. - * Doesn't make sense, but we try to be bug for bug compatible. */ - editor->nUDArrowX = -1; - } else { - ME_DisplayItem *pRun = run_get_di( pCursor->run ); - ME_DisplayItem *pLast; - int x, y, yd, yp; - int yOldScrollPos = editor->vert_si.nPos; - - x = ME_GetXForArrow(editor, pCursor); - - p = ME_FindItemBack(pRun, diStartRowOrParagraph); - assert(p->type == diStartRow); - yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y; - y = yp + p->member.row.pt.y; + if (editor->vert_si.nPos < row->nHeight) + { + ME_SetCursorToStart( editor, cursor ); + /* Native clears seems to clear this x value on page up at the top + * of the text, but not on page down at the end of the text. + * Doesn't make sense, but we try to be bug for bug compatible. */ + editor->nUDArrowX = -1; + } + else + { + x = ME_GetXForArrow( editor, cursor ); + row = row_from_cursor( cursor );
- ME_ScrollUp(editor, editor->sizeWindow.cy); - /* Only move the cursor by the amount scrolled. */ - yd = y + editor->vert_si.nPos - yOldScrollPos; - pLast = p; + ME_ScrollUp( editor, editor->sizeWindow.cy ); + /* Only move the cursor by the amount scrolled. */ + yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos; + last_row = row;
- do { - p = ME_FindItemBack(p, diStartRowOrParagraph); - if (!p) - break; - if (p->type == diParagraph) { /* crossing paragraphs */ - if (p->member.para.prev_para == NULL) - break; - yp = p->member.para.prev_para->member.para.pt.y; - continue; - } - y = yp + p->member.row.pt.y; - if (y < yd) - break; - pLast = p; - } while(1); + while ((row = row_prev_all_paras( row ))) + { + if (row_para( row )->pt.y + row->pt.y < yd) break; + last_row = row; + }
- row_cursor( editor, &pLast->member.row, x, pCursor ); - } + row_cursor( editor, last_row, x, cursor ); + } }
-static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowPageDown( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *pLast; - int x, y; + ME_Row *row = para_end_row( para_prev( editor_end_para( editor ) ) ), *last_row; + int x, yd, old_scroll_pos = editor->vert_si.nPos;
- /* Find y position of the last row */ - pLast = editor->pBuffer->pLast; - y = pLast->member.para.prev_para->member.para.pt.y - + ME_FindItemBack(pLast, diStartRow)->member.row.pt.y; + x = ME_GetXForArrow( editor, cursor );
- x = ME_GetXForArrow(editor, pCursor); + if (editor->vert_si.nPos >= row_para( row )->pt.y + row->pt.y - editor->sizeWindow.cy) + ME_SetCursorToEnd( editor, cursor, FALSE ); + else + { + row = row_from_cursor( cursor );
- if (editor->vert_si.nPos >= y - editor->sizeWindow.cy) - { - ME_SetCursorToEnd(editor, pCursor, FALSE); - } else { - ME_DisplayItem *pRun = run_get_di( pCursor->run ); - ME_DisplayItem *p; - int yd, yp; - int yOldScrollPos = editor->vert_si.nPos; - - p = ME_FindItemBack(pRun, diStartRowOrParagraph); - assert(p->type == diStartRow); - yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y; - y = yp + p->member.row.pt.y; - - /* For native richedit controls: - * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us - * v4.1 can scroll past this position here. */ - ME_ScrollDown(editor, editor->sizeWindow.cy); - /* Only move the cursor by the amount scrolled. */ - yd = y + editor->vert_si.nPos - yOldScrollPos; - pLast = p; + /* For native richedit controls: + * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us + * v4.1 can scroll past this position here. */ + ME_ScrollDown( editor, editor->sizeWindow.cy ); + /* Only move the cursor by the amount scrolled. */ + yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos; + last_row = row;
- do { - p = ME_FindItemFwd(p, diStartRowOrParagraph); - if (!p) - break; - if (p->type == diParagraph) { - yp = p->member.para.pt.y; - continue; - } - y = yp + p->member.row.pt.y; - if (y >= yd) - break; - pLast = p; - } while(1); + while ((row = row_next_all_paras( row ))) + { + if (row_para( row )->pt.y + row->pt.y >= yd) break; + last_row = row; + }
- row_cursor( editor, &pLast->member.row, x, pCursor ); - } + row_cursor( editor, last_row, x, cursor ); + } }
static void ME_ArrowHome( ME_TextEditor *editor, ME_Cursor *cursor ) diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index c29619cc793..e7ae7b806be 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -115,8 +115,11 @@ ME_Run *row_first_run( ME_Row *row ) DECLSPEC_HIDDEN; ME_Row *row_from_cursor( ME_Cursor *cursor ) DECLSPEC_HIDDEN; ME_Row *row_from_row_number( ME_TextEditor *editor, int row_num ) DECLSPEC_HIDDEN; ME_Row *row_next( ME_Row *row ) DECLSPEC_HIDDEN; +ME_Row *row_next_all_paras( ME_Row *row ) DECLSPEC_HIDDEN; ME_Run *row_next_run( ME_Row *row, ME_Run *run ) DECLSPEC_HIDDEN; int row_number_from_char_ofs( ME_TextEditor *editor, int ofs ) DECLSPEC_HIDDEN; +ME_Paragraph *row_para( ME_Row *row ) DECLSPEC_HIDDEN; +ME_Row *row_prev_all_paras( ME_Row *row ) DECLSPEC_HIDDEN; static inline ME_DisplayItem *row_get_di( ME_Row *row ) { return (ME_DisplayItem *)((ptrdiff_t)row - offsetof(ME_DisplayItem, member)); diff --git a/dlls/riched20/row.c b/dlls/riched20/row.c index f5d3ad15701..715d2adbf62 100644 --- a/dlls/riched20/row.c +++ b/dlls/riched20/row.c @@ -33,6 +33,24 @@ ME_Row *row_next( ME_Row *row ) return &item->member.row; }
+ME_Row *row_next_all_paras( ME_Row *row ) +{ + ME_DisplayItem *item; + + item = ME_FindItemFwd( row_get_di( row ), diStartRow ); + if (!item) return NULL; + return &item->member.row; +} + +ME_Row *row_prev_all_paras( ME_Row *row ) +{ + ME_DisplayItem *item; + + item = ME_FindItemBack( row_get_di( row ), diStartRow ); + if (!item) return NULL; + return &item->member.row; +} + ME_Run *row_first_run( ME_Row *row ) { ME_DisplayItem *item; @@ -82,6 +100,14 @@ void row_end_cursor( ME_Row *row, ME_Cursor *cursor, BOOL include_eop ) cursor->nOffset = (item->type == diStartRow || include_eop) ? cursor->run->len : 0; }
+ME_Paragraph *row_para( ME_Row *row ) +{ + ME_Cursor cursor; + + row_first_cursor( row, &cursor ); + return cursor.para; +} + ME_Row *row_from_row_number( ME_TextEditor *editor, int row_num ) { ME_Paragraph *para = editor_first_para( editor );