[PATCH 15/24] [RichEdit]: now drawing the paragraph borders (if any) from paraformat2
Eric Pouech
eric.pouech at orange.fr
Tue Jan 1 15:04:46 CST 2008
A+
---
dlls/riched20/editor.h | 3 +
dlls/riched20/paint.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++
dlls/riched20/wrap.c | 17 ++++++
3 files changed, 147 insertions(+), 1 deletions(-)
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 93789d6..f67b9e7 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -254,6 +254,9 @@ void ME_UpdateScrollBar(ME_TextEditor *editor);
int ME_GetYScrollPos(ME_TextEditor *editor);
BOOL ME_GetYScrollVisible(ME_TextEditor *editor);
+/* other functions in paint.c */
+int ME_GetParaBorderWidth(ME_TextEditor *editor, int);
+
/* richole.c */
extern LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *);
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index 8f71fa5..b5211e2 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -306,6 +306,131 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
}
}
+static struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;} border_details[] = {
+ /* none */ {0, 0, PS_SOLID, FALSE},
+ /* 3/4 */ {3, 4, PS_SOLID, FALSE},
+ /* 1 1/2 */ {3, 2, PS_SOLID, FALSE},
+ /* 2 1/4 */ {9, 4, PS_SOLID, FALSE},
+ /* 3 */ {3, 1, PS_SOLID, FALSE},
+ /* 4 1/2 */ {9, 2, PS_SOLID, FALSE},
+ /* 6 */ {6, 1, PS_SOLID, FALSE},
+ /* 3/4 double */ {3, 4, PS_SOLID, TRUE},
+ /* 1 1/2 double */ {3, 2, PS_SOLID, TRUE},
+ /* 2 1/4 double */ {9, 4, PS_SOLID, TRUE},
+ /* 3/4 gray */ {3, 4, PS_DOT /* FIXME */, FALSE},
+ /* 1 1/2 dashed */ {3, 2, PS_DASH, FALSE},
+};
+
+static COLORREF pen_colors[16] = {
+ /* Black */ RGB(0x00, 0x00, 0x00), /* Blue */ RGB(0x00, 0x00, 0xFF),
+ /* Cyan */ RGB(0x00, 0xFF, 0xFF), /* Green */ RGB(0x00, 0xFF, 0x00),
+ /* Magenta */ RGB(0xFF, 0x00, 0xFF), /* Red */ RGB(0xFF, 0x00, 0x00),
+ /* Yellow */ RGB(0xFF, 0xFF, 0x00), /* White */ RGB(0xFF, 0xFF, 0xFF),
+ /* Dark blue */ RGB(0x00, 0x00, 0x80), /* Dark cyan */ RGB(0x00, 0x80, 0x80),
+ /* Dark green */ RGB(0x00, 0x80, 0x80), /* Dark magenta */ RGB(0x80, 0x00, 0x80),
+ /* Dark red */ RGB(0x80, 0x00, 0x00), /* Dark yellow */ RGB(0x80, 0x80, 0x00),
+ /* Dark gray */ RGB(0x80, 0x80, 0x80), /* Light gray */ RGB(0xc0, 0xc0, 0xc0),
+};
+
+static int ME_GetBorderPenWidth(ME_TextEditor* editor, int idx)
+{
+ int width;
+
+ if (editor->nZoomNumerator == 0)
+ {
+ width = border_details[idx].width_num + border_details[idx].width_den / 2;
+ width /= border_details[idx].width_den;
+ }
+ else
+ {
+ width = border_details[idx].width_num * editor->nZoomNumerator;
+ width += border_details[idx].width_den * editor->nZoomNumerator / 2;
+ width /= border_details[idx].width_den * editor->nZoomDenominator;
+ }
+ return width;
+}
+
+int ME_GetParaBorderWidth(ME_TextEditor* editor, int flags)
+{
+ int idx = (flags >> 8) & 0xF;
+ int width;
+
+ if (idx >= sizeof(border_details) / sizeof(border_details[0]))
+ {
+ FIXME("Unsupported border value %d\n", idx);
+ return 0;
+ }
+ width = ME_GetBorderPenWidth(editor, idx);
+ if (border_details[idx].dble) width = width * 2 + 1;
+ return width;
+}
+
+static int ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y)
+{
+ HPEN pen, oldpen;
+ POINT pt;
+ int idx, pen_width, border_width;
+ COLORREF pencr;
+
+ if (!(para->pFmt->dwMask & PFM_BORDER)) return 0;
+
+ if (para->pFmt->wBorders & 0x00B0)
+ FIXME("Unsupported border flags %x\n", para->pFmt->wBorders);
+ border_width = ME_GetParaBorderWidth(c->editor, para->pFmt->wBorders);
+ if (border_width == 0 || !(para->pFmt->wBorders & 0xF)) return 0;
+ idx = (para->pFmt->wBorders >> 8) & 0xF;
+
+ if (para->pFmt->wBorders & 64) /* autocolor */
+ pencr = GetSysColor(COLOR_WINDOWTEXT);
+ else
+ pencr = pen_colors[(para->pFmt->wBorders >> 12) & 0xF];
+
+ pen_width = ME_GetBorderPenWidth(c->editor, idx);
+ pen = CreatePen(border_details[idx].pen_style, pen_width, pencr);
+ oldpen = SelectObject(c->hDC, pen);
+ MoveToEx(c->hDC, 0, 0, &pt);
+ if (para->pFmt->wBorders & 1)
+ {
+ MoveToEx(c->hDC, c->rcView.left, y, NULL);
+ LineTo(c->hDC, c->rcView.left, y + para->nHeight);
+ if (border_details[idx].dble) {
+ MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + pen_width + 1, NULL);
+ LineTo(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - pen_width - 1);
+ }
+ }
+ if (para->pFmt->wBorders & 2)
+ {
+ MoveToEx(c->hDC, c->rcView.right, y, NULL);
+ LineTo(c->hDC, c->rcView.right, y + para->nHeight);
+ if (border_details[idx].dble) {
+ MoveToEx(c->hDC, c->rcView.right - pen_width - 1, y + pen_width + 1, NULL);
+ LineTo(c->hDC, c->rcView.right - pen_width - 1, y + para->nHeight - pen_width - 1);
+ }
+ }
+ if (para->pFmt->wBorders & 4)
+ {
+ MoveToEx(c->hDC, c->rcView.left, y, NULL);
+ LineTo(c->hDC, c->rcView.right, y);
+ if (border_details[idx].dble) {
+ MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + pen_width + 1, NULL);
+ LineTo(c->hDC, c->rcView.right - pen_width - 1, y + pen_width + 1);
+ }
+ }
+ if (para->pFmt->wBorders & 8)
+ {
+ MoveToEx(c->hDC, c->rcView.left, y + para->nHeight - 1, NULL);
+ LineTo(c->hDC, c->rcView.right, y + para->nHeight - 1);
+ if (border_details[idx].dble) {
+ MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - 1 - pen_width - 1, NULL);
+ LineTo(c->hDC, c->rcView.right - pen_width - 1, y + para->nHeight - 1 - pen_width - 1);
+ }
+ }
+ MoveToEx(c->hDC, pt.x, pt.y, NULL);
+ SelectObject(c->hDC, oldpen);
+ DeleteObject(pen);
+ return (para->pFmt->wBorders & 4) ? border_width : 0;
+}
+
void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
int align = SetTextAlign(c->hDC, TA_BASELINE);
int dpi = GetDeviceCaps(c->hDC, LOGPIXELSX);
@@ -318,7 +443,7 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
int xs = 0, xe = 0;
BOOL visible = FALSE;
int nMargWidth = 0;
-
+
c->pt.x = c->rcView.left;
rcPara.left = c->rcView.left;
rcPara.right = c->rcView.right;
@@ -332,6 +457,7 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
nMargWidth += ME_twips2points(c, para->pFmt->dxOffset, dpi);
xs = c->rcView.left+nMargWidth;
xe = c->rcView.right - ME_twips2points(c, para->pFmt->dxRightIndent, dpi);
+ y += ME_DrawParaDecoration(c, para, y);
break;
case diStartRow:
y += height;
diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c
index 310aad7..2069261 100644
--- a/dlls/riched20/wrap.c
+++ b/dlls/riched20/wrap.c
@@ -342,6 +342,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD begino
ME_DisplayItem *p;
ME_WrapContext wc;
int dpi = GetDeviceCaps(c->hDC, LOGPIXELSX);
+ int border = 0;
assert(tp->type == diParagraph);
if (!(tp->member.para.nFlags & MEPF_REWRAP)) {
@@ -358,6 +359,19 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD begino
wc.nRow = 0;
wc.pt.x = 0;
wc.pt.y = 0;
+ if (tp->member.para.pFmt->dwMask & PFM_BORDER)
+ {
+ border = ME_GetParaBorderWidth(c->editor, tp->member.para.pFmt->wBorders);
+ if (tp->member.para.pFmt->wBorders & 1) {
+ wc.nFirstMargin += border;
+ wc.nLeftMargin += border;
+ }
+ if (tp->member.para.pFmt->wBorders & 2)
+ wc.nRightMargin -= border;
+ if (tp->member.para.pFmt->wBorders & 4)
+ wc.pt.y += border;
+ }
+
wc.nTotalWidth = c->rcView.right - c->rcView.left;
wc.nAvailWidth = wc.nTotalWidth - wc.nFirstMargin - wc.nRightMargin;
wc.pRowStart = NULL;
@@ -372,6 +386,9 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD begino
p = p->next;
}
ME_WrapEndParagraph(&wc, p);
+ if ((tp->member.para.pFmt->dwMask & PFM_BORDER) && (tp->member.para.pFmt->wBorders & 8))
+ wc.pt.y += border;
+
tp->member.para.nFlags &= ~MEPF_REWRAP;
tp->member.para.nHeight = wc.pt.y;
tp->member.para.nRows = wc.nRow;
More information about the wine-patches
mailing list