forked from Mirrors/wine-wine
riched20: Add support for displaying bulleted lists.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>oldstable
parent
d132009ae9
commit
8a428d52a7
|
@ -217,6 +217,8 @@ BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt) D
|
|||
void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN;
|
||||
void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN;
|
||||
void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN;
|
||||
void para_num_init( ME_Context *c, ME_Paragraph *para ) DECLSPEC_HIDDEN;
|
||||
void para_num_clear( struct para_num *pn ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* paint.c */
|
||||
void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -188,6 +188,14 @@ typedef struct tagME_BorderRect
|
|||
ME_Border right;
|
||||
} ME_BorderRect;
|
||||
|
||||
struct para_num
|
||||
{
|
||||
ME_Style *style;
|
||||
ME_String *text;
|
||||
INT width;
|
||||
POINT pt;
|
||||
};
|
||||
|
||||
typedef struct tagME_Paragraph
|
||||
{
|
||||
PARAFORMAT2 fmt;
|
||||
|
@ -201,6 +209,7 @@ typedef struct tagME_Paragraph
|
|||
POINT pt;
|
||||
int nHeight, nWidth;
|
||||
int nRows;
|
||||
struct para_num para_num;
|
||||
ME_Run *eop_run; /* ptr to the end-of-para run */
|
||||
struct tagME_DisplayItem *prev_para, *next_para;
|
||||
} ME_Paragraph;
|
||||
|
|
|
@ -164,6 +164,7 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item)
|
|||
if (item->type==diParagraph)
|
||||
{
|
||||
ME_DestroyString(item->member.para.text);
|
||||
para_num_clear( &item->member.para.para_num );
|
||||
}
|
||||
|
||||
if (item->type==diRun)
|
||||
|
|
|
@ -898,6 +898,25 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph)
|
|||
}
|
||||
}
|
||||
|
||||
static void draw_para_number( ME_Context *c, ME_DisplayItem *p )
|
||||
{
|
||||
ME_Paragraph *para = &p->member.para;
|
||||
HFONT old_font;
|
||||
int x, y;
|
||||
|
||||
if (para->fmt.wNumbering)
|
||||
{
|
||||
old_font = ME_SelectStyleFont( c, para->para_num.style );
|
||||
|
||||
x = c->pt.x + para->para_num.pt.x;
|
||||
y = c->pt.y + para->pt.y + para->para_num.pt.y;
|
||||
|
||||
ExtTextOutW( c->hDC, x, y, 0, NULL, para->para_num.text->szData, para->para_num.text->nLen, NULL );
|
||||
|
||||
ME_UnselectStyleFont( c, para->para_num.style, old_font );
|
||||
}
|
||||
}
|
||||
|
||||
static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
|
||||
{
|
||||
int align = SetTextAlign(c->hDC, TA_BASELINE);
|
||||
|
@ -1023,6 +1042,7 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
|
|||
}
|
||||
|
||||
ME_DrawTableBorders(c, paragraph);
|
||||
draw_para_number(c, paragraph);
|
||||
|
||||
SetTextAlign(c->hDC, align);
|
||||
}
|
||||
|
|
|
@ -128,6 +128,55 @@ static void ME_UpdateTableFlags(ME_DisplayItem *para)
|
|||
para->member.para.fmt.wEffects &= ~PFE_TABLE;
|
||||
}
|
||||
|
||||
void para_num_init( ME_Context *c, ME_Paragraph *para )
|
||||
{
|
||||
ME_Style *style;
|
||||
CHARFORMAT2W cf;
|
||||
static const WCHAR bullet_font[] = {'S','y','m','b','o','l',0};
|
||||
static const WCHAR bullet_str[] = {0xb7, 0};
|
||||
static const WCHAR spaceW[] = {' ', 0};
|
||||
HFONT old_font;
|
||||
SIZE sz;
|
||||
|
||||
if (para->para_num.style && para->para_num.text) return;
|
||||
|
||||
if (!para->para_num.style)
|
||||
{
|
||||
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 );
|
||||
|
||||
para->para_num.style = style;
|
||||
}
|
||||
|
||||
if (!para->para_num.text)
|
||||
{
|
||||
para->para_num.text = ME_MakeStringConst( bullet_str, 1 );
|
||||
}
|
||||
|
||||
old_font = ME_SelectStyleFont( c, para->para_num.style );
|
||||
GetTextExtentPointW( c->hDC, para->para_num.text->szData, para->para_num.text->nLen, &sz );
|
||||
para->para_num.width = sz.cx;
|
||||
GetTextExtentPointW( c->hDC, spaceW, 1, &sz );
|
||||
para->para_num.width += sz.cx;
|
||||
ME_UnselectStyleFont( c, para->para_num.style, old_font );
|
||||
}
|
||||
|
||||
void para_num_clear( struct para_num *pn )
|
||||
{
|
||||
if (pn->style)
|
||||
{
|
||||
ME_ReleaseStyle( pn->style );
|
||||
pn->style = NULL;
|
||||
}
|
||||
ME_DestroyString( pn->text );
|
||||
pn->text = NULL;
|
||||
}
|
||||
|
||||
static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *pFmt)
|
||||
{
|
||||
PARAFORMAT2 copy;
|
||||
|
|
|
@ -37,8 +37,10 @@ typedef struct tagME_WrapContext
|
|||
{
|
||||
ME_Style *style;
|
||||
ME_Context *context;
|
||||
int nLeftMargin, nRightMargin, nFirstMargin;
|
||||
int nAvailWidth;
|
||||
int nLeftMargin, nRightMargin;
|
||||
int nFirstMargin; /* Offset to first line's text, always to the text itself even if a para number is present */
|
||||
int nParaNumOffset; /* Offset to the para number */
|
||||
int nAvailWidth; /* Width avail for text to wrap into. Does not include any para number text */
|
||||
int nRow;
|
||||
POINT pt;
|
||||
BOOL bOverflown, bWordWrap;
|
||||
|
@ -303,7 +305,12 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
|
|||
BOOL bSkippingSpaces = TRUE;
|
||||
int ascent = 0, descent = 0, width=0, shift = 0, align = 0;
|
||||
|
||||
/* wrap text */
|
||||
/* Include height of para numbering label */
|
||||
if (wc->nRow == 0 && para->fmt.wNumbering)
|
||||
{
|
||||
ascent = para->para_num.style->tm.tmAscent;
|
||||
descent = para->para_num.style->tm.tmDescent;
|
||||
}
|
||||
|
||||
for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev)
|
||||
{
|
||||
|
@ -367,6 +374,13 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
|
|||
p->member.run.pt.x += row->member.row.nLMargin+shift;
|
||||
}
|
||||
}
|
||||
|
||||
if (wc->nRow == 0 && para->fmt.wNumbering)
|
||||
{
|
||||
para->para_num.pt.x = wc->nParaNumOffset + shift;
|
||||
para->para_num.pt.y = wc->pt.y + row->member.row.nBaseline;
|
||||
}
|
||||
|
||||
ME_InsertBefore(wc->pRowStart, row);
|
||||
wc->nRow++;
|
||||
wc->pt.y += row->member.row.nHeight;
|
||||
|
@ -869,6 +883,9 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
|
|||
}
|
||||
ME_PrepareParagraphForWrapping(c, tp);
|
||||
|
||||
/* Calculate paragraph numbering label */
|
||||
para_num_init( c, &tp->member.para );
|
||||
|
||||
/* For now treating all non-password text as complex for better testing */
|
||||
if (!c->editor->cPasswordMask /* &&
|
||||
ScriptIsComplex( tp->member.para.text->szData, tp->member.para.text->nLen, SIC_COMPLEX ) == S_OK */)
|
||||
|
@ -883,6 +900,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
|
|||
wc.pPara = tp;
|
||||
/* wc.para_style = tp->member.para.style; */
|
||||
wc.style = NULL;
|
||||
wc.nParaNumOffset = 0;
|
||||
if (tp->member.para.nFlags & MEPF_ROWEND) {
|
||||
wc.nFirstMargin = wc.nLeftMargin = wc.nRightMargin = 0;
|
||||
} else {
|
||||
|
@ -890,8 +908,15 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
|
|||
if (tp->member.para.pCell) {
|
||||
dxStartIndent += ME_GetTableRowEnd(tp)->member.para.fmt.dxOffset;
|
||||
}
|
||||
wc.nLeftMargin = ME_twips2pointsX(c, dxStartIndent + pFmt->dxOffset);
|
||||
wc.nFirstMargin = ME_twips2pointsX(c, dxStartIndent);
|
||||
wc.nLeftMargin = wc.nFirstMargin + ME_twips2pointsX(c, pFmt->dxOffset);
|
||||
if (pFmt->wNumbering)
|
||||
{
|
||||
wc.nParaNumOffset = wc.nFirstMargin;
|
||||
dxStartIndent = max( ME_twips2pointsX(c, pFmt->wNumberingTab),
|
||||
tp->member.para.para_num.width );
|
||||
wc.nFirstMargin += dxStartIndent;
|
||||
}
|
||||
wc.nRightMargin = ME_twips2pointsX(c, pFmt->dxRightIndent);
|
||||
|
||||
if (wc.nFirstMargin < 0)
|
||||
|
|
Loading…
Reference in New Issue