Huw Davies : riched20: Use row ptrs in the page up/down handlers.

Alexandre Julliard julliard at winehq.org
Mon Nov 9 15:11:50 CST 2020


Module: wine
Branch: master
Commit: ab95fb31fc0e81d802064ba328bcb592ef57f49b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ab95fb31fc0e81d802064ba328bcb592ef57f49b

Author: Huw Davies <huw at codeweavers.com>
Date:   Mon Nov  9 08:45:04 2020 +0000

riched20: Use row ptrs in the page up/down handlers.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 );




More information about the wine-cvs mailing list