void ME_InvalidateParagraphRange(ME_TextEditor *editor, ME_DisplayItem *start_para, ME_DisplayItem *last_para) { ME_Context c; RECT rc; int ofs; ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); rc = c.rcView; ofs = editor->vert_si.nPos; if (start_para) { start_para = ME_GetOuterParagraph(start_para); last_para = ME_GetOuterParagraph(last_para); rc.top = c.rcView.top + start_para->member.para.pt.y - ofs; } else { rc.top = c.rcView.top + editor->nTotalLength - ofs; } if (editor->nTotalLength < editor->nLastTotalLength) rc.bottom = c.rcView.top + editor->nLastTotalLength - ofs; else rc.bottom = c.rcView.top + last_para->member.para.pt.y + last_para->member.para.nHeight - ofs; ITextHost_TxInvalidateRect(editor->texthost, &rc, TRUE); ME_DestroyContext(&c); }
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor, ME_DisplayItem *start_para, ME_DisplayItem *end_para) { ME_Context c; RECT rc; int ofs; ME_DisplayItem *item; ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); rc = c.rcView; ofs = editor->vert_si.nPos; item = start_para; while(item && item != end_para) { if (item->member.para.nFlags & MEPF_REPAINT) { rc.top = c.rcView.top + item->member.para.pt.y - ofs; rc.bottom = max(rc.top + item->member.para.nHeight, c.rcView.bottom); ITextHost_TxInvalidateRect(editor->texthost, &rc, TRUE); item->member.para.nFlags &= ~MEPF_REPAINT; } item = item->member.para.next_para; } if (editor->nTotalLength < editor->nLastTotalLength) { rc.top = c.rcView.top + editor->nTotalLength - ofs; rc.bottom = c.rcView.top + editor->nLastTotalLength - ofs; ITextHost_TxInvalidateRect(editor->texthost, &rc, TRUE); } ME_DestroyContext(&c); }
void ME_MakeFirstParagraph(ME_TextEditor *editor) { ME_Context c; CHARFORMAT2W cf; LOGFONTW lf; HFONT hf; ME_TextBuffer *text = editor->pBuffer; ME_DisplayItem *para = make_para(editor); ME_DisplayItem *run; ME_Style *style; int eol_len; WCHAR cr_lf[] = {'\r','\n',0}; ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); hf = GetStockObject(SYSTEM_FONT); assert(hf); GetObjectW(hf, sizeof(LOGFONTW), &lf); ZeroMemory(&cf, sizeof(cf)); cf.cbSize = sizeof(cf); cf.dwMask = CFM_BACKCOLOR|CFM_COLOR|CFM_FACE|CFM_SIZE|CFM_CHARSET; cf.dwMask |= CFM_ALLCAPS|CFM_BOLD|CFM_DISABLED|CFM_EMBOSS|CFM_HIDDEN; cf.dwMask |= CFM_IMPRINT|CFM_ITALIC|CFM_LINK|CFM_OUTLINE|CFM_PROTECTED; cf.dwMask |= CFM_REVISED|CFM_SHADOW|CFM_SMALLCAPS|CFM_STRIKEOUT; cf.dwMask |= CFM_SUBSCRIPT|CFM_UNDERLINETYPE|CFM_WEIGHT; cf.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR; lstrcpyW(cf.szFaceName, lf.lfFaceName); /* Convert system font height from logical units to twips for cf.yHeight */ cf.yHeight = (lf.lfHeight * 72 * 1440) / (c.dpi.cy * c.dpi.cy); if (lf.lfWeight > FW_NORMAL) cf.dwEffects |= CFE_BOLD; cf.wWeight = lf.lfWeight; if (lf.lfItalic) cf.dwEffects |= CFE_ITALIC; cf.bUnderlineType = (lf.lfUnderline) ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE; if (lf.lfStrikeOut) cf.dwEffects |= CFE_STRIKEOUT; cf.bPitchAndFamily = lf.lfPitchAndFamily; cf.bCharSet = lf.lfCharSet; style = ME_MakeStyle(&cf); text->pDefaultStyle = style; eol_len = editor->bEmulateVersion10 ? 2 : 1; para->member.para.text = ME_MakeStringN( cr_lf, eol_len ); run = ME_MakeRun(style, MERF_ENDPARA); run->member.run.nCharOfs = 0; run->member.run.len = eol_len; run->member.run.para = ¶->member.para; ME_InsertBefore(text->pLast, para); ME_InsertBefore(text->pLast, run); para->member.para.prev_para = text->pFirst; para->member.para.next_para = text->pLast; text->pFirst->member.para.next_para = para; text->pLast->member.para.prev_para = para; text->pLast->member.para.nCharOfs = editor->bEmulateVersion10 ? 2 : 1; ME_DestroyContext(&c); }
static void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, int *x, int *y, int *height) { ME_DisplayItem *row; ME_DisplayItem *run = pCursor->pRun; ME_DisplayItem *para = pCursor->pPara; ME_DisplayItem *pSizeRun = run; ME_Context c; SIZE sz = {0, 0}; assert(height && x && y); assert(~para->member.para.nFlags & MEPF_REWRAP); assert(run && run->type == diRun); assert(para && para->type == diParagraph); row = ME_FindItemBack(run, diStartRowOrParagraph); assert(row && row->type == diStartRow); ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); if (!pCursor->nOffset) { ME_DisplayItem *prev = ME_FindItemBack(run, diRunOrParagraph); assert(prev); if (prev->type == diRun) pSizeRun = prev; } if (editor->bCaretAtEnd && !pCursor->nOffset && run == ME_FindItemFwd(row, diRun)) { ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph); assert(tmp); if (tmp->type == diRun) { row = ME_FindItemBack(tmp, diStartRow); pSizeRun = run = tmp; assert(run); assert(run->type == diRun); sz = ME_GetRunSize(&c, ¶->member.para, &run->member.run, run->member.run.len, row->member.row.nLMargin); } } if (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; *x = c.rcView.left + run->member.run.pt.x + sz.cx - editor->horz_si.nPos; *y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline + run->member.run.pt.y - pSizeRun->member.run.nAscent - editor->vert_si.nPos; ME_DestroyContext(&c); return; }
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, BOOL visual_order) { ME_Context c; int ret; ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) ); ret = ME_CharFromPointContext( &c, cx, run, closest, visual_order ); ME_DestroyContext(&c); return ret; }
/****************************************************************************** * ME_PointFromChar * * Calls ME_PointFromCharContext after first creating a context. */ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order) { ME_Context c; int ret; ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); ret = ME_PointFromCharContext( &c, pRun, nOffset, visual_order ); ME_DestroyContext(&c); return ret; }
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { ME_DisplayItem *item; ME_Context c; int totalWidth = 0; ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL; ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); c.pt.x = 0; item = editor->pBuffer->pFirst->next; while(item != editor->pBuffer->pLast) { BOOL bRedraw = FALSE; assert(item->type == diParagraph); if ((item->member.para.nFlags & MEPF_REWRAP) || (item->member.para.pt.y != c.pt.y)) bRedraw = TRUE; item->member.para.pt = c.pt; ME_WrapTextParagraph(&c, item); if (bRedraw) ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); if (item->member.para.nFlags & MEPF_ROWSTART) { ME_DisplayItem *cell = ME_FindItemFwd(item, diCell); ME_DisplayItem *endRowPara; int borderWidth = 0; cell->member.cell.pt = c.pt; /* 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; 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) { /* Set all the cells to the height of the largest cell */ ME_DisplayItem *startRowPara; int prevHeight, nHeight, bottomBorder = 0; ME_DisplayItem *cell = ME_FindItemBack(item, diCell); item->member.para.nWidth = cell->member.cell.pt.x + cell->member.cell.nWidth; 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 + 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; cell->member.cell.nHeight = nHeight; } /* Also set the height of the start row paragraph */ startRowPara = ME_FindItemBack(cell, diParagraph); startRowPara->member.para.nHeight = nHeight; c.pt.x = startRowPara->member.para.pt.x; c.pt.y = cell->member.cell.pt.y + nHeight; if (prevHeight < nHeight) { /* The height of the cells has grown, so invalidate the bottom of * the cells. */ ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); cell = ME_FindItemBack(item, diCell); while (cell) { ME_MarkRepaintEnd(ME_FindItemBack(cell, diParagraph), &repaint_start, &repaint_end); cell = cell->member.cell.prev_cell; } } } else if (item->member.para.pCell && item->member.para.pCell != item->member.para.next_para->member.para.pCell) { /* The next paragraph is in the next cell in the table row. */ ME_Cell *cell = &item->member.para.pCell->member.cell; cell->nHeight = c.pt.y + item->member.para.nHeight - cell->pt.y; /* Propagate the largest height to the end so that it can be easily * sent back to all the cells at the end of the row. */ if (cell->prev_cell) cell->nHeight = max(cell->nHeight, cell->prev_cell->member.cell.nHeight); c.pt.x = cell->pt.x + cell->nWidth; c.pt.y = cell->pt.y; cell->next_cell->member.cell.pt = c.pt; if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND)) c.pt.y += cell->yTextOffset; } else { if (item->member.para.pCell) { /* Next paragraph in the same cell. */ c.pt.x = item->member.para.pCell->member.cell.pt.x; } else { /* Normal paragraph */ c.pt.x = 0; } c.pt.y += item->member.para.nHeight; } totalWidth = max(totalWidth, item->member.para.nWidth); item = item->member.para.next_para; } editor->sizeWindow.cx = c.rcView.right-c.rcView.left; editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top; editor->nTotalLength = c.pt.y; editor->nTotalWidth = totalWidth; editor->pBuffer->pLast->member.para.pt.x = 0; editor->pBuffer->pLast->member.para.pt.y = c.pt.y; ME_DestroyContext(&c); if (repaint_start || editor->nTotalLength < editor->nLastTotalLength) ME_InvalidateParagraphRange(editor, repaint_start, repaint_end); return !!repaint_start; }