[PATCH 1/4] riched20: Add support for arabic number labelled lists.

Huw Davies huw at codeweavers.com
Mon Oct 10 07:13:02 CDT 2016


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/riched20/editor.h |   1 +
 dlls/riched20/para.c   | 102 ++++++++++++++++++++++++++++++++++++++++++++++---
 dlls/riched20/string.c |   6 +--
 3 files changed, 100 insertions(+), 9 deletions(-)

diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 7d46692..237036c 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -101,6 +101,7 @@ void ME_DumpDocument(ME_TextBuffer *buffer) DECLSPEC_HIDDEN;
 ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) DECLSPEC_HIDDEN;
 ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars) DECLSPEC_HIDDEN;
 ME_String *ME_MakeStringConst(const WCHAR *str, int len) DECLSPEC_HIDDEN;
+ME_String *ME_MakeStringEmpty(int len) DECLSPEC_HIDDEN;
 void ME_DestroyString(ME_String *s) DECLSPEC_HIDDEN;
 BOOL ME_AppendString(ME_String *s, const WCHAR *append, int len) DECLSPEC_HIDDEN;
 ME_String *ME_VSplitString(ME_String *orig, int nVPos) DECLSPEC_HIDDEN;
diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c
index 3c62da2..ffd0a1d 100644
--- a/dlls/riched20/para.c
+++ b/dlls/riched20/para.c
@@ -128,6 +128,59 @@ static void ME_UpdateTableFlags(ME_DisplayItem *para)
     para->member.para.fmt.wEffects &= ~PFE_TABLE;
 }
 
+static inline BOOL para_num_same_list( const PARAFORMAT2 *item, const PARAFORMAT2 *base )
+{
+    return item->wNumbering == base->wNumbering &&
+        item->wNumberingStart == base->wNumberingStart &&
+        item->wNumberingStyle == base->wNumberingStyle &&
+        !(item->wNumberingStyle & PFNS_NEWNUMBER);
+}
+
+static int para_num_get_num( ME_Paragraph *para )
+{
+    ME_DisplayItem *prev;
+    int num = para->fmt.wNumberingStart;
+
+    for (prev = para->prev_para; prev->type == diParagraph;
+         para = &prev->member.para, prev = prev->member.para.prev_para, num++)
+    {
+        if (!para_num_same_list( &prev->member.para.fmt, &para->fmt )) break;
+    }
+    return num;
+}
+
+static ME_String *para_num_get_str( ME_Paragraph *para, WORD num )
+{
+    /* max 5 digits + '(' + ')' */
+    ME_String *str = ME_MakeStringEmpty( 5 + 2 );
+    WCHAR *p = str->szData;
+    static const WCHAR fmtW[] = {'%', 'd', 0};
+
+    if (!str) return NULL;
+
+    if ((para->fmt.wNumberingStyle & 0xf00) == PFNS_PARENS)
+        *p++ = '(';
+
+    p += sprintfW( p, fmtW, num );
+
+    switch (para->fmt.wNumberingStyle & 0xf00)
+    {
+    case PFNS_PARENS:
+    case PFNS_PAREN:
+        *p++ = ')';
+        *p = 0;
+        break;
+
+    case PFNS_PERIOD:
+        *p++ = '.';
+        *p = 0;
+        break;
+    }
+
+    str->nLen = p - str->szData;
+    return str;
+}
+
 void para_num_init( ME_Context *c, ME_Paragraph *para )
 {
     ME_Style *style;
@@ -144,18 +197,28 @@ void para_num_init( ME_Context *c, ME_Paragraph *para )
     {
         style = para->eop_run->style;
 
-        cf.cbSize = sizeof(cf);
-        cf.dwMask = CFM_FACE | CFM_CHARSET;
-        memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) );
-        cf.bCharSet = SYMBOL_CHARSET;
-        style = ME_ApplyStyle( c->editor, style, &cf );
+        if (para->fmt.wNumbering == PFN_BULLET)
+        {
+            cf.cbSize = sizeof(cf);
+            cf.dwMask = CFM_FACE | CFM_CHARSET;
+            memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) );
+            cf.bCharSet = SYMBOL_CHARSET;
+            style = ME_ApplyStyle( c->editor, style, &cf );
+        }
+        else
+        {
+            ME_AddRefStyle( style );
+        }
 
         para->para_num.style = style;
     }
 
     if (!para->para_num.text)
     {
-        para->para_num.text = ME_MakeStringConst( bullet_str, 1 );
+        if (para->fmt.wNumbering != PFN_BULLET)
+            para->para_num.text = para_num_get_str( para, para_num_get_num( para ) );
+        else
+            para->para_num.text = ME_MakeStringConst( bullet_str, 1 );
     }
 
     old_font = ME_SelectStyleFont( c, para->para_num.style );
@@ -177,6 +240,17 @@ void para_num_clear( struct para_num *pn )
     pn->text = NULL;
 }
 
+static void para_num_clear_list( ME_Paragraph *para, const PARAFORMAT2 *orig_fmt )
+{
+    do
+    {
+        para->nFlags |= MEPF_REWRAP;
+        para_num_clear( &para->para_num );
+        if (para->next_para->type != diParagraph) break;
+        para = &para->next_para->member.para;
+    } while (para_num_same_list( &para->fmt, orig_fmt ));
+}
+
 static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *pFmt)
 {
   PARAFORMAT2 copy;
@@ -244,7 +318,15 @@ static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PA
 #undef COPY_FIELD
 
   if (memcmp(&copy, &para->fmt, sizeof(PARAFORMAT2)))
+  {
     para->nFlags |= MEPF_REWRAP;
+    if (((dwMask & PFM_NUMBERING)      && (copy.wNumbering != para->fmt.wNumbering)) ||
+        ((dwMask & PFM_NUMBERINGSTART) && (copy.wNumberingStart != para->fmt.wNumberingStart)) ||
+        ((dwMask & PFM_NUMBERINGSTYLE) && (copy.wNumberingStyle != para->fmt.wNumberingStyle)))
+    {
+        para_num_clear_list( para, &copy );
+    }
+  }
 
   return TRUE;
 }
@@ -277,6 +359,10 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run,
   run_para = ME_GetParagraph(run);
   assert(run_para->member.para.fmt.cbSize == sizeof(PARAFORMAT2));
 
+  /* Clear any cached para numbering following this paragraph */
+  if (run_para->member.para.fmt.wNumbering)
+      para_num_clear_list( &run_para->member.para, &run_para->member.para.fmt );
+
   new_para->member.para.text = ME_VSplitString( run_para->member.para.text, run->member.run.nCharOfs );
 
   end_run = ME_MakeRun(style, run_flags);
@@ -399,6 +485,10 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
   assert(tp->member.para.next_para);
   assert(tp->member.para.next_para->type == diParagraph);
 
+  /* Clear any cached para numbering following this paragraph */
+  if (tp->member.para.fmt.wNumbering)
+      para_num_clear_list( &tp->member.para, &tp->member.para.fmt );
+
   pNext = tp->member.para.next_para;
 
   /* Need to locate end-of-paragraph run here, in order to know end_len */
diff --git a/dlls/riched20/string.c b/dlls/riched20/string.c
index 47aceca..cfb149a 100644
--- a/dlls/riched20/string.c
+++ b/dlls/riched20/string.c
@@ -55,7 +55,7 @@ static void heap_string_free(ME_String *s)
 }
 
 /* Create a buffer (uninitialized string) of size nMaxChars */
-static ME_String *ME_MakeStringB(int nMaxChars)
+ME_String *ME_MakeStringEmpty(int nMaxChars)
 {
   ME_String *s = make_string( heap_string_free );
 
@@ -74,7 +74,7 @@ static ME_String *ME_MakeStringB(int nMaxChars)
 
 ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars)
 {
-  ME_String *s = ME_MakeStringB(nMaxChars);
+  ME_String *s = ME_MakeStringEmpty(nMaxChars);
 
   if (!s) return NULL;
   memcpy(s->szData, szText, s->nLen * sizeof(WCHAR));
@@ -85,7 +85,7 @@ ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars)
 ME_String *ME_MakeStringR(WCHAR cRepeat, int nMaxChars)
 {
   int i;
-  ME_String *s = ME_MakeStringB(nMaxChars);
+  ME_String *s = ME_MakeStringEmpty(nMaxChars);
 
   if (!s) return NULL;
   for (i = 0; i < nMaxChars; i++)
-- 
2.8.2




More information about the wine-patches mailing list