riched20: Add the ability to CharFromPoint to either pick the closest leading edge or the leading edge of the selected character.

This commit is contained in:
Huw Davies 2013-02-18 13:43:48 +00:00 committed by Alexandre Julliard
parent 1cb663f5ce
commit acaad0a842
4 changed files with 41 additions and 66 deletions

View File

@ -873,7 +873,7 @@ static BOOL ME_ReturnFoundPos(ME_TextEditor *editor, ME_DisplayItem *found,
if ((found->member.run.nFlags & MERF_ENDPARA) || rx < 0)
rx = 0;
result->pRun = found;
result->nOffset = ME_CharFromPointCursor(editor, rx, &found->member.run);
result->nOffset = ME_CharFromPoint(editor, rx, &found->member.run, TRUE);
if (result->nOffset == found->member.run.len && rx)
{
result->pRun = ME_FindItemFwd(result->pRun, diRun);
@ -1194,7 +1194,7 @@ static ME_DisplayItem *ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pR
}
if (x >= run_x && x < run_x+width)
{
int ch = ME_CharFromPointCursor(editor, x-run_x, &pNext->member.run);
int ch = ME_CharFromPoint(editor, x-run_x, &pNext->member.run, TRUE);
if (ch < pNext->member.run.len) {
if (pOffset)
*pOffset = ch;

View File

@ -141,7 +141,8 @@ ME_DisplayItem *ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor,
void ME_CheckCharOffsets(ME_TextEditor *editor) DECLSPEC_HIDDEN;
void ME_PropagateCharOffset(ME_DisplayItem *p, int shift) DECLSPEC_HIDDEN;
/* this one accounts for 1/2 char tolerance */
int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run) DECLSPEC_HIDDEN;
int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest) DECLSPEC_HIDDEN;
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest) DECLSPEC_HIDDEN;
int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset) DECLSPEC_HIDDEN;
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset) DECLSPEC_HIDDEN;
int ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) DECLSPEC_HIDDEN;

View File

@ -404,22 +404,22 @@ void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run)
}
/******************************************************************************
* ME_CharFromPointCursor
* ME_CharFromPointContext
*
* 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).
* pixel horizontal position.
*
* It is used for mouse click handling, for better usability (and compatibility
* with the native control).
* 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_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest)
{
ME_String *mask_text = NULL;
WCHAR *str;
int fit = 0;
ME_Context c;
HGDIOBJ hOldFont;
SIZE sz, sz2, sz3;
if (!run->len || cx <= 0)
@ -427,47 +427,54 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
if (run->nFlags & (MERF_TAB | MERF_ENDCELL))
{
if (cx < run->nWidth/2)
return 0;
return 1;
}
ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
if (run->nFlags & MERF_GRAPHICS)
{
SIZE sz;
ME_GetOLEObjectSize(&c, run, &sz);
ME_DestroyContext(&c);
if (cx < sz.cx/2)
return 0;
if (!closest || cx < run->nWidth / 2) return 0;
return 1;
}
if (editor->cPasswordMask)
if (run->nFlags & MERF_GRAPHICS)
{
mask_text = ME_MakeStringR( editor->cPasswordMask, run->len );
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,
hOldFont = ME_SelectStyleFont(c, run->style);
GetTextExtentExPointW(c->hDC, str, run->len,
cx, &fit, NULL, &sz);
if (fit != run->len)
if (closest && fit != run->len)
{
GetTextExtentPoint32W(c.hDC, str, fit, &sz2);
GetTextExtentPoint32W(c.hDC, str, fit + 1, &sz3);
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);
ME_DestroyContext(&c);
ME_UnselectStyleFont(c, run->style, hOldFont);
return fit;
}
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest)
{
ME_Context c;
int ret;
ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) );
ret = ME_CharFromPointContext( &c, cx, run, closest );
ME_DestroyContext(&c);
return ret;
}
/******************************************************************************
* ME_GetTextExtent
*

View File

@ -106,41 +106,8 @@ static ME_DisplayItem *split_run_extents(ME_WrapContext *wc, ME_DisplayItem *ite
*/
static int find_split_point( ME_Context *c, int cx, ME_Run *run )
{
int fit = 0;
HGDIOBJ hOldFont;
SIZE sz;
if (!run->len || cx <= 0) return 0;
if (run->nFlags & MERF_TAB ||
(run->nFlags & (MERF_ENDCELL|MERF_ENDPARA)) == MERF_ENDCELL)
{
if (cx < run->nWidth / 2) return 0;
return 1;
}
if (run->nFlags & MERF_GRAPHICS)
{
SIZE sz;
ME_GetOLEObjectSize( c, run, &sz );
if (cx < sz.cx) return 0;
return 1;
}
hOldFont = ME_SelectStyleFont( c, run->style );
if (c->editor->cPasswordMask)
{
ME_String *strMasked = ME_MakeStringR( c->editor->cPasswordMask, run->len );
GetTextExtentExPointW( c->hDC, strMasked->szData, run->len, cx, &fit, NULL, &sz );
ME_DestroyString( strMasked );
}
else
{
GetTextExtentExPointW( c->hDC, get_text( run, 0 ), run->len, cx, &fit, NULL, &sz );
}
ME_UnselectStyleFont( c, run->style, hOldFont );
return fit;
return ME_CharFromPointContext( c, cx, run, FALSE );
}
static ME_DisplayItem *ME_MakeRow(int height, int baseline, int width)