diff --git a/reactos/lib/riched20/caret.c b/reactos/lib/riched20/caret.c index 8181f0a385f..24b37589ca2 100644 --- a/reactos/lib/riched20/caret.c +++ b/reactos/lib/riched20/caret.c @@ -41,6 +41,38 @@ int ME_GetTextLength(ME_TextEditor *editor) return ME_CharOfsFromRunOfs(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun), 0); } + +int ME_GetTextLengthEx(ME_TextEditor *editor, GETTEXTLENGTHEX *how) +{ + int length; + + if (how->flags & GTL_PRECISE && how->flags & GTL_CLOSE) + return E_INVALIDARG; + if (how->flags & GTL_NUMCHARS && how->flags & GTL_NUMBYTES) + return E_INVALIDARG; + + length = ME_GetTextLength(editor); + + if (how->flags & GTL_USECRLF) + length += editor->nParagraphs; + + if (how->flags & GTL_NUMBYTES) + { + CPINFO cpinfo; + + if (how->codepage == 1200) + return length * 2; + if (how->flags & GTL_PRECISE) + FIXME("GTL_PRECISE flag unsupported. Using GTL_CLOSE\n"); + if (GetCPInfo(how->codepage, &cpinfo)) + return length * cpinfo.MaxCharSize; + ERR("Invalid codepage %u\n", how->codepage); + return E_INVALIDARG; + } + return length; +} + + void ME_SetSelection(ME_TextEditor *editor, int from, int to) { if (from == 0 && to == -1) diff --git a/reactos/lib/riched20/editor.c b/reactos/lib/riched20/editor.c index 075502853ad..0e4d2b7a11a 100644 --- a/reactos/lib/riched20/editor.c +++ b/reactos/lib/riched20/editor.c @@ -65,7 +65,7 @@ - EM_GETSCROLLPOS 3.0 ! - EM_GETTHUMB - EM_GETTEXTEX 2.0 - - EM_GETTEXTLENGTHEX + + EM_GETTEXTLENGTHEX (GTL_PRECISE unimplemented) - EM_GETTEXTMODE 2.0 ? + EM_GETTEXTRANGE (ANSI&Unicode) - EM_GETTYPOGRAPHYOPTIONS 3.0 @@ -231,7 +231,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); int me_debug = 0; HANDLE me_heap = NULL; -ME_TextBuffer *ME_MakeText() { +ME_TextBuffer *ME_MakeText(void) { ME_TextBuffer *buf = ALLOC_OBJ(ME_TextBuffer); @@ -321,11 +321,26 @@ void ME_RTFCharAttrHook(RTF_Info *info) case rtfUnderline: fmt.dwMask = CFM_UNDERLINE; fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0; + fmt.bUnderlineType = CFU_CF1UNDERLINE; + break; + case rtfNoUnderline: + fmt.dwMask = CFM_UNDERLINE; + fmt.dwEffects = 0; break; case rtfStrikeThru: fmt.dwMask = CFM_STRIKEOUT; fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0; break; + case rtfSubScript: + case rtfSuperScript: + case rtfSubScrShrink: + case rtfSuperScrShrink: + case rtfNoSuperSub: + fmt.dwMask = CFM_SUBSCRIPT|CFM_SUPERSCRIPT; + if (info->rtfMinor == rtfSubScrShrink) fmt.dwEffects = CFE_SUBSCRIPT; + if (info->rtfMinor == rtfSuperScrShrink) fmt.dwEffects = CFE_SUPERSCRIPT; + if (info->rtfMinor == rtfNoSuperSub) fmt.dwEffects = 0; + break; case rtfBackColor: fmt.dwMask = CFM_BACKCOLOR; fmt.dwEffects = 0; @@ -831,7 +846,6 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP UNSUPPORTED_MSG(EM_GETREDONAME) UNSUPPORTED_MSG(EM_GETSCROLLPOS) UNSUPPORTED_MSG(EM_GETTEXTEX) - UNSUPPORTED_MSG(EM_GETTEXTLENGTHEX) UNSUPPORTED_MSG(EM_GETTEXTMODE) UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS) UNSUPPORTED_MSG(EM_GETUNDONAME) @@ -901,10 +915,14 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP return 0; case EM_GETSEL: { - ME_GetSelection(editor, (int *)wParam, (int *)lParam); - if (!((wParam|lParam) & 0xFFFF0000)) - return (lParam<<16)|wParam; - return -1; + /* Note: wParam/lParam can be NULL */ + UINT from, to; + PUINT pfrom = wParam ? (PUINT)wParam : &from; + PUINT pto = lParam ? (PUINT)lParam : &to; + ME_GetSelection(editor, pfrom, pto); + if ((*pfrom|*pto) & 0xFFFF0000) + return -1; + return MAKELONG(*pfrom,*pto); } case EM_EXGETSEL: { @@ -1156,6 +1174,8 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP } case WM_GETTEXTLENGTH: return ME_GetTextLength(editor); + case EM_GETTEXTLENGTHEX: + return ME_GetTextLengthEx(editor, (GETTEXTLENGTHEX *)wParam); case WM_GETTEXT: { TEXTRANGEW tr; /* W and A differ only by rng->lpstrText */ @@ -1464,7 +1484,7 @@ void ME_RegisterEditorClass(HINSTANCE hInstance) WNDCLASSW wcW; WNDCLASSA wcA; - wcW.style = CS_HREDRAW | CS_VREDRAW; + wcW.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; wcW.lpfnWndProc = RichEditANSIWndProc; wcW.cbClsExtra = 0; wcW.cbWndExtra = 4; @@ -1480,7 +1500,7 @@ void ME_RegisterEditorClass(HINSTANCE hInstance) bResult = RegisterClassW(&wcW); assert(bResult); - wcA.style = CS_HREDRAW | CS_VREDRAW; + wcA.style = CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; wcA.lpfnWndProc = RichEditANSIWndProc; wcA.cbClsExtra = 0; wcA.cbWndExtra = 4; diff --git a/reactos/lib/riched20/editor.h b/reactos/lib/riched20/editor.h index 5cbcfbde224..a0eab82c3c9 100644 --- a/reactos/lib/riched20/editor.h +++ b/reactos/lib/riched20/editor.h @@ -160,6 +160,7 @@ void ME_SendSelChange(ME_TextEditor *editor); void ME_InsertGraphicsFromCursor(ME_TextEditor *editor, int nCursor); void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars); int ME_GetTextLength(ME_TextEditor *editor); +int ME_GetTextLengthEx(ME_TextEditor *editor, GETTEXTLENGTHEX *how); ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor); BOOL ME_UpdateSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor); @@ -202,7 +203,7 @@ extern LRESULT CreateIRichEditOle(LPVOID *); /* wintest.c */ /* editor.c */ -void ME_RegisterEditorClass(); +void ME_RegisterEditorClass(HINSTANCE hInstance); ME_TextEditor *ME_MakeEditor(HWND hWnd); void ME_DestroyEditor(ME_TextEditor *editor); void ME_SendOldNotify(ME_TextEditor *editor, int nCode); diff --git a/reactos/lib/riched20/paint.c b/reactos/lib/riched20/paint.c index e8ffd5a0be9..d02bd258308 100644 --- a/reactos/lib/riched20/paint.c +++ b/reactos/lib/riched20/paint.c @@ -178,13 +178,23 @@ void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChar HDC hDC = c->hDC; HGDIOBJ hOldFont; COLORREF rgbOld, rgbBack; + int yOffset = 0, yTwipsOffset = 0; hOldFont = ME_SelectStyleFont(c->editor, hDC, s); rgbBack = ME_GetBackColor(c->editor); if ((s->fmt.dwMask & CFM_COLOR) && (s->fmt.dwEffects & CFE_AUTOCOLOR)) rgbOld = SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT)); else rgbOld = SetTextColor(hDC, s->fmt.crTextColor); - ExtTextOutW(hDC, x, y, 0, NULL, szText, nChars, NULL); + if ((s->fmt.dwMask & s->fmt.dwEffects) & CFM_OFFSET) { + yTwipsOffset = s->fmt.yOffset; + } + if ((s->fmt.dwMask & s->fmt.dwEffects) & (CFM_SUPERSCRIPT | CFM_SUBSCRIPT)) { + if (s->fmt.dwEffects & CFE_SUPERSCRIPT) yTwipsOffset = s->fmt.yHeight/3; + if (s->fmt.dwEffects & CFE_SUBSCRIPT) yTwipsOffset = -s->fmt.yHeight/12; + } + if (yTwipsOffset) + yOffset = yTwipsOffset*GetDeviceCaps(hDC, LOGPIXELSY)/1440; + ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL); if (width) { SIZE sz; GetTextExtentPoint32W(hDC, szText, nChars, &sz); diff --git a/reactos/lib/riched20/richole.c b/reactos/lib/riched20/richole.c index 21e50cb4a23..4f399a2067a 100644 --- a/reactos/lib/riched20/richole.c +++ b/reactos/lib/riched20/richole.c @@ -36,7 +36,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); typedef struct IRichEditOleImpl { - IRichEditOleVtbl *lpVtbl; + const IRichEditOleVtbl *lpVtbl; DWORD ref; } IRichEditOleImpl; @@ -228,7 +228,7 @@ IRichEditOle_fnSetLinkAvailable(IRichEditOle *me, LONG iob, BOOL fAvailable) return E_NOTIMPL; } -static IRichEditOleVtbl revt = { +static const IRichEditOleVtbl revt = { IRichEditOle_fnQueryInterface, IRichEditOle_fnAddRef, IRichEditOle_fnRelease, diff --git a/reactos/lib/riched20/style.c b/reactos/lib/riched20/style.c index 01b6fc598ed..3bc8b9e4173 100644 --- a/reactos/lib/riched20/style.c +++ b/reactos/lib/riched20/style.c @@ -268,6 +268,8 @@ void ME_LogFontFromStyle(HDC hDC, LOGFONTW *lf, ME_Style *s) 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; diff --git a/reactos/lib/riched20/writer.c b/reactos/lib/riched20/writer.c index a86c9fb6ca9..176c1619e79 100644 --- a/reactos/lib/riched20/writer.c +++ b/reactos/lib/riched20/writer.c @@ -45,11 +45,23 @@ ME_StreamOutFlush(ME_TextEditor *editor) { LONG nStart = 0; LONG nWritten = 0; + LONG nRemaining = 0; EDITSTREAM *stream = editor->pStream->stream; do { + TRACE("sending %lu bytes\n", editor->pStream->pos - nStart); + /* Some apps seem not to set *pcb unless a problem arises, relying + on initial random nWritten value, which is usually >STREAMOUT_BUFFER_SIZE */ + nRemaining = editor->pStream->pos - nStart; + nWritten = 0xDEADBEEF; stream->dwError = stream->pfnCallback(stream->dwCookie, editor->pStream->buffer + nStart, editor->pStream->pos - nStart, &nWritten); + TRACE("error=%lu written=%lu\n", stream->dwError, nWritten); + if (nWritten > (editor->pStream->pos - nStart) || nWritten<0) { + FIXME("Invalid returned written size *pcb: 0x%x (%ld) instead of %ld\n", + (unsigned)nWritten, nWritten, nRemaining); + nWritten = nRemaining; + } if (nWritten == 0 || stream->dwError) return FALSE; editor->pStream->written += nWritten; @@ -64,6 +76,7 @@ static LONG ME_StreamOutFree(ME_TextEditor *editor) { LONG written = editor->pStream->written; + TRACE("total length = %lu\n", written); FREE_OBJ(editor->pStream); editor->pStream = NULL; @@ -379,6 +392,7 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_DisplayItem *para) } if (fmt->rgxTabs[i] >> 28 <= 5) strcat(props, leader[fmt->rgxTabs[i] >> 28]); + sprintf(props+strlen(props), "\\tx%ld", fmt->rgxTabs[i]&0x00FFFFFF); } } @@ -781,7 +795,7 @@ ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream) ME_StreamOutRTF(editor, nStart, nTo - nStart, dwFormat); else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED) ME_StreamOutText(editor, nStart, nTo - nStart, dwFormat); - - ME_StreamOutFlush(editor); + if (!editor->pStream->stream->dwError) + ME_StreamOutFlush(editor); return ME_StreamOutFree(editor); }