diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 15ad39f24b2..2b0703f7b72 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -761,19 +761,16 @@ static void ME_RTFTblAttrHook(RTF_Info *info) case rtfRowDef: { if (!info->tableDef) { - info->tableDef = ALLOC_OBJ(RTFTable); - ZeroMemory(info->tableDef, sizeof(RTFTable)); + info->tableDef = ME_MakeTableDef(info->editor); } else { - ZeroMemory(info->tableDef->cells, sizeof(info->tableDef->cells)); - info->tableDef->numCellsDefined = 0; + ME_InitTableDef(info->editor, info->tableDef); } break; } case rtfCellPos: if (!info->tableDef) { - info->tableDef = ALLOC_OBJ(RTFTable); - ZeroMemory(info->tableDef, sizeof(RTFTable)); + info->tableDef = ME_MakeTableDef(info->editor); } if (info->tableDef->numCellsDefined >= MAX_TABLE_CELLS) break; @@ -789,6 +786,14 @@ static void ME_RTFTblAttrHook(RTF_Info *info) } info->tableDef->numCellsDefined++; break; + case rtfRowGapH: + if (info->tableDef) + info->tableDef->gapH = info->rtfParam; + break; + case rtfRowLeftEdge: + if (info->tableDef) + info->tableDef->leftEdge = info->rtfParam; + break; } } @@ -902,6 +907,8 @@ static void ME_RTFSpecialCharHook(RTF_Info *info) } para = ME_InsertTableRowEndFromCursor(info->editor); + para->member.para.pFmt->dxOffset = abs(info->tableDef->gapH); + para->member.para.pFmt->dxStartIndent = info->tableDef->leftEdge; info->nestingLevel--; if (!info->nestingLevel) { @@ -922,6 +929,8 @@ static void ME_RTFSpecialCharHook(RTF_Info *info) WCHAR endl = '\r'; ME_DisplayItem *para = ME_GetParagraph(info->editor->pCursors[0].pRun); PARAFORMAT2 *pFmt = para->member.para.pFmt; + pFmt->dxOffset = info->tableDef->gapH; + pFmt->dxStartIndent = info->tableDef->leftEdge; while (tableDef->numCellsInserted < tableDef->numCellsDefined) { WCHAR tab = '\t'; diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index b123a2d287a..5e6f4cb502c 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -297,6 +297,8 @@ ME_DisplayItem *ME_GetTableRowStart(ME_DisplayItem *para); void ME_CheckTablesForCorruption(ME_TextEditor *editor); void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars); void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow); +struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor); +void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef); /* undo.c */ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_DisplayItem *pdi); diff --git a/dlls/riched20/rtf.h b/dlls/riched20/rtf.h index d18d2599869..84ddf5ce934 100644 --- a/dlls/riched20/rtf.h +++ b/dlls/riched20/rtf.h @@ -1018,6 +1018,8 @@ struct RTFTable RTFCell cells[MAX_TABLE_CELLS]; int numCellsDefined; + int gapH, leftEdge; + /* Used in v1.0 - v3.0 */ int numCellsInserted; diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index fd3715557f2..bb34ad864ed 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -671,13 +671,21 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run if (run->nFlags & MERF_TAB) { - int pos = 0, i = 0, ppos; + int pos = 0, i = 0, ppos, shift = 0; PARAFORMAT2 *pFmt = para->pFmt; + if (c->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ + pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + /* The horizontal gap shifts the tab positions to leave the gap. */ + shift = pFmt->dxOffset * 2; do { if (i < pFmt->cTabCount) { - pos = pFmt->rgxTabs[i]&0x00FFFFFF; + /* Only one side of the horizontal gap is needed at the end of + * the table row. */ + if (i == pFmt->cTabCount -1) + shift = shift >> 1; + pos = shift + (pFmt->rgxTabs[i]&0x00FFFFFF); i++; } else diff --git a/dlls/riched20/table.c b/dlls/riched20/table.c index a62182598ba..e71350a5bef 100644 --- a/dlls/riched20/table.c +++ b/dlls/riched20/table.c @@ -52,6 +52,7 @@ */ #include "editor.h" +#include "rtf.h" WINE_DEFAULT_DEBUG_CHANNEL(richedit); WINE_DECLARE_DEBUG_CHANNEL(richedit_lists); @@ -594,3 +595,23 @@ void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow) ME_ShowCaret(editor); ME_SendSelChange(editor); } + +struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor) +{ + RTFTable *tableDef = ALLOC_OBJ(RTFTable); + ZeroMemory(tableDef, sizeof(RTFTable)); + if (!editor->bEmulateVersion10) /* v4.1 */ + tableDef->gapH = 10; + return tableDef; +} + +void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef) +{ + ZeroMemory(tableDef->cells, sizeof(tableDef->cells)); + tableDef->numCellsDefined = 0; + tableDef->leftEdge = 0; + if (!editor->bEmulateVersion10) /* v4.1 */ + tableDef->gapH = 10; + else /* v1.0 - 3.0 */ + tableDef->gapH = 0; +} diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 27aec2d6a8b..21121a4909e 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -62,6 +62,11 @@ static void ME_BeginRow(ME_WrapContext *wc, ME_DisplayItem *para) width = cell->nRightBoundary; if (cell->prev_cell) width -= cell->prev_cell->member.cell.nRightBoundary; + if (!cell->prev_cell) + { + int rowIndent = ME_GetTableRowEnd(para)->member.para.pFmt->dxStartIndent; + width -= rowIndent; + } cell->nWidth = max(ME_twips2pointsX(wc->context, width), 0); wc->nAvailWidth = cell->nWidth @@ -427,33 +432,49 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD begino ME_WrapContext wc; int border = 0; int linespace = 0; + PARAFORMAT2 *pFmt; assert(tp->type == diParagraph); if (!(tp->member.para.nFlags & MEPF_REWRAP)) { return; } ME_PrepareParagraphForWrapping(c, tp); + pFmt = tp->member.para.pFmt; wc.context = c; /* wc.para_style = tp->member.para.style; */ wc.style = NULL; - wc.nFirstMargin = ME_twips2pointsX(c, tp->member.para.pFmt->dxStartIndent) + beginofs; - wc.nLeftMargin = wc.nFirstMargin + ME_twips2pointsX(c, tp->member.para.pFmt->dxOffset); - wc.nRightMargin = ME_twips2pointsX(c, tp->member.para.pFmt->dxRightIndent); + if (tp->member.para.nFlags & MEPF_ROWEND) { + wc.nFirstMargin = wc.nLeftMargin = wc.nRightMargin = 0; + } else { + int dxStartIndent = pFmt->dxStartIndent; + if (tp->member.para.pCell) { + dxStartIndent += ME_GetTableRowEnd(tp)->member.para.pFmt->dxOffset; + } + wc.nFirstMargin = ME_twips2pointsX(c, dxStartIndent); + wc.nLeftMargin = wc.nFirstMargin + ME_twips2pointsX(c, pFmt->dxOffset); + wc.nRightMargin = ME_twips2pointsX(c, pFmt->dxRightIndent); + } + if (c->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ + pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + { + wc.nFirstMargin += ME_twips2pointsX(c, pFmt->dxOffset * 2); + } wc.nRow = 0; wc.pt.y = 0; - if (tp->member.para.pFmt->dwMask & PFM_SPACEBEFORE) - wc.pt.y += ME_twips2pointsY(c, tp->member.para.pFmt->dySpaceBefore); - if (tp->member.para.pFmt->dwMask & PFM_BORDER) + if (pFmt->dwMask & PFM_SPACEBEFORE) + wc.pt.y += ME_twips2pointsY(c, pFmt->dySpaceBefore); + if (!(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) && + pFmt->dwMask & PFM_BORDER) { border = ME_GetParaBorderWidth(c->editor, tp->member.para.pFmt->wBorders); - if (tp->member.para.pFmt->wBorders & 1) { + if (pFmt->wBorders & 1) { wc.nFirstMargin += border; wc.nLeftMargin += border; } - if (tp->member.para.pFmt->wBorders & 2) + if (pFmt->wBorders & 2) wc.nRightMargin -= border; - if (tp->member.para.pFmt->wBorders & 4) + if (pFmt->wBorders & 4) wc.pt.y += border; } @@ -470,10 +491,11 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD begino wc.pt.y += linespace; } ME_WrapEndParagraph(&wc, p); - if ((tp->member.para.pFmt->dwMask & PFM_BORDER) && (tp->member.para.pFmt->wBorders & 8)) + if (!(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) && + (pFmt->dwMask & PFM_BORDER) && (pFmt->wBorders & 8)) wc.pt.y += border; if (tp->member.para.pFmt->dwMask & PFM_SPACEAFTER) - wc.pt.y += ME_twips2pointsY(c, tp->member.para.pFmt->dySpaceAfter); + wc.pt.y += ME_twips2pointsY(c, pFmt->dySpaceAfter); tp->member.para.nFlags &= ~MEPF_REWRAP; tp->member.para.nHeight = wc.pt.y; @@ -528,6 +550,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { int yLastPos = 0; ME_InitContext(&c, editor, GetDC(editor->hWnd)); + c.pt.x = editor->selofs; editor->nHeight = 0; item = editor->pBuffer->pFirst->next; while(item != editor->pBuffer->pLast) { @@ -556,7 +579,16 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { if (item->member.para.nFlags & MEPF_ROWSTART) { ME_DisplayItem *cell = ME_FindItemFwd(item, diCell); + ME_DisplayItem *endRowPara; cell->member.cell.pt = c.pt; + endRowPara = ME_GetTableRowEnd(item); + if (endRowPara->member.para.pFmt->dxStartIndent > 0) + { + int dxStartIndent = endRowPara->member.para.pFmt->dxStartIndent; + cell = ME_FindItemFwd(item, diCell); + cell->member.cell.pt.x += ME_twips2pointsX(&c, dxStartIndent); + c.pt.x = cell->member.cell.pt.x; + } } else if (item->member.para.nFlags & MEPF_ROWEND) { @@ -614,7 +646,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { c.pt.x = item->member.para.pCell->member.cell.pt.x; } else { /* Normal paragraph */ - c.pt.x = 0; + c.pt.x = editor->selofs; } c.pt.y += item->member.para.nHeight; } diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c index 742addadc7a..912cae3f48e 100644 --- a/dlls/riched20/writer.c +++ b/dlls/riched20/writer.c @@ -298,9 +298,7 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, cell = para->member.para.next_para->member.para.pCell; assert(cell); do { - sprintf(props, "\\cellx%d", cell->member.cell.nRightBoundary); - if (!ME_StreamOutPrint(pStream, props)) - return FALSE; + sprintf(props + strlen(props), "\\cellx%d", cell->member.cell.nRightBoundary); cell = cell->member.cell.next_cell; } while (cell->member.cell.next_cell); } else { /* v1.0 - 3.0 */ @@ -308,13 +306,17 @@ ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, int i; assert(!(para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL))); + if (pFmt->dxOffset) + sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset); + if (pFmt->dxStartIndent) + sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent); for (i = 0; i < pFmt->cTabCount; i++) { - sprintf(props, "\\cellx%d", pFmt->rgxTabs[i] & 0x00FFFFFF); - if (!ME_StreamOutPrint(pStream, props)) - return FALSE; + sprintf(props + strlen(props), "\\cellx%d", pFmt->rgxTabs[i] & 0x00FFFFFF); } } + if (!ME_StreamOutPrint(pStream, props)) + return FALSE; props[0] = '\0'; return TRUE; } @@ -405,43 +407,45 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, if (fmt->dwMask & PFM_SIDEBYSIDE && fmt->wEffects & PFE_SIDEBYSIDE) strcat(props, "\\sbys"); - if (fmt->dwMask & PFM_OFFSET) - sprintf(props + strlen(props), "\\li%d", fmt->dxOffset); - if (fmt->dwMask & PFM_OFFSETINDENT || fmt->dwMask & PFM_STARTINDENT) - sprintf(props + strlen(props), "\\fi%d", fmt->dxStartIndent); - if (fmt->dwMask & PFM_RIGHTINDENT) - sprintf(props + strlen(props), "\\ri%d", fmt->dxRightIndent); + if (!(editor->bEmulateVersion10 && /* v1.0 - 3.0 */ + fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE)) + { + if (fmt->dwMask & PFM_OFFSET) + sprintf(props + strlen(props), "\\li%d", fmt->dxOffset); + if (fmt->dwMask & PFM_OFFSETINDENT || fmt->dwMask & PFM_STARTINDENT) + sprintf(props + strlen(props), "\\fi%d", fmt->dxStartIndent); + if (fmt->dwMask & PFM_RIGHTINDENT) + sprintf(props + strlen(props), "\\ri%d", fmt->dxRightIndent); + if (fmt->dwMask & PFM_TABSTOPS) { + static const char * const leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" }; + + for (i = 0; i < fmt->cTabCount; i++) { + switch ((fmt->rgxTabs[i] >> 24) & 0xF) { + case 1: + strcat(props, "\\tqc"); + break; + case 2: + strcat(props, "\\tqr"); + break; + case 3: + strcat(props, "\\tqdec"); + break; + case 4: + /* Word bar tab (vertical bar). Handled below */ + break; + } + if (fmt->rgxTabs[i] >> 28 <= 5) + strcat(props, leader[fmt->rgxTabs[i] >> 28]); + sprintf(props+strlen(props), "\\tx%d", fmt->rgxTabs[i]&0x00FFFFFF); + } + } + } if (fmt->dwMask & PFM_SPACEAFTER) sprintf(props + strlen(props), "\\sa%d", fmt->dySpaceAfter); if (fmt->dwMask & PFM_SPACEBEFORE) sprintf(props + strlen(props), "\\sb%d", fmt->dySpaceBefore); if (fmt->dwMask & PFM_STYLE) sprintf(props + strlen(props), "\\s%d", fmt->sStyle); - - if (fmt->dwMask & PFM_TABSTOPS) { - static const char * const leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" }; - - for (i = 0; i < fmt->cTabCount; i++) { - switch ((fmt->rgxTabs[i] >> 24) & 0xF) { - case 1: - strcat(props, "\\tqc"); - break; - case 2: - strcat(props, "\\tqr"); - break; - case 3: - strcat(props, "\\tqdec"); - break; - case 4: - /* Word bar tab (vertical bar). Handled below */ - break; - } - if (fmt->rgxTabs[i] >> 28 <= 5) - strcat(props, leader[fmt->rgxTabs[i] >> 28]); - sprintf(props+strlen(props), "\\tx%d", fmt->rgxTabs[i]&0x00FFFFFF); - } - } - if (fmt->dwMask & PFM_SHADING) { static const char * const style[16] = { "", "\\bgdkhoriz", "\\bgdkvert", "\\bgdkfdiag",