From 4f95ffdf12ef606feac387c80af5ebeb7f1b1c2a Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 23 Nov 2015 09:36:58 +0000 Subject: [PATCH] [RICHED20] Sync with Wine Staging 1.7.55. CORE-10536 svn path=/trunk/; revision=70055 --- reactos/dll/win32/riched20/caret.c | 2 +- reactos/dll/win32/riched20/editor.c | 383 +++++++++++++++++---------- reactos/dll/win32/riched20/editor.h | 7 +- reactos/dll/win32/riched20/editstr.h | 25 +- reactos/dll/win32/riched20/list.c | 7 - reactos/dll/win32/riched20/para.c | 18 +- reactos/dll/win32/riched20/reader.c | 2 + reactos/dll/win32/riched20/rtf.h | 4 +- reactos/dll/win32/riched20/run.c | 23 +- reactos/dll/win32/riched20/style.c | 149 +++++++---- reactos/dll/win32/riched20/txthost.c | 2 +- reactos/dll/win32/riched20/txtsrv.c | 2 +- reactos/dll/win32/riched20/undo.c | 1 + reactos/dll/win32/riched20/writer.c | 2 + reactos/media/doc/README.WINE | 2 +- 15 files changed, 388 insertions(+), 241 deletions(-) diff --git a/reactos/dll/win32/riched20/caret.c b/reactos/dll/win32/riched20/caret.c index e3e42cc85f7..ca50f189e94 100644 --- a/reactos/dll/win32/riched20/caret.c +++ b/reactos/dll/win32/riched20/caret.c @@ -446,7 +446,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, continue; } } - if (delete_all) ME_SetDefaultParaFormat( start_para->member.para.pFmt ); + if (delete_all) ME_SetDefaultParaFormat( editor, start_para->member.para.pFmt ); return TRUE; } diff --git a/reactos/dll/win32/riched20/editor.c b/reactos/dll/win32/riched20/editor.c index 8d995f7446f..6af69249d13 100644 --- a/reactos/dll/win32/riched20/editor.c +++ b/reactos/dll/win32/riched20/editor.c @@ -96,7 +96,7 @@ + EM_SETCHARFORMAT (partly done, no ANSI) - EM_SETEDITSTYLE + EM_SETEVENTMASK (few notifications supported) - - EM_SETFONTSIZE + + EM_SETFONTSIZE - EM_SETIMECOLOR 1.0asian - EM_SETIMEOPTIONS 1.0asian - EM_SETIMESTATUS @@ -172,14 +172,14 @@ - ES_AUTOHSCROLL - ES_AUTOVSCROLL - - ES_CENTER + + ES_CENTER + ES_DISABLENOSCROLL (scrollbar is always visible) - ES_EX_NOCALLOLEINIT - - ES_LEFT + + ES_LEFT - ES_MULTILINE (currently single line controls aren't supported) - ES_NOIME - ES_READONLY (I'm not sure if beeping is the proper behaviour) - - ES_RIGHT + + ES_RIGHT - ES_SAVESEL - ES_SELFIME - ES_SUNKEN @@ -530,7 +530,7 @@ void ME_RTFCharAttrHook(RTF_Info *info) ME_Style *style2; RTFFlushOutputBuffer(info); /* FIXME too slow ? how come ? */ - style2 = ME_ApplyStyle(info->style, &fmt); + style2 = ME_ApplyStyle(info->editor, info->style, &fmt); ME_ReleaseStyle(info->style); info->style = style2; info->styleChanged = TRUE; @@ -1233,136 +1233,191 @@ static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE hemf, HBITMAP hbm return ret; } +static void ME_RTFReadShpPictGroup( RTF_Info *info ) +{ + int level = 1; + + for (;;) + { + RTFGetToken (info); + + if (info->rtfClass == rtfEOF) return; + if (RTFCheckCM( info, rtfGroup, rtfEndGroup )) + { + if (--level == 0) break; + } + else if (RTFCheckCM( info, rtfGroup, rtfBeginGroup )) + { + level++; + } + else + { + RTFRouteToken( info ); + if (RTFCheckCM( info, rtfGroup, rtfEndGroup )) + level--; + } + } + + RTFRouteToken( info ); /* feed "}" back to router */ + return; +} + +static DWORD read_hex_data( RTF_Info *info, BYTE **out ) +{ + DWORD read = 0, size = 1024; + BYTE *buf, val; + BOOL flip; + + *out = NULL; + + if (info->rtfClass != rtfText) + { + ERR("Called with incorrect token\n"); + return 0; + } + + buf = HeapAlloc( GetProcessHeap(), 0, size ); + if (!buf) return 0; + + val = info->rtfMajor; + for (flip = TRUE;; flip = !flip) + { + RTFGetToken( info ); + if (info->rtfClass == rtfEOF) + { + HeapFree( GetProcessHeap(), 0, buf ); + return 0; + } + if (info->rtfClass != rtfText) break; + if (flip) + { + if (read >= size) + { + size *= 2; + buf = HeapReAlloc( GetProcessHeap(), 0, buf, size ); + if (!buf) return 0; + } + buf[read++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor); + } + else + val = info->rtfMajor; + } + if (flip) FIXME("wrong hex string\n"); + + *out = buf; + return read; +} + static void ME_RTFReadPictGroup(RTF_Info *info) { - SIZEL sz; - BYTE* buffer = NULL; - unsigned bufsz, bufidx; - BOOL flip; - BYTE val; - METAFILEPICT mfp; - HENHMETAFILE hemf; - HBITMAP hbmp; - enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown; + SIZEL sz; + BYTE *buffer = NULL; + DWORD size = 0; + METAFILEPICT mfp; + HENHMETAFILE hemf; + HBITMAP hbmp; + enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown; + int level = 1; - RTFGetToken (info); - if (info->rtfClass == rtfEOF) + mfp.mm = MM_TEXT; + sz.cx = sz.cy = 0; + + for (;;) + { + RTFGetToken( info ); + + if (info->rtfClass == rtfText) + { + if (level == 1) + { + if (!buffer) + size = read_hex_data( info, &buffer ); + } + else + { + RTFSkipGroup( info ); + } + } /* We potentially have a new token so fall through. */ + + if (info->rtfClass == rtfEOF) return; + + if (RTFCheckCM( info, rtfGroup, rtfEndGroup )) + { + if (--level == 0) break; + continue; + } + if (RTFCheckCM( info, rtfGroup, rtfBeginGroup )) + { + level++; + continue; + } + if (!RTFCheckCM( info, rtfControl, rtfPictAttr )) + { + RTFRouteToken( info ); + if (RTFCheckCM( info, rtfGroup, rtfEndGroup )) + level--; + continue; + } + + if (RTFCheckMM( info, rtfPictAttr, rtfWinMetafile )) + { + mfp.mm = info->rtfParam; + gfx = gfx_metafile; + } + else if (RTFCheckMM( info, rtfPictAttr, rtfDevIndBitmap )) + { + if (info->rtfParam != 0) FIXME("dibitmap should be 0 (%d)\n", info->rtfParam); + gfx = gfx_dib; + } + else if (RTFCheckMM( info, rtfPictAttr, rtfEmfBlip )) + gfx = gfx_enhmetafile; + else if (RTFCheckMM( info, rtfPictAttr, rtfPicWid )) + mfp.xExt = info->rtfParam; + else if (RTFCheckMM( info, rtfPictAttr, rtfPicHt )) + mfp.yExt = info->rtfParam; + else if (RTFCheckMM( info, rtfPictAttr, rtfPicGoalWid )) + sz.cx = info->rtfParam; + else if (RTFCheckMM( info, rtfPictAttr, rtfPicGoalHt )) + sz.cy = info->rtfParam; + else + FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor); + } + + if (buffer) + { + switch (gfx) + { + case gfx_enhmetafile: + if ((hemf = SetEnhMetaFileBits( size, buffer ))) + ME_RTFInsertOleObject( info, hemf, NULL, &sz ); + break; + case gfx_metafile: + if ((hemf = SetWinMetaFileBits( size, buffer, NULL, &mfp ))) + ME_RTFInsertOleObject( info, hemf, NULL, &sz ); + break; + case gfx_dib: + { + BITMAPINFO *bi = (BITMAPINFO*)buffer; + HDC hdc = GetDC(0); + unsigned nc = bi->bmiHeader.biClrUsed; + + /* not quite right, especially for bitfields type of compression */ + if (!nc && bi->bmiHeader.biBitCount <= 8) + nc = 1 << bi->bmiHeader.biBitCount; + if ((hbmp = CreateDIBitmap( hdc, &bi->bmiHeader, + CBM_INIT, (char*)(bi + 1) + nc * sizeof(RGBQUAD), + bi, DIB_RGB_COLORS)) ) + ME_RTFInsertOleObject( info, NULL, hbmp, &sz ); + ReleaseDC( 0, hdc ); + break; + } + default: + break; + } + } + HeapFree( GetProcessHeap(), 0, buffer ); + RTFRouteToken( info ); /* feed "}" back to router */ return; - mfp.mm = MM_TEXT; - /* fetch picture type */ - if (RTFCheckMM (info, rtfPictAttr, rtfWinMetafile)) - { - mfp.mm = info->rtfParam; - gfx = gfx_metafile; - } - else if (RTFCheckMM (info, rtfPictAttr, rtfDevIndBitmap)) - { - if (info->rtfParam != 0) FIXME("dibitmap should be 0 (%d)\n", info->rtfParam); - gfx = gfx_dib; - } - else if (RTFCheckMM (info, rtfPictAttr, rtfEmfBlip)) - { - gfx = gfx_enhmetafile; - } - else - { - FIXME("%d %d\n", info->rtfMajor, info->rtfMinor); - goto skip_group; - } - sz.cx = sz.cy = 0; - /* fetch picture attributes */ - for (;;) - { - RTFGetToken (info); - if (info->rtfClass == rtfEOF) - return; - if (info->rtfClass == rtfText) - break; - if (!RTFCheckCM (info, rtfControl, rtfPictAttr)) - { - ERR("Expected picture attribute (%d %d)\n", - info->rtfClass, info->rtfMajor); - goto skip_group; - } - else if (RTFCheckMM (info, rtfPictAttr, rtfPicWid)) - { - if (gfx == gfx_metafile) mfp.xExt = info->rtfParam; - } - else if (RTFCheckMM (info, rtfPictAttr, rtfPicHt)) - { - if (gfx == gfx_metafile) mfp.yExt = info->rtfParam; - } - else if (RTFCheckMM (info, rtfPictAttr, rtfPicGoalWid)) - sz.cx = info->rtfParam; - else if (RTFCheckMM (info, rtfPictAttr, rtfPicGoalHt)) - sz.cy = info->rtfParam; - else - FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor); - } - /* fetch picture data */ - bufsz = 1024; - bufidx = 0; - buffer = HeapAlloc(GetProcessHeap(), 0, bufsz); - val = info->rtfMajor; - for (flip = TRUE;; flip = !flip) - { - RTFGetToken (info); - if (info->rtfClass == rtfEOF) - { - HeapFree(GetProcessHeap(), 0, buffer); - return; /* Warn ?? */ - } - if (RTFCheckCM(info, rtfGroup, rtfEndGroup)) - break; - if (info->rtfClass != rtfText) goto skip_group; - if (flip) - { - if (bufidx >= bufsz && - !(buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, bufsz += 1024))) - goto skip_group; - buffer[bufidx++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor); - } - else - val = info->rtfMajor; - } - if (flip) FIXME("wrong hex string\n"); - - switch (gfx) - { - case gfx_enhmetafile: - if ((hemf = SetEnhMetaFileBits(bufidx, buffer))) - ME_RTFInsertOleObject(info, hemf, NULL, &sz); - break; - case gfx_metafile: - if ((hemf = SetWinMetaFileBits(bufidx, buffer, NULL, &mfp))) - ME_RTFInsertOleObject(info, hemf, NULL, &sz); - break; - case gfx_dib: - { - BITMAPINFO* bi = (BITMAPINFO*)buffer; - HDC hdc = GetDC(0); - unsigned nc = bi->bmiHeader.biClrUsed; - - /* not quite right, especially for bitfields type of compression */ - if (!nc && bi->bmiHeader.biBitCount <= 8) - nc = 1 << bi->bmiHeader.biBitCount; - if ((hbmp = CreateDIBitmap(hdc, &bi->bmiHeader, - CBM_INIT, (char*)(bi + 1) + nc * sizeof(RGBQUAD), - bi, DIB_RGB_COLORS))) - ME_RTFInsertOleObject(info, NULL, hbmp, &sz); - ReleaseDC(0, hdc); - } - break; - default: - break; - } - HeapFree(GetProcessHeap(), 0, buffer); - RTFRouteToken (info); /* feed "}" back to router */ - return; -skip_group: - HeapFree(GetProcessHeap(), 0, buffer); - RTFSkipGroup(info); - RTFRouteToken(info); /* feed "}" back to router */ } /* for now, lookup the \result part and use it, whatever the object */ @@ -1506,7 +1561,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_GetTextLength(editor), FALSE); from = to = 0; ME_ClearTempStyle(editor); - ME_SetDefaultParaFormat(editor->pCursors[0].pPara->member.para.pFmt); + ME_SetDefaultParaFormat(editor, editor->pCursors[0].pPara->member.para.pFmt); } @@ -1551,6 +1606,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre WriterInit(&parser); RTFInit(&parser); RTFSetReadHook(&parser, ME_RTFReadHook); + RTFSetDestinationCallback(&parser, rtfShpPict, ME_RTFReadShpPictGroup); RTFSetDestinationCallback(&parser, rtfPict, ME_RTFReadPictGroup); RTFSetDestinationCallback(&parser, rtfObject, ME_RTFReadObjectGroup); if (!parser.editor->bEmulateVersion10) /* v4.1 */ @@ -2306,7 +2362,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) ME_InsertTextFromCursor(editor, 0, &endl, 1, editor->pCursors[0].pRun->member.run.style); para = editor->pBuffer->pFirst->member.para.next_para; - ME_SetDefaultParaFormat(para->member.para.pFmt); + ME_SetDefaultParaFormat(editor, para->member.para.pFmt); para->member.para.nFlags = MEPF_REWRAP; editor->pCursors[0].pPara = para; editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); @@ -2732,7 +2788,7 @@ static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y) return TRUE; } -ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) +ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10, DWORD csStyle) { ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor); int i; @@ -2746,6 +2802,11 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->reOle = NULL; ed->bEmulateVersion10 = bEmulateVersion10; ed->styleFlags = 0; + ed->alignStyle = PFA_LEFT; + if (csStyle & ES_RIGHT) + ed->alignStyle = PFA_RIGHT; + if (csStyle & ES_CENTER) + ed->alignStyle = PFA_CENTER; ITextHost_TxGetPropertyBits(texthost, (TXTBIT_RICHTEXT|TXTBIT_MULTILINE| TXTBIT_READONLY|TXTBIT_USEPASSWORD| @@ -2857,6 +2918,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->wheel_remain = 0; + list_init( &ed->style_list ); OleInitialize(NULL); return ed; @@ -2866,6 +2928,7 @@ void ME_DestroyEditor(ME_TextEditor *editor) { ME_DisplayItem *pFirst = editor->pBuffer->pFirst; ME_DisplayItem *p = pFirst, *pNext = NULL; + ME_Style *s, *cursor2; int i; ME_ClearTempStyle(editor); @@ -2875,6 +2938,10 @@ void ME_DestroyEditor(ME_TextEditor *editor) ME_DestroyDisplayItem(p); p = pNext; } + + LIST_FOR_EACH_ENTRY_SAFE( s, cursor2, &editor->style_list, ME_Style, entry ) + ME_DestroyStyle( s ); + ME_ReleaseStyle(editor->pBuffer->pDefaultStyle); for (i=0; i 0); + + if (editor->mode & TM_PLAINTEXT) + return FALSE; + + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_SIZE; + ME_GetSelectionCharFormat(editor, &cf); + tmp_size = (cf.yHeight / 20) + wParam; + + if (tmp_size <= 1) + size = 1; + else if (tmp_size > 12 && tmp_size < 28 && tmp_size % 2) + size = tmp_size + (is_increase ? 1 : -1); + else if (tmp_size > 28 && tmp_size < 36) + size = is_increase ? 36 : 28; + else if (tmp_size > 36 && tmp_size < 48) + size = is_increase ? 48 : 36; + else if (tmp_size > 48 && tmp_size < 72) + size = is_increase ? 72 : 48; + else if (tmp_size > 72 && tmp_size < 80) + size = is_increase ? 80 : 72; + else if (tmp_size > 80 && tmp_size < 1638) + size = 10 * (is_increase ? (tmp_size / 10 + 1) : (tmp_size / 10)); + else if (tmp_size >= 1638) + size = 1638; + else + size = tmp_size; + + cf.yHeight = size * 20; /* convert twips to points */ + ME_SetSelectionCharFormat(editor, &cf); + ME_CommitUndo(editor); + ME_WrapMarkedParagraphs(editor); + ME_UpdateScrollBar(editor); + ME_Repaint(editor); + + return TRUE; + } case EM_SETOPTIONS: { /* these flags are equivalent to ES_* counterparts, except for @@ -3723,7 +3831,10 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, if (!wParam) wParam = (WPARAM)GetStockObject(SYSTEM_FONT); - GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf); + + if (!GetObjectW((HGDIOBJ)wParam, sizeof(LOGFONTW), &lf)) + return 0; + hDC = ITextHost_TxGetDC(editor->texthost); ME_CharFormatFromLogFont(hDC, &lf, &fmt); ITextHost_TxReleaseDC(editor->texthost, hDC); diff --git a/reactos/dll/win32/riched20/editor.h b/reactos/dll/win32/riched20/editor.h index 4054c99dfd1..9ef6165a1d9 100644 --- a/reactos/dll/win32/riched20/editor.h +++ b/reactos/dll/win32/riched20/editor.h @@ -104,9 +104,10 @@ static inline const char *debugstr_run( const ME_Run *run ) /* style.c */ ME_Style *ME_MakeStyle(CHARFORMAT2W *style) DECLSPEC_HIDDEN; void ME_AddRefStyle(ME_Style *item) DECLSPEC_HIDDEN; +void ME_DestroyStyle(ME_Style *item) DECLSPEC_HIDDEN; void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN; ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) DECLSPEC_HIDDEN; -ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) DECLSPEC_HIDDEN; +ME_Style *ME_ApplyStyle(ME_TextEditor *ed, ME_Style *sSrc, CHARFORMAT2W *style) DECLSPEC_HIDDEN; HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s) DECLSPEC_HIDDEN; void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) DECLSPEC_HIDDEN; void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN; @@ -248,7 +249,7 @@ void ME_DumpParaStyleToBuf(const PARAFORMAT2 *pFmt, char buf[2048]) DECLSPEC_HID BOOL ME_SetSelectionParaFormat(ME_TextEditor *editor, const PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN; -void ME_SetDefaultParaFormat(PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; +void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; /* paint.c */ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; @@ -284,7 +285,7 @@ void ME_DeleteReObject(REOBJECT* reo) DECLSPEC_HIDDEN; void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) DECLSPEC_HIDDEN; /* editor.c */ -ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) DECLSPEC_HIDDEN; +ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10, DWORD csStyle) DECLSPEC_HIDDEN; void ME_DestroyEditor(ME_TextEditor *editor) DECLSPEC_HIDDEN; LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode, HRESULT* phresult) DECLSPEC_HIDDEN; diff --git a/reactos/dll/win32/riched20/editstr.h b/reactos/dll/win32/riched20/editstr.h index cecd552d646..cf090109ce6 100644 --- a/reactos/dll/win32/riched20/editstr.h +++ b/reactos/dll/win32/riched20/editstr.h @@ -31,14 +31,25 @@ typedef struct tagME_String int nLen, nBuffer; } ME_String; +typedef struct tagME_FontCacheItem +{ + LOGFONTW lfSpecs; + HFONT hFont; + int nRefs; + int nAge; +} ME_FontCacheItem; + +#define HFONT_CACHE_SIZE 10 + typedef struct tagME_Style { CHARFORMAT2W fmt; - HFONT hFont; /* cached font for the style */ + ME_FontCacheItem *font_cache; /* cached font for the style */ TEXTMETRICW tm; /* cached font metrics for the style */ int nRefs; /* reference count */ SCRIPT_CACHE script_cache; + struct list entry; } ME_Style; typedef enum { @@ -343,16 +354,6 @@ typedef struct tagME_OutStream { UINT nNestingLevel; } ME_OutStream; -typedef struct tagME_FontCacheItem -{ - LOGFONTW lfSpecs; - HFONT hFont; - int nRefs; - int nAge; -} ME_FontCacheItem; - -#define HFONT_CACHE_SIZE 10 - typedef struct tagME_TextEditor { HWND hWnd, hwndParent; @@ -362,6 +363,7 @@ typedef struct tagME_TextEditor ME_TextBuffer *pBuffer; ME_Cursor *pCursors; DWORD styleFlags; + DWORD alignStyle; DWORD exStyleFlags; int nCursors; SIZE sizeWindow; @@ -414,6 +416,7 @@ typedef struct tagME_TextEditor BOOL bMouseCaptured; int wheel_remain; + struct list style_list; } ME_TextEditor; typedef struct tagME_Context diff --git a/reactos/dll/win32/riched20/list.c b/reactos/dll/win32/riched20/list.c index 10732e523dd..c57e5264f2e 100644 --- a/reactos/dll/win32/riched20/list.c +++ b/reactos/dll/win32/riched20/list.c @@ -179,13 +179,6 @@ ME_DisplayItem *ME_MakeDI(ME_DIType type) ZeroMemory(item, sizeof(ME_DisplayItem)); item->type = type; item->prev = item->next = NULL; - if (type == diParagraph) - { - item->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2); - ME_SetDefaultParaFormat(item->member.para.pFmt); - item->member.para.nFlags = MEPF_REWRAP; - } - return item; } diff --git a/reactos/dll/win32/riched20/para.c b/reactos/dll/win32/riched20/para.c index 8cf3d241594..3ea98c5976a 100644 --- a/reactos/dll/win32/riched20/para.c +++ b/reactos/dll/win32/riched20/para.c @@ -23,6 +23,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); +static ME_DisplayItem *make_para(ME_TextEditor *editor) +{ + ME_DisplayItem *item = ME_MakeDI(diParagraph); + + item->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2); + ME_SetDefaultParaFormat(editor, item->member.para.pFmt); + item->member.para.nFlags = MEPF_REWRAP; + return item; +} + void ME_MakeFirstParagraph(ME_TextEditor *editor) { ME_Context c; @@ -30,7 +40,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor) LOGFONTW lf; HFONT hf; ME_TextBuffer *text = editor->pBuffer; - ME_DisplayItem *para = ME_MakeDI(diParagraph); + ME_DisplayItem *para = make_para(editor); ME_DisplayItem *run; ME_Style *style; int eol_len; @@ -196,7 +206,7 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, { ME_DisplayItem *next_para = NULL; ME_DisplayItem *run_para = NULL; - ME_DisplayItem *new_para = ME_MakeDI(diParagraph); + ME_DisplayItem *new_para = make_para(editor); ME_DisplayItem *end_run; int ofs, i; ME_DisplayItem *pp; @@ -619,12 +629,12 @@ void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) } } -void ME_SetDefaultParaFormat(PARAFORMAT2 *pFmt) +void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) { ZeroMemory(pFmt, sizeof(PARAFORMAT2)); pFmt->cbSize = sizeof(PARAFORMAT2); pFmt->dwMask = PFM_ALL2; - pFmt->wAlignment = PFA_LEFT; + pFmt->wAlignment = editor->alignStyle; pFmt->sStyle = -1; pFmt->bOutlineLevel = TRUE; } diff --git a/reactos/dll/win32/riched20/reader.c b/reactos/dll/win32/riched20/reader.c index 5e35d739391..d723e6f0138 100644 --- a/reactos/dll/win32/riched20/reader.c +++ b/reactos/dll/win32/riched20/reader.c @@ -1797,6 +1797,8 @@ static RTFKey rtfKey[] = { rtfDestination, rtfNeXTGraphic, "NeXTGraphic", 0 }, { rtfDestination, rtfNestTableProps, "nesttableprops", 0 }, { rtfDestination, rtfNoNestTables, "nonesttables", 0 }, + { rtfDestination, rtfShpPict, "shppict", 0 }, + { rtfDestination, rtfNonShpPict, "nonshppict", 0 }, /* * Font families diff --git a/reactos/dll/win32/riched20/rtf.h b/reactos/dll/win32/riched20/rtf.h index 4b10744b8ef..b690ffa8ecb 100644 --- a/reactos/dll/win32/riched20/rtf.h +++ b/reactos/dll/win32/riched20/rtf.h @@ -174,7 +174,9 @@ # define rtfGenerator 74 # define rtfNestTableProps 75 # define rtfNoNestTables 76 -# define rtfMaxDestination 77 /* highest dest + 1 */ +# define rtfShpPict 77 +# define rtfNonShpPict 78 +# define rtfMaxDestination 79 /* highest dest + 1 */ # define rtfFontFamily 4 # define rtfFFNil 0 diff --git a/reactos/dll/win32/riched20/run.c b/reactos/dll/win32/riched20/run.c index 4a93bbc9fc0..f3b4db6d464 100644 --- a/reactos/dll/win32/riched20/run.c +++ b/reactos/dll/win32/riched20/run.c @@ -700,7 +700,7 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) ME_Style *s; if (!editor->pBuffer->pCharStyle) editor->pBuffer->pCharStyle = ME_GetInsertStyle(editor, 0); - s = ME_ApplyStyle(editor->pBuffer->pCharStyle, pFmt); + s = ME_ApplyStyle(editor, editor->pBuffer->pCharStyle, pFmt); ME_ReleaseStyle(editor->pBuffer->pCharStyle); editor->pBuffer->pCharStyle = s; } else { @@ -758,7 +758,7 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C for (run = start_run; run != end_run; run = ME_FindItemFwd( run, diRun )) { - ME_Style *new_style = ME_ApplyStyle(run->member.run.style, pFmt); + ME_Style *new_style = ME_ApplyStyle(editor, run->member.run.style, pFmt); add_undo_set_char_fmt( editor, run->member.run.para->nCharOfs + run->member.run.nCharOfs, run->member.run.len, &run->member.run.style->fmt ); @@ -768,25 +768,6 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C } } -/****************************************************************************** - * ME_SetDefaultCharFormat - * - * Applies a style change to the default character style. - */ -void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod) -{ - ME_Style *style; - - assert(mod->cbSize == sizeof(CHARFORMAT2W)); - style = ME_ApplyStyle(editor->pBuffer->pDefaultStyle, mod); - editor->pBuffer->pDefaultStyle->fmt = style->fmt; - editor->pBuffer->pDefaultStyle->tm = style->tm; - ScriptFreeCache( &editor->pBuffer->pDefaultStyle->script_cache ); - ME_ReleaseStyle(style); - ME_MarkAllForWrapping(editor); - /* pcf = editor->pBuffer->pDefaultStyle->fmt; */ -} - static void ME_GetRunCharFormat(ME_TextEditor *editor, ME_DisplayItem *run, CHARFORMAT2W *pFmt) { ME_CopyCharFormat(pFmt, &run->member.run.style->fmt); diff --git a/reactos/dll/win32/riched20/style.c b/reactos/dll/win32/riched20/style.c index 0817ea80004..06c0e6f65eb 100644 --- a/reactos/dll/win32/riched20/style.c +++ b/reactos/dll/win32/riched20/style.c @@ -146,25 +146,26 @@ ME_Style *ME_MakeStyle(CHARFORMAT2W *style) assert(style->cbSize == sizeof(CHARFORMAT2W)); s->fmt = *style; s->nRefs = 1; - s->hFont = NULL; + s->font_cache = NULL; memset(&s->tm, 0, sizeof(s->tm)); s->tm.tmAscent = -1; s->script_cache = NULL; + list_init(&s->entry); all_refs++; TRACE_(richedit_style)("ME_MakeStyle %p, total refs=%d\n", s, all_refs); return s; } #define COPY_STYLE_ITEM(mask, member) \ - if (style->dwMask & mask) { \ - s->fmt.dwMask |= mask;\ - s->fmt.member = style->member;\ + if (mod->dwMask & mask) { \ + fmt.dwMask |= mask;\ + fmt.member = mod->member;\ } #define COPY_STYLE_ITEM_MEMCPY(mask, member) \ - if (style->dwMask & mask) { \ - s->fmt.dwMask |= mask;\ - CopyMemory(s->fmt.member, style->member, sizeof(style->member));\ + if (mod->dwMask & mask) { \ + fmt.dwMask |= mask;\ + CopyMemory(fmt.member, mod->member, sizeof(mod->member));\ } void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) @@ -173,10 +174,12 @@ void ME_InitCharFormat2W(CHARFORMAT2W *pFmt) pFmt->cbSize = sizeof(CHARFORMAT2W); } -ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) +ME_Style *ME_ApplyStyle(ME_TextEditor *editor, ME_Style *sSrc, CHARFORMAT2W *mod) { - ME_Style *s = ME_MakeStyle(&sSrc->fmt); - assert(style->cbSize == sizeof(CHARFORMAT2W)); + CHARFORMAT2W fmt = sSrc->fmt; + ME_Style *s; + + assert(mod->cbSize == sizeof(CHARFORMAT2W)); COPY_STYLE_ITEM(CFM_ANIMATION, bAnimation); COPY_STYLE_ITEM(CFM_BACKCOLOR, crBackColor); COPY_STYLE_ITEM(CFM_CHARSET, bCharSet); @@ -186,9 +189,9 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) COPY_STYLE_ITEM(CFM_LCID, lcid); COPY_STYLE_ITEM(CFM_OFFSET, yOffset); COPY_STYLE_ITEM(CFM_REVAUTHOR, bRevAuthor); - if (style->dwMask & CFM_SIZE) { - s->fmt.dwMask |= CFM_SIZE; - s->fmt.yHeight = min(style->yHeight, yHeightCharPtsMost * 20); + if (mod->dwMask & CFM_SIZE) { + fmt.dwMask |= CFM_SIZE; + fmt.yHeight = min(mod->yHeight, yHeightCharPtsMost * 20); } COPY_STYLE_ITEM(CFM_SPACING, sSpacing); COPY_STYLE_ITEM(CFM_STYLE, sStyle); @@ -197,31 +200,46 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style) /* 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; - if (style->dwMask & CFM_COLOR) + fmt.dwEffects &= ~(mod->dwMask); + fmt.dwEffects |= mod->dwEffects & mod->dwMask; + fmt.dwMask |= mod->dwMask; + if (mod->dwMask & CFM_COLOR) { - if (style->dwEffects & CFE_AUTOCOLOR) - s->fmt.dwEffects |= CFE_AUTOCOLOR; + if (mod->dwEffects & CFE_AUTOCOLOR) + fmt.dwEffects |= CFE_AUTOCOLOR; else - s->fmt.dwEffects &= ~CFE_AUTOCOLOR; + fmt.dwEffects &= ~CFE_AUTOCOLOR; } - if (style->dwMask & CFM_UNDERLINE) + if (mod->dwMask & CFM_UNDERLINE) { - s->fmt.dwMask |= CFM_UNDERLINETYPE; - s->fmt.bUnderlineType = (style->dwEffects & CFM_UNDERLINE) ? + fmt.dwMask |= CFM_UNDERLINETYPE; + fmt.bUnderlineType = (mod->dwEffects & CFM_UNDERLINE) ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE; } - if (style->dwMask & CFM_BOLD && !(style->dwMask & CFM_WEIGHT)) + if (mod->dwMask & CFM_BOLD && !(mod->dwMask & CFM_WEIGHT)) { - s->fmt.wWeight = (style->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL; - } else if (style->dwMask & CFM_WEIGHT && !(style->dwMask & CFM_BOLD)) { - if (style->wWeight > FW_NORMAL) - s->fmt.dwEffects |= CFE_BOLD; + fmt.wWeight = (mod->dwEffects & CFE_BOLD) ? FW_BOLD : FW_NORMAL; + } else if (mod->dwMask & CFM_WEIGHT && !(mod->dwMask & CFM_BOLD)) { + if (mod->wWeight > FW_NORMAL) + fmt.dwEffects |= CFE_BOLD; else - s->fmt.dwEffects &= ~CFE_BOLD; + fmt.dwEffects &= ~CFE_BOLD; } + + LIST_FOR_EACH_ENTRY(s, &editor->style_list, ME_Style, entry) + { + if (!memcmp( &s->fmt, &fmt, sizeof(fmt) )) + { + TRACE_(richedit_style)("found existing style %p\n", s); + ME_AddRefStyle( s ); + return s; + } + } + + s = ME_MakeStyle( &fmt ); + if (s) + list_add_head( &editor->style_list, &s->entry ); + TRACE_(richedit_style)("created new style %p\n", s); return s; } @@ -383,8 +401,6 @@ HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s) { item = &c->editor->pFontCache[i]; TRACE_(richedit_style)("font reused %d\n", i); - - s->hFont = item->hFont; item->nRefs++; } else @@ -397,44 +413,41 @@ HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s) DeleteObject(item->hFont); item->hFont = NULL; } - s->hFont = CreateFontIndirectW(&lf); - assert(s->hFont); + item->hFont = CreateFontIndirectW(&lf); TRACE_(richedit_style)("font created %d\n", nEmpty); - item->hFont = s->hFont; item->nRefs = 1; item->lfSpecs = lf; } - hOldFont = SelectObject(c->hDC, s->hFont); + s->font_cache = item; + hOldFont = SelectObject(c->hDC, item->hFont); /* should be cached too, maybe ? */ GetTextMetricsW(c->hDC, &s->tm); return hOldFont; } -void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) +static void release_font_cache(ME_FontCacheItem *item) { - int i; - - assert(s); - SelectObject(c->hDC, hOldFont); - for (i=0; ieditor->pFontCache[i]; - if (pItem->hFont == s->hFont && pItem->nRefs > 0) + if (item->nRefs > 0) { - pItem->nRefs--; - pItem->nAge = 0; - s->hFont = NULL; - return; + item->nRefs--; + item->nAge = 0; } - } - assert(0 == "UnselectStyleFont without SelectStyleFont"); } -static void ME_DestroyStyle(ME_Style *s) { - if (s->hFont) +void ME_UnselectStyleFont(ME_Context *c, ME_Style *s, HFONT hOldFont) +{ + SelectObject(c->hDC, hOldFont); + release_font_cache(s->font_cache); + s->font_cache = NULL; +} + +void ME_DestroyStyle(ME_Style *s) +{ + list_remove( &s->entry ); + if (s->font_cache) { - DeleteObject(s->hFont); - s->hFont = NULL; + release_font_cache( s->font_cache ); + s->font_cache = NULL; } ScriptFreeCache( &s->script_cache ); FREE_OBJ(s); @@ -514,3 +527,31 @@ void ME_ClearTempStyle(ME_TextEditor *editor) ME_ReleaseStyle(editor->pBuffer->pCharStyle); editor->pBuffer->pCharStyle = NULL; } + +/****************************************************************************** + * ME_SetDefaultCharFormat + * + * Applies a style change to the default character style. + * + * The default style is special in that it is mutable - runs + * in the document that have this style should change if the + * default style changes. That means we need to fix up this + * style manually. + */ +void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod) +{ + ME_Style *style, *def = editor->pBuffer->pDefaultStyle; + + assert(mod->cbSize == sizeof(CHARFORMAT2W)); + style = ME_ApplyStyle(editor, def, mod); + def->fmt = style->fmt; + def->tm = style->tm; + if (def->font_cache) + { + release_font_cache( def->font_cache ); + def->font_cache = NULL; + } + ScriptFreeCache( &def->script_cache ); + ME_ReleaseStyle( style ); + ME_MarkAllForWrapping( editor ); +} diff --git a/reactos/dll/win32/riched20/txthost.c b/reactos/dll/win32/riched20/txthost.c index 5f6862e5c41..04e61ab9a2b 100644 --- a/reactos/dll/win32/riched20/txthost.c +++ b/reactos/dll/win32/riched20/txthost.c @@ -44,7 +44,7 @@ ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion1 texthost->hWnd = hwnd; texthost->bEmulateVersion10 = bEmulateVersion10; - editor = ME_MakeEditor(&texthost->ITextHost_iface, bEmulateVersion10); + editor = ME_MakeEditor(&texthost->ITextHost_iface, bEmulateVersion10, cs->style); editor->exStyleFlags = GetWindowLongW(hwnd, GWL_EXSTYLE); editor->styleFlags |= GetWindowLongW(hwnd, GWL_STYLE) & ES_WANTRETURN; editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */ diff --git a/reactos/dll/win32/riched20/txtsrv.c b/reactos/dll/win32/riched20/txtsrv.c index 4aacffae554..e4a418c8175 100644 --- a/reactos/dll/win32/riched20/txtsrv.c +++ b/reactos/dll/win32/riched20/txtsrv.c @@ -402,7 +402,7 @@ HRESULT WINAPI CreateTextServices(IUnknown *pUnkOuter, ITextHost *pITextHost, I ITextImpl->pMyHost = pITextHost; ITextImpl->IUnknown_inner.lpVtbl = &textservices_inner_vtbl; ITextImpl->ITextServices_iface.lpVtbl = &textservices_vtbl; - ITextImpl->editor = ME_MakeEditor(pITextHost, FALSE); + ITextImpl->editor = ME_MakeEditor(pITextHost, FALSE, ES_LEFT); ITextImpl->editor->exStyleFlags = 0; ITextImpl->editor->rcFormat.left = 0; ITextImpl->editor->rcFormat.top = 0; diff --git a/reactos/dll/win32/riched20/undo.c b/reactos/dll/win32/riched20/undo.c index 9db690eec6b..7b22e6de57b 100644 --- a/reactos/dll/win32/riched20/undo.c +++ b/reactos/dll/win32/riched20/undo.c @@ -341,6 +341,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo) add_undo_set_para_fmt( editor, ¶->member.para ); *para->member.para.pFmt = undo->u.set_para_fmt.fmt; para->member.para.border = undo->u.set_para_fmt.border; + para->member.para.nFlags |= MEPF_REWRAP; break; } case undo_set_char_fmt: diff --git a/reactos/dll/win32/riched20/writer.c b/reactos/dll/win32/riched20/writer.c index bedfd3fcb64..f38ea30c9c7 100644 --- a/reactos/dll/win32/riched20/writer.c +++ b/reactos/dll/win32/riched20/writer.c @@ -59,6 +59,8 @@ ME_StreamOutFlush(ME_OutStream *pStream) return FALSE; /* Don't resend partial chunks if nWritten < pStream->pos */ } + if (nWritten == pStream->pos) + pStream->written += nWritten; pStream->pos = 0; return TRUE; } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index ef8db21587b..06612bce208 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -162,7 +162,7 @@ reactos/dll/win32/qmgrprxy # Synced to WineStaging-1.7.47 reactos/dll/win32/query # Synced to WineStaging-1.7.47 reactos/dll/win32/rasapi32 # Synced to WineStaging-1.7.47 reactos/dll/win32/resutils # Synced to WineStaging-1.7.47 -reactos/dll/win32/riched20 # Synced to WineStaging-1.7.47 +reactos/dll/win32/riched20 # Synced to WineStaging-1.7.55 reactos/dll/win32/riched32 # Synced to WineStaging-1.7.47 reactos/dll/win32/rpcrt4 # Synced to WineStaging-1.7.55 reactos/dll/win32/rsabase # Synced to WineStaging-1.7.47