Example #1
0
/******************************************************************************
 * ME_CharFromPointContext
 *
 * Returns a character position inside the run given a run-relative
 * pixel horizontal position.
 *
 * If closest is FALSE return the actual character
 * If closest is TRUE will round to the closest leading edge.
 * ie. if the second character is at pixel position 8 and third at 16 then for:
 * closest = FALSE cx = 0..7 return 0, cx = 8..15 return 1
 * closest = TRUE  cx = 0..3 return 0, cx = 4..11 return 1.
 */
int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BOOL visual_order)
{
  ME_String *mask_text = NULL;
  WCHAR *str;
  int fit = 0;
  HGDIOBJ hOldFont;
  SIZE sz, sz2, sz3;
  if (!run->len || cx <= 0)
    return 0;

  if (run->nFlags & (MERF_TAB | MERF_ENDCELL))
  {
    if (!closest || cx < run->nWidth / 2) return 0;
    return 1;
  }

  if (run->nFlags & MERF_GRAPHICS)
  {
    SIZE sz;
    ME_GetOLEObjectSize(c, run, &sz);
    if (!closest || cx < sz.cx / 2) return 0;
    return 1;
  }

  if (run->para->nFlags & MEPF_COMPLEX)
  {
      int cp, trailing;
      if (visual_order && run->script_analysis.fRTL) cx = run->nWidth - cx - 1;

      ScriptXtoCP( cx, run->len, run->num_glyphs, run->clusters, run->vis_attrs, run->advances, &run->script_analysis,
                   &cp, &trailing );
      TRACE("x %d cp %d trailing %d (run width %d) rtl %d log order %d\n", cx, cp, trailing, run->nWidth,
            run->script_analysis.fRTL, run->script_analysis.fLogicalOrder);
      return closest ? cp + trailing : cp;
  }

  if (c->editor->cPasswordMask)
  {
    mask_text = ME_MakeStringR( c->editor->cPasswordMask, run->len );
    str = mask_text->szData;
  }
  else
    str = get_text( run, 0 );

  hOldFont = ME_SelectStyleFont(c, run->style);
  GetTextExtentExPointW(c->hDC, str, run->len,
                        cx, &fit, NULL, &sz);
  if (closest && fit != run->len)
  {
    GetTextExtentPoint32W(c->hDC, str, fit, &sz2);
    GetTextExtentPoint32W(c->hDC, str, fit + 1, &sz3);
    if (cx >= (sz2.cx+sz3.cx)/2)
      fit = fit + 1;
  }

  ME_DestroyString( mask_text );

  ME_UnselectStyleFont(c, run->style, hOldFont);
  return fit;
}
Example #2
0
/******************************************************************************
 * 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)
{
  HGDIOBJ hOldFont;
  if (c->hDC) {
    hOldFont = ME_SelectStyleFont(c, s);
    GetTextExtentPoint32W(c->hDC, szText, nChars, size);
    ME_UnselectStyleFont(c, s, hOldFont);
  } else {
    size->cx = 0;
    size->cy = 0;
  }
}
Example #3
0
static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChars, 
  ME_Style *s, int *width, int nSelFrom, int nSelTo, int ymin, int cy) {
  HDC hDC = c->hDC;
  HGDIOBJ hOldFont;
  COLORREF rgbOld, rgbBack;
  int yOffset = 0, yTwipsOffset = 0;
  hOldFont = ME_SelectStyleFont(c->editor, hDC, s);
  rgbBack = ME_GetBackColor(c->editor);
  if ((s->fmt.dwMask & CFM_COLOR) && (s->fmt.dwEffects & CFE_AUTOCOLOR))
    rgbOld = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
  else
    rgbOld = SetTextColor(hDC, s->fmt.crTextColor);
  if ((s->fmt.dwMask & s->fmt.dwEffects) & CFM_OFFSET) {
    yTwipsOffset = s->fmt.yOffset;
  }
  if ((s->fmt.dwMask & s->fmt.dwEffects) & (CFM_SUPERSCRIPT | CFM_SUBSCRIPT)) {
    if (s->fmt.dwEffects & CFE_SUPERSCRIPT) yTwipsOffset = s->fmt.yHeight/3;
    if (s->fmt.dwEffects & CFE_SUBSCRIPT) yTwipsOffset = -s->fmt.yHeight/12;
  }
  if (yTwipsOffset)
  {
    int numerator = 1;
    int denominator = 1;
    
    if (c->editor->nZoomNumerator)
    {
      numerator = c->editor->nZoomNumerator;
      denominator = c->editor->nZoomDenominator;
    }
    yOffset = yTwipsOffset * GetDeviceCaps(hDC, LOGPIXELSY) * numerator / denominator / 1440;
  }
  ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL);
  if (width) {
    SIZE sz;
    GetTextExtentPoint32W(hDC, szText, nChars, &sz);
    *width = sz.cx;
  }
  if (nSelFrom < nChars && nSelTo >= 0 && nSelFrom<nSelTo)
  {
    SIZE sz;
    if (nSelFrom < 0) nSelFrom = 0;
    if (nSelTo > nChars) nSelTo = nChars;
    GetTextExtentPoint32W(hDC, szText, nSelFrom, &sz);
    x += sz.cx;
    GetTextExtentPoint32W(hDC, szText+nSelFrom, nSelTo-nSelFrom, &sz);
    
    /* Invert selection if not hidden by EM_HIDESELECTION */
    if (c->editor->bHideSelection == FALSE)
	PatBlt(hDC, x, ymin, sz.cx, cy, DSTINVERT);
  }
  SetTextColor(hDC, rgbOld);
  ME_UnselectStyleFont(c->editor, hDC, s, hOldFont);
}
Example #4
0
/******************************************************************************
 * ME_CharFromPointContext
 *
 * Returns a character position inside the run given a run-relative
 * pixel horizontal position.
 *
 * If closest is FALSE return the actual character
 * If closest is TRUE will round to the closest leading edge.
 * ie. if the second character is at pixel position 8 and third at 16 then for:
 * closest = FALSE cx = 0..7 return 0, cx = 8..15 return 1
 * closest = TRUE  cx = 0..3 return 0, cx = 4..11 return 1.
 */
int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BOOL visual_order)
{
  ME_String *mask_text = NULL;
  WCHAR *str;
  int fit = 0;
  HGDIOBJ hOldFont;
  SIZE sz, sz2, sz3;
  if (!run->len || cx <= 0)
    return 0;

  if (run->nFlags & (MERF_TAB | MERF_ENDCELL))
  {
    if (!closest || cx < run->nWidth / 2) return 0;
    return 1;
  }

  if (run->nFlags & MERF_GRAPHICS)
  {
    SIZE sz;
    ME_GetOLEObjectSize(c, run, &sz);
    if (!closest || cx < sz.cx / 2) return 0;
    return 1;
  }

  if (c->editor->cPasswordMask)
  {
    mask_text = ME_MakeStringR( c->editor->cPasswordMask, run->len );
    str = mask_text->szData;
  }
  else
    str = get_text( run, 0 );

  hOldFont = ME_SelectStyleFont(c, run->style);
  GetTextExtentExPointW(c->hDC, str, run->len,
                        cx, &fit, NULL, &sz);
  if (closest && fit != run->len)
  {
    GetTextExtentPoint32W(c->hDC, str, fit, &sz2);
    GetTextExtentPoint32W(c->hDC, str, fit + 1, &sz3);
    if (cx >= (sz2.cx+sz3.cx)/2)
      fit = fit + 1;
  }

  ME_DestroyString( mask_text );

  ME_UnselectStyleFont(c, run->style, hOldFont);
  return fit;
}
Example #5
0
static HRESULT shape_run( ME_Context *c, ME_Run *run )
{
    HRESULT hr;
    HFONT old_font;
    int i;

    if (!run->glyphs)
    {
        run->max_glyphs = 1.5 * run->len + 16; /* This is suggested in the uniscribe documentation */
        run->max_glyphs = (run->max_glyphs + 7) & ~7; /* Keep alignment simple */
        get_run_glyph_buffers( run );
    }

    if (run->max_clusters < run->len)
    {
        heap_free( run->clusters );
        run->max_clusters = run->len * 2;
        run->clusters = heap_alloc( run->max_clusters * sizeof(WORD) );
    }

    old_font = ME_SelectStyleFont( c, run->style );
    while (1)
    {
        hr = ScriptShape( c->hDC, &run->style->script_cache, get_text( run, 0 ), run->len, run->max_glyphs,
                          &run->script_analysis, run->glyphs, run->clusters, run->vis_attrs, &run->num_glyphs );
        if (hr != E_OUTOFMEMORY) break;
        if (run->max_glyphs > 10 * run->len) break; /* something has clearly gone wrong */
        run->max_glyphs *= 2;
        get_run_glyph_buffers( run );
    }

    if (SUCCEEDED(hr))
        hr = ScriptPlace( c->hDC, &run->style->script_cache, run->glyphs, run->num_glyphs, run->vis_attrs,
                          &run->script_analysis, run->advances, run->offsets, NULL );

    if (SUCCEEDED(hr))
    {
        for (i = 0, run->nWidth = 0; i < run->num_glyphs; i++)
            run->nWidth += run->advances[i];
    }

    ME_UnselectStyleFont( c, run->style, old_font );

    return hr;
}
Example #6
0
void para_num_init( ME_Context *c, ME_Paragraph *para )
{
    ME_Style *style;
    CHARFORMAT2W cf;
    static const WCHAR bullet_font[] = {'S','y','m','b','o','l',0};
    static const WCHAR bullet_str[] = {0xb7, 0};
    static const WCHAR spaceW[] = {' ', 0};
    HFONT old_font;
    SIZE sz;

    if (para->para_num.style && para->para_num.text) return;

    if (!para->para_num.style)
    {
        style = para->eop_run->style;

        cf.cbSize = sizeof(cf);
        cf.dwMask = CFM_FACE | CFM_CHARSET;
        memcpy( cf.szFaceName, bullet_font, sizeof(bullet_font) );
        cf.bCharSet = SYMBOL_CHARSET;
        style = ME_ApplyStyle( c->editor, style, &cf );

        para->para_num.style = style;
    }

    if (!para->para_num.text)
    {
        para->para_num.text = ME_MakeStringConst( bullet_str, 1 );
    }

    old_font = ME_SelectStyleFont( c, para->para_num.style );
    GetTextExtentPointW( c->hDC, para->para_num.text->szData, para->para_num.text->nLen, &sz );
    para->para_num.width = sz.cx;
    GetTextExtentPointW( c->hDC, spaceW, 1, &sz );
    para->para_num.width += sz.cx;
    ME_UnselectStyleFont( c, para->para_num.style, old_font );
}