From a86d7bdcea5c038d63e9fd8798d79f1412ad0dc1 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Sun, 16 Mar 2008 21:47:08 +0100 Subject: [PATCH] richedit: Pass left margin around when computing the size of a run, so that a tab will get a correct size. --- dlls/riched20/caret.c | 7 +++++-- dlls/riched20/editor.h | 6 +++--- dlls/riched20/run.c | 26 ++++++++++++++------------ dlls/riched20/wrap.c | 23 +++++++++++++++-------- 4 files changed, 37 insertions(+), 25 deletions(-) diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index adf90ace4b7..18204e22f4b 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -202,11 +202,14 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, pSizeRun = run = tmp; assert(run); assert(run->type == diRun); - sz = ME_GetRunSize(&c, ¶->member.para, &run->member.run, ME_StrLen(run->member.run.strText)); + sz = ME_GetRunSize(&c, ¶->member.para, + &run->member.run, ME_StrLen(run->member.run.strText), + row->member.row.nLMargin); } } if (pCursor->nOffset && !(run->member.run.nFlags & MERF_SKIPPED)) { - sz = ME_GetRunSize(&c, ¶->member.para, &run->member.run, pCursor->nOffset); + sz = ME_GetRunSize(&c, ¶->member.para, &run->member.run, pCursor->nOffset, + row->member.row.nLMargin); } *height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent; diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index bfcc794dc8d..7b9be5e3dda 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -156,13 +156,13 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset); int ME_GetLastSplittablePlace(ME_Context *c, ME_Run *run); int ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2); void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p); -ME_DisplayItem *ME_SplitRun(ME_Context *c, ME_DisplayItem *item, int nChar); +ME_DisplayItem *ME_SplitRun(ME_WrapContext *wc, ME_DisplayItem *item, int nChar); ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_DisplayItem *item, int nChar); int ME_FindSplitPoint(ME_Context *c, POINT *pt, ME_Run *run, int desperate); void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run); ME_DisplayItem *ME_SplitFurther(ME_TextEditor *editor, ME_DisplayItem *run); -void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, ME_Run *run); -SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen); +void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run); +SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx); void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor); void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppRun, int *pOfs); int ME_CharOfsFromRunOfs(ME_TextEditor *editor, ME_DisplayItem *pRun, int nOfs); diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 9ed14d34445..a762695805c 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -267,9 +267,9 @@ void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p) * Splits a run into two in a given place. It also updates the screen position * and size (extent) of the newly generated runs. */ -ME_DisplayItem *ME_SplitRun(ME_Context *c, ME_DisplayItem *item, int nVChar) +ME_DisplayItem *ME_SplitRun(ME_WrapContext *wc, ME_DisplayItem *item, int nVChar) { - ME_TextEditor *editor = c->editor; + ME_TextEditor *editor = wc->context->editor; ME_DisplayItem *item2 = NULL; ME_Run *run, *run2; ME_Paragraph *para = &ME_GetParagraph(item)->member.para; @@ -291,8 +291,8 @@ ME_DisplayItem *ME_SplitRun(ME_Context *c, ME_DisplayItem *item, int nVChar) run2 = &item2->member.run; - ME_CalcRunExtent(c, para, run); - ME_CalcRunExtent(c, para, run2); + ME_CalcRunExtent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run); + ME_CalcRunExtent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run2); run2->pt.x = run->pt.x+run->nWidth; run2->pt.y = run->pt.y; @@ -638,7 +638,7 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset) * (nLen). */ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, - int *pAscent, int *pDescent) + int startx, int *pAscent, int *pDescent) { SIZE size; int nMaxLen = ME_StrVLen(run->strText); @@ -668,8 +668,8 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run if (run->nFlags & MERF_TAB) { int pos = 0, i = 0, ppos; - PARAFORMAT2 *pFmt = para->pFmt; + do { if (i < pFmt->cTabCount) { @@ -681,8 +681,8 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run pos += 720-(pos%720); } ppos = ME_twips2pointsX(c, pos); - if (ppos>run->pt.x) { - size.cx = ppos - run->pt.x; + if (ppos > startx + run->pt.x) { + size.cx = ppos - startx - run->pt.x; break; } } while(1); @@ -711,10 +711,11 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run * Finds width and height (but not ascent and descent) of a part of the run * up to given character. */ -SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen) +SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, + ME_Run *run, int nLen, int startx) { int asc, desc; - return ME_GetRunSizeCommon(c, para, run, nLen, &asc, &desc); + return ME_GetRunSizeCommon(c, para, run, nLen, startx, &asc, &desc); } /****************************************************************************** @@ -724,14 +725,15 @@ SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLe * is calculated based on whole row's ascent and descent anyway, so no need * to use it here. */ -void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, ME_Run *run) +void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run) { if (run->nFlags & MERF_HIDDEN) run->nWidth = 0; else { int nEnd = ME_StrVLen(run->strText); - SIZE size = ME_GetRunSizeCommon(c, para, run, nEnd, &run->nAscent, &run->nDescent); + SIZE size = ME_GetRunSizeCommon(c, para, run, nEnd, startx, + &run->nAscent, &run->nDescent); run->nWidth = size.cx; if (!size.cx) WARN("size.cx == 0\n"); diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index cd1f325a1fa..4c24dec2233 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -117,7 +117,8 @@ static void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p) ME_UpdateRunFlags(wc->context->editor, &p->member.run); - ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para, &p->member.run); + ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para, + wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &p->member.run); } static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, int i) @@ -128,7 +129,7 @@ static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, i return NULL; j = ME_ReverseFindNonWhitespaceV(p->member.run.strText, i); if (j>0) { - pp = ME_SplitRun(wc->context, piter, j); + pp = ME_SplitRun(wc, piter, j); wc->pt.x += piter->member.run.nWidth; return pp; } @@ -147,7 +148,7 @@ static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, i if (piter->member.run.nFlags & MERF_ENDWHITE) { j = ME_ReverseFindNonWhitespaceV(piter->member.run.strText, i); - pp = ME_SplitRun(wc->context, piter, i); + pp = ME_SplitRun(wc, piter, i); wc->pt = pp->member.run.pt; return pp; } @@ -202,7 +203,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem if (i == len) i = ME_ReverseFindNonWhitespaceV(run->strText, len); if (i) { - ME_DisplayItem *piter2 = ME_SplitRun(wc->context, piter, i); + ME_DisplayItem *piter2 = ME_SplitRun(wc, piter, i); wc->pt = piter2->member.run.pt; return piter2; } @@ -219,7 +220,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem TRACE("Backtracking failed, trying desperate: %s\n", debugstr_w(p->member.run.strText->szData)); /* OK, no better idea, so assume we MAY split words if we can split at all*/ if (idesp) - return ME_SplitRun(wc->context, piter, idesp); + return ME_SplitRun(wc, piter, idesp); else if (wc->pRowStart && piter != wc->pRowStart) { @@ -235,7 +236,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem int pos2 = ME_StrRelPos(run->strText, 0, &chars); if (pos2 != len) { /* the run is more than 1 char, so we may split */ - return ME_SplitRun(wc->context, piter, pos2); + return ME_SplitRun(wc, piter, pos2); } /* the run is one char, can't split it */ return piter; @@ -272,7 +273,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) black = ME_FindNonWhitespaceV(run->strText, 0); if (black) { wc->bOverflown = FALSE; - pp = ME_SplitRun(wc->context, p, black); + pp = ME_SplitRun(wc, p, black); p->member.run.nFlags |= MERF_SKIPPED; ME_InsertRowStart(wc, pp); return pp; @@ -290,6 +291,12 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) return p; } /* we're not at the end of the row */ + if (run->nFlags & MERF_TAB) { + /* force recomputation of tabs' size as it depends on position */ + ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para, + wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run); + } + /* will current run fit? */ if (wc->pt.x + run->nWidth > wc->nAvailWidth) { @@ -315,7 +322,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) { /* we aren't sure if it's *really* necessary, it's a good start however */ int black = ME_ReverseFindNonWhitespaceV(run->strText, len); - ME_SplitRun(wc->context, p, black); + ME_SplitRun(wc, p, black); /* handle both parts again */ return p; }