static void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p) { /* FIXME compose style (out of character and paragraph styles) here */ ME_UpdateRunFlags(wc->context->editor, &p->member.run); calc_run_extent(wc->context, &wc->pPara->member.para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &p->member.run); }
/****************************************************************************** * split_run_extents * * Splits a run into two in a given place. It also updates the screen position * and size (extent) of the newly generated runs. */ static ME_DisplayItem *split_run_extents(ME_WrapContext *wc, ME_DisplayItem *item, int nVChar) { ME_TextEditor *editor = wc->context->editor; ME_Run *run, *run2; ME_Paragraph *para = &wc->pPara->member.para; ME_Cursor cursor = {wc->pPara, item, nVChar}; assert(item->member.run.nCharOfs != -1); if(TRACE_ON(richedit)) { TRACE("Before check before split\n"); ME_CheckCharOffsets(editor); TRACE("After check before split\n"); } run = &item->member.run; TRACE("Before split: %s(%d, %d)\n", debugstr_run( run ), run->pt.x, run->pt.y); ME_SplitRunSimple(editor, &cursor); run2 = &cursor.pRun->member.run; calc_run_extent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run); run2->pt.x = run->pt.x+run->nWidth; run2->pt.y = run->pt.y; if(TRACE_ON(richedit)) { TRACE("Before check after split\n"); ME_CheckCharOffsets(editor); TRACE("After check after split\n"); TRACE("After split: %s(%d, %d), %s(%d, %d)\n", debugstr_run( run ), run->pt.x, run->pt.y, debugstr_run( run2 ), run2->pt.x, run2->pt.y); } return cursor.pRun; }
static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) { ME_DisplayItem *pp; ME_Run *run; int len; assert(p->type == diRun); if (!wc->pRowStart) wc->pRowStart = p; run = &p->member.run; run->pt.x = wc->pt.x; run->pt.y = wc->pt.y; ME_WrapSizeRun(wc, p); len = run->len; if (wc->bOverflown) /* just skipping final whitespaces */ { /* End paragraph run can't overflow to the next line by itself. */ if (run->nFlags & MERF_ENDPARA) return p->next; if (run->nFlags & MERF_WHITESPACE) { wc->pt.x += run->nWidth; /* skip runs consisting of only whitespaces */ return p->next; } if (run->nFlags & MERF_STARTWHITE) { /* try to split the run at the first non-white char */ int black; black = find_non_whitespace( get_text( run, 0 ), run->len, 0 ); if (black) { wc->bOverflown = FALSE; pp = split_run_extents(wc, p, black); calc_run_extent(wc->context, &wc->pPara->member.para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &pp->member.run); ME_InsertRowStart(wc, pp); return pp; } } /* black run: the row goes from pRowStart to the previous run */ ME_InsertRowStart(wc, p); return p; } /* simply end the current row and move on to next one */ if (run->nFlags & MERF_ENDROW) { p = p->next; ME_InsertRowStart(wc, p); return p; } /* will current run fit? */ if (wc->bWordWrap && wc->pt.x + run->nWidth - wc->context->pt.x > wc->nAvailWidth) { int loc = wc->context->pt.x + wc->nAvailWidth - wc->pt.x; /* total white run ? */ if (run->nFlags & MERF_WHITESPACE) { /* let the overflow logic handle it */ wc->bOverflown = TRUE; return p; } /* TAB: we can split before */ if (run->nFlags & MERF_TAB) { wc->bOverflown = TRUE; if (wc->pRowStart == p) /* Don't split before the start of the run, or we will get an * endless loop. */ return p->next; else return p; } /* graphics: we can split before, if run's width is smaller than row's width */ if ((run->nFlags & MERF_GRAPHICS) && run->nWidth <= wc->nAvailWidth) { wc->bOverflown = TRUE; return p; } /* can we separate out the last spaces ? (to use overflow logic later) */ if (run->nFlags & MERF_ENDWHITE) { /* we aren't sure if it's *really* necessary, it's a good start however */ int black = reverse_find_non_whitespace( get_text( run, 0 ), len ); split_run_extents(wc, p, black); /* handle both parts again */ return p; } /* determine the split point by backtracking */ pp = ME_SplitByBacktracking(wc, p, loc); if (pp == wc->pRowStart) { if (run->nFlags & MERF_STARTWHITE) { /* We had only spaces so far, so we must be on the first line of the * paragraph (or the first line after MERF_ENDROW forced the line * break within the paragraph), since no other lines of the paragraph * start with spaces. */ /* The lines will only contain spaces, and the rest of the run will * overflow onto the next line. */ wc->bOverflown = TRUE; return p; } /* Couldn't split the first run, possible because we have a large font * with a single character that caused an overflow. */ wc->pt.x += run->nWidth; return p->next; } if (p != pp) /* found a suitable split point */ { wc->bOverflown = TRUE; return pp; } /* we detected that it's best to split on start of this run */ if (wc->bOverflown) return pp; ERR("failure!\n"); /* not found anything - writing over margins is the only option left */ } if ((run->nFlags & (MERF_SPLITTABLE | MERF_STARTWHITE)) || ((run->nFlags & (MERF_GRAPHICS|MERF_TAB)) && (p != wc->pRowStart))) { wc->pLastSplittableRun = p; } wc->pt.x += run->nWidth; return p->next; }