richedit: Properly restore style after end of rtf group. (Bug 18409)

Dylan Smith dylan.ah.smith at gmail.com
Fri Jul 17 12:24:13 CDT 2009


Rich text files have groupings of text, where styles are pushed onto the
stack when encountering a start of the group, then popped at the end of
the group.  This was being handled improperly before, because a single
styleChanged flag was being stored to keep track of whether the style
needed to be restored at the end of a group. This fails to work properly
since the single flag isn't keeping track of all the levels of the
stack, so some styles are not restored properly.

This following test case shows the bug:
{\rtf{\v{\par}}text}

Previously the invisible control word, \v, was applied to the text in
the outer group.

This was fixed by using the ME_Style objects instead of CHARFORMAT2W
structures for stack entries, since ME_Style objects are handled with
reference counting. Releasing a style is quick if no changes are
made, so the code remains efficient.
---
 dlls/riched20/editor.c |   19 ++++++++-----------
 dlls/riched20/reader.c |    4 ++++
 dlls/riched20/rtf.h    |    2 +-
 3 files changed, 13 insertions(+), 12 deletions(-)
-------------- next part --------------
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 14a7246..c3cd187 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -1345,7 +1345,8 @@ static void ME_RTFReadHook(RTF_Info *info)
       {
         case rtfBeginGroup:
           if (info->stackTop < maxStack) {
-            info->stack[info->stackTop].fmt = info->style->fmt;
+            info->stack[info->stackTop].style = info->style;
+            ME_AddRefStyle(info->style);
             info->stack[info->stackTop].codePage = info->codePage;
             info->stack[info->stackTop].unicodeLength = info->unicodeLength;
           }
@@ -1354,7 +1355,6 @@ static void ME_RTFReadHook(RTF_Info *info)
           break;
         case rtfEndGroup:
         {
-          ME_Style *s;
           RTFFlushOutputBuffer(info);
           info->stackTop--;
           if (info->stackTop<=0) {
@@ -1362,15 +1362,12 @@ static void ME_RTFReadHook(RTF_Info *info)
             return;
           }
           assert(info->stackTop >= 0);
-          if (info->styleChanged)
-          {
-            /* FIXME too slow ? how come ? */
-            s = ME_ApplyStyle(info->style, &info->stack[info->stackTop].fmt);
-            ME_ReleaseStyle(info->style);
-            info->style = s;
-            info->codePage = info->stack[info->stackTop].codePage;
-            info->unicodeLength = info->stack[info->stackTop].unicodeLength;
-          }
+
+          ME_ReleaseStyle(info->style);
+          info->style = info->stack[info->stackTop].style;
+          ME_AddRefStyle(info->style);
+          info->codePage = info->stack[info->stackTop].codePage;
+          info->unicodeLength = info->stack[info->stackTop].unicodeLength;
           break;
         }
       }
diff --git a/dlls/riched20/reader.c b/dlls/riched20/reader.c
index 0462f71..a589a8e 100644
--- a/dlls/riched20/reader.c
+++ b/dlls/riched20/reader.c
@@ -442,7 +442,11 @@ static void RTFUngetToken(RTF_Info *info)
 	 * increment the value to compensate for it being decremented
 	 * twice due to the RTFUngetToken. */
 	if(RTFCheckCM (info, rtfGroup, rtfEndGroup))
+	{
+		info->stack[info->stackTop].style = info->style;
+		ME_AddRefStyle(info->style);
 		info->stackTop++;
+	}
 }
 
 
diff --git a/dlls/riched20/rtf.h b/dlls/riched20/rtf.h
index 3277301..d8ac323 100644
--- a/dlls/riched20/rtf.h
+++ b/dlls/riched20/rtf.h
@@ -1095,7 +1095,7 @@ typedef	void (*RTFFuncPtr) (RTF_Info *);		/* generic function pointer */
 
 /* RTF parser stack element */
 struct tagRTFState {
-        CHARFORMAT2W fmt;
+        ME_Style *style;
         int codePage;
         int unicodeLength;
 };


More information about the wine-patches mailing list