⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 run.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
  assert(!(item->member.run.nFlags & MERF_NONTEXT));
  assert(item->member.run.nCharOfs != -1);

  item2 = ME_MakeRun(run->style,
      ME_VSplitString(run->strText, nVChar), run->nFlags&MERF_SPLITMASK);

  item2->member.run.nCharOfs = item->member.run.nCharOfs+
    ME_VPosToPos(item->member.run.strText, nVChar);

  run2 = &item2->member.run;
  ME_InsertBefore(item->next, item2);

  ME_UpdateRunFlags(editor, run);
  ME_UpdateRunFlags(editor, run2);
  for (i=0; i<editor->nCursors; i++) {
    if (editor->pCursors[i].pRun == item &&
        editor->pCursors[i].nOffset >= nVChar) {
      assert(item2->type == diRun);
      editor->pCursors[i].pRun = item2;
      editor->pCursors[i].nOffset -= nVChar;
    }
  }
  ME_GetParagraph(item)->member.para.nFlags |= MEPF_REWRAP;
  return item2;
}

/******************************************************************************
 * ME_MakeRun
 * 
 * A helper function to create run structures quickly.
 */   
ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags)
{
  ME_DisplayItem *item = ME_MakeDI(diRun);
  item->member.run.style = s;
  item->member.run.strText = strData;
  item->member.run.nFlags = nFlags;
  item->member.run.nCharOfs = -1;
  ME_AddRefStyle(s);
  return item;
}

/******************************************************************************
 * ME_InsertRun
 * 
 * Inserts a run at a given character position (offset).
 */   
ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem *pItem)
{
  ME_Cursor tmp;
  ME_DisplayItem *pDI;

  assert(pItem->type == diRun || pItem->type == diUndoInsertRun);

  ME_CursorFromCharOfs(editor, nCharOfs, &tmp);
  pDI = ME_InsertRunAtCursor(editor, &tmp, pItem->member.run.style,
                             pItem->member.run.strText->szData,
                             pItem->member.run.strText->nLen,
                             pItem->member.run.nFlags);
  
  return pDI;
}

/******************************************************************************
 * ME_InsertRunAtCursor
 * 
 * Inserts a new run with given style, flags and content at a given position,
 * which is passed as a cursor structure (which consists of a run and 
 * a run-relative character offset). 
 */   
ME_DisplayItem *
ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style,
                     const WCHAR *str, int len, int flags)
{
  ME_DisplayItem *pDI;
  ME_UndoItem *pUI;
  
  if (cursor->nOffset) {
  	/* We're inserting at the middle of the existing run, which means that
		 * that run must be split. It isn't always necessary, but */
    cursor->pRun = ME_SplitRunSimple(editor, cursor->pRun, cursor->nOffset);
    cursor->nOffset = 0;
  }
  
  pUI = ME_AddUndoItem(editor, diUndoDeleteRun, NULL);
  if (pUI) {
    pUI->nStart = (ME_GetParagraph(cursor->pRun)->member.para.nCharOfs
                   + cursor->pRun->member.run.nCharOfs);
    pUI->nLen = len;
  }
  
  pDI = ME_MakeRun(style, ME_MakeStringN(str, len), flags);
  pDI->member.run.nCharOfs = cursor->pRun->member.run.nCharOfs;
  ME_InsertBefore(cursor->pRun, pDI);
  TRACE("Shift length:%d\n", len);
  ME_PropagateCharOffset(cursor->pRun, len);
  ME_GetParagraph(cursor->pRun)->member.para.nFlags |= MEPF_REWRAP;
  return pDI;
}

/******************************************************************************
 * ME_UpdateRunFlags
 * 
 * Determine some of run attributes given its content (style, text content).
 * Some flags cannot be determined by this function (MERF_GRAPHICS, 
 * MERF_ENDPARA)     
 */ 
void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run)
{
  assert(run->nCharOfs != -1);

  if (RUN_IS_HIDDEN(run))
    run->nFlags |= MERF_HIDDEN;
  else
    run->nFlags &= ~MERF_HIDDEN;

  if (ME_IsSplitable(run->strText))
    run->nFlags |= MERF_SPLITTABLE;
  else
    run->nFlags &= ~MERF_SPLITTABLE;

  if (!(run->nFlags & MERF_NOTEXT)) {
    if (ME_IsWhitespaces(run->strText))
      run->nFlags |= MERF_WHITESPACE | MERF_STARTWHITE | MERF_ENDWHITE;
    else
    {
      run->nFlags &= ~MERF_WHITESPACE;

      if (ME_IsWSpace(ME_GetCharFwd(run->strText,0)))
        run->nFlags |= MERF_STARTWHITE;
      else
        run->nFlags &= ~MERF_STARTWHITE;

      if (ME_IsWSpace(ME_GetCharBack(run->strText,0)))
        run->nFlags |= MERF_ENDWHITE;
      else
        run->nFlags &= ~MERF_ENDWHITE;
    }
  }
  else
    run->nFlags &= ~(MERF_WHITESPACE | MERF_STARTWHITE | MERF_ENDWHITE);
}

/******************************************************************************
 * ME_GetGraphicsSize
 * 
 * Sets run extent for graphics runs. This functionality is just a placeholder
 * for future OLE object support, and will be removed.
 */     
void ME_GetGraphicsSize(ME_TextEditor *editor, ME_Run *run, SIZE *pSize)
{
  assert(run->nFlags & MERF_GRAPHICS);
  pSize->cx = 64;
  pSize->cy = 64;
}

/******************************************************************************
 * ME_CharFromPoint
 * 
 * Returns a character position inside the run given a run-relative
 * pixel horizontal position. This version rounds left (ie. if the second
 * character is at pixel position 8, then for cx=0..7 it returns 0).  
 */     
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run)
{
  int fit = 0;
  HGDIOBJ hOldFont;
  HDC hDC;
  SIZE sz;
  if (!run->strText->nLen)
    return 0;

  if (run->nFlags & (MERF_TAB | MERF_CELL))
  {
    if (cx < run->nWidth/2) 
      return 0;
    return 1;
  }
  if (run->nFlags & MERF_GRAPHICS)
  {
    SIZE sz;
    ME_GetGraphicsSize(editor, run, &sz);
    if (cx < sz.cx)
      return 0;
    return 1;
  }
  hDC = GetDC(editor->hWnd);
  hOldFont = ME_SelectStyleFont(editor, hDC, run->style);
  
  if (editor->cPasswordMask)
  {
    ME_String *strMasked = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(run->strText));
    GetTextExtentExPointW(hDC, strMasked->szData, run->strText->nLen,
      cx, &fit, NULL, &sz);
    ME_DestroyString(strMasked);
  }
  else
  {
    GetTextExtentExPointW(hDC, run->strText->szData, run->strText->nLen,
      cx, &fit, NULL, &sz);
  }
  
  ME_UnselectStyleFont(editor, hDC, run->style, hOldFont);
  ReleaseDC(editor->hWnd, hDC);
  return fit;
}

/******************************************************************************
 * ME_CharFromPointCursor
 * 
 * Returns a character position inside the run given a run-relative
 * pixel horizontal position. This version rounds to the nearest character edge 
 * (ie. if the second character is at pixel position 8, then for cx=0..3 
 * it returns 0, and for cx=4..7 it returns 1).
 * 
 * It is used for mouse click handling, for better usability (and compatibility
 * with the native control).        
 */     
int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
{
  ME_String *strRunText;
  /* This could point to either the run's real text, or it's masked form in a password control */
	
  int fit = 0, fit1 = 0;
  HGDIOBJ hOldFont;
  HDC hDC;
  SIZE sz, sz2, sz3;
  if (!run->strText->nLen)
    return 0;

  if (run->nFlags & (MERF_TAB | MERF_CELL))
  {
    if (cx < run->nWidth/2)
      return 0;
    return 1;
  }
  if (run->nFlags & MERF_GRAPHICS)
  {
    SIZE sz;
    ME_GetGraphicsSize(editor, run, &sz);
    if (cx < sz.cx/2)
      return 0;
    return 1;
  }
  
  if (editor->cPasswordMask)
    strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(run->strText));
  else
    strRunText = run->strText;

  hDC = GetDC(editor->hWnd);
  hOldFont = ME_SelectStyleFont(editor, hDC, run->style);
  GetTextExtentExPointW(hDC, strRunText->szData, strRunText->nLen,
    cx, &fit, NULL, &sz);
  if (fit != strRunText->nLen)
  {
    int chars = 1;

    GetTextExtentPoint32W(hDC, strRunText->szData, fit, &sz2);
    fit1 = ME_StrRelPos(strRunText, fit, &chars);
    GetTextExtentPoint32W(hDC, strRunText->szData, fit1, &sz3);
    if (cx >= (sz2.cx+sz3.cx)/2)
      fit = fit1;
  }
  
  if (editor->cPasswordMask)
    ME_DestroyString(strRunText);
  
  ME_UnselectStyleFont(editor, hDC, run->style, hOldFont);
  ReleaseDC(editor->hWnd, hDC);
  return fit;
}

/******************************************************************************
 * ME_PointFromChar
 * 
 * Returns a run-relative pixel position given a run-relative character
 * position (character offset)
 */     
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
{
  SIZE size;
  HDC hDC = GetDC(editor->hWnd);
  HGDIOBJ hOldFont;
  ME_String *strRunText;
  /* This could point to either the run's real text, or it's masked form in a password control */

  if (pRun->nFlags & MERF_GRAPHICS)
  {
    if (!nOffset) return 0;
    ME_GetGraphicsSize(editor, pRun, &size);
    return 1;
  }
  
   if (editor->cPasswordMask)
    strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(pRun->strText));
  else
    strRunText = pRun->strText;
  
  hOldFont = ME_SelectStyleFont(editor, hDC, pRun->style);
  GetTextExtentPoint32W(hDC, strRunText->szData, nOffset, &size);
  ME_UnselectStyleFont(editor, hDC, pRun->style, hOldFont);
  ReleaseDC(editor->hWnd, hDC);
  if (editor->cPasswordMask)
    ME_DestroyString(strRunText);
  return size.cx;
}

/******************************************************************************
 * ME_GetTextExtent
 *
 * Finds a width and a height of the text using a specified style
 */
static void ME_GetTextExtent(ME_Context *c, LPCWSTR szText, int nChars, ME_Style *s, SIZE *size)
{
  HDC hDC = c->hDC;
  HGDIOBJ hOldFont;
  hOldFont = ME_SelectStyleFont(c->editor, hDC, s);
  GetTextExtentPoint32W(hDC, szText, nChars, size);
  ME_UnselectStyleFont(c->editor, hDC, s, hOldFont);
}

/******************************************************************************
 * ME_GetRunSizeCommon
 * 
 * Finds width, height, ascent and descent of a run, up to given character

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -