Exemplo n.º 1
0
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, &para->member.para,
                         &run->member.run, run->member.run.len,
                         row->member.row.nLMargin);
    }
  }
  if (pCursor->nOffset) {
    sz = ME_GetRunSize(&c, &para->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;
}
Exemplo n.º 2
0
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, &para->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);
}
Exemplo n.º 3
0
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, &para->member.para,
                             &run->member.run, ME_StrLen(run->member.run.strText),
                             row->member.row.nLMargin);
        }
      }
      if (pCursor->nOffset) {
        sz = ME_GetRunSize(&c, &para->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;
}