Commit 8a428d52 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

riched20: Add support for displaying bulleted lists.

parent d132009a
...@@ -217,6 +217,8 @@ BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt) D ...@@ -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_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN;
void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN;
void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) 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 */ /* paint.c */
void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN;
......
...@@ -188,6 +188,14 @@ typedef struct tagME_BorderRect ...@@ -188,6 +188,14 @@ typedef struct tagME_BorderRect
ME_Border right; ME_Border right;
} ME_BorderRect; } ME_BorderRect;
struct para_num
{
ME_Style *style;
ME_String *text;
INT width;
POINT pt;
};
typedef struct tagME_Paragraph typedef struct tagME_Paragraph
{ {
PARAFORMAT2 fmt; PARAFORMAT2 fmt;
...@@ -201,6 +209,7 @@ typedef struct tagME_Paragraph ...@@ -201,6 +209,7 @@ typedef struct tagME_Paragraph
POINT pt; POINT pt;
int nHeight, nWidth; int nHeight, nWidth;
int nRows; int nRows;
struct para_num para_num;
ME_Run *eop_run; /* ptr to the end-of-para run */ ME_Run *eop_run; /* ptr to the end-of-para run */
struct tagME_DisplayItem *prev_para, *next_para; struct tagME_DisplayItem *prev_para, *next_para;
} ME_Paragraph; } ME_Paragraph;
......
...@@ -164,6 +164,7 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item) ...@@ -164,6 +164,7 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item)
if (item->type==diParagraph) if (item->type==diParagraph)
{ {
ME_DestroyString(item->member.para.text); ME_DestroyString(item->member.para.text);
para_num_clear( &item->member.para.para_num );
} }
if (item->type==diRun) if (item->type==diRun)
......
...@@ -898,6 +898,25 @@ static void ME_DrawTableBorders(ME_Context *c, ME_DisplayItem *paragraph) ...@@ -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) static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
{ {
int align = SetTextAlign(c->hDC, TA_BASELINE); int align = SetTextAlign(c->hDC, TA_BASELINE);
...@@ -1023,6 +1042,7 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) ...@@ -1023,6 +1042,7 @@ static void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph)
} }
ME_DrawTableBorders(c, paragraph); ME_DrawTableBorders(c, paragraph);
draw_para_number(c, paragraph);
SetTextAlign(c->hDC, align); SetTextAlign(c->hDC, align);
} }
......
...@@ -128,6 +128,55 @@ static void ME_UpdateTableFlags(ME_DisplayItem *para) ...@@ -128,6 +128,55 @@ static void ME_UpdateTableFlags(ME_DisplayItem *para)
para->member.para.fmt.wEffects &= ~PFE_TABLE; 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) static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *pFmt)
{ {
PARAFORMAT2 copy; PARAFORMAT2 copy;
......
...@@ -37,8 +37,10 @@ typedef struct tagME_WrapContext ...@@ -37,8 +37,10 @@ typedef struct tagME_WrapContext
{ {
ME_Style *style; ME_Style *style;
ME_Context *context; ME_Context *context;
int nLeftMargin, nRightMargin, nFirstMargin; int nLeftMargin, nRightMargin;
int nAvailWidth; 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; int nRow;
POINT pt; POINT pt;
BOOL bOverflown, bWordWrap; BOOL bOverflown, bWordWrap;
...@@ -303,7 +305,12 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) ...@@ -303,7 +305,12 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
BOOL bSkippingSpaces = TRUE; BOOL bSkippingSpaces = TRUE;
int ascent = 0, descent = 0, width=0, shift = 0, align = 0; 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) 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) ...@@ -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; 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); ME_InsertBefore(wc->pRowStart, row);
wc->nRow++; wc->nRow++;
wc->pt.y += row->member.row.nHeight; wc->pt.y += row->member.row.nHeight;
...@@ -869,6 +883,9 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { ...@@ -869,6 +883,9 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
} }
ME_PrepareParagraphForWrapping(c, 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 */ /* For now treating all non-password text as complex for better testing */
if (!c->editor->cPasswordMask /* && if (!c->editor->cPasswordMask /* &&
ScriptIsComplex( tp->member.para.text->szData, tp->member.para.text->nLen, SIC_COMPLEX ) == S_OK */) 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) { ...@@ -883,6 +900,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
wc.pPara = tp; wc.pPara = tp;
/* wc.para_style = tp->member.para.style; */ /* wc.para_style = tp->member.para.style; */
wc.style = NULL; wc.style = NULL;
wc.nParaNumOffset = 0;
if (tp->member.para.nFlags & MEPF_ROWEND) { if (tp->member.para.nFlags & MEPF_ROWEND) {
wc.nFirstMargin = wc.nLeftMargin = wc.nRightMargin = 0; wc.nFirstMargin = wc.nLeftMargin = wc.nRightMargin = 0;
} else { } else {
...@@ -890,8 +908,15 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { ...@@ -890,8 +908,15 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
if (tp->member.para.pCell) { if (tp->member.para.pCell) {
dxStartIndent += ME_GetTableRowEnd(tp)->member.para.fmt.dxOffset; dxStartIndent += ME_GetTableRowEnd(tp)->member.para.fmt.dxOffset;
} }
wc.nLeftMargin = ME_twips2pointsX(c, dxStartIndent + pFmt->dxOffset);
wc.nFirstMargin = ME_twips2pointsX(c, dxStartIndent); 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); wc.nRightMargin = ME_twips2pointsX(c, pFmt->dxRightIndent);
if (wc.nFirstMargin < 0) if (wc.nFirstMargin < 0)
......
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