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:
parent
1cb663f5ce
commit
acaad0a842
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue