riched20: Add support for arabic number labelled lists.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4116d72078
commit
db783986dc
|
@ -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, ¶->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_num );
|
||||
if (para->next_para->type != diParagraph) break;
|
||||
para = ¶->next_para->member.para;
|
||||
} while (para_num_same_list( ¶->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(©, ¶->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, © );
|
||||
}
|
||||
}
|
||||
|
||||
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++)
|
||||
|
|
Loading…
Reference in New Issue