Autosyncing with Wine HEAD

svn path=/trunk/; revision=31789
This commit is contained in:
The Wine Synchronizer 2008-01-14 15:52:45 +00:00
parent 5df342fc2e
commit 1fbef3e9c2
18 changed files with 962 additions and 437 deletions

View file

@ -27,7 +27,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
static BOOL
ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs);
void ME_GetSelection(ME_TextEditor *editor, int *from, int *to)
{
*from = ME_GetCursorOfs(editor, 0);
@ -59,7 +58,7 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
length = ME_GetTextLength(editor);
if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE) && (how->flags & GTL_USECRLF))
length += editor->nParagraphs;
length += editor->nParagraphs - 1;
if (how->flags & GTL_NUMBYTES)
{
@ -705,102 +704,83 @@ int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor)
+ pCursor->pRun->member.run.nCharOfs + pCursor->nOffset;
}
int ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol)
static void ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol)
{
ME_DisplayItem *p = editor->pBuffer->pFirst->member.para.next_para;
ME_DisplayItem *last = NULL;
int rx = 0;
if (is_eol)
*is_eol = 0;
while(p != editor->pBuffer->pLast)
/* find paragraph */
for (; p != editor->pBuffer->pLast; p = p->member.para.next_para)
{
if (p->type == diParagraph)
assert(p->type == diParagraph);
if (y < p->member.para.nYPos + p->member.para.nHeight)
{
int ry = y - p->member.para.nYPos;
if (ry < 0)
{
result->pRun = ME_FindItemFwd(p, diRun);
result->nOffset = 0;
return 0;
}
if (ry >= p->member.para.nHeight)
{
p = p->member.para.next_para;
continue;
}
y -= p->member.para.nYPos;
p = ME_FindItemFwd(p, diStartRow);
y = ry;
continue;
break;
}
if (p->type == diStartRow)
}
/* find row */
for (; p != editor->pBuffer->pLast; )
{
ME_DisplayItem *pp;
assert(p->type == diStartRow);
if (y < p->member.row.nYPos + p->member.row.nHeight)
{
int ry = y - p->member.row.nYPos;
if (ry < 0)
return 0;
if (ry >= p->member.row.nHeight)
{
p = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd);
if (p->type != diStartRow)
return 0;
continue;
}
p = ME_FindItemFwd(p, diRun);
continue;
p = ME_FindItemFwd(p, diRun);
break;
}
if (p->type == diRun)
pp = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd);
if (pp->type != diStartRow)
{
ME_DisplayItem *pp;
p = ME_FindItemFwd(p, diRun);
break;
}
p = pp;
}
for (; p != editor->pBuffer->pLast; p = p->next)
{
switch (p->type)
{
case diRun:
rx = x - p->member.run.pt.x;
if (rx < 0)
rx = 0;
if (rx >= p->member.run.nWidth) /* not this run yet... find next item */
if (rx < p->member.run.nWidth)
{
pp = p;
do {
p = p->next;
if (p->type == diRun)
{
rx = x - p->member.run.pt.x;
goto continue_search;
}
if (p->type == diStartRow)
{
p = ME_FindItemFwd(p, diRun);
if (is_eol)
*is_eol = 1;
rx = 0; /* FIXME not sure */
goto found_here;
}
if (p->type == diParagraph || p->type == diTextEnd)
{
rx = 0; /* FIXME not sure */
p = pp;
goto found_here;
}
} while(1);
continue;
found_here:
assert(p->type == diRun);
if ((p->member.run.nFlags & MERF_ENDPARA) || rx < 0)
rx = 0;
result->pRun = p;
result->nOffset = ME_CharFromPointCursor(editor, rx, &p->member.run);
if (editor->pCursors[0].nOffset == p->member.run.strText->nLen && rx)
{
result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
result->nOffset = 0;
}
return;
}
found_here:
if (p->member.run.nFlags & MERF_ENDPARA)
rx = 0;
result->pRun = p;
result->nOffset = ME_CharFromPointCursor(editor, rx, &p->member.run);
if (editor->pCursors[0].nOffset == p->member.run.strText->nLen && rx)
{
result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
result->nOffset = 0;
}
return 1;
break;
case diStartRow:
p = ME_FindItemFwd(p, diRun);
if (is_eol) *is_eol = 1;
rx = 0; /* FIXME not sure */
goto found_here;
case diParagraph:
case diTextEnd:
rx = 0; /* FIXME not sure */
p = last;
goto found_here;
default: assert(0);
}
assert(0);
continue_search:
;
last = p;
}
result->pRun = ME_FindItemBack(p, diRun);
result->nOffset = 0;
assert(result->pRun->member.run.nFlags & MERF_ENDPARA);
return 0;
}
@ -832,25 +812,64 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y)
tmp_cursor = editor->pCursors[0];
is_selection = ME_IsSelection(editor);
ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd);
if (GetKeyState(VK_SHIFT)>=0)
if (x >= editor->selofs)
{
editor->pCursors[1] = editor->pCursors[0];
}
else
{
if (!is_selection) {
ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd);
if (GetKeyState(VK_SHIFT)>=0)
{
editor->pCursors[1] = editor->pCursors[0];
}
else if (!is_selection) {
editor->pCursors[1] = tmp_cursor;
is_selection = 1;
}
ME_InvalidateSelection(editor);
HideCaret(editor->hWnd);
ME_MoveCaret(editor);
ShowCaret(editor->hWnd);
ME_ClearTempStyle(editor);
ME_SendSelChange(editor);
}
else
{
ME_DisplayItem *pRow;
editor->linesel = 1;
editor->sely = y;
/* Set pCursors[0] to beginning of line */
ME_FindPixelPos(editor, x, y, &editor->pCursors[1], &editor->bCaretAtEnd);
/* Set pCursors[1] to end of line */
pRow = ME_FindItemFwd(editor->pCursors[1].pRun, diStartRowOrParagraphOrEnd);
assert(pRow);
/* pCursor[0] is the position where the cursor will be drawn,
* pCursor[1] is the other end of the selection range
* pCursor[2] and [3] are backups of [0] and [1] so I
* don't have to look them up again
*/
if (pRow->type == diStartRow) {
/* FIXME WTF was I thinking about here ? */
ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun);
assert(pRun);
editor->pCursors[0].pRun = pRun;
editor->pCursors[0].nOffset = 0;
editor->bCaretAtEnd = 1;
} else {
editor->pCursors[0].pRun = ME_FindItemBack(pRow, diRun);
assert(editor->pCursors[0].pRun && editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA);
editor->pCursors[0].nOffset = 0;
editor->bCaretAtEnd = 0;
}
editor->pCursors[2] = editor->pCursors[0];
editor->pCursors[3] = editor->pCursors[1];
ME_InvalidateSelection(editor);
HideCaret(editor->hWnd);
ME_MoveCaret(editor);
ShowCaret(editor->hWnd);
ME_ClearTempStyle(editor);
ME_SendSelChange(editor);
}
ME_InvalidateSelection(editor);
HideCaret(editor->hWnd);
ME_MoveCaret(editor);
ShowCaret(editor->hWnd);
ME_ClearTempStyle(editor);
ME_SendSelChange(editor);
}
void ME_MouseMove(ME_TextEditor *editor, int x, int y)
@ -861,14 +880,33 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
tmp_cursor = editor->pCursors[0];
/* FIXME: do something with the return value of ME_FindPixelPos */
ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd);
if (tmp_cursor.pRun == editor->pCursors[0].pRun &&
tmp_cursor.nOffset == editor->pCursors[0].nOffset)
if (!editor->linesel)
ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd);
else ME_FindPixelPos(editor, (y > editor->sely) * editor->rcFormat.right, y, &tmp_cursor, &editor->bCaretAtEnd);
if (!memcmp(&tmp_cursor, editor->pCursors, sizeof(tmp_cursor)))
return;
ME_InvalidateSelection(editor);
editor->pCursors[0] = tmp_cursor;
if (!editor->linesel)
editor->pCursors[0] = tmp_cursor;
else if (!memcmp(&tmp_cursor, editor->pCursors+2, sizeof(tmp_cursor)) ||
!memcmp(&tmp_cursor, editor->pCursors+3, sizeof(tmp_cursor)))
{
editor->pCursors[0] = editor->pCursors[2];
editor->pCursors[1] = editor->pCursors[3];
}
else if (y < editor->sely)
{
editor->pCursors[0] = tmp_cursor;
editor->pCursors[1] = editor->pCursors[2];
}
else
{
editor->pCursors[0] = tmp_cursor;
editor->pCursors[1] = editor->pCursors[3];
}
HideCaret(editor->hWnd);
ME_MoveCaret(editor);
ME_InvalidateSelection(editor);
@ -1206,11 +1244,11 @@ ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor)
{
ME_Style *style;
int from, to;
ME_Cursor c;
ME_GetSelection(editor, &from, &to);
ME_CursorFromCharOfs(editor, from, &c);
if (from != to) {
ME_Cursor c;
ME_CursorFromCharOfs(editor, from, &c);
style = c.pRun->member.run.style;
ME_AddRefStyle(style); /* ME_GetInsertStyle has already done that */
}
@ -1240,7 +1278,6 @@ void ME_SendSelChange(ME_TextEditor *editor)
SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, sc.nmhdr.idFrom, (LPARAM)&sc);
}
BOOL
ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl)
{

View file

@ -77,7 +77,7 @@ static ULONG WINAPI EnumFormatImpl_Release(IEnumFORMATETC *iface)
if(!ref) {
GlobalFree(This->fmtetc);
richedit_free(This);
heap_free(This);
}
return ref;
@ -152,7 +152,7 @@ static HRESULT EnumFormatImpl_Create(const FORMATETC *fmtetc, UINT fmtetc_cnt, I
EnumFormatImpl *ret;
TRACE("\n");
ret = richedit_alloc(sizeof(EnumFormatImpl));
ret = heap_alloc(sizeof(EnumFormatImpl));
ret->lpVtbl = &VT_EnumFormatImpl;
ret->ref = 1;
ret->cur = 0;
@ -195,7 +195,7 @@ static ULONG WINAPI DataObjectImpl_Release(IDataObject* iface)
if(This->unicode) GlobalFree(This->unicode);
if(This->rtf) GlobalFree(This->rtf);
if(This->fmtetc) GlobalFree(This->fmtetc);
richedit_free(This);
heap_free(This);
}
return ref;
@ -388,7 +388,7 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAO
DataObjectImpl *obj;
TRACE("(%p,%d,%d)\n", editor, lpchrg->cpMin, lpchrg->cpMax);
obj = richedit_alloc(sizeof(DataObjectImpl));
obj = heap_alloc(sizeof(DataObjectImpl));
if(cfRTF == 0)
cfRTF = RegisterClipboardFormatA("Rich Text Format");

View file

@ -29,6 +29,8 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
c->pt.y = 0;
c->hbrMargin = CreateSolidBrush(RGB(224,224,224));
c->rcView = editor->rcFormat;
c->dpi.cx = GetDeviceCaps(hDC, LOGPIXELSX);
c->dpi.cy = GetDeviceCaps(hDC, LOGPIXELSY);
}
void ME_DestroyContext(ME_Context *c)

View file

@ -228,6 +228,7 @@
#include "shlwapi.h"
#include "rtf.h"
#include "imm.h"
#include "res.h"
#define STACK_SIZE_DEFAULT 100
#define STACK_SIZE_MAX 1000
@ -242,6 +243,8 @@ static const WCHAR RichEdit20W[] = {'R', 'i', 'c', 'h', 'E', 'd', 'i', 't', '2',
static const WCHAR RichEdit50W[] = {'R', 'i', 'c', 'h', 'E', 'd', 'i', 't', '5', '0', 'W', 0};
static const WCHAR REListBox20W[] = {'R','E','L','i','s','t','B','o','x','2','0','W', 0};
static const WCHAR REComboBox20W[] = {'R','E','C','o','m','b','o','B','o','x','2','0','W', 0};
static HCURSOR hLeft;
static HCURSOR hBeam;
int me_debug = 0;
HANDLE me_heap = NULL;
@ -329,10 +332,11 @@ static void ME_RTFCharAttrHook(RTF_Info *info)
{
case rtfPlain:
/* FIXME add more flags once they're implemented */
fmt.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR | CFM_BACKCOLOR | CFM_SIZE | CFM_WEIGHT;
fmt.dwMask = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINETYPE | CFM_STRIKEOUT | CFM_COLOR | CFM_BACKCOLOR | CFM_SIZE | CFM_WEIGHT;
fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
fmt.yHeight = 12*20; /* 12pt */
fmt.wWeight = 400;
fmt.bUnderlineType = CFU_UNDERLINENONE;
break;
case rtfBold:
fmt.dwMask = CFM_BOLD;
@ -343,13 +347,24 @@ static void ME_RTFCharAttrHook(RTF_Info *info)
fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
break;
case rtfUnderline:
fmt.dwMask = CFM_UNDERLINE;
fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
fmt.bUnderlineType = CFU_CF1UNDERLINE;
fmt.dwMask = CFM_UNDERLINETYPE;
fmt.bUnderlineType = info->rtfParam ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
break;
case rtfDotUnderline:
fmt.dwMask = CFM_UNDERLINETYPE;
fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEDOTTED : CFU_UNDERLINENONE;
break;
case rtfDbUnderline:
fmt.dwMask = CFM_UNDERLINETYPE;
fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEDOUBLE : CFU_UNDERLINENONE;
break;
case rtfWordUnderline:
fmt.dwMask = CFM_UNDERLINETYPE;
fmt.bUnderlineType = info->rtfParam ? CFU_UNDERLINEWORD : CFU_UNDERLINENONE;
break;
case rtfNoUnderline:
fmt.dwMask = CFM_UNDERLINE;
fmt.dwEffects = 0;
fmt.dwMask = CFM_UNDERLINETYPE;
fmt.bUnderlineType = CFU_UNDERLINENONE;
break;
case rtfStrikeThru:
fmt.dwMask = CFM_STRIKEOUT;
@ -404,6 +419,7 @@ static void ME_RTFCharAttrHook(RTF_Info *info)
fmt.szFaceName[sizeof(fmt.szFaceName)/sizeof(WCHAR)-1] = '\0';
fmt.bCharSet = f->rtfFCharSet;
fmt.dwMask = CFM_FACE | CFM_CHARSET;
fmt.bPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
}
}
break;
@ -1031,6 +1047,27 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
return -1;
}
/* helper to send a msg filter notification */
static BOOL
ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam)
{
MSGFILTER msgf;
msgf.nmhdr.hwndFrom = editor->hWnd;
msgf.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
msgf.nmhdr.code = EN_MSGFILTER;
msgf.msg = msg;
msgf.wParam = *wParam;
msgf.lParam = *lParam;
if (SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf))
return FALSE;
*wParam = msgf.wParam;
*lParam = msgf.lParam;
msgf.wParam = *wParam;
return TRUE;
}
static BOOL
ME_KeyDown(ME_TextEditor *editor, WORD nKey)
@ -1088,6 +1125,14 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
return FALSE;
}
static void ME_SetCursor(ME_TextEditor *editor, int x)
{
if (x < editor->selofs || editor->linesel)
SetCursor(hLeft);
else
SetCursor(hBeam);
}
static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
{
CHARRANGE selrange;
@ -1115,21 +1160,21 @@ static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor);
HDC hDC;
int i;
ed->hWnd = hWnd;
ed->bEmulateVersion10 = FALSE;
ed->pBuffer = ME_MakeText();
hDC = GetDC(hWnd);
ME_MakeFirstParagraph(hDC, ed->pBuffer);
ReleaseDC(hWnd, hDC);
ed->nZoomNumerator = ed->nZoomDenominator = 0;
ME_MakeFirstParagraph(ed);
ed->bCaretShown = FALSE;
ed->nCursors = 2;
ed->nCursors = 4;
ed->pCursors = ALLOC_N_OBJ(ME_Cursor, ed->nCursors);
ed->pCursors[0].pRun = ME_FindItemFwd(ed->pBuffer->pFirst, diRun);
ed->pCursors[0].nOffset = 0;
ed->pCursors[1].pRun = ME_FindItemFwd(ed->pBuffer->pFirst, diRun);
ed->pCursors[1].nOffset = 0;
ed->pCursors[2] = ed->pCursors[0];
ed->pCursors[3] = ed->pCursors[1];
ed->nLastTotalLength = ed->nTotalLength = 0;
ed->nHeight = 0;
ed->nUDArrowX = -1;
@ -1147,7 +1192,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->nParagraphs = 1;
ed->nLastSelStart = ed->nLastSelEnd = 0;
ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph);
ed->nZoomNumerator = ed->nZoomDenominator = 0;
ed->bRedraw = TRUE;
ed->bHideSelection = FALSE;
ed->nInvalidOfs = -1;
@ -1165,7 +1209,12 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
}
ME_CheckCharOffsets(ed);
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_SELECTIONBAR)
ed->selofs = 16;
else
ed->selofs = 0;
ed->linesel = 0;
if (GetWindowLongW(hWnd, GWL_STYLE) & ES_PASSWORD)
ed->cPasswordMask = '*';
else
@ -1235,7 +1284,8 @@ void ME_DestroyEditor(ME_TextEditor *editor)
if (editor->pFontCache[i].hFont)
DeleteObject(editor->pFontCache[i].hFont);
}
DeleteObject(editor->hbrBackground);
if (editor->rgbBackColor != -1)
DeleteObject(editor->hbrBackground);
if(editor->lpOleCallback)
IUnknown_Release(editor->lpOleCallback);
@ -1254,6 +1304,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
DisableThreadLibraryCalls(hinstDLL);
me_heap = HeapCreate (0, 0x10000, 0);
if (!ME_RegisterEditorClass(hinstDLL)) return FALSE;
hLeft = LoadCursorW(hinstDLL, MAKEINTRESOURCEW(OCR_REVERSE));
hBeam = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM));
LookupInit();
break;
@ -1551,7 +1603,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
* setting the bit to work
*/
DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN;
ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
DWORD raw = GetWindowLongW(hWnd, GWL_STYLE);
DWORD settings = mask & raw;
@ -1571,19 +1623,23 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
SetWindowLongW(hWnd, GWL_STYLE, (raw & ~mask) | (settings & mask));
if (lParam & ECO_AUTOWORDSELECTION)
if (settings & ECO_AUTOWORDSELECTION)
FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
if (lParam & ECO_SELECTIONBAR)
FIXME("ECO_SELECTIONBAR not implemented yet!\n");
if (lParam & ECO_VERTICAL)
if (settings & ECO_SELECTIONBAR)
editor->selofs = 16;
else
editor->selofs = 0;
ME_WrapMarkedParagraphs(editor);
if (settings & ECO_VERTICAL)
FIXME("ECO_VERTICAL not implemented yet!\n");
if (lParam & ECO_AUTOHSCROLL)
if (settings & ECO_AUTOHSCROLL)
FIXME("ECO_AUTOHSCROLL not implemented yet!\n");
if (lParam & ECO_AUTOVSCROLL)
if (settings & ECO_AUTOVSCROLL)
FIXME("ECO_AUTOVSCROLL not implemented yet!\n");
if (lParam & ECO_NOHIDESEL)
if (settings & ECO_NOHIDESEL)
FIXME("ECO_NOHIDESEL not implemented yet!\n");
if (lParam & ECO_WANTRETURN)
if (settings & ECO_WANTRETURN)
FIXME("ECO_WANTRETURN not implemented yet!\n");
return settings;
@ -1677,9 +1733,13 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
}
case EM_SETBKGNDCOLOR:
{
LRESULT lColor = ME_GetBackColor(editor);
if (editor->rgbBackColor != -1)
LRESULT lColor;
if (editor->rgbBackColor != -1) {
DeleteObject(editor->hbrBackground);
lColor = editor->rgbBackColor;
}
else lColor = GetSysColor(COLOR_WINDOW);
if (wParam)
{
editor->rgbBackColor = -1;
@ -1996,19 +2056,47 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
return 0;
}
case WM_GETTEXTLENGTH:
return ME_GetTextLength(editor);
{
GETTEXTLENGTHEX how;
how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS;
how.codepage = unicode ? 1200 : CP_ACP;
return ME_GetTextLengthEx(editor, &how);
}
case EM_GETTEXTLENGTHEX:
return ME_GetTextLengthEx(editor, (GETTEXTLENGTHEX *)wParam);
case WM_GETTEXT:
{
GETTEXTEX ex;
LRESULT rc;
LPSTR bufferA = NULL;
LPWSTR bufferW = NULL;
ex.cb = wParam;
if (unicode)
bufferW = heap_alloc((wParam + 2) * sizeof(WCHAR));
else
bufferA = heap_alloc(wParam + 2);
ex.cb = wParam + (unicode ? 2*sizeof(WCHAR) : 2);
ex.flags = GT_USECRLF;
ex.codepage = unicode ? 1200 : CP_ACP;
ex.lpDefaultChar = NULL;
ex.lpUsedDefaultChar = NULL;
return RichEditWndProc_common(hWnd, EM_GETTEXTEX, (WPARAM)&ex, lParam, unicode);
rc = RichEditWndProc_common(hWnd, EM_GETTEXTEX, (WPARAM)&ex, unicode ? (LPARAM)bufferW : (LPARAM)bufferA, unicode);
if (unicode)
{
memcpy((LPWSTR)lParam, bufferW, wParam);
if (lstrlenW(bufferW) >= wParam / sizeof(WCHAR)) rc = 0;
}
else
{
memcpy((LPSTR)lParam, bufferA, wParam);
if (strlen(bufferA) >= wParam) rc = 0;
}
heap_free(bufferA);
heap_free(bufferW);
return rc;
}
case EM_GETTEXTEX:
{
@ -2039,7 +2127,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
/* potentially each char may be a CR, why calculate the exact value with O(N) when
we can just take a bigger buffer? :) */
int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
LPWSTR buffer = richedit_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
LPWSTR buffer = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
DWORD buflen = ex->cb;
LRESULT rc;
DWORD flags = 0;
@ -2048,7 +2136,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
rc = WideCharToMultiByte(ex->codepage, flags, buffer, -1, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefaultChar);
if (rc) rc--; /* do not count 0 terminator */
richedit_free(buffer);
heap_free(buffer);
return rc;
}
}
@ -2324,25 +2412,47 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
SetWindowLongPtrW(hWnd, 0, 0);
return 0;
case WM_LBUTTONDOWN:
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
SetFocus(hWnd);
ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
SetCapture(hWnd);
ME_LinkNotify(editor,msg,wParam,lParam);
ME_SetCursor(editor, LOWORD(lParam));
break;
case WM_MOUSEMOVE:
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
if (GetCapture() == hWnd)
ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
ME_LinkNotify(editor,msg,wParam,lParam);
ME_SetCursor(editor, LOWORD(lParam));
break;
case WM_LBUTTONUP:
if (GetCapture() == hWnd)
ReleaseCapture();
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
editor->linesel = 0;
ME_SetCursor(editor, LOWORD(lParam));
ME_LinkNotify(editor,msg,wParam,lParam);
break;
case WM_LBUTTONDBLCLK:
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
ME_LinkNotify(editor,msg,wParam,lParam);
ME_SelectWord(editor);
break;
case WM_RBUTTONUP:
case WM_RBUTTONDOWN:
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
goto do_default;
case WM_CONTEXTMENU:
if (!ME_ShowContextMenu(editor, (short)LOWORD(lParam), (short)HIWORD(lParam)))
goto do_default;
@ -2384,7 +2494,15 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
case WM_COMMAND:
TRACE("editor wnd command = %d\n", LOWORD(wParam));
return 0;
case WM_KEYUP:
if ((editor->nEventMask & ENM_KEYEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
goto do_default;
case WM_KEYDOWN:
if ((editor->nEventMask & ENM_KEYEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
if (ME_KeyDown(editor, LOWORD(wParam)))
return 0;
goto do_default;
@ -2491,7 +2609,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
{
int gcWheelDelta;
UINT pulScrollLines;
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
!ME_FilterEvent(editor, msg, &wParam, &lParam))
return 0;
SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0);
gcWheelDelta = -GET_WHEEL_DELTA_WPARAM(wParam);
@ -2538,7 +2660,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
ME_SendRequestResize(editor, TRUE);
return 0;
case WM_SETREDRAW:
editor->bRedraw = wParam;
if ((editor->bRedraw = wParam))
ME_RewrapRepaint(editor);
return 0;
case WM_SIZE:
{
@ -2804,7 +2927,10 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in
if (!ME_FindItemFwd(item, diRun))
/* No '\r' is appended to the last paragraph. */
nLen = 0;
else {
else if (bCRLF && nChars == 1) {
nLen = 0;
nChars = 0;
} else {
*buffer = '\r';
if (bCRLF)
{
@ -2847,7 +2973,7 @@ static BOOL ME_RegisterEditorClass(HINSTANCE hInstance)
wcW.cbWndExtra = sizeof(ME_TextEditor *);
wcW.hInstance = NULL; /* hInstance would register DLL-local class */
wcW.hIcon = NULL;
wcW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM));
wcW.hCursor = hBeam;
wcW.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcW.lpszMenuName = NULL;

View file

@ -23,24 +23,24 @@
extern HANDLE me_heap;
static inline void *richedit_alloc( size_t len )
static inline void *heap_alloc( size_t len )
{
return HeapAlloc( me_heap, 0, len );
}
static inline BOOL richedit_free( void *ptr )
static inline BOOL heap_free( void *ptr )
{
return HeapFree( me_heap, 0, ptr );
}
static inline void *richedit_realloc( void *ptr, size_t len )
static inline void *heap_realloc( void *ptr, size_t len )
{
return HeapReAlloc( me_heap, 0, ptr, len );
}
#define ALLOC_OBJ(type) richedit_alloc(sizeof(type))
#define ALLOC_N_OBJ(type, count) richedit_alloc((count)*sizeof(type))
#define FREE_OBJ(ptr) richedit_free(ptr)
#define ALLOC_OBJ(type) heap_alloc(sizeof(type))
#define ALLOC_N_OBJ(type, count) heap_alloc((count)*sizeof(type))
#define FREE_OBJ(ptr) heap_free(ptr)
#define RUN_IS_HIDDEN(run) ((run)->style->fmt.dwMask & CFM_HIDDEN \
&& (run)->style->fmt.dwEffects & CFE_HIDDEN)
@ -60,8 +60,8 @@ void ME_AddRefStyle(ME_Style *item);
void ME_ReleaseStyle(ME_Style *item);
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor);
ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style);
HFONT ME_SelectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s);
void ME_UnselectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s, HFONT hOldFont);
HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s);
void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont);
void ME_InitCharFormat2W(CHARFORMAT2W *pFmt);
void ME_SaveTempStyle(ME_TextEditor *editor);
void ME_ClearTempStyle(ME_TextEditor *editor);
@ -150,7 +150,7 @@ ME_DisplayItem *ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor,
void ME_CheckCharOffsets(ME_TextEditor *editor);
void ME_PropagateCharOffset(ME_DisplayItem *p, int shift);
void ME_GetGraphicsSize(ME_TextEditor *editor, ME_Run *run, SIZE *pSize);
int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run);
int ME_CharFromPoint(ME_Context *c, int cx, ME_Run *run);
/* this one accounts for 1/2 char tolerance */
int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run);
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset);
@ -181,7 +181,6 @@ void ME_SelectWord(ME_TextEditor *editor);
void ME_HideCaret(ME_TextEditor *ed);
void ME_ShowCaret(ME_TextEditor *ed);
void ME_MoveCaret(ME_TextEditor *ed);
int ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol);
int ME_CharFromPos(ME_TextEditor *editor, int x, int y);
void ME_LButtonDown(ME_TextEditor *editor, int x, int y);
void ME_MouseMove(ME_TextEditor *editor, int x, int y);
@ -211,18 +210,16 @@ ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor);
BOOL ME_UpdateSelection(ME_TextEditor *editor, const ME_Cursor *pTempCursor);
/* wrap.c */
void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp);
ME_DisplayItem *ME_MakeRow(int height, int baseline, int width);
void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd);
void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp);
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor);
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor);
void ME_SendRequestResize(ME_TextEditor *editor, BOOL force);
int ME_twips2pointsX(ME_Context *c, int x);
int ME_twips2pointsY(ME_Context *c, int y);
/* para.c */
ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run);
void ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end);
void ME_MakeFirstParagraph(HDC hDC, ME_TextBuffer *editor);
void ME_MakeFirstParagraph(ME_TextEditor *editor);
ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style);
ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp);
void ME_DumpParaStyle(ME_Paragraph *s);
@ -243,7 +240,6 @@ void ME_RewrapRepaint(ME_TextEditor *editor);
void ME_UpdateRepaint(ME_TextEditor *editor);
void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph);
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
COLORREF ME_GetBackColor(const ME_TextEditor *editor);
void ME_InvalidateSelection(ME_TextEditor *editor);
void ME_QueueInvalidateFromCursor(ME_TextEditor *editor, int nCursor);
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator);
@ -258,6 +254,10 @@ void ME_UpdateScrollBar(ME_TextEditor *editor);
int ME_GetYScrollPos(ME_TextEditor *editor);
BOOL ME_GetYScrollVisible(ME_TextEditor *editor);
/* other functions in paint.c */
int ME_GetParaBorderWidth(ME_TextEditor *editor, int);
int ME_GetParaLineSpace(ME_Context *c, ME_Paragraph*);
/* richole.c */
extern LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *);

View file

@ -167,7 +167,6 @@ typedef struct tagME_Paragraph
struct tagME_TableCell *pCells; /* list of cells and their properties */
struct tagME_TableCell *pLastCell; /* points to the last cell in the list */
int nLeftMargin, nRightMargin, nFirstMargin;
int nCharOfs;
int nFlags;
int nYPos, nHeight;
@ -325,6 +324,7 @@ typedef struct tagME_TextEditor
BOOL bHaveFocus;
/*for IME */
int imeStartIndex;
DWORD selofs, linesel, sely;
} ME_TextEditor;
typedef struct tagME_Context
@ -334,6 +334,7 @@ typedef struct tagME_Context
POINT ptRowOffset;
RECT rcView;
HBRUSH hbrMargin;
SIZE dpi;
/* those are valid inside ME_WrapTextParagraph and related */
POINT ptFirstRun;

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View file

@ -109,7 +109,8 @@ void ME_UpdateRepaint(ME_TextEditor *editor)
{
/* Should be called whenever the contents of the control have changed */
ME_Cursor *pCursor;
if (!editor->bRedraw) return;
if (ME_WrapMarkedParagraphs(editor))
ME_UpdateScrollBar(editor);
@ -135,27 +136,47 @@ ME_RewrapRepaint(ME_TextEditor *editor)
* looks, but not content. Like resizing. */
ME_MarkAllForWrapping(editor);
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
ME_Repaint(editor);
if (editor->bRedraw)
{
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
ME_Repaint(editor);
}
}
int ME_twips2pointsX(ME_Context *c, int x)
{
if (c->editor->nZoomNumerator == 0)
return x * c->dpi.cx / 1440;
else
return x * c->dpi.cx * c->editor->nZoomNumerator / 1440 / c->editor->nZoomDenominator;
}
int ME_twips2pointsY(ME_Context *c, int y)
{
if (c->editor->nZoomNumerator == 0)
return y * c->dpi.cy / 1440;
else
return y * c->dpi.cy * c->editor->nZoomNumerator / 1440 / c->editor->nZoomDenominator;
}
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;
COLORREF rgbOld;
int yOffset = 0, yTwipsOffset = 0;
hOldFont = ME_SelectStyleFont(c->editor, hDC, s);
rgbBack = ME_GetBackColor(c->editor);
SIZE sz;
COLORREF rgb;
hOldFont = ME_SelectStyleFont(c, s);
if ((s->fmt.dwMask & CFM_LINK) && (s->fmt.dwEffects & CFE_LINK))
rgbOld = SetTextColor(hDC, RGB(0,0,255));
rgb = RGB(0,0,255);
else if ((s->fmt.dwMask & CFM_COLOR) && (s->fmt.dwEffects & CFE_AUTOCOLOR))
rgbOld = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
rgb = GetSysColor(COLOR_WINDOWTEXT);
else
rgbOld = SetTextColor(hDC, s->fmt.crTextColor);
rgb = s->fmt.crTextColor;
rgbOld = SetTextColor(hDC, rgb);
if ((s->fmt.dwMask & s->fmt.dwEffects) & CFM_OFFSET) {
yTwipsOffset = s->fmt.yOffset;
}
@ -164,26 +185,43 @@ static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, in
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;
}
yOffset = ME_twips2pointsY(c, yTwipsOffset);
ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL);
if (width) {
SIZE sz;
GetTextExtentPoint32W(hDC, szText, nChars, &sz);
*width = sz.cx;
GetTextExtentPoint32W(hDC, szText, nChars, &sz);
if (width) *width = sz.cx;
if (s->fmt.dwMask & CFM_UNDERLINETYPE)
{
HPEN hPen;
switch (s->fmt.bUnderlineType)
{
case CFU_UNDERLINE:
case CFU_UNDERLINEWORD: /* native seems to map it to simple underline (MSDN) */
case CFU_UNDERLINEDOUBLE: /* native seems to map it to simple underline (MSDN) */
hPen = CreatePen(PS_SOLID, 1, rgb);
break;
case CFU_UNDERLINEDOTTED:
hPen = CreatePen(PS_DOT, 1, rgb);
break;
default:
WINE_FIXME("Unknown underline type (%u)\n", s->fmt.bUnderlineType);
/* fall through */
case CFU_CF1UNDERLINE: /* this type is supported in the font, do nothing */
case CFU_UNDERLINENONE:
hPen = NULL;
break;
}
if (hPen != NULL)
{
HPEN hOldPen = SelectObject(hDC, hPen);
/* FIXME: should use textmetrics info for Descent info */
MoveToEx(hDC, x, y - yOffset + 1, NULL);
LineTo(hDC, x + sz.cx, y - yOffset + 1);
SelectObject(hDC, hOldPen);
DeleteObject(hPen);
}
}
if (nSelFrom < nChars && nSelTo >= 0 && nSelFrom<nSelTo)
{
SIZE sz;
if (nSelFrom < 0) nSelFrom = 0;
if (nSelTo > nChars) nSelTo = nChars;
GetTextExtentPoint32W(hDC, szText, nSelFrom, &sz);
@ -195,7 +233,7 @@ static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, in
PatBlt(hDC, x, ymin, sz.cx, cy, DSTINVERT);
}
SetTextColor(hDC, rgbOld);
ME_UnselectStyleFont(c->editor, hDC, s, hOldFont);
ME_UnselectStyleFont(c, s, hOldFont);
}
static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) {
@ -239,7 +277,7 @@ static void ME_DrawGraphics(ME_Context *c, int x, int y, ME_Run *run,
static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para)
{
ME_Run *run = &rundi->member.run;
ME_DisplayItem *start = ME_FindItemBack(rundi, diStartRow);
ME_DisplayItem *start;
int runofs = run->nCharOfs+para->nCharOfs;
int nSelFrom, nSelTo;
const WCHAR wszSpace[] = {' ', 0};
@ -247,6 +285,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
if (run->nFlags & MERF_HIDDEN)
return;
start = ME_FindItemBack(rundi, diStartRow);
ME_GetSelection(c->editor, &nSelFrom, &nSelTo);
/* Draw selected end-of-paragraph mark */
@ -278,15 +317,184 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
}
}
COLORREF ME_GetBackColor(const ME_TextEditor *editor)
static struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;} border_details[] = {
/* none */ {0, 0, PS_SOLID, FALSE},
/* 3/4 */ {3, 4, PS_SOLID, FALSE},
/* 1 1/2 */ {3, 2, PS_SOLID, FALSE},
/* 2 1/4 */ {9, 4, PS_SOLID, FALSE},
/* 3 */ {3, 1, PS_SOLID, FALSE},
/* 4 1/2 */ {9, 2, PS_SOLID, FALSE},
/* 6 */ {6, 1, PS_SOLID, FALSE},
/* 3/4 double */ {3, 4, PS_SOLID, TRUE},
/* 1 1/2 double */ {3, 2, PS_SOLID, TRUE},
/* 2 1/4 double */ {9, 4, PS_SOLID, TRUE},
/* 3/4 gray */ {3, 4, PS_DOT /* FIXME */, FALSE},
/* 1 1/2 dashed */ {3, 2, PS_DASH, FALSE},
};
static COLORREF pen_colors[16] = {
/* Black */ RGB(0x00, 0x00, 0x00), /* Blue */ RGB(0x00, 0x00, 0xFF),
/* Cyan */ RGB(0x00, 0xFF, 0xFF), /* Green */ RGB(0x00, 0xFF, 0x00),
/* Magenta */ RGB(0xFF, 0x00, 0xFF), /* Red */ RGB(0xFF, 0x00, 0x00),
/* Yellow */ RGB(0xFF, 0xFF, 0x00), /* White */ RGB(0xFF, 0xFF, 0xFF),
/* Dark blue */ RGB(0x00, 0x00, 0x80), /* Dark cyan */ RGB(0x00, 0x80, 0x80),
/* Dark green */ RGB(0x00, 0x80, 0x80), /* Dark magenta */ RGB(0x80, 0x00, 0x80),
/* Dark red */ RGB(0x80, 0x00, 0x00), /* Dark yellow */ RGB(0x80, 0x80, 0x00),
/* Dark gray */ RGB(0x80, 0x80, 0x80), /* Light gray */ RGB(0xc0, 0xc0, 0xc0),
};
static int ME_GetBorderPenWidth(ME_TextEditor* editor, int idx)
{
/* Looks like I was seriously confused
return GetSysColor((GetWindowLong(editor->hWnd, GWL_STYLE) & ES_READONLY) ? COLOR_3DFACE: COLOR_WINDOW);
*/
if (editor->rgbBackColor == -1)
return GetSysColor(COLOR_WINDOW);
int width;
if (editor->nZoomNumerator == 0)
{
width = border_details[idx].width_num + border_details[idx].width_den / 2;
width /= border_details[idx].width_den;
}
else
return editor->rgbBackColor;
{
width = border_details[idx].width_num * editor->nZoomNumerator;
width += border_details[idx].width_den * editor->nZoomNumerator / 2;
width /= border_details[idx].width_den * editor->nZoomDenominator;
}
return width;
}
int ME_GetParaBorderWidth(ME_TextEditor* editor, int flags)
{
int idx = (flags >> 8) & 0xF;
int width;
if (idx >= sizeof(border_details) / sizeof(border_details[0]))
{
FIXME("Unsupported border value %d\n", idx);
return 0;
}
width = ME_GetBorderPenWidth(editor, idx);
if (border_details[idx].dble) width = width * 2 + 1;
return width;
}
int ME_GetParaLineSpace(ME_Context* c, ME_Paragraph* para)
{
int sp = 0, ls = 0;
if (!(para->pFmt->dwMask & PFM_LINESPACING)) return 0;
/* FIXME: how to compute simply the line space in ls ??? */
/* FIXME: does line spacing include the line itself ??? */
switch (para->pFmt->bLineSpacingRule)
{
case 0: sp = ls; break;
case 1: sp = (3 * ls) / 2; break;
case 2: sp = 2 * ls; break;
case 3: sp = ME_twips2pointsY(c, para->pFmt->dyLineSpacing); if (sp < ls) sp = ls; break;
case 4: sp = ME_twips2pointsY(c, para->pFmt->dyLineSpacing); break;
case 5: sp = para->pFmt->dyLineSpacing / 20; break;
default: FIXME("Unsupported spacing rule value %d\n", para->pFmt->bLineSpacingRule);
}
if (c->editor->nZoomNumerator == 0)
return sp;
else
return sp * c->editor->nZoomNumerator / c->editor->nZoomDenominator;
}
static int ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y)
{
int idx, border_width;
int ybefore, yafter;
RECT rc;
if (!(para->pFmt->dwMask & (PFM_BORDER | PFM_SPACEBEFORE | PFM_SPACEAFTER))) return 0;
if (para->pFmt->dwMask & PFM_SPACEBEFORE)
{
rc.left = c->rcView.left;
rc.right = c->rcView.right;
rc.top = y;
ybefore = ME_twips2pointsY(c, para->pFmt->dySpaceBefore);
rc.bottom = y + ybefore;
FillRect(c->hDC, &rc, c->editor->hbrBackground);
}
else ybefore = 0;
if (para->pFmt->dwMask & PFM_SPACEAFTER)
{
rc.left = c->rcView.left;
rc.right = c->rcView.right;
rc.bottom = y + para->nHeight;
yafter = ME_twips2pointsY(c, para->pFmt->dySpaceAfter);
rc.top = rc.bottom - yafter;
FillRect(c->hDC, &rc, c->editor->hbrBackground);
}
else yafter = 0;
border_width = 0;
idx = (para->pFmt->wBorders >> 8) & 0xF;
if ((para->pFmt->dwMask & PFM_BORDER) && idx != 0 && (para->pFmt->wBorders & 0xF)) {
int pen_width;
COLORREF pencr;
HPEN pen = NULL, oldpen = NULL;
POINT pt;
if (para->pFmt->wBorders & 0x00B0)
FIXME("Unsupported border flags %x\n", para->pFmt->wBorders);
border_width = ME_GetParaBorderWidth(c->editor, para->pFmt->wBorders);
if (para->pFmt->wBorders & 64) /* autocolor */
pencr = GetSysColor(COLOR_WINDOWTEXT);
else
pencr = pen_colors[(para->pFmt->wBorders >> 12) & 0xF];
pen_width = ME_GetBorderPenWidth(c->editor, idx);
pen = CreatePen(border_details[idx].pen_style, pen_width, pencr);
oldpen = SelectObject(c->hDC, pen);
MoveToEx(c->hDC, 0, 0, &pt);
/* before & after spaces are not included in border */
if (para->pFmt->wBorders & 1)
{
MoveToEx(c->hDC, c->rcView.left, y + ybefore, NULL);
LineTo(c->hDC, c->rcView.left, y + para->nHeight - yafter);
if (border_details[idx].dble) {
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + ybefore + pen_width + 1, NULL);
LineTo(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - yafter - pen_width - 1);
}
}
if (para->pFmt->wBorders & 2)
{
MoveToEx(c->hDC, c->rcView.right, y + ybefore, NULL);
LineTo(c->hDC, c->rcView.right, y + para->nHeight - yafter);
if (border_details[idx].dble) {
MoveToEx(c->hDC, c->rcView.right - pen_width - 1, y + ybefore + pen_width + 1, NULL);
LineTo(c->hDC, c->rcView.right - pen_width - 1, y + para->nHeight - yafter - pen_width - 1);
}
}
if (para->pFmt->wBorders & 4)
{
MoveToEx(c->hDC, c->rcView.left, y + ybefore, NULL);
LineTo(c->hDC, c->rcView.right, y + ybefore);
if (border_details[idx].dble) {
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + ybefore + pen_width + 1, NULL);
LineTo(c->hDC, c->rcView.right - pen_width - 1, y + ybefore + pen_width + 1);
}
}
if (para->pFmt->wBorders & 8)
{
MoveToEx(c->hDC, c->rcView.left, y + para->nHeight - yafter - 1, NULL);
LineTo(c->hDC, c->rcView.right, y + para->nHeight - yafter - 1);
if (border_details[idx].dble) {
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - yafter - 1 - pen_width - 1, NULL);
LineTo(c->hDC, c->rcView.right - pen_width - 1, y + para->nHeight - yafter - 1 - pen_width - 1);
}
}
MoveToEx(c->hDC, pt.x, pt.y, NULL);
SelectObject(c->hDC, oldpen);
DeleteObject(pen);
}
return ybefore +
((para->pFmt->dwMask & PFM_BORDER) && (para->pFmt->wBorders & 4) ?
border_width : 0);
}
void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
@ -297,10 +505,10 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
RECT rc, rcPara;
int y = c->pt.y;
int height = 0, baseline = 0, no=0, pno = 0;
int xs, xe;
int visible = 0;
int xs = 0, xe = 0;
BOOL visible = FALSE;
int nMargWidth = 0;
c->pt.x = c->rcView.left;
rcPara.left = c->rcView.left;
rcPara.right = c->rcView.right;
@ -308,33 +516,33 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
switch(p->type) {
case diParagraph:
para = &p->member.para;
assert(para);
nMargWidth = ME_twips2pointsX(c, para->pFmt->dxStartIndent);
if (pno != 0)
nMargWidth += ME_twips2pointsX(c, para->pFmt->dxOffset);
xs = c->rcView.left+nMargWidth;
xe = c->rcView.right - ME_twips2pointsX(c, para->pFmt->dxRightIndent);
y += ME_DrawParaDecoration(c, para, y);
break;
case diStartRow:
assert(para);
nMargWidth = (pno==0?para->nFirstMargin:para->nLeftMargin);
xs = c->rcView.left+nMargWidth;
xe = c->rcView.right-para->nRightMargin;
y += height;
rcPara.top = y;
rcPara.bottom = y+p->member.row.nHeight;
visible = RectVisible(c->hDC, &rcPara);
if (visible) {
HBRUSH hbr;
hbr = CreateSolidBrush(ME_GetBackColor(c->editor));
/* left margin */
rc.left = c->rcView.left;
rc.right = c->rcView.left+nMargWidth;
rc.top = y;
rc.bottom = y+p->member.row.nHeight;
FillRect(c->hDC, &rc, hbr/* c->hbrMargin */);
FillRect(c->hDC, &rc, c->editor->hbrBackground);
/* right margin */
rc.left = xe;
rc.right = c->rcView.right;
FillRect(c->hDC, &rc, hbr/* c->hbrMargin */);
FillRect(c->hDC, &rc, c->editor->hbrBackground);
rc.left = c->rcView.left+nMargWidth;
rc.right = xe;
FillRect(c->hDC, &rc, hbr);
DeleteObject(hbr);
FillRect(c->hDC, &rc, c->editor->hbrBackground);
}
if (me_debug)
{
@ -489,8 +697,7 @@ int ME_GetYScrollPos(ME_TextEditor *editor)
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
GetScrollInfo(editor->hWnd, SB_VERT, &si);
return si.nPos;
return GetScrollInfo(editor->hWnd, SB_VERT, &si) ? si.nPos : 0;
}
BOOL ME_GetYScrollVisible(ME_TextEditor *editor)
@ -558,25 +765,26 @@ ME_InvalidateSelection(ME_TextEditor *editor)
assert(para2->type == diParagraph);
/* last selection markers aren't always updated, which means
they can point past the end of the document */
if (editor->nLastSelStart > len)
editor->nLastSelEnd = len;
if (editor->nLastSelEnd > len)
editor->nLastSelEnd = len;
/* if the start part of selection is being expanded or contracted... */
if (nStart < editor->nLastSelStart) {
ME_MarkForPainting(editor, para1, ME_FindItemFwd(editor->pLastSelStartPara, diParagraphOrEnd));
} else
if (nStart > editor->nLastSelStart) {
ME_MarkForPainting(editor, editor->pLastSelStartPara, ME_FindItemFwd(para1, diParagraphOrEnd));
}
if (editor->nLastSelStart > len || editor->nLastSelEnd > len) {
ME_MarkForPainting(editor,
ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph),
ME_FindItemFwd(editor->pBuffer->pFirst, diTextEnd));
} else {
/* if the start part of selection is being expanded or contracted... */
if (nStart < editor->nLastSelStart) {
ME_MarkForPainting(editor, para1, ME_FindItemFwd(editor->pLastSelStartPara, diParagraphOrEnd));
} else
if (nStart > editor->nLastSelStart) {
ME_MarkForPainting(editor, editor->pLastSelStartPara, ME_FindItemFwd(para1, diParagraphOrEnd));
}
/* if the end part of selection is being contracted or expanded... */
if (nEnd < editor->nLastSelEnd) {
ME_MarkForPainting(editor, para2, ME_FindItemFwd(editor->pLastSelEndPara, diParagraphOrEnd));
} else
if (nEnd > editor->nLastSelEnd) {
ME_MarkForPainting(editor, editor->pLastSelEndPara, ME_FindItemFwd(para2, diParagraphOrEnd));
/* if the end part of selection is being contracted or expanded... */
if (nEnd < editor->nLastSelEnd) {
ME_MarkForPainting(editor, para2, ME_FindItemFwd(editor->pLastSelEndPara, diParagraphOrEnd));
} else
if (nEnd > editor->nLastSelEnd) {
ME_MarkForPainting(editor, editor->pLastSelEndPara, ME_FindItemFwd(para2, diParagraphOrEnd));
}
}
ME_InvalidateMarkedParagraphs(editor);

View file

@ -25,16 +25,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
static const WCHAR wszParagraphSign[] = {0xB6, 0};
void ME_MakeFirstParagraph(HDC hDC, ME_TextBuffer *text)
void ME_MakeFirstParagraph(ME_TextEditor *editor)
{
ME_Context c;
HDC hDC;
PARAFORMAT2 fmt;
CHARFORMAT2W cf;
LOGFONTW lf;
HFONT hf;
ME_TextBuffer *text = editor->pBuffer;
ME_DisplayItem *para = ME_MakeDI(diParagraph);
ME_DisplayItem *run;
ME_Style *style;
hDC = GetDC(editor->hWnd);
ME_InitContext(&c, editor, hDC);
hf = (HFONT)GetStockObject(SYSTEM_FONT);
assert(hf);
GetObjectW(hf, sizeof(LOGFONTW), &lf);
@ -44,21 +50,23 @@ void ME_MakeFirstParagraph(HDC hDC, ME_TextBuffer *text)
cf.dwMask |= CFM_ALLCAPS|CFM_BOLD|CFM_DISABLED|CFM_EMBOSS|CFM_HIDDEN;
cf.dwMask |= CFM_IMPRINT|CFM_ITALIC|CFM_LINK|CFM_OUTLINE|CFM_PROTECTED;
cf.dwMask |= CFM_REVISED|CFM_SHADOW|CFM_SMALLCAPS|CFM_STRIKEOUT;
cf.dwMask |= CFM_SUBSCRIPT|CFM_UNDERLINE;
cf.dwMask |= CFM_SUBSCRIPT|CFM_UNDERLINETYPE|CFM_WEIGHT;
cf.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
lstrcpyW(cf.szFaceName, lf.lfFaceName);
cf.yHeight=lf.lfHeight*1440/GetDeviceCaps(hDC, LOGPIXELSY);
if (lf.lfWeight>=700) /* FIXME correct weight ? */
cf.dwEffects |= CFE_BOLD;
cf.yHeight = ME_twips2pointsY(&c, lf.lfHeight);
if (lf.lfWeight >= 700) cf.dwEffects |= CFE_BOLD;
cf.wWeight = lf.lfWeight;
if (lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
if (lf.lfUnderline) cf.dwEffects |= CFE_UNDERLINE;
cf.bUnderlineType = (lf.lfUnderline) ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
if (lf.lfStrikeOut) cf.dwEffects |= CFE_STRIKEOUT;
cf.bPitchAndFamily = lf.lfPitchAndFamily;
cf.bCharSet = lf.lfCharSet;
ZeroMemory(&fmt, sizeof(fmt));
fmt.cbSize = sizeof(fmt);
fmt.dwMask = PFM_ALIGNMENT | PFM_OFFSET | PFM_STARTINDENT | PFM_RIGHTINDENT | PFM_TABSTOPS;
fmt.wAlignment = PFA_LEFT;
CopyMemory(para->member.para.pFmt, &fmt, sizeof(PARAFORMAT2));
@ -76,6 +84,9 @@ void ME_MakeFirstParagraph(HDC hDC, ME_TextBuffer *text)
text->pLast->member.para.prev_para = para;
text->pLast->member.para.nCharOfs = 1;
ME_DestroyContext(&c);
ReleaseDC(editor->hWnd, hDC);
}
void ME_MarkAllForWrapping(ME_TextEditor *editor)
@ -138,11 +149,6 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME
new_para->member.para.nFlags = MEPF_REWRAP; /* FIXME copy flags (if applicable) */
/* FIXME initialize format style and call ME_SetParaFormat blah blah */
CopyMemory(new_para->member.para.pFmt, run_para->member.para.pFmt, sizeof(PARAFORMAT2));
/* FIXME remove this as soon as nLeftMargin etc are replaced with proper fields of PARAFORMAT2 */
new_para->member.para.nLeftMargin = run_para->member.para.nLeftMargin;
new_para->member.para.nRightMargin = run_para->member.para.nRightMargin;
new_para->member.para.nFirstMargin = run_para->member.para.nFirstMargin;
new_para->member.para.bTable = run_para->member.para.bTable;
@ -277,45 +283,67 @@ ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *item) {
return ME_FindItemBackOrHere(item, diParagraph);
}
static void ME_DumpStyleEffect(char **p, const char *name, const PARAFORMAT2 *fmt, int mask)
{
*p += sprintf(*p, "%-22s%s\n", name, (fmt->dwMask & mask) ? ((fmt->wEffects & mask) ? "yes" : "no") : "N/A");
}
void ME_DumpParaStyleToBuf(const PARAFORMAT2 *pFmt, char buf[2048])
{
/* FIXME only PARAFORMAT styles implemented */
char *p;
p = buf;
p += sprintf(p, "Alignment: %s\n",
!(pFmt->dwMask & PFM_ALIGNMENT) ? "N/A" :
((pFmt->wAlignment == PFA_LEFT) ? "left" :
((pFmt->wAlignment == PFA_RIGHT) ? "right" :
((pFmt->wAlignment == PFA_CENTER) ? "center" :
/*((pFmt->wAlignment == PFA_JUSTIFY) ? "justify" : "incorrect")*/
"incorrect"))));
if (pFmt->dwMask & PFM_OFFSET)
p += sprintf(p, "Offset: %d\n", (int)pFmt->dxOffset);
else
p += sprintf(p, "Offset: N/A\n");
if (pFmt->dwMask & PFM_OFFSETINDENT)
p += sprintf(p, "Offset indent: %d\n", (int)pFmt->dxStartIndent);
else
p += sprintf(p, "Offset indent: N/A\n");
if (pFmt->dwMask & PFM_STARTINDENT)
p += sprintf(p, "Start indent: %d\n", (int)pFmt->dxStartIndent);
else
p += sprintf(p, "Start indent: N/A\n");
if (pFmt->dwMask & PFM_RIGHTINDENT)
p += sprintf(p, "Right indent: %d\n", (int)pFmt->dxRightIndent);
else
p += sprintf(p, "Right indent: N/A\n");
ME_DumpStyleEffect(&p, "Page break before:", pFmt, PFM_PAGEBREAKBEFORE);
#define DUMP(mask, name, fmt, field) \
if (pFmt->dwMask & (mask)) p += sprintf(p, "%-22s" fmt "\n", name, pFmt->field); \
else p += sprintf(p, "%-22sN/A\n", name);
/* we take for granted that PFE_xxx is the hiword of the corresponding PFM_xxx */
#define DUMP_EFFECT(mask, name) \
p += sprintf(p, "%-22s%s\n", name, (pFmt->dwMask & (mask)) ? ((pFmt->wEffects & ((mask) >> 8)) ? "yes" : "no") : "N/A");
DUMP(PFM_NUMBERING, "Numbering:", "%u", wNumbering);
DUMP_EFFECT(PFM_DONOTHYPHEN, "Disable auto-hyphen:");
DUMP_EFFECT(PFM_KEEP, "No page break in para:");
DUMP_EFFECT(PFM_KEEPNEXT, "No page break in para & next:");
DUMP_EFFECT(PFM_NOLINENUMBER, "No line number:");
DUMP_EFFECT(PFM_NOWIDOWCONTROL, "No widow & orphan:");
DUMP_EFFECT(PFM_PAGEBREAKBEFORE, "Page break before:");
DUMP_EFFECT(PFM_RTLPARA, "RTL para:");
DUMP_EFFECT(PFM_SIDEBYSIDE, "Side by side:");
DUMP_EFFECT(PFM_TABLE, "Table:");
DUMP(PFM_OFFSETINDENT, "Offset indent:", "%d", dxStartIndent);
DUMP(PFM_STARTINDENT, "Start indent:", "%d", dxStartIndent);
DUMP(PFM_RIGHTINDENT, "Right indent:", "%d", dxRightIndent);
DUMP(PFM_OFFSET, "Offset:", "%d", dxOffset);
if (pFmt->dwMask & PFM_ALIGNMENT) {
switch (pFmt->wAlignment) {
case PFA_LEFT : p += sprintf(p, "Alignment: left\n"); break;
case PFA_RIGHT : p += sprintf(p, "Alignment: right\n"); break;
case PFA_CENTER : p += sprintf(p, "Alignment: center\n"); break;
case PFA_JUSTIFY: p += sprintf(p, "Alignment: justify\n"); break;
default : p += sprintf(p, "Alignment: incorrect %d\n", pFmt->wAlignment); break;
}
}
else p += sprintf(p, "Alignment: N/A\n");
DUMP(PFM_TABSTOPS, "Tab Stops:", "%d", cTabCount);
if (pFmt->dwMask & PFM_TABSTOPS) {
int i;
p += sprintf(p, "\t");
for (i = 0; i < pFmt->cTabCount; i++) p += sprintf(p, "%x ", pFmt->rgxTabs[i]);
p += sprintf(p, "\n");
}
DUMP(PFM_SPACEBEFORE, "Space Before:", "%d", dySpaceBefore);
DUMP(PFM_SPACEAFTER, "Space After:", "%d", dySpaceAfter);
DUMP(PFM_LINESPACING, "Line spacing:", "%d", dyLineSpacing);
DUMP(PFM_STYLE, "Text style:", "%d", sStyle);
DUMP(PFM_LINESPACING, "Line spacing rule:", "%u", bLineSpacingRule);
/* bOutlineLevel should be 0 */
DUMP(PFM_SHADING, "Shading Weigth:", "%u", wShadingWeight);
DUMP(PFM_SHADING, "Shading Style:", "%u", wShadingStyle);
DUMP(PFM_NUMBERINGSTART, "Numbering Start:", "%u", wNumberingStart);
DUMP(PFM_NUMBERINGSTYLE, "Numbering Style:", "0x%x", wNumberingStyle);
DUMP(PFM_NUMBERINGTAB, "Numbering Tab:", "%u", wNumberingStyle);
DUMP(PFM_BORDER, "Border Space:", "%u", wBorderSpace);
DUMP(PFM_BORDER, "Border Width:", "%u", wBorderWidth);
DUMP(PFM_BORDER, "Borders:", "%u", wBorders);
#undef DUMP
#undef DUMP_EFFECT
}
void ME_SetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, const PARAFORMAT2 *pFmt)
@ -326,22 +354,51 @@ void ME_SetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, const PARAFOR
CopyMemory(&copy, para->member.para.pFmt, sizeof(PARAFORMAT2));
if (pFmt->dwMask & PFM_ALIGNMENT)
para->member.para.pFmt->wAlignment = pFmt->wAlignment;
if (pFmt->dwMask & PFM_STARTINDENT)
para->member.para.pFmt->dxStartIndent = pFmt->dxStartIndent;
if (pFmt->dwMask & PFM_OFFSET)
para->member.para.pFmt->dxOffset = pFmt->dxOffset;
#define COPY_FIELD(m, f) \
if (pFmt->dwMask & (m)) { \
para->member.para.pFmt->dwMask |= m; \
para->member.para.pFmt->f = pFmt->f; \
}
COPY_FIELD(PFM_NUMBERING, wNumbering);
#define EFFECTS_MASK (PFM_RTLPARA|PFM_KEEP|PFM_KEEPNEXT|PFM_PAGEBREAKBEFORE| \
PFM_NOLINENUMBER|PFM_NOWIDOWCONTROL|PFM_DONOTHYPHEN|PFM_SIDEBYSIDE| \
PFM_TABLE)
/* we take for granted that PFE_xxx is the hiword of the corresponding PFM_xxx */
if (pFmt->dwMask & EFFECTS_MASK) {
para->member.para.pFmt->dwMask &= ~(pFmt->dwMask & EFFECTS_MASK);
para->member.para.pFmt->wEffects |= pFmt->wEffects & HIWORD(pFmt->dwMask);
}
#undef EFFECTS_MASK
COPY_FIELD(PFM_STARTINDENT, dxStartIndent);
if (pFmt->dwMask & PFM_OFFSETINDENT)
para->member.para.pFmt->dxStartIndent += pFmt->dxStartIndent;
COPY_FIELD(PFM_RIGHTINDENT, dxRightIndent);
COPY_FIELD(PFM_OFFSET, dxOffset);
COPY_FIELD(PFM_ALIGNMENT, wAlignment);
if (pFmt->dwMask & PFM_TABSTOPS)
{
para->member.para.pFmt->cTabCount = pFmt->cTabCount;
memcpy(para->member.para.pFmt->rgxTabs, pFmt->rgxTabs, pFmt->cTabCount*sizeof(int));
memcpy(para->member.para.pFmt->rgxTabs, pFmt->rgxTabs, pFmt->cTabCount*sizeof(LONG));
}
/* FIXME to be continued (indents, bulleting and such) */
COPY_FIELD(PFM_SPACEBEFORE, dySpaceBefore);
COPY_FIELD(PFM_SPACEAFTER, dySpaceAfter);
COPY_FIELD(PFM_LINESPACING, dyLineSpacing);
COPY_FIELD(PFM_STYLE, sStyle);
COPY_FIELD(PFM_LINESPACING, bLineSpacingRule);
COPY_FIELD(PFM_SHADING, wShadingWeight);
COPY_FIELD(PFM_SHADING, wShadingStyle);
COPY_FIELD(PFM_NUMBERINGSTART, wNumberingStart);
COPY_FIELD(PFM_NUMBERINGSTYLE, wNumberingStyle);
COPY_FIELD(PFM_NUMBERINGTAB, wNumberingTab);
COPY_FIELD(PFM_BORDER, wBorderSpace);
COPY_FIELD(PFM_BORDER, wBorderWidth);
COPY_FIELD(PFM_BORDER, wBorders);
para->member.para.pFmt->dwMask |= pFmt->dwMask;
#undef COPY_FIELD
if (memcmp(&copy, para->member.para.pFmt, sizeof(PARAFORMAT2)))
para->member.para.nFlags |= MEPF_REWRAP;
@ -410,28 +467,45 @@ void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
ZeroMemory(&tmp, sizeof(tmp));
tmp.cbSize = sizeof(tmp);
ME_GetParaFormat(editor, para, &tmp);
assert(tmp.dwMask & PFM_ALIGNMENT);
if (pFmt->wAlignment != tmp.wAlignment)
pFmt->dwMask &= ~PFM_ALIGNMENT;
#define CHECK_FIELD(m, f) \
if (pFmt->f != tmp.f) pFmt->dwMask &= ~(m);
CHECK_FIELD(PFM_NUMBERING, wNumbering);
/* para->member.para.pFmt->wEffects = pFmt->wEffects; */
assert(tmp.dwMask & PFM_ALIGNMENT);
CHECK_FIELD(PFM_NUMBERING, wNumbering);
assert(tmp.dwMask & PFM_STARTINDENT);
if (pFmt->dxStartIndent != tmp.dxStartIndent)
pFmt->dwMask &= ~PFM_STARTINDENT;
CHECK_FIELD(PFM_STARTINDENT, dxStartIndent);
assert(tmp.dwMask & PFM_RIGHTINDENT);
CHECK_FIELD(PFM_RIGHTINDENT, dxRightIndent);
assert(tmp.dwMask & PFM_OFFSET);
if (pFmt->dxOffset != tmp.dxOffset)
pFmt->dwMask &= ~PFM_OFFSET;
assert(tmp.dwMask & PFM_TABSTOPS);
CHECK_FIELD(PFM_OFFSET, dxOffset);
CHECK_FIELD(PFM_ALIGNMENT, wAlignment);
assert(tmp.dwMask & PFM_TABSTOPS);
if (pFmt->dwMask & PFM_TABSTOPS) {
if (pFmt->cTabCount != tmp.cTabCount)
pFmt->dwMask &= ~PFM_TABSTOPS;
else
if (memcmp(pFmt->rgxTabs, tmp.rgxTabs, tmp.cTabCount*sizeof(int)))
if (pFmt->cTabCount != tmp.cTabCount ||
memcmp(pFmt->rgxTabs, tmp.rgxTabs, tmp.cTabCount*sizeof(int)))
pFmt->dwMask &= ~PFM_TABSTOPS;
}
CHECK_FIELD(PFM_SPACEBEFORE, dySpaceBefore);
CHECK_FIELD(PFM_SPACEAFTER, dySpaceAfter);
CHECK_FIELD(PFM_LINESPACING, dyLineSpacing);
CHECK_FIELD(PFM_STYLE, sStyle);
CHECK_FIELD(PFM_SPACEAFTER, bLineSpacingRule);
CHECK_FIELD(PFM_SHADING, wShadingWeight);
CHECK_FIELD(PFM_SHADING, wShadingStyle);
CHECK_FIELD(PFM_NUMBERINGSTART, wNumberingStart);
CHECK_FIELD(PFM_NUMBERINGSTYLE, wNumberingStyle);
CHECK_FIELD(PFM_NUMBERINGTAB, wNumberingTab);
CHECK_FIELD(PFM_BORDER, wBorderSpace);
CHECK_FIELD(PFM_BORDER, wBorderWidth);
CHECK_FIELD(PFM_BORDER, wBorders);
#undef CHECK_FIELD
if (para == para_end)
return;
para = para->member.para.next_para;

View file

@ -76,18 +76,6 @@ static void RTFPutCodePageChar(RTF_Info *info, int c);
/* ---------------------------------------------------------------------- */
/*
* Memory allocation routines
*/
/*
* Return pointer to block of size bytes, or NULL if there's
* not enough memory available.
*/
#define RTFAlloc(size) richedit_alloc(size)
#define RTFReAlloc(ptr, size) richedit_realloc(ptr, size)
#define RTFFree(ptr) richedit_free(ptr)
/*
* Saves a string on the heap and returns a pointer to it.
@ -96,7 +84,7 @@ static inline char *RTFStrSave(const char *s)
{
char *p;
p = RTFAlloc (lstrlenA(s) + 1);
p = heap_alloc (lstrlenA(s) + 1);
if (p == NULL)
return NULL;
return lstrcpyA (p, s);
@ -143,14 +131,14 @@ RTFDestroyAttrs(RTF_Info *info)
while (info->fontList)
{
fp = info->fontList->rtfNextFont;
RTFFree (info->fontList->rtfFName);
RTFFree (info->fontList);
heap_free (info->fontList->rtfFName);
heap_free (info->fontList);
info->fontList = fp;
}
while (info->colorList)
{
cp = info->colorList->rtfNextColor;
RTFFree (info->colorList);
heap_free (info->colorList);
info->colorList = cp;
}
while (info->styleList)
@ -160,12 +148,12 @@ RTFDestroyAttrs(RTF_Info *info)
while (eltList)
{
ep = eltList->rtfNextSE;
RTFFree (eltList->rtfSEText);
RTFFree (eltList);
heap_free (eltList->rtfSEText);
heap_free (eltList);
eltList = ep;
}
RTFFree (info->styleList->rtfSName);
RTFFree (info->styleList);
heap_free (info->styleList->rtfSName);
heap_free (info->styleList);
info->styleList = sp;
}
}
@ -176,11 +164,11 @@ RTFDestroy(RTF_Info *info)
{
if (info->rtfTextBuf)
{
RTFFree(info->rtfTextBuf);
RTFFree(info->pushedTextBuf);
heap_free(info->rtfTextBuf);
heap_free(info->pushedTextBuf);
}
RTFDestroyAttrs(info);
RTFFree(info->cpOutputBuffer);
heap_free(info->cpOutputBuffer);
}
@ -196,15 +184,15 @@ void RTFInit(RTF_Info *info)
if (info->rtfTextBuf == NULL) /* initialize the text buffers */
{
info->rtfTextBuf = RTFAlloc (rtfBufSiz);
info->pushedTextBuf = RTFAlloc (rtfBufSiz);
info->rtfTextBuf = heap_alloc (rtfBufSiz);
info->pushedTextBuf = heap_alloc (rtfBufSiz);
if (info->rtfTextBuf == NULL || info->pushedTextBuf == NULL)
ERR ("Cannot allocate text buffers.\n");
info->rtfTextBuf[0] = info->pushedTextBuf[0] = '\0';
}
RTFFree (info->inputName);
RTFFree (info->outputName);
heap_free (info->inputName);
heap_free (info->outputName);
info->inputName = info->outputName = NULL;
for (i = 0; i < rtfMaxClass; i++)
@ -245,7 +233,7 @@ void RTFInit(RTF_Info *info)
if (!info->cpOutputBuffer)
{
info->dwMaxCPOutputCount = 0x1000;
info->cpOutputBuffer = RTFAlloc(info->dwMaxCPOutputCount);
info->cpOutputBuffer = heap_alloc(info->dwMaxCPOutputCount);
}
}
@ -564,7 +552,7 @@ RTFCharSetToCodePage(RTF_Info *info, int charset)
/* FIXME: TranslateCharsetInfo does not work as good as it
* should, so let's use it only when all else fails */
if (!TranslateCharsetInfo(&n, &csi, TCI_SRCCHARSET))
ERR("%s: unknown charset %u\n", __FUNCTION__, charset);
ERR("unknown charset %d\n", charset);
else
return csi.ciACP;
}
@ -2300,9 +2288,9 @@ void LookupInit(void)
rp->rtfKHash = Hash (rp->rtfKStr);
index = rp->rtfKHash % (RTF_KEY_COUNT * 2);
if (!rtfHashTable[index].count)
rtfHashTable[index].value = RTFAlloc(sizeof(RTFKey *));
rtfHashTable[index].value = heap_alloc(sizeof(RTFKey *));
else
rtfHashTable[index].value = RTFReAlloc(rtfHashTable[index].value, sizeof(RTFKey *) * (rtfHashTable[index].count + 1));
rtfHashTable[index].value = heap_realloc(rtfHashTable[index].value, sizeof(RTFKey *) * (rtfHashTable[index].count + 1));
rtfHashTable[index].value[rtfHashTable[index].count++] = rp;
}
}
@ -2313,7 +2301,7 @@ void LookupCleanup(void)
for (i=0; i<RTF_KEY_COUNT*2; i++)
{
RTFFree( rtfHashTable[i].value );
heap_free( rtfHashTable[i].value );
rtfHashTable[i].value = NULL;
rtfHashTable[i].count = 0;
}
@ -2682,7 +2670,7 @@ static void
RTFFlushCPOutputBuffer(RTF_Info *info)
{
int bufferMax = info->dwCPOutputCount * 2 * sizeof(WCHAR);
WCHAR *buffer = RTFAlloc(bufferMax);
WCHAR *buffer = heap_alloc(bufferMax);
int length;
length = MultiByteToWideChar(info->codePage, 0, info->cpOutputBuffer,
@ -2690,7 +2678,7 @@ RTFFlushCPOutputBuffer(RTF_Info *info)
info->dwCPOutputCount = 0;
RTFPutUnicodeString(info, buffer, length);
RTFFree((char *)buffer);
heap_free((char *)buffer);
}
void
@ -2719,7 +2707,7 @@ RTFPutCodePageChar(RTF_Info *info, int c)
if (info->dwCPOutputCount >= info->dwMaxCPOutputCount)
{
info->dwMaxCPOutputCount *= 2;
info->cpOutputBuffer = RTFReAlloc(info->cpOutputBuffer, info->dwMaxCPOutputCount);
info->cpOutputBuffer = heap_realloc(info->cpOutputBuffer, info->dwMaxCPOutputCount);
}
info->cpOutputBuffer[info->dwCPOutputCount++] = c;
}

View file

@ -0,0 +1,21 @@
/*
* Top level resource file for MOUSE driver dll
*
* Copyright 2007 Maarten Lankhorst for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define OCR_REVERSE 32768

View file

@ -1,5 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<group>
<module name="riched20" type="win32dll" baseaddress="${BASEADDRESS_RICHED20}" installbase="system32" installname="riched20.dll" allowwarnings="true">
<importlibrary definition="riched20.spec.def" />
<include base="riched20">.</include>
@ -35,3 +36,4 @@
<file>version.rc</file>
<file>riched20.spec</file>
</module>
</group>

View file

@ -112,7 +112,7 @@ IRichEditOle_fnRelease(IRichEditOle *me)
if (!ref)
{
TRACE ("Destroying %p\n", This);
richedit_free(This);
heap_free(This);
}
return ref;
}
@ -529,7 +529,7 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj)
{
IRichEditOleImpl *reo;
reo = richedit_alloc(sizeof(IRichEditOleImpl));
reo = heap_alloc(sizeof(IRichEditOleImpl));
if (!reo)
return 0;

View file

@ -36,7 +36,7 @@
* that only care about gross token distinctions.
* Major/minor numbers: Within their class, tokens have a major
* number, and may also have a minor number to further
* distinquish tokens with the same major number.
* distinguish tokens with the same major number.
*
* *** Class, major and minor token numbers are all >= 0 ***
*
@ -1005,7 +1005,7 @@ struct RTFStyleElt
* if no memory available.
*/
# define New(t) ((t *) RTFAlloc ((int) sizeof (t)))
# define New(t) (heap_alloc (sizeof (t)))
/* Parser stack size */

View file

@ -487,11 +487,10 @@ void ME_GetGraphicsSize(ME_TextEditor *editor, ME_Run *run, SIZE *pSize)
* 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 ME_CharFromPoint(ME_Context *c, int cx, ME_Run *run)
{
int fit = 0;
HGDIOBJ hOldFont;
HDC hDC;
SIZE sz;
if (!run->strText->nLen)
return 0;
@ -505,29 +504,28 @@ int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run)
if (run->nFlags & MERF_GRAPHICS)
{
SIZE sz;
ME_GetGraphicsSize(editor, run, &sz);
ME_GetGraphicsSize(c->editor, run, &sz);
if (cx < sz.cx)
return 0;
return 1;
}
hDC = GetDC(editor->hWnd);
hOldFont = ME_SelectStyleFont(editor, hDC, run->style);
hOldFont = ME_SelectStyleFont(c, run->style);
if (editor->cPasswordMask)
if (c->editor->cPasswordMask)
{
ME_String *strMasked = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(run->strText));
GetTextExtentExPointW(hDC, strMasked->szData, run->strText->nLen,
ME_String *strMasked = ME_MakeStringR(c->editor->cPasswordMask,ME_StrVLen(run->strText));
GetTextExtentExPointW(c->hDC, strMasked->szData, run->strText->nLen,
cx, &fit, NULL, &sz);
ME_DestroyString(strMasked);
}
else
{
GetTextExtentExPointW(hDC, run->strText->szData, run->strText->nLen,
GetTextExtentExPointW(c->hDC, run->strText->szData, run->strText->nLen,
cx, &fit, NULL, &sz);
}
ME_UnselectStyleFont(editor, hDC, run->style, hOldFont);
ReleaseDC(editor->hWnd, hDC);
ME_UnselectStyleFont(c, run->style, hOldFont);
return fit;
}
@ -548,8 +546,8 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
/* This could point to either the run's real text, or it's masked form in a password control */
int fit = 0, fit1 = 0;
ME_Context c;
HGDIOBJ hOldFont;
HDC hDC;
SIZE sz, sz2, sz3;
if (!run->strText->nLen)
return 0;
@ -574,17 +572,17 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
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);
ME_InitContext(&c, editor, GetDC(editor->hWnd));
hOldFont = ME_SelectStyleFont(&c, run->style);
GetTextExtentExPointW(c.hDC, strRunText->szData, strRunText->nLen,
cx, &fit, NULL, &sz);
if (fit != strRunText->nLen)
{
int chars = 1;
GetTextExtentPoint32W(hDC, strRunText->szData, fit, &sz2);
GetTextExtentPoint32W(c.hDC, strRunText->szData, fit, &sz2);
fit1 = ME_StrRelPos(strRunText, fit, &chars);
GetTextExtentPoint32W(hDC, strRunText->szData, fit1, &sz3);
GetTextExtentPoint32W(c.hDC, strRunText->szData, fit1, &sz3);
if (cx >= (sz2.cx+sz3.cx)/2)
fit = fit1;
}
@ -592,11 +590,24 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
if (editor->cPasswordMask)
ME_DestroyString(strRunText);
ME_UnselectStyleFont(editor, hDC, run->style, hOldFont);
ReleaseDC(editor->hWnd, hDC);
ME_UnselectStyleFont(&c, run->style, hOldFont);
ReleaseDC(editor->hWnd, c.hDC);
return fit;
}
/******************************************************************************
* 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;
hOldFont = ME_SelectStyleFont(c, s);
GetTextExtentPoint32W(c->hDC, szText, nChars, size);
ME_UnselectStyleFont(c, s, hOldFont);
}
/******************************************************************************
* ME_PointFromChar
*
@ -606,8 +617,7 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
{
SIZE size;
HDC hDC = GetDC(editor->hWnd);
HGDIOBJ hOldFont;
ME_Context c;
ME_String *strRunText;
/* This could point to either the run's real text, or it's masked form in a password control */
@ -623,29 +633,14 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
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);
ME_InitContext(&c, editor, GetDC(editor->hWnd));
ME_GetTextExtent(&c, strRunText->szData, nOffset, pRun->style, &size);
ReleaseDC(editor->hWnd, c.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
*
@ -683,7 +678,7 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
if (run->nFlags & MERF_TAB)
{
int pos = 0, i = 0, ppos;
int lpsx = GetDeviceCaps(c->hDC, LOGPIXELSX);
PARAFORMAT2 *pFmt = para->pFmt;
do {
if (i < pFmt->cTabCount)
@ -695,7 +690,7 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
{
pos += 720-(pos%720);
}
ppos = pos*lpsx/1440;
ppos = ME_twips2pointsX(c, pos);
if (ppos>run->pt.x) {
size.cx = ppos - run->pt.x;
break;
@ -714,9 +709,7 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
}
if (run->nFlags & MERF_CELL)
{
int lpsx = GetDeviceCaps(c->hDC, LOGPIXELSX);
size.cx = run->pCell->nRightBoundary * lpsx / 1440 - run->pt.x;
size.cx = ME_twips2pointsX(c, run->pCell->nRightBoundary) - run->pt.x;
return size;
}
return size;
@ -938,8 +931,8 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
do {
/* FIXME add more style feature comparisons */
int nAttribs = CFM_SIZE | CFM_FACE | CFM_COLOR;
int nEffects = CFM_BOLD | CFM_ITALIC | CFM_UNDERLINE;
int nAttribs = CFM_SIZE | CFM_FACE | CFM_COLOR | CFM_UNDERLINETYPE;
int nEffects = CFM_BOLD | CFM_ITALIC;
run = ME_FindItemFwd(run, diRun);
@ -957,11 +950,14 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
{
if (!(tmp.dwMask & CFM_FACE))
pFmt->dwMask &= ~CFM_FACE;
else if (lstrcmpW(pFmt->szFaceName, tmp.szFaceName))
else if (lstrcmpW(pFmt->szFaceName, tmp.szFaceName) ||
pFmt->bPitchAndFamily != tmp.bPitchAndFamily)
pFmt->dwMask &= ~CFM_FACE;
}
if (pFmt->yHeight != tmp.yHeight)
pFmt->dwMask &= ~CFM_SIZE;
if (pFmt->bUnderlineType != tmp.bUnderlineType)
pFmt->dwMask &= ~CFM_UNDERLINETYPE;
if (pFmt->dwMask & CFM_COLOR)
{
if (!((pFmt->dwEffects&CFE_AUTOCOLOR) & (tmp.dwEffects&CFE_AUTOCOLOR)))

View file

@ -25,12 +25,20 @@ WINE_DECLARE_DEBUG_CHANNEL(richedit_style);
static int all_refs = 0;
/* the following routines assume that:
* - char2[AW] extends char[AW] by adding fields at the end of the charA form)
* - szFaceName is the last field of char[AW] form, and wWeight the first of 2[AW]
* - the difference between A and W form is the szFaceName as Ansi vs Unicode string
* - because of alignment, offset of wWeight field in 2[AW] structure *IS NOT*
* sizeof(char[AW])
*/
CHARFORMAT2W *ME_ToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from)
{
if (from->cbSize == sizeof(CHARFORMATA))
{
CHARFORMATA *f = (CHARFORMATA *)from;
CopyMemory(to, f, sizeof(*f)-sizeof(f->szFaceName));
CopyMemory(to, f, FIELD_OFFSET(CHARFORMATA, szFaceName));
to->cbSize = sizeof(CHARFORMAT2W);
if (f->dwMask & CFM_FACE) {
MultiByteToWideChar(0, 0, f->szFaceName, -1, to->szFaceName, sizeof(to->szFaceName)/sizeof(WCHAR));
@ -42,20 +50,20 @@ CHARFORMAT2W *ME_ToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from)
CHARFORMATW *f = (CHARFORMATW *)from;
CopyMemory(to, f, sizeof(*f));
/* theoretically, we don't need to zero the remaining memory */
ZeroMemory(((CHARFORMATW *)to)+1, sizeof(CHARFORMAT2W)-sizeof(CHARFORMATW));
ZeroMemory(&to->wWeight, sizeof(CHARFORMAT2W)-FIELD_OFFSET(CHARFORMAT2W, wWeight));
to->cbSize = sizeof(CHARFORMAT2W);
return to;
}
if (from->cbSize == sizeof(CHARFORMAT2A))
{
CHARFORMATA *f = (CHARFORMATA *)from;
CHARFORMAT2A *f = (CHARFORMAT2A *)from;
/* copy the A structure without face name */
CopyMemory(to, f, sizeof(CHARFORMATA)-sizeof(f->szFaceName));
CopyMemory(to, f, FIELD_OFFSET(CHARFORMATA, szFaceName));
/* convert face name */
if (f->dwMask & CFM_FACE)
MultiByteToWideChar(0, 0, f->szFaceName, -1, to->szFaceName, sizeof(to->szFaceName)/sizeof(WCHAR));
/* copy the rest of the 2A structure to 2W */
CopyMemory(1+((CHARFORMATW *)to), f+1, sizeof(CHARFORMAT2A)-sizeof(CHARFORMATA));
CopyMemory(&to->wWeight, &f->wWeight, sizeof(CHARFORMAT2A)-FIELD_OFFSET(CHARFORMAT2A, wWeight));
to->cbSize = sizeof(CHARFORMAT2W);
return to;
}
@ -75,8 +83,22 @@ CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from)
if (to->cbSize == sizeof(CHARFORMATA))
{
CHARFORMATA *t = (CHARFORMATA *)to;
CopyMemory(t, from, sizeof(*t)-sizeof(t->szFaceName));
CopyMemory(t, from, FIELD_OFFSET(CHARFORMATA, szFaceName));
WideCharToMultiByte(0, 0, from->szFaceName, -1, t->szFaceName, sizeof(t->szFaceName), 0, 0);
if (from->dwMask & CFM_UNDERLINETYPE)
{
switch (from->bUnderlineType)
{
case CFU_CF1UNDERLINE:
to->dwMask |= CFM_UNDERLINE;
to->dwEffects |= CFE_UNDERLINE;
break;
case CFU_UNDERLINENONE:
to->dwMask |= CFM_UNDERLINE;
to->dwEffects &= ~CFE_UNDERLINE;
break;
}
}
t->cbSize = sizeof(*t); /* it was overwritten by CopyMemory */
return to;
}
@ -84,6 +106,20 @@ CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from)
{
CHARFORMATW *t = (CHARFORMATW *)to;
CopyMemory(t, from, sizeof(*t));
if (from->dwMask & CFM_UNDERLINETYPE)
{
switch (from->bUnderlineType)
{
case CFU_CF1UNDERLINE:
to->dwMask |= CFM_UNDERLINE;
to->dwEffects |= CFE_UNDERLINE;
break;
case CFU_UNDERLINENONE:
to->dwMask |= CFM_UNDERLINE;
to->dwEffects &= ~CFE_UNDERLINE;
break;
}
}
t->cbSize = sizeof(*t); /* it was overwritten by CopyMemory */
return to;
}
@ -91,15 +127,15 @@ CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from)
{
CHARFORMAT2A *t = (CHARFORMAT2A *)to;
/* copy the A structure without face name */
CopyMemory(t, from, sizeof(CHARFORMATA)-sizeof(t->szFaceName));
CopyMemory(t, from, FIELD_OFFSET(CHARFORMATA, szFaceName));
/* convert face name */
WideCharToMultiByte(0, 0, from->szFaceName, -1, t->szFaceName, sizeof(t->szFaceName), 0, 0);
/* copy the rest of the 2A structure to 2W */
CopyMemory(&t->wWeight, &from->wWeight, sizeof(CHARFORMAT2A)-sizeof(CHARFORMATA));
CopyMemory(&t->wWeight, &from->wWeight, sizeof(CHARFORMAT2W)-FIELD_OFFSET(CHARFORMAT2W,wWeight));
t->cbSize = sizeof(*t); /* it was overwritten by CopyMemory */
return to;
}
assert(to->cbSize >= sizeof(CHARFORMAT2W));
assert(to->cbSize >= sizeof(CHARFORMAT2W));
return from;
}
@ -166,7 +202,9 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style)
COPY_STYLE_ITEM(CFM_STYLE, sStyle);
COPY_STYLE_ITEM(CFM_UNDERLINETYPE, bUnderlineType);
COPY_STYLE_ITEM(CFM_WEIGHT, wWeight);
/* FIXME: this is not documented this way, but that's the more logical */
COPY_STYLE_ITEM(CFM_FACE, bPitchAndFamily);
s->fmt.dwEffects &= ~(style->dwMask);
s->fmt.dwEffects |= style->dwEffects & style->dwMask;
s->fmt.dwMask |= style->dwMask;
@ -177,6 +215,13 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style)
else
s->fmt.dwEffects &= ~CFE_AUTOCOLOR;
}
if (style->dwMask & CFM_UNDERLINE)
{
s->fmt.dwMask |= CFM_UNDERLINETYPE;
s->fmt.dwMask &= ~CFM_UNDERLINE;
s->fmt.bUnderlineType = (style->dwEffects & CFM_UNDERLINE) ?
CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
}
return s;
}
@ -252,37 +297,33 @@ void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048])
static void
ME_LogFontFromStyle(HDC hDC, LOGFONTW *lf, const ME_Style *s, int nZoomNumerator, int nZoomDenominator)
ME_LogFontFromStyle(ME_Context* c, LOGFONTW *lf, const ME_Style *s)
{
int rx, ry;
rx = GetDeviceCaps(hDC, LOGPIXELSX);
ry = GetDeviceCaps(hDC, LOGPIXELSY);
ZeroMemory(lf, sizeof(LOGFONTW));
lstrcpyW(lf->lfFaceName, s->fmt.szFaceName);
if (nZoomNumerator == 0)
{
nZoomNumerator = 1;
nZoomDenominator = 1;
}
lf->lfHeight = -s->fmt.yHeight*ry*nZoomNumerator/nZoomDenominator/1440;
lf->lfHeight = ME_twips2pointsY(c, -s->fmt.yHeight);
lf->lfWeight = 400;
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_BOLD)
lf->lfWeight = 700;
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_WEIGHT)
if (s->fmt.dwMask & CFM_WEIGHT)
lf->lfWeight = s->fmt.wWeight;
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_ITALIC)
lf->lfItalic = 1;
if (s->fmt.dwEffects & s->fmt.dwMask & (CFM_UNDERLINE | CFE_LINK))
lf->lfUnderline = 1;
if (s->fmt.dwMask & CFM_UNDERLINETYPE && s->fmt.bUnderlineType == CFU_CF1UNDERLINE)
lf->lfUnderline = 1;
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_STRIKEOUT)
lf->lfStrikeOut = 1;
if (s->fmt.dwEffects & s->fmt.dwMask & (CFM_SUBSCRIPT|CFM_SUPERSCRIPT))
lf->lfHeight = (lf->lfHeight*2)/3;
/*lf.lfQuality = PROOF_QUALITY; */
lf->lfPitchAndFamily = s->fmt.bPitchAndFamily;
lf->lfCharSet = s->fmt.bCharSet;
if (s->fmt.dwMask & CFM_FACE)
lf->lfPitchAndFamily = s->fmt.bPitchAndFamily;
if (s->fmt.dwMask & CFM_CHARSET)
lf->lfCharSet = s->fmt.bCharSet;
}
void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt)
@ -316,22 +357,22 @@ static BOOL ME_IsFontEqual(const LOGFONTW *p1, const LOGFONTW *p2)
return TRUE;
}
HFONT ME_SelectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s)
HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s)
{
HFONT hOldFont;
LOGFONTW lf;
int i, nEmpty, nAge = 0x7FFFFFFF;
ME_FontCacheItem *item;
assert(hDC);
assert(c->hDC);
assert(s);
ME_LogFontFromStyle(hDC, &lf, s, editor->nZoomNumerator, editor->nZoomDenominator);
ME_LogFontFromStyle(c, &lf, s);
for (i=0; i<HFONT_CACHE_SIZE; i++)
editor->pFontCache[i].nAge++;
c->editor->pFontCache[i].nAge++;
for (i=0, nEmpty=-1, nAge=0; i<HFONT_CACHE_SIZE; i++)
{
item = &editor->pFontCache[i];
item = &c->editor->pFontCache[i];
if (!item->nRefs)
{
if (item->nAge > nAge)
@ -342,7 +383,7 @@ HFONT ME_SelectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s)
}
if (i < HFONT_CACHE_SIZE) /* found */
{
item = &editor->pFontCache[i];
item = &c->editor->pFontCache[i];
TRACE_(richedit_style)("font reused %d\n", i);
s->hFont = item->hFont;
@ -350,7 +391,7 @@ HFONT ME_SelectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s)
}
else
{
item = &editor->pFontCache[nEmpty]; /* this legal even when nEmpty == -1, as we don't dereference it */
item = &c->editor->pFontCache[nEmpty]; /* this legal even when nEmpty == -1, as we don't dereference it */
assert(nEmpty != -1); /* otherwise we leak cache entries or get too many fonts at once*/
if (item->hFont) {
@ -365,22 +406,22 @@ HFONT ME_SelectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s)
item->nRefs = 1;
memcpy(&item->lfSpecs, &lf, sizeof(LOGFONTW));
}
hOldFont = SelectObject(hDC, s->hFont);
hOldFont = SelectObject(c->hDC, s->hFont);
/* should be cached too, maybe ? */
GetTextMetricsW(hDC, &s->tm);
GetTextMetricsW(c->hDC, &s->tm);
return hOldFont;
}
void ME_UnselectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s, HFONT hOldFont)
void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont)
{
int i;
assert(hDC);
assert(c->hDC);
assert(s);
SelectObject(hDC, hOldFont);
SelectObject(c->hDC, hOldFont);
for (i=0; i<HFONT_CACHE_SIZE; i++)
{
ME_FontCacheItem *pItem = &editor->pFontCache[i];
ME_FontCacheItem *pItem = &c->editor->pFontCache[i];
if (pItem->hFont == s->hFont && pItem->nRefs > 0)
{
pItem->nRefs--;

View file

@ -24,3 +24,7 @@
#define WINE_PRODUCTVERSION_STR "5,30,23,1215"
#include "wine/wine_common_ver.rc"
#include "res.h"
OCR_REVERSE CURSOR ocr_reverse.cur

View file

@ -32,7 +32,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
* - no tabs
*/
ME_DisplayItem *ME_MakeRow(int height, int baseline, int width)
static ME_DisplayItem *ME_MakeRow(int height, int baseline, int width)
{
ME_DisplayItem *item = ME_MakeDI(diStartRow);
@ -51,7 +51,7 @@ static void ME_BeginRow(ME_WrapContext *wc)
wc->pt.x = 0;
}
void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd)
{
ME_DisplayItem *p, *row, *para;
int ascent = 0, descent = 0, width=0, shift = 0, align = 0;
@ -168,7 +168,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem
int i, idesp, len;
ME_Run *run = &p->member.run;
idesp = i = ME_CharFromPoint(wc->context->editor, loc, run);
idesp = i = ME_CharFromPoint(wc->context, loc, run);
len = ME_StrVLen(run->strText);
assert(len>0);
assert(i<len);
@ -336,10 +336,13 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
return p->next;
}
void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp);
static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD beginofs) {
ME_DisplayItem *p;
ME_WrapContext wc;
int dpi = GetDeviceCaps(c->hDC, LOGPIXELSX);
int border = 0;
int linespace = 0;
assert(tp->type == diParagraph);
if (!(tp->member.para.nFlags & MEPF_REWRAP)) {
@ -350,36 +353,56 @@ void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
wc.context = c;
/* wc.para_style = tp->member.para.style; */
wc.style = NULL;
tp->member.para.nRightMargin = tp->member.para.pFmt->dxRightIndent*dpi/1440;
tp->member.para.nFirstMargin = tp->member.para.pFmt->dxStartIndent*dpi/1440;
tp->member.para.nLeftMargin = (tp->member.para.pFmt->dxStartIndent+tp->member.para.pFmt->dxOffset)*dpi/1440;
wc.nFirstMargin = tp->member.para.nFirstMargin;
wc.nLeftMargin = tp->member.para.nLeftMargin;
wc.nRightMargin = tp->member.para.nRightMargin;
wc.nFirstMargin = ME_twips2pointsX(c, tp->member.para.pFmt->dxStartIndent) + beginofs;
wc.nLeftMargin = wc.nFirstMargin + ME_twips2pointsX(c, tp->member.para.pFmt->dxOffset) + beginofs;
wc.nRightMargin = ME_twips2pointsX(c, tp->member.para.pFmt->dxRightIndent);
wc.nRow = 0;
wc.pt.x = 0;
wc.pt.y = 0;
if (tp->member.para.pFmt->dwMask & PFM_SPACEBEFORE)
wc.pt.y += ME_twips2pointsY(c, tp->member.para.pFmt->dySpaceBefore);
if (tp->member.para.pFmt->dwMask & PFM_BORDER)
{
border = ME_GetParaBorderWidth(c->editor, tp->member.para.pFmt->wBorders);
if (tp->member.para.pFmt->wBorders & 1) {
wc.nFirstMargin += border;
wc.nLeftMargin += border;
}
if (tp->member.para.pFmt->wBorders & 2)
wc.nRightMargin -= border;
if (tp->member.para.pFmt->wBorders & 4)
wc.pt.y += border;
}
wc.nTotalWidth = c->rcView.right - c->rcView.left;
wc.nAvailWidth = wc.nTotalWidth - wc.nFirstMargin - wc.nRightMargin;
wc.pRowStart = NULL;
linespace = ME_GetParaLineSpace(c, &tp->member.para);
ME_BeginRow(&wc);
for (p = tp->next; p!=tp->member.para.next_para; ) {
assert(p->type != diStartRow);
if (p->type == diRun) {
p = ME_WrapHandleRun(&wc, p);
continue;
}
p = p->next;
else p = p->next;
if (wc.nRow && p == wc.pRowStart)
wc.pt.y += linespace;
}
ME_WrapEndParagraph(&wc, p);
if ((tp->member.para.pFmt->dwMask & PFM_BORDER) && (tp->member.para.pFmt->wBorders & 8))
wc.pt.y += border;
if (tp->member.para.pFmt->dwMask & PFM_SPACEAFTER)
wc.pt.y += ME_twips2pointsY(c, tp->member.para.pFmt->dySpaceAfter);
tp->member.para.nFlags &= ~MEPF_REWRAP;
tp->member.para.nHeight = wc.pt.y;
tp->member.para.nRows = wc.nRow;
}
void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
ME_DisplayItem *p, *pRow;
/* remove all items that will be reinserted by paragraph wrapper anyway */
@ -441,7 +464,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
bRedraw = TRUE;
item->member.para.nYPos = c.pt.y;
ME_WrapTextParagraph(&c, item);
ME_WrapTextParagraph(&c, item, editor->selofs);
if (bRedraw)
{
@ -519,9 +542,11 @@ ME_SendRequestResize(ME_TextEditor *editor, BOOL force)
info.nmhdr.code = EN_REQUESTRESIZE;
info.rc = rc;
info.rc.bottom = editor->nTotalLength;
editor->nEventMask &= ~ENM_REQUESTRESIZE;
SendMessageW(GetParent(editor->hWnd), WM_NOTIFY,
info.nmhdr.idFrom, (LPARAM)&info);
editor->nEventMask |= ENM_REQUESTRESIZE;
}
}
}