Commit db783986 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

riched20: Add support for arabic number labelled lists.

parent 4116d720
......@@ -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;
......
......@@ -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 */
......
......@@ -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++)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment