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; }
static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) { ME_DisplayItem *p, *row, *para; BOOL bSkippingSpaces = TRUE; int ascent = 0, descent = 0, width=0, shift = 0, align = 0; PARAFORMAT2 *pFmt; /* wrap text */ para = wc->pPara; pFmt = para->member.para.pFmt; for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev) { /* ENDPARA run shouldn't affect row height, except if it's the only run in the paragraph */ if (p->type==diRun && ((p==wc->pRowStart) || !(p->member.run.nFlags & MERF_ENDPARA))) { /* FIXME add more run types */ if (p->member.run.nAscent>ascent) ascent = p->member.run.nAscent; if (p->member.run.nDescent>descent) descent = p->member.run.nDescent; if (bSkippingSpaces) { /* Exclude space characters from run width. * Other whitespace or delimiters are not treated this way. */ SIZE sz; int len = p->member.run.strText->nLen; WCHAR *text = p->member.run.strText->szData + len - 1; assert (len); if (~p->member.run.nFlags & MERF_GRAPHICS) while (len && *(text--) == ' ') len--; if (len) { if (len == p->member.run.strText->nLen) { width += p->member.run.nWidth; } else { sz = ME_GetRunSize(wc->context, ¶->member.para, &p->member.run, len, p->member.run.pt.x); width += sz.cx; } } bSkippingSpaces = !len; } else if (!(p->member.run.nFlags & MERF_ENDPARA)) width += p->member.run.nWidth; } } para->member.para.nWidth = max(para->member.para.nWidth, width); row = ME_MakeRow(ascent+descent, ascent, width); if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) { /* The text was shifted down in ME_BeginRow so move the wrap context * back to where it should be. */ wc->pt.y--; /* The height of the row is increased by the borders. */ row->member.row.nHeight += 2; } row->member.row.pt = wc->pt; row->member.row.nLMargin = (!wc->nRow ? wc->nFirstMargin : wc->nLeftMargin); row->member.row.nRMargin = wc->nRightMargin; assert(para->member.para.pFmt->dwMask & PFM_ALIGNMENT); align = para->member.para.pFmt->wAlignment; if (align == PFA_CENTER) shift = max((wc->nAvailWidth-width)/2, 0); if (align == PFA_RIGHT) shift = max(wc->nAvailWidth-width, 0); for (p = wc->pRowStart; p!=pEnd; p = p->next) { if (p->type==diRun) { /* FIXME add more run types */ p->member.run.pt.x += row->member.row.nLMargin+shift; } } ME_InsertBefore(wc->pRowStart, row); wc->nRow++; wc->pt.y += row->member.row.nHeight; ME_BeginRow(wc); }
void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, int *x, int *y, int *height) { ME_DisplayItem *pCursorRun = pCursor->pRun; ME_DisplayItem *pSizeRun = pCursor->pRun; assert(height && x && y); assert(!(ME_GetParagraph(pCursorRun)->member.para.nFlags & MEPF_REWRAP)); assert(pCursor->pRun); assert(pCursor->pRun->type == diRun); if (pCursorRun->type == diRun) { ME_DisplayItem *row = ME_FindItemBack(pCursorRun, diStartRowOrParagraph); if (row) { HDC hDC = GetDC(editor->hWnd); ME_Context c; ME_DisplayItem *run = pCursorRun; ME_DisplayItem *para = NULL; SIZE sz = {0, 0}; ME_InitContext(&c, editor, hDC); if (!pCursor->nOffset) { ME_DisplayItem *prev = ME_FindItemBack(pCursorRun, diRunOrParagraph); assert(prev); if (prev->type == diRun) pSizeRun = prev; } assert(row->type == diStartRow); /* paragraph -> run without start row ?*/ para = ME_FindItemBack(row, diParagraph); assert(para); assert(para->type == diParagraph); 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, ME_StrLen(run->member.run.strText), 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, editor->hWnd); return; } } *height = 10; /* FIXME use global font */ *x = 0; *y = 0; }