Commit 421c5b0e authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

richedit: Borders are now drawn for tables and nested tables.

parent 967c148a
......@@ -451,6 +451,10 @@ static void ME_RTFParAttrHook(RTF_Info *info)
switch(info->rtfMinor)
{
case rtfParDef: /* restores default paragraph attributes */
if (!info->editor->bEmulateVersion10) /* v4.1 */
info->borderType = RTFBorderParaLeft;
else /* v1.0 - 3.0 */
info->borderType = RTFBorderParaTop;
fmt.dwMask = PFM_ALIGNMENT | PFM_BORDER | PFM_LINESPACING | PFM_TABSTOPS |
PFM_OFFSET | PFM_RIGHTINDENT | PFM_SPACEAFTER | PFM_SPACEBEFORE |
PFM_STARTINDENT;
......@@ -656,6 +660,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt.wNumberingStart = info->rtfParam;
break;
case rtfBorderLeft:
info->borderType = RTFBorderParaLeft;
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
......@@ -667,6 +672,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt.dwMask = PFM_BORDER;
break;
case rtfBorderRight:
info->borderType = RTFBorderParaRight;
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
......@@ -678,6 +684,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt.dwMask = PFM_BORDER;
break;
case rtfBorderTop:
info->borderType = RTFBorderParaTop;
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
......@@ -689,6 +696,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt.dwMask = PFM_BORDER;
break;
case rtfBorderBottom:
info->borderType = RTFBorderParaBottom;
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
......@@ -735,11 +743,24 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt.dwMask = PFM_BORDER;
break;
case rtfBorderWidth:
{
int borderSide = info->borderType & RTFBorderSideMask;
RTFTable *tableDef = info->tableDef;
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorderWidth |= ((info->rtfParam / 15) & 7) << 8;
if ((info->borderType & RTFBorderTypeMask) == RTFBorderTypeCell)
{
RTFBorder *border;
if (!tableDef || tableDef->numCellsDefined >= MAX_TABLE_CELLS)
break;
border = &tableDef->cells[tableDef->numCellsDefined].border[borderSide];
border->width = info->rtfParam;
break;
}
fmt.dwMask = PFM_BORDER;
break;
}
case rtfBorderSpace:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
......@@ -760,6 +781,10 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
{
case rtfRowDef:
{
if (!info->editor->bEmulateVersion10) /* v4.1 */
info->borderType = 0; /* Not sure */
else /* v1.0 - 3.0 */
info->borderType = RTFBorderRowTop;
if (!info->tableDef) {
info->tableDef = ME_MakeTableDef(info->editor);
} else {
......@@ -786,6 +811,30 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
}
info->tableDef->numCellsDefined++;
break;
case rtfRowBordTop:
info->borderType = RTFBorderRowTop;
break;
case rtfRowBordLeft:
info->borderType = RTFBorderRowLeft;
break;
case rtfRowBordBottom:
info->borderType = RTFBorderRowBottom;
break;
case rtfRowBordRight:
info->borderType = RTFBorderRowRight;
break;
case rtfCellBordTop:
info->borderType = RTFBorderCellTop;
break;
case rtfCellBordLeft:
info->borderType = RTFBorderCellLeft;
break;
case rtfCellBordBottom:
info->borderType = RTFBorderCellBottom;
break;
case rtfCellBordRight:
info->borderType = RTFBorderCellRight;
break;
case rtfRowGapH:
if (info->tableDef)
info->tableDef->gapH = info->rtfParam;
......@@ -882,6 +931,10 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
for (i = 0; i < tableDef->numCellsDefined; i++)
{
cell->member.cell.nRightBoundary = tableDef->cells[i].rightBoundary;
cell->member.cell.border.top.width = tableDef->cells[i].border[0].width;
cell->member.cell.border.left.width = tableDef->cells[i].border[1].width;
cell->member.cell.border.bottom.width = tableDef->cells[i].border[2].width;
cell->member.cell.border.right.width = tableDef->cells[i].border[3].width;
cell = cell->member.cell.next_cell;
if (!cell)
{
......
......@@ -165,6 +165,19 @@ typedef struct tagME_Document {
int last_wrapped_line;
} ME_Document;
typedef struct tagME_Border
{
int width;
} ME_Border;
typedef struct tagME_BorderRect
{
ME_Border top;
ME_Border left;
ME_Border bottom;
ME_Border right;
} ME_BorderRect;
typedef struct tagME_Paragraph
{
PARAFORMAT2 *pFmt;
......@@ -184,8 +197,10 @@ typedef struct tagME_Cell /* v4.1 */
{
int nNestingLevel; /* 0 for normal cells, and greater for nested cells */
int nRightBoundary;
ME_BorderRect border;
POINT pt;
int nHeight, nWidth;
int yTextOffset; /* The text offset is caused by the largest top border. */
struct tagME_DisplayItem *prev_cell, *next_cell, *parent_cell;
} ME_Cell;
......
......@@ -247,6 +247,7 @@ void RTFInit(RTF_Info *info)
info->tableDef = NULL;
info->nestingLevel = 0;
info->canInheritInTbl = FALSE;
info->borderType = 0;
}
/*
......
......@@ -950,6 +950,7 @@ typedef struct RTFFont RTFFont;
typedef struct RTFColor RTFColor;
typedef struct RTFStyle RTFStyle;
typedef struct RTFStyleElt RTFStyleElt;
typedef struct RTFBorder RTFBorder;
typedef struct RTFCell RTFCell;
typedef struct RTFTable RTFTable;
......@@ -1006,10 +1007,15 @@ struct RTFStyleElt
RTFStyleElt *rtfNextSE; /* next element in style */
};
struct RTFBorder
{
int width;
};
struct RTFCell
{
int rightBoundary;
RTFBorder border[4];
};
......@@ -1019,6 +1025,8 @@ struct RTFTable
int numCellsDefined;
int gapH, leftEdge;
/* borders for the table row */
RTFBorder border[6];
/* Used in v1.0 - v3.0 */
int numCellsInserted;
......@@ -1033,6 +1041,40 @@ struct RTFTable
RTFTable *parent;
};
# define RTFBorderTypeNone 0x00
# define RTFBorderTypePara 0x10 /* for \brdrX control words */
# define RTFBorderTypeRow 0x20 /* for \trbrdrX control words */
# define RTFBorderTypeCell 0x30 /* for \clbrdrX control words */
# define RTFBorderTypeMask 0xf0
/* The X in the control words \brdrX \trbrdrX and \clbrdrX mentioned above
* should be one of t, l, b, r which stand for top, left, bottom, right
* respectively. */
# define RTFBorderSideTop 0x00
# define RTFBorderSideLeft 0x01
# define RTFBorderSideBottom 0x02
# define RTFBorderSideRight 0x03
# define RTFBorderSideHorizontal 0x04
# define RTFBorderSideVertical 0x05
# define RTFBorderSideMask 0x0f
/* Here are the values from the border types and sides put together. */
# define RTFBorderParaTop 0x10
# define RTFBorderParaLeft 0x11
# define RTFBorderParaBottom 0x12
# define RTFBorderParaRight 0x13
# define RTFBorderRowTop 0x20
# define RTFBorderRowLeft 0x21
# define RTFBorderRowBottom 0x22
# define RTFBorderRowRight 0x23
# define RTFBorderRowHorizontal 0x24
# define RTFBorderRowVertical 0x25
# define RTFBorderCellTop 0x30
# define RTFBorderCellLeft 0x31
# define RTFBorderCellBottom 0x32
# define RTFBorderCellRight 0x33
/*
* Return pointer to new element of type t, or NULL
* if no memory available.
......@@ -1141,6 +1183,7 @@ struct _RTF_Info {
RTFTable *tableDef;
int nestingLevel;
BOOL canInheritInTbl;
int borderType; /* value corresponds to the RTFBorder constants. */
};
......
......@@ -608,6 +608,7 @@ struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor)
void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef)
{
ZeroMemory(tableDef->cells, sizeof(tableDef->cells));
ZeroMemory(tableDef->border, sizeof(tableDef->border));
tableDef->numCellsDefined = 0;
tableDef->leftEdge = 0;
if (!editor->bEmulateVersion10) /* v4.1 */
......
......@@ -606,8 +606,24 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
{
ME_DisplayItem *cell = ME_FindItemFwd(item, diCell);
ME_DisplayItem *endRowPara;
int borderWidth = 0;
cell->member.cell.pt = c.pt;
endRowPara = ME_GetTableRowEnd(item);
/* Offset the text by the largest top border width. */
while (cell->member.cell.next_cell) {
borderWidth = max(borderWidth, cell->member.cell.border.top.width);
cell = cell->member.cell.next_cell;
}
endRowPara = ME_FindItemFwd(cell, diParagraph);
assert(endRowPara->member.para.nFlags & MEPF_ROWEND);
if (borderWidth > 0)
{
borderWidth = max(ME_twips2pointsY(&c, borderWidth), 1);
while (cell) {
cell->member.cell.yTextOffset = borderWidth;
cell = cell->member.cell.prev_cell;
}
c.pt.y += borderWidth;
}
if (endRowPara->member.para.pFmt->dxStartIndent > 0)
{
int dxStartIndent = endRowPara->member.para.pFmt->dxStartIndent;
......@@ -620,13 +636,26 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
{
/* Set all the cells to the height of the largest cell */
ME_DisplayItem *startRowPara;
int prevHeight, nHeight;
int prevHeight, nHeight, bottomBorder = 0;
ME_DisplayItem *cell = ME_FindItemBack(item, diCell);
if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWSTART))
{
/* Last row, the bottom border is added to the height. */
cell = cell->member.cell.prev_cell;
while (cell)
{
bottomBorder = max(bottomBorder, cell->member.cell.border.bottom.width);
cell = cell->member.cell.prev_cell;
}
bottomBorder = ME_twips2pointsY(&c, bottomBorder);
cell = ME_FindItemBack(item, diCell);
}
prevHeight = cell->member.cell.nHeight;
nHeight = cell->member.cell.prev_cell->member.cell.nHeight;
nHeight = cell->member.cell.prev_cell->member.cell.nHeight + bottomBorder;
cell->member.cell.nHeight = nHeight;
item->member.para.nHeight = nHeight;
cell = cell->member.cell.prev_cell;
cell->member.cell.nHeight = nHeight;
while (cell->member.cell.prev_cell)
{
cell = cell->member.cell.prev_cell;
......@@ -664,6 +693,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
c.pt.x = cell->pt.x + cell->nWidth;
c.pt.y = cell->pt.y;
cell->next_cell->member.cell.pt = c.pt;
c.pt.y += cell->yTextOffset;
}
else
{
......
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