Update to Wine. Need winesynced. Tested with Qemu.

svn path=/trunk/; revision=32788
This commit is contained in:
James Tabor 2008-03-31 04:55:20 +00:00
parent 068bad469b
commit ec07bd1531
17 changed files with 877 additions and 214 deletions

View file

@ -202,19 +202,21 @@ ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
pSizeRun = run = tmp;
assert(run);
assert(run->type == diRun);
sz = ME_GetRunSize(&c, &para->member.para, &run->member.run, ME_StrLen(run->member.run.strText));
sz = ME_GetRunSize(&c, &para->member.para,
&run->member.run, ME_StrLen(run->member.run.strText),
row->member.row.nLMargin);
}
}
if (pCursor->nOffset && !(run->member.run.nFlags & MERF_SKIPPED)) {
sz = ME_GetRunSize(&c, &para->member.para, &run->member.run, pCursor->nOffset);
sz = ME_GetRunSize(&c, &para->member.para, &run->member.run, pCursor->nOffset,
row->member.row.nLMargin);
}
*height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent;
*x = run->member.run.pt.x + sz.cx;
*y = para->member.para.nYPos + row->member.row.nBaseline + pSizeRun->member.run.pt.y - pSizeRun->member.run.nAscent - ME_GetYScrollPos(editor);
ME_DestroyContext(&c);
ReleaseDC(editor->hWnd, hDC);
ME_DestroyContext(&c, editor->hWnd);
return;
}
}
@ -393,22 +395,39 @@ ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor,
}
/* FIXME this is temporary, just to have something to test how bad graphics handler is */
void ME_InsertGraphicsFromCursor(ME_TextEditor *editor, int nCursor)
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor)
{
ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
WCHAR space = ' ';
ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
ME_DisplayItem *di;
WCHAR space = ' ';
/* FIXME no no no */
if (ME_IsSelection(editor))
ME_DeleteSelection(editor);
ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle,
MERF_GRAPHICS);
di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle,
MERF_GRAPHICS);
di->member.run.ole_obj = ALLOC_OBJ(*reo);
ME_CopyReObject(di->member.run.ole_obj, reo);
ME_SendSelChange(editor);
}
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor)
{
ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
ME_DisplayItem *di;
WCHAR space = ' ';
/* FIXME no no no */
if (ME_IsSelection(editor))
ME_DeleteSelection(editor);
di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle,
MERF_ENDROW);
ME_SendSelChange(editor);
}
void
ME_InsertTableCellFromCursor(ME_TextEditor *editor, int nCursor)
{

View file

@ -252,14 +252,14 @@ static HRESULT WINAPI DataObjectImpl_QueryGetData(IDataObject* iface, FORMATETC
return foundFormat?DV_E_FORMATETC:DV_E_TYMED;
}
static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject* iface, FORMATETC *pformatectIn,
static HRESULT WINAPI DataObjectImpl_GetCanonicalFormatEtc(IDataObject* iface, FORMATETC *pformatetcIn,
FORMATETC *pformatetcOut)
{
DataObjectImpl *This = (DataObjectImpl*)iface;
TRACE("(%p)->(%p,%p)\n", This, pformatectIn, pformatetcOut);
TRACE("(%p)->(%p,%p)\n", This, pformatetcIn, pformatetcOut);
if(pformatetcOut) {
memcpy(pformatetcOut, pformatectIn, sizeof(FORMATETC));
*pformatetcOut = *pformatetcIn;
pformatetcOut->ptd = NULL;
}
return DATA_S_SAMEFORMATETC;

View file

@ -33,7 +33,8 @@ void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
c->dpi.cy = GetDeviceCaps(hDC, LOGPIXELSY);
}
void ME_DestroyContext(ME_Context *c)
void ME_DestroyContext(ME_Context *c, HWND hWnd)
{
if (hWnd) ReleaseDC(hWnd, c->hDC);
DeleteObject(c->hbrMargin);
}

View file

@ -4,6 +4,7 @@
* Copyright 2004 by Krzysztof Foltman
* Copyright 2005 by Cihan Altinay
* Copyright 2005 by Phil Krylov
* Copyright 2008 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -113,7 +114,7 @@
+ EM_SETSEL
+ EM_SETSCROLLPOS 3.0
- EM_SETTABSTOPS 3.0
- EM_SETTARGETDEVICE
- EM_SETTARGETDEVICE (partial)
+ EM_SETTEXTEX 3.0 (no rich text insertion handling, proper style?)
- EM_SETTEXTMODE 2.0
- EM_SETTYPOGRAPHYOPTIONS 3.0
@ -244,7 +245,6 @@ static const WCHAR RichEdit50W[] = {'R', 'i', 'c', 'h', 'E', 'd', 'i', 't', '5',
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;
@ -335,12 +335,13 @@ static void ME_RTFCharAttrHook(RTF_Info *info)
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.wWeight = FW_NORMAL;
fmt.bUnderlineType = CFU_UNDERLINENONE;
break;
case rtfBold:
fmt.dwMask = CFM_BOLD;
fmt.dwEffects = info->rtfParam ? fmt.dwMask : 0;
fmt.dwMask = CFM_BOLD | CFM_WEIGHT;
fmt.dwEffects = info->rtfParam ? CFE_BOLD : 0;
fmt.wWeight = info->rtfParam ? FW_BOLD : FW_NORMAL;
break;
case rtfItalic:
fmt.dwMask = CFM_ITALIC;
@ -419,7 +420,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;
fmt.bPitchAndFamily = f->rtfFPitch | (f->rtfFFamily << 4);
}
}
break;
@ -451,10 +452,17 @@ static void ME_RTFParAttrHook(RTF_Info *info)
switch(info->rtfMinor)
{
case rtfParDef: /* restores default paragraph attributes */
fmt.dwMask = PFM_ALIGNMENT | PFM_TABSTOPS | PFM_OFFSET | PFM_STARTINDENT;
fmt.dwMask = PFM_ALIGNMENT | PFM_BORDER | PFM_LINESPACING | PFM_TABSTOPS | PFM_OFFSET |
PFM_RIGHTINDENT | PFM_SPACEAFTER | PFM_SPACEBEFORE | PFM_STARTINDENT;
/* TODO: numbering, shading */
fmt.wAlignment = PFA_LEFT;
fmt.cTabCount = 0;
fmt.dxOffset = fmt.dxStartIndent = 0;
fmt.dxOffset = fmt.dxStartIndent = fmt.dxRightIndent = 0;
fmt.wBorderWidth = fmt.wBorders = 0;
fmt.wBorderSpace = 0;
fmt.bLineSpacingRule = 0;
fmt.dySpaceBefore = fmt.dySpaceAfter = 0;
fmt.dyLineSpacing = 0;
RTFFlushOutputBuffer(info);
ME_GetParagraph(info->editor->pCursors[0].pRun)->member.para.bTable = FALSE;
break;
@ -470,14 +478,16 @@ static void ME_RTFParAttrHook(RTF_Info *info)
}
case rtfFirstIndent:
ME_GetSelectionParaFormat(info->editor, &fmt);
fmt.dwMask = PFM_STARTINDENT | PFM_OFFSET;
fmt.dxStartIndent += info->rtfParam + fmt.dxOffset;
fmt.dwMask |= PFM_STARTINDENT | PFM_OFFSET;
fmt.dxStartIndent += info->rtfParam;
fmt.dxOffset = -info->rtfParam;
break;
case rtfLeftIndent:
/* we assume rtfLeftIndent is always specified before rtfFirstIndent */
ME_GetSelectionParaFormat(info->editor, &fmt);
fmt.dwMask = PFM_STARTINDENT;
fmt.dxStartIndent = -fmt.dxOffset + info->rtfParam;
fmt.dwMask |= PFM_STARTINDENT;
fmt.dxStartIndent = info->rtfParam;
fmt.dxOffset = 0;
break;
case rtfRightIndent:
fmt.dwMask = PFM_RIGHTINDENT;
@ -506,6 +516,147 @@ static void ME_RTFParAttrHook(RTF_Info *info)
if (fmt.cTabCount < MAX_TAB_STOPS)
fmt.rgxTabs[fmt.cTabCount++] = info->rtfParam;
break;
case rtfKeep:
fmt.dwMask = PFM_KEEP;
fmt.wEffects = PFE_KEEP;
break;
case rtfNoWidowControl:
fmt.dwMask = PFM_NOWIDOWCONTROL;
fmt.wEffects = PFE_NOWIDOWCONTROL;
break;
case rtfKeepNext:
fmt.dwMask = PFM_KEEPNEXT;
fmt.wEffects = PFE_KEEPNEXT;
break;
case rtfSpaceAfter:
fmt.dwMask = PFM_SPACEAFTER;
fmt.dySpaceAfter = info->rtfParam;
break;
case rtfSpaceBefore:
fmt.dwMask = PFM_SPACEBEFORE;
fmt.dySpaceBefore = info->rtfParam;
break;
case rtfSpaceBetween:
fmt.dwMask = PFM_LINESPACING;
if ((int)info->rtfParam > 0)
{
fmt.dyLineSpacing = info->rtfParam;
fmt.bLineSpacingRule = 3;
}
else
{
fmt.dyLineSpacing = info->rtfParam;
fmt.bLineSpacingRule = 4;
}
case rtfSpaceMultiply:
fmt.dwMask = PFM_LINESPACING;
fmt.dyLineSpacing = info->rtfParam * 20;
fmt.bLineSpacingRule = 5;
break;
case rtfParBullet:
fmt.dwMask = PFM_NUMBERING;
fmt.wNumbering = PFN_BULLET;
break;
case rtfParSimple:
fmt.dwMask = PFM_NUMBERING;
fmt.wNumbering = 2; /* FIXME: MSDN says it's not used ?? */
break;
case rtfParNumDecimal:
fmt.dwMask = PFM_NUMBERING;
fmt.wNumbering = 2; /* FIXME: MSDN says it's not used ?? */
break;
case rtfParNumIndent:
fmt.dwMask = PFM_NUMBERINGTAB;
fmt.wNumberingTab = info->rtfParam;
break;
case rtfParNumStartAt:
fmt.dwMask = PFM_NUMBERINGSTART;
fmt.wNumberingStart = info->rtfParam;
break;
case rtfBorderLeft:
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
fmt.dwMask |= PFM_BORDER;
fmt.wBorderSpace = 0;
fmt.wBorderWidth = 1;
fmt.wBorders = 0;
}
fmt.wBorders |= 1;
break;
case rtfBorderRight:
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
fmt.dwMask |= PFM_BORDER;
fmt.wBorderSpace = 0;
fmt.wBorderWidth = 1;
fmt.wBorders = 0;
}
fmt.wBorders |= 2;
break;
case rtfBorderTop:
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
fmt.dwMask |= PFM_BORDER;
fmt.wBorderSpace = 0;
fmt.wBorderWidth = 1;
fmt.wBorders = 0;
}
fmt.wBorders |= 4;
break;
case rtfBorderBottom:
ME_GetSelectionParaFormat(info->editor, &fmt);
if (!(fmt.dwMask & PFM_BORDER))
{
fmt.dwMask |= PFM_BORDER;
fmt.wBorderSpace = 0;
fmt.wBorderWidth = 1;
fmt.wBorders = 0;
}
fmt.wBorders |= 8;
break;
case rtfBorderSingle:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorders &= ~0x70;
fmt.wBorders |= 1 << 8;
break;
case rtfBorderThick:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorders &= ~0x70;
fmt.wBorders |= 2 << 8;
break;
case rtfBorderShadow:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorders &= ~0x70;
fmt.wBorders |= 10 << 8;
break;
case rtfBorderDouble:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorders &= ~0x70;
fmt.wBorders |= 7 << 8;
break;
case rtfBorderDot:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorders &= ~0x70;
fmt.wBorders |= 11 << 8;
break;
case rtfBorderWidth:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorderWidth |= ((info->rtfParam / 15) & 7) << 8;
break;
case rtfBorderSpace:
ME_GetSelectionParaFormat(info->editor, &fmt);
/* we assume that borders have been created before (RTF spec) */
fmt.wBorderSpace = info->rtfParam;
break;
}
if (fmt.dwMask) {
RTFFlushOutputBuffer(info);
@ -549,6 +700,257 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
}
}
static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE hemf, HBITMAP hbmp,
const SIZEL* sz)
{
LPOLEOBJECT lpObject = NULL;
LPSTORAGE lpStorage = NULL;
LPOLECLIENTSITE lpClientSite = NULL;
LPDATAOBJECT lpDataObject = NULL;
LPOLECACHE lpOleCache = NULL;
STGMEDIUM stgm;
FORMATETC fm;
CLSID clsid;
BOOL ret = FALSE;
DWORD conn;
if (hemf)
{
stgm.tymed = TYMED_ENHMF;
stgm.u.hEnhMetaFile = hemf;
fm.cfFormat = CF_ENHMETAFILE;
}
else if (hbmp)
{
stgm.tymed = TYMED_GDI;
stgm.u.hBitmap = hbmp;
fm.cfFormat = CF_BITMAP;
}
stgm.pUnkForRelease = NULL;
fm.ptd = NULL;
fm.dwAspect = DVASPECT_CONTENT;
fm.lindex = -1;
fm.tymed = stgm.tymed;
if (!info->lpRichEditOle)
{
CreateIRichEditOle(info->editor, (VOID**)&info->lpRichEditOle);
}
if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK &&
#if 0
/* FIXME: enable it when rich-edit properly implements this method */
IRichEditOle_GetClientSite(info->lpRichEditOle, &lpClientSite) == S_OK &&
IOleObject_SetClientSite(lpObject, lpClientSite) == S_OK &&
#endif
IOleObject_GetUserClassID(lpObject, &clsid) == S_OK &&
IOleObject_QueryInterface(lpObject, &IID_IOleCache, (void**)&lpOleCache) == S_OK &&
IOleCache_Cache(lpOleCache, &fm, 0, &conn) == S_OK &&
IOleObject_QueryInterface(lpObject, &IID_IDataObject, (void**)&lpDataObject) == S_OK &&
IDataObject_SetData(lpDataObject, &fm, &stgm, TRUE) == S_OK)
{
REOBJECT reobject;
reobject.cbStruct = sizeof(reobject);
reobject.cp = REO_CP_SELECTION;
reobject.clsid = clsid;
reobject.poleobj = lpObject;
reobject.pstg = lpStorage;
reobject.polesite = lpClientSite;
/* convert from twips to .01 mm */
reobject.sizel.cx = MulDiv(sz->cx, 254, 144);
reobject.sizel.cy = MulDiv(sz->cy, 254, 144);
reobject.dvaspect = DVASPECT_CONTENT;
reobject.dwFlags = 0; /* FIXME */
reobject.dwUser = 0;
/* FIXME: could be simpler */
ret = IRichEditOle_InsertObject(info->lpRichEditOle, &reobject) == S_OK;
}
if (lpObject) IOleObject_Release(lpObject);
if (lpClientSite) IOleClientSite_Release(lpClientSite);
if (lpStorage) IStorage_Release(lpStorage);
if (lpDataObject) IDataObject_Release(lpDataObject);
if (lpOleCache) IOleCache_Release(lpOleCache);
return ret;
}
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;
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
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 */
static void ME_RTFReadObjectGroup(RTF_Info *info)
{
for (;;)
{
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
return;
if (RTFCheckCM(info, rtfGroup, rtfEndGroup))
break;
if (RTFCheckCM(info, rtfGroup, rtfBeginGroup))
{
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
return;
if (RTFCheckCMM(info, rtfControl, rtfDestination, rtfObjResult))
{
int level = 1;
while (RTFGetToken (info) != rtfEOF)
{
if (info->rtfClass == rtfGroup)
{
if (info->rtfMajor == rtfBeginGroup) level++;
else if (info->rtfMajor == rtfEndGroup && --level < 0) break;
}
RTFRouteToken(info);
}
}
else RTFSkipGroup(info);
continue;
}
if (!RTFCheckCM (info, rtfControl, rtfObjAttr))
{
FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor);
return;
}
}
RTFRouteToken(info); /* feed "}" back to router */
}
static void ME_RTFReadHook(RTF_Info *info) {
switch(info->rtfClass)
{
@ -557,7 +959,7 @@ static void ME_RTFReadHook(RTF_Info *info) {
{
case rtfBeginGroup:
if (info->stackTop < maxStack) {
memcpy(&info->stack[info->stackTop].fmt, &info->style->fmt, sizeof(CHARFORMAT2W));
info->stack[info->stackTop].fmt = info->style->fmt;
info->stack[info->stackTop].codePage = info->codePage;
info->stack[info->stackTop].unicodeLength = info->unicodeLength;
}
@ -628,9 +1030,9 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
int nEventMask = editor->nEventMask;
ME_InStream inStream;
TRACE("stream==%p hWnd==%p format==0x%X\n", stream, editor->hWnd, (UINT)format);
TRACE("stream==%p hWnd==%p format==0x%X\n", stream, editor->hWnd, format);
editor->nEventMask = 0;
ME_GetSelection(editor, &from, &to);
if ((format & SFF_SELECTION) && (editor->mode & TM_RICHTEXT)) {
style = ME_GetSelectionInsertStyle(editor);
@ -687,12 +1089,16 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
WriterInit(&parser);
RTFInit(&parser);
RTFSetReadHook(&parser, ME_RTFReadHook);
RTFSetDestinationCallback(&parser, rtfPict, ME_RTFReadPictGroup);
RTFSetDestinationCallback(&parser, rtfObject, ME_RTFReadObjectGroup);
BeginFile(&parser);
/* do the parsing */
RTFRead(&parser);
RTFFlushOutputBuffer(&parser);
RTFDestroy(&parser);
if (parser.lpRichEditOle)
IRichEditOle_Release(parser.lpRichEditOle);
style = parser.style;
}
@ -1125,12 +1531,15 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
return FALSE;
}
static void ME_SetCursor(ME_TextEditor *editor, int x)
static BOOL ME_SetCursor(ME_TextEditor *editor, int x)
{
if (x < editor->selofs || editor->linesel)
if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_SELECTIONBAR) &&
(x < editor->selofs || editor->linesel))
{
SetCursor(hLeft);
else
SetCursor(hBeam);
return TRUE;
}
return FALSE;
}
static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
@ -1140,7 +1549,7 @@ static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
int seltype = 0;
if(!editor->lpOleCallback)
return FALSE;
ME_GetSelection(editor, (int *)&selrange.cpMin, (int *)&selrange.cpMax);
ME_GetSelection(editor, &selrange.cpMin, &selrange.cpMax);
if(selrange.cpMin == selrange.cpMax)
seltype |= SEL_EMPTY;
else
@ -1193,6 +1602,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->nLastSelStart = ed->nLastSelEnd = 0;
ed->pLastSelStartPara = ed->pLastSelEndPara = ME_FindItemFwd(ed->pBuffer->pFirst, diParagraph);
ed->bRedraw = TRUE;
ed->bWordWrap = (GetWindowLongW(hWnd, GWL_STYLE) & WS_HSCROLL) ? FALSE : TRUE;
ed->bHideSelection = FALSE;
ed->nInvalidOfs = -1;
ed->pfnWordBreak = NULL;
@ -1305,7 +1715,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
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;
@ -1504,7 +1913,6 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
UNSUPPORTED_MSG(EM_SETLANGOPTIONS)
UNSUPPORTED_MSG(EM_SETPALETTE)
UNSUPPORTED_MSG(EM_SETTABSTOPS)
UNSUPPORTED_MSG(EM_SETTARGETDEVICE)
UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS)
UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX)
UNSUPPORTED_MSG(WM_STYLECHANGING)
@ -1561,7 +1969,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
case EM_EXGETSEL:
{
CHARRANGE *pRange = (CHARRANGE *)lParam;
ME_GetSelection(editor, (int *)&pRange->cpMin, (int *)&pRange->cpMax);
ME_GetSelection(editor, &pRange->cpMin, &pRange->cpMax);
TRACE("EM_EXGETSEL = (%d,%d)\n", pRange->cpMin, pRange->cpMax);
return 0;
}
@ -2034,11 +2442,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
LPDATAOBJECT dataObj = NULL;
CHARRANGE range;
HRESULT hr = S_OK;
if (editor->cPasswordMask)
return 0; /* Copying or Cutting masked text isn't allowed */
ME_GetSelection(editor, (int*)&range.cpMin, (int*)&range.cpMax);
ME_GetSelection(editor, &range.cpMin, &range.cpMax);
if(editor->lpOleCallback)
hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, &range, RECO_COPY, &dataObj);
if(FAILED(hr) || !dataObj)
@ -2077,17 +2485,17 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
else
bufferA = heap_alloc(wParam + 2);
ex.cb = wParam + (unicode ? 2*sizeof(WCHAR) : 2);
ex.cb = (wParam + 2) * (unicode ? sizeof(WCHAR) : sizeof(CHAR));
ex.flags = GT_USECRLF;
ex.codepage = unicode ? 1200 : CP_ACP;
ex.lpDefaultChar = NULL;
ex.lpUsedDefaultChar = NULL;
ex.lpUsedDefChar = NULL;
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;
memcpy((LPWSTR)lParam, bufferW, wParam * sizeof(WCHAR));
if (lstrlenW(bufferW) >= wParam) rc = 0;
}
else
{
@ -2101,7 +2509,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
case EM_GETTEXTEX:
{
GETTEXTEX *ex = (GETTEXTEX*)wParam;
int nStart, nCount;
int nStart, nCount; /* in chars */
if (ex->flags & ~(GT_SELECTION | GT_USECRLF))
FIXME("GETTEXTEX flags 0x%08x not supported\n", ex->flags & ~(GT_SELECTION | GT_USECRLF));
@ -2110,12 +2518,11 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
{
ME_GetSelection(editor, &nStart, &nCount);
nCount -= nStart;
nCount = min(nCount, ex->cb - 1);
}
else
{
nStart = 0;
nCount = ex->cb - 1;
nCount = 0x7fffffff;
}
if (ex->codepage == 1200)
{
@ -2127,13 +2534,16 @@ 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 = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
LPWSTR buffer;
DWORD buflen = ex->cb;
LRESULT rc;
DWORD flags = 0;
nCount = min(nCount, ex->cb - 1);
buffer = heap_alloc((crlfmul*nCount + 1) * sizeof(WCHAR));
buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags & GT_USECRLF);
rc = WideCharToMultiByte(ex->codepage, flags, buffer, -1, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefaultChar);
rc = WideCharToMultiByte(ex->codepage, flags, buffer, -1, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefChar);
if (rc) rc--; /* do not count 0 terminator */
heap_free(buffer);
@ -2393,6 +2803,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
pt.x = 0;
pt.y = editor->pBuffer->pLast->member.para.nYPos;
}
pt.x += editor->selofs;
if (wParam >= 0x40000) {
*(POINTL *)wParam = pt;
}
@ -2419,7 +2830,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
SetCapture(hWnd);
ME_LinkNotify(editor,msg,wParam,lParam);
ME_SetCursor(editor, LOWORD(lParam));
if (!ME_SetCursor(editor, LOWORD(lParam))) goto do_default;
break;
case WM_MOUSEMOVE:
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
@ -2428,7 +2839,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
if (GetCapture() == hWnd)
ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
ME_LinkNotify(editor,msg,wParam,lParam);
ME_SetCursor(editor, LOWORD(lParam));
if (!ME_SetCursor(editor, LOWORD(lParam))) goto do_default;
break;
case WM_LBUTTONUP:
if (GetCapture() == hWnd)
@ -2436,9 +2847,14 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
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);
else
{
BOOL ret;
editor->linesel = 0;
ret = ME_SetCursor(editor, LOWORD(lParam));
ME_LinkNotify(editor,msg,wParam,lParam);
if (!ret) goto do_default;
}
break;
case WM_LBUTTONDBLCLK:
if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
@ -2561,7 +2977,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
{
ME_Style *style = ME_GetInsertStyle(editor, 0);
ME_SaveTempStyle(editor);
ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
if (wstr == '\r' && (GetKeyState(VK_SHIFT) & 0x8000))
ME_InsertEndRowFromCursor(editor, 0);
else
ME_InsertTextFromCursor(editor, 0, &wstr, 1, style);
ME_ReleaseStyle(style);
ME_CommitUndo(editor);
}
@ -2785,6 +3204,13 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
ME_RewrapRepaint(editor);
return 0;
}
case EM_SETTARGETDEVICE:
if (wParam == 0)
{
editor->bWordWrap = (lParam == 0);
}
else FIXME("Unsupported yet non NULL device in EM_SETTARGETDEVICE\n");
break;
default:
do_default:
return DefWindowProcW(hWnd, msg, wParam, lParam);
@ -2973,7 +3399,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 = hBeam;
wcW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM));
wcW.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
wcW.lpszMenuName = NULL;

View file

@ -149,7 +149,6 @@ ME_DisplayItem *ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor,
ME_Style *style, const WCHAR *str, int len, int flags);
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_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);
@ -157,13 +156,13 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset);
int ME_GetLastSplittablePlace(ME_Context *c, ME_Run *run);
int ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2);
void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p);
ME_DisplayItem *ME_SplitRun(ME_Context *c, ME_DisplayItem *item, int nChar);
ME_DisplayItem *ME_SplitRun(ME_WrapContext *wc, ME_DisplayItem *item, int nChar);
ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_DisplayItem *item, int nChar);
int ME_FindSplitPoint(ME_Context *c, POINT *pt, ME_Run *run, int desperate);
void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run);
ME_DisplayItem *ME_SplitFurther(ME_TextEditor *editor, ME_DisplayItem *run);
void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, ME_Run *run);
SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen);
void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run);
SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx);
void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor);
void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppRun, int *pOfs);
int ME_CharOfsFromRunOfs(ME_TextEditor *editor, ME_DisplayItem *pRun, int nOfs);
@ -187,10 +186,11 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y);
void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
const WCHAR *str, int len, ME_Style *style);
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor);
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl);
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC);
void ME_DestroyContext(ME_Context *c);
void ME_DestroyContext(ME_Context *c, HWND release);
ME_Style *GetInsertStyle(ME_TextEditor *editor, int nCursor);
void ME_MustBeWrapped(ME_Context *c, ME_DisplayItem *para);
void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
@ -201,7 +201,7 @@ int ME_CountParagraphsBetween(ME_TextEditor *editor, int from, int to);
BOOL ME_IsSelection(ME_TextEditor *editor);
void ME_DeleteSelection(ME_TextEditor *editor);
void ME_SendSelChange(ME_TextEditor *editor);
void ME_InsertGraphicsFromCursor(ME_TextEditor *editor, int nCursor);
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor);
void ME_InsertTableCellFromCursor(ME_TextEditor *editor, int nCursor);
void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars);
int ME_GetTextLength(ME_TextEditor *editor);
@ -259,7 +259,11 @@ int ME_GetParaBorderWidth(ME_TextEditor *editor, int);
int ME_GetParaLineSpace(ME_Context *c, ME_Paragraph*);
/* richole.c */
extern LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *);
LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *);
void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, ME_Paragraph *para, BOOL selected);
void ME_GetOLEObjectSize(ME_Context *c, ME_Run *run, SIZE *pSize);
void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src);
void ME_DeleteReObject(REOBJECT* reo);
/* wintest.c */

View file

@ -92,11 +92,11 @@ typedef enum {
/******************************** run flags *************************/
#define MERF_STYLEFLAGS 0x0FFF
/* run contains non-text content, which has its own rules for wrapping, sizing etc */
#define MERF_GRAPHICS 1
#define MERF_GRAPHICS 0x001
/* run is a tab (or, in future, any kind of content whose size is dependent on run position) */
#define MERF_TAB 2
#define MERF_TAB 0x002
/* run is a cell boundary */
#define MERF_CELL 4
#define MERF_CELL 0x004
#define MERF_NONTEXT (MERF_GRAPHICS | MERF_TAB | MERF_CELL)
@ -114,13 +114,15 @@ typedef enum {
#define MERF_CALCBYWRAP 0x0F0000
/* the "end of paragraph" run, contains 1 character */
#define MERF_ENDPARA 0x100000
/* forcing the "end of row" run, contains 1 character */
#define MERF_ENDROW 0x200000
/* run is hidden */
#define MERF_HIDDEN 0x200000
#define MERF_HIDDEN 0x400000
/* runs with any of these flags set cannot be joined */
#define MERF_NOJOIN (MERF_GRAPHICS|MERF_TAB|MERF_ENDPARA)
#define MERF_NOJOIN (MERF_GRAPHICS|MERF_TAB|MERF_ENDPARA|MERF_ENDROW)
/* runs that don't contain real text */
#define MERF_NOTEXT (MERF_GRAPHICS|MERF_TAB|MERF_ENDPARA)
#define MERF_NOTEXT (MERF_GRAPHICS|MERF_TAB|MERF_ENDPARA|MERF_ENDROW)
/* those flags are kept when the row is split */
#define MERF_SPLITMASK (~(0))
@ -145,6 +147,7 @@ typedef struct tagME_Run
int nAscent, nDescent; /* pixels above/below baseline */
POINT pt; /* relative to para's position */
struct tagME_TableCell *pCell; /* for MERF_CELL: points to respective cell in ME_Paragraph */
REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */
} ME_Run;
typedef struct tagME_Document {
@ -309,6 +312,7 @@ typedef struct tagME_TextEditor
int nZoomNumerator, nZoomDenominator;
RECT rcFormat;
BOOL bRedraw;
BOOL bWordWrap;
int nInvalidOfs;
int nTextLimit;
EDITWORDBREAKPROCW pfnWordBreak;
@ -347,7 +351,7 @@ typedef struct tagME_WrapContext
ME_Style *style;
ME_Context *context;
int nLeftMargin, nRightMargin, nFirstMargin;
int nTotalWidth, nAvailWidth;
int nAvailWidth;
int nRow;
POINT pt;
BOOL bOverflown;

View file

@ -115,6 +115,7 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item) {
ME_DestroyTableCellList(item);
}
if (item->type==diRun || item->type == diUndoInsertRun) {
if (item->member.run.ole_obj) ME_DeleteReObject(item->member.run.ole_obj);
ME_ReleaseStyle(item->member.run.style);
ME_DestroyString(item->member.run.strText);
}

View file

@ -91,7 +91,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
if (editor->nTotalLength != editor->nLastTotalLength)
ME_SendRequestResize(editor, FALSE);
editor->nLastTotalLength = editor->nTotalLength;
ME_DestroyContext(&c);
ME_DestroyContext(&c, NULL);
}
void ME_Repaint(ME_TextEditor *editor)
@ -246,34 +246,6 @@ static void ME_DebugWrite(HDC hDC, const POINT *pt, LPCWSTR szText) {
SetTextColor(hDC, color);
}
static void ME_DrawGraphics(ME_Context *c, int x, int y, ME_Run *run,
ME_Paragraph *para, BOOL selected) {
SIZE sz;
int xs, ys, xe, ye, h, ym, width, eyes;
ME_GetGraphicsSize(c->editor, run, &sz);
xs = run->pt.x;
ys = y-sz.cy;
xe = xs+sz.cx;
ye = y;
h = ye-ys;
ym = ys+h/4;
width = sz.cx;
eyes = width/8;
/* draw a smiling face :) */
Ellipse(c->hDC, xs, ys, xe, ye);
Ellipse(c->hDC, xs+width/8, ym, x+width/8+eyes, ym+eyes);
Ellipse(c->hDC, xs+7*width/8-eyes, ym, xs+7*width/8, ym+eyes);
MoveToEx(c->hDC, xs+width/8, ys+3*h/4-eyes, NULL);
LineTo(c->hDC, xs+width/8, ys+3*h/4);
LineTo(c->hDC, xs+7*width/8, ys+3*h/4);
LineTo(c->hDC, xs+7*width/8, ys+3*h/4-eyes);
if (selected)
{
/* descent is usually (always?) 0 for graphics */
PatBlt(c->hDC, x, y-run->nAscent, sz.cx, run->nAscent+run->nDescent, DSTINVERT);
}
}
static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para)
{
ME_Run *run = &rundi->member.run;
@ -299,7 +271,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
return;
if (run->nFlags & MERF_GRAPHICS)
ME_DrawGraphics(c, x, y, run, para, (runofs >= nSelFrom) && (runofs < nSelTo));
ME_DrawOLE(c, x, y, run, para, (runofs >= nSelFrom) && (runofs < nSelTo));
else
{
if (c->editor->cPasswordMask)
@ -318,7 +290,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
}
static struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;} border_details[] = {
/* none */ {0, 0, PS_SOLID, FALSE},
/* none */ {0, 1, 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},

View file

@ -28,7 +28,6 @@ static const WCHAR wszParagraphSign[] = {0xB6, 0};
void ME_MakeFirstParagraph(ME_TextEditor *editor)
{
ME_Context c;
HDC hDC;
PARAFORMAT2 fmt;
CHARFORMAT2W cf;
LOGFONTW lf;
@ -38,9 +37,8 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
ME_DisplayItem *run;
ME_Style *style;
hDC = GetDC(editor->hWnd);
ME_InitContext(&c, editor, GetDC(editor->hWnd));
ME_InitContext(&c, editor, hDC);
hf = (HFONT)GetStockObject(SYSTEM_FONT);
assert(hf);
GetObjectW(hf, sizeof(LOGFONTW), &lf);
@ -55,7 +53,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
cf.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
lstrcpyW(cf.szFaceName, lf.lfFaceName);
cf.yHeight = ME_twips2pointsY(&c, lf.lfHeight);
if (lf.lfWeight >= 700) cf.dwEffects |= CFE_BOLD;
if (lf.lfWeight > FW_NORMAL) cf.dwEffects |= CFE_BOLD;
cf.wWeight = lf.lfWeight;
if (lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
cf.bUnderlineType = (lf.lfUnderline) ? CFU_CF1UNDERLINE : CFU_UNDERLINENONE;
@ -68,8 +66,8 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
fmt.dwMask = PFM_ALIGNMENT | PFM_OFFSET | PFM_STARTINDENT | PFM_RIGHTINDENT | PFM_TABSTOPS;
fmt.wAlignment = PFA_LEFT;
CopyMemory(para->member.para.pFmt, &fmt, sizeof(PARAFORMAT2));
*para->member.para.pFmt = fmt;
style = ME_MakeStyle(&cf);
text->pDefaultStyle = style;
@ -85,8 +83,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
text->pLast->member.para.nCharOfs = 1;
ME_DestroyContext(&c);
ReleaseDC(editor->hWnd, hDC);
ME_DestroyContext(&c, editor->hWnd);
}
void ME_MarkAllForWrapping(ME_TextEditor *editor)
@ -148,7 +145,7 @@ 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));
*new_para->member.para.pFmt = *run_para->member.para.pFmt;
new_para->member.para.bTable = run_para->member.para.bTable;
@ -226,7 +223,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
{
undo->nStart = pNext->member.para.nCharOfs - end_len;
assert(pNext->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
CopyMemory(undo->di.member.para.pFmt, pNext->member.para.pFmt, sizeof(PARAFORMAT2));
*undo->di.member.para.pFmt = *pNext->member.para.pFmt;
}
shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len;
@ -352,7 +349,7 @@ void ME_SetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, const PARAFOR
assert(sizeof(*para->member.para.pFmt) == sizeof(PARAFORMAT2));
ME_AddUndoItem(editor, diUndoSetParagraphFormat, para);
CopyMemory(&copy, para->member.para.pFmt, sizeof(PARAFORMAT2));
copy = *para->member.para.pFmt;
#define COPY_FIELD(m, f) \
if (pFmt->dwMask & (m)) { \
@ -447,7 +444,7 @@ void ME_GetParaFormat(ME_TextEditor *editor, const ME_DisplayItem *para, PARAFOR
{
if (pFmt->cbSize >= sizeof(PARAFORMAT2))
{
CopyMemory(pFmt, para->member.para.pFmt, sizeof(PARAFORMAT2));
*pFmt = *para->member.para.pFmt;
return;
}
CopyMemory(pFmt, para->member.para.pFmt, pFmt->cbSize);

View file

@ -857,9 +857,9 @@ static void ReadFontTbl(RTF_Info *info)
fp->rtfFName = NULL;
fp->rtfFAltName = NULL;
fp->rtfFNum = -1;
fp->rtfFFamily = 0;
fp->rtfFFamily = FF_DONTCARE;
fp->rtfFCharSet = DEFAULT_CHARSET; /* 1 */
fp->rtfFPitch = 0;
fp->rtfFPitch = DEFAULT_PITCH;
fp->rtfFType = 0;
fp->rtfFCodePage = CP_ACP;
@ -1788,6 +1788,7 @@ static RTFKey rtfKey[] =
{ rtfPictAttr, rtfWinMetafile, "wmetafile", 0 },
{ rtfPictAttr, rtfDevIndBitmap, "dibitmap", 0 },
{ rtfPictAttr, rtfWinBitmap, "wbitmap", 0 },
{ rtfPictAttr, rtfEmfBlip, "emfblip", 0 },
{ rtfPictAttr, rtfPixelBits, "wbmbitspixel", 0 },
{ rtfPictAttr, rtfBitmapPlanes, "wbmplanes", 0 },
{ rtfPictAttr, rtfBitmapWid, "wbmwidthbytes", 0 },
@ -2596,10 +2597,13 @@ static void SpecialChar (RTF_Info *info)
}
break;
}
case rtfLine:
RTFFlushOutputBuffer(info);
ME_InsertEndRowFromCursor(info->editor, 0);
break;
case rtfPage:
case rtfSect:
case rtfRow:
case rtfLine:
case rtfPar:
RTFPutUnicodeChar (info, '\n');
break;
@ -2648,6 +2652,7 @@ RTFFlushUnicodeOutputBuffer(RTF_Info *info)
}
}
static void
RTFPutUnicodeString(RTF_Info *info, const WCHAR *string, int length)
{

View file

@ -162,7 +162,7 @@ IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
if(!lplpdataobj)
return E_INVALIDARG;
if(!lpchrg) {
ME_GetSelection(This->editor, (int*)&tmpchrg.cpMin, (int*)&tmpchrg.cpMax);
ME_GetSelection(This->editor, &tmpchrg.cpMin, &tmpchrg.cpMax);
lpchrg = &tmpchrg;
}
return ME_GetDataObject(This->editor, lpchrg, lplpdataobj);
@ -218,11 +218,18 @@ IRichEditOle_fnInPlaceDeactivate(IRichEditOle *me)
}
static HRESULT WINAPI
IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *lpreobject)
IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
{
IRichEditOleImpl *This = impl_from_IRichEditOle(me);
FIXME("stub %p\n",This);
return E_NOTIMPL;
TRACE("(%p,%p)\n", This, reo);
if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
if (reo->poleobj) IOleObject_AddRef(reo->poleobj);
if (reo->pstg) IStorage_AddRef(reo->pstg);
if (reo->polesite) IOleClientSite_AddRef(reo->polesite);
ME_InsertOLEFromCursor(This->editor, reo, 0);
return S_OK;
}
static HRESULT WINAPI IRichEditOle_fnSaveCompleted(IRichEditOle *me, LONG iob,
@ -542,3 +549,204 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj)
return 1;
}
static void convert_sizel(ME_Context *c, const SIZEL* szl, SIZE* sz)
{
/* sizel is in .01 millimeters, sz in pixels */
sz->cx = MulDiv(szl->cx, c->dpi.cx, 2540);
sz->cy = MulDiv(szl->cy, c->dpi.cy, 2540);
}
/******************************************************************************
* ME_GetOLEObjectSize
*
* Sets run extent for OLE objects.
*/
void ME_GetOLEObjectSize(ME_Context *c, ME_Run *run, SIZE *pSize)
{
IDataObject* ido;
FORMATETC fmt;
STGMEDIUM stgm;
DIBSECTION dibsect;
ENHMETAHEADER emh;
assert(run->nFlags & MERF_GRAPHICS);
assert(run->ole_obj);
if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
{
convert_sizel(c, &run->ole_obj->sizel, pSize);
return;
}
IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido);
fmt.cfFormat = CF_BITMAP;
fmt.ptd = NULL;
fmt.dwAspect = DVASPECT_CONTENT;
fmt.lindex = -1;
fmt.tymed = TYMED_GDI;
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
{
fmt.cfFormat = CF_ENHMETAFILE;
fmt.tymed = TYMED_ENHMF;
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
{
FIXME("unsupported format\n");
pSize->cx = pSize->cy = 0;
IDataObject_Release(ido);
return;
}
}
switch (stgm.tymed)
{
case TYMED_GDI:
GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
pSize->cx = dibsect.dsBm.bmWidth;
pSize->cy = dibsect.dsBm.bmHeight;
if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
break;
case TYMED_ENHMF:
GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
pSize->cx = emh.rclBounds.right - emh.rclBounds.left;
pSize->cy = emh.rclBounds.bottom - emh.rclBounds.top;
if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
break;
default:
FIXME("Unsupported tymed %d\n", stgm.tymed);
break;
}
IDataObject_Release(ido);
if (c->editor->nZoomNumerator != 0)
{
pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
}
void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run,
ME_Paragraph *para, BOOL selected)
{
IDataObject* ido;
FORMATETC fmt;
STGMEDIUM stgm;
DIBSECTION dibsect;
ENHMETAHEADER emh;
HDC hMemDC;
SIZE sz;
BOOL has_size;
assert(run->nFlags & MERF_GRAPHICS);
assert(run->ole_obj);
if (IOleObject_QueryInterface(run->ole_obj->poleobj, &IID_IDataObject, (void**)&ido) != S_OK)
{
FIXME("Couldn't get interface\n");
return;
}
has_size = run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0;
fmt.cfFormat = CF_BITMAP;
fmt.ptd = NULL;
fmt.dwAspect = DVASPECT_CONTENT;
fmt.lindex = -1;
fmt.tymed = TYMED_GDI;
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
{
fmt.cfFormat = CF_ENHMETAFILE;
fmt.tymed = TYMED_ENHMF;
if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
{
FIXME("Couldn't get storage medium\n");
IDataObject_Release(ido);
return;
}
}
switch (stgm.tymed)
{
case TYMED_GDI:
GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
hMemDC = CreateCompatibleDC(c->hDC);
SelectObject(hMemDC, stgm.u.hBitmap);
if (!has_size && c->editor->nZoomNumerator == 0)
{
sz.cx = dibsect.dsBm.bmWidth;
sz.cy = dibsect.dsBm.bmHeight;
BitBlt(c->hDC, x, y - dibsect.dsBm.bmHeight,
dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight,
hMemDC, 0, 0, SRCCOPY);
}
else
{
if (has_size)
{
convert_sizel(c, &run->ole_obj->sizel, &sz);
}
else
{
sz.cx = MulDiv(dibsect.dsBm.bmWidth,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
sz.cy = MulDiv(dibsect.dsBm.bmHeight,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
}
if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
break;
case TYMED_ENHMF:
GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
if (!has_size && c->editor->nZoomNumerator == 0)
{
sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
sz.cx = emh.rclBounds.right - emh.rclBounds.left;
}
else
{
if (has_size)
{
convert_sizel(c, &run->ole_obj->sizel, &sz);
}
else
{
sz.cy = MulDiv(emh.rclBounds.bottom - emh.rclBounds.top,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
sz.cx = MulDiv(emh.rclBounds.right - emh.rclBounds.left,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
}
{
RECT rc;
rc.left = x;
rc.top = y - sz.cy;
rc.right = x + sz.cx;
rc.bottom = y;
PlayEnhMetaFile(c->hDC, stgm.u.hEnhMetaFile, &rc);
}
if (!stgm.pUnkForRelease) DeleteEnhMetaFile(stgm.u.hEnhMetaFile);
break;
default:
FIXME("Unsupported tymed %d\n", stgm.tymed);
selected = FALSE;
break;
}
if (selected && !c->editor->bHideSelection)
PatBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy, DSTINVERT);
IDataObject_Release(ido);
}
void ME_DeleteReObject(REOBJECT* reo)
{
if (reo->poleobj) IOleObject_Release(reo->poleobj);
if (reo->pstg) IStorage_Release(reo->pstg);
if (reo->polesite) IOleClientSite_Release(reo->polesite);
FREE_OBJ(reo);
}
void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
{
*dst = *src;
if (dst->poleobj) IOleObject_AddRef(dst->poleobj);
if (dst->pstg) IStorage_AddRef(dst->pstg);
if (dst->polesite) IOleClientSite_AddRef(dst->polesite);
}

View file

@ -597,23 +597,24 @@
# define rtfWinMetafile 2
# define rtfDevIndBitmap 3
# define rtfWinBitmap 4
# define rtfPixelBits 5
# define rtfBitmapPlanes 6
# define rtfBitmapWid 7
# define rtfPicWid 8
# define rtfPicHt 9
# define rtfPicGoalWid 10
# define rtfPicGoalHt 11
# define rtfPicScaleX 12
# define rtfPicScaleY 13
# define rtfPicScaled 14
# define rtfPicCropTop 15
# define rtfPicCropBottom 16
# define rtfPicCropLeft 17
# define rtfPicCropRight 18
# define rtfPicMFHasBitmap 19 /* new in 1.10 */
# define rtfPicMFBitsPerPixel 20 /* new in 1.10 */
# define rtfPicBinary 21
# define rtfEmfBlip 5
# define rtfPixelBits 6
# define rtfBitmapPlanes 7
# define rtfBitmapWid 8
# define rtfPicWid 9
# define rtfPicHt 10
# define rtfPicGoalWid 11
# define rtfPicGoalHt 12
# define rtfPicScaleX 13
# define rtfPicScaleY 14
# define rtfPicScaled 15
# define rtfPicCropTop 16
# define rtfPicCropBottom 17
# define rtfPicCropLeft 18
# define rtfPicCropRight 19
# define rtfPicMFHasBitmap 20 /* new in 1.10 */
# define rtfPicMFBitsPerPixel 21 /* new in 1.10 */
# define rtfPicBinary 22
# define rtfBookmarkAttr 14
# define rtfBookmarkFirstCol 0
@ -1103,6 +1104,7 @@ struct _RTF_Info {
RTFState stack[maxStack];
int stackTop;
BOOL styleChanged;
LPRICHEDITOLE lpRichEditOle;
};

View file

@ -267,9 +267,9 @@ void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p)
* Splits a run into two in a given place. It also updates the screen position
* and size (extent) of the newly generated runs.
*/
ME_DisplayItem *ME_SplitRun(ME_Context *c, ME_DisplayItem *item, int nVChar)
ME_DisplayItem *ME_SplitRun(ME_WrapContext *wc, ME_DisplayItem *item, int nVChar)
{
ME_TextEditor *editor = c->editor;
ME_TextEditor *editor = wc->context->editor;
ME_DisplayItem *item2 = NULL;
ME_Run *run, *run2;
ME_Paragraph *para = &ME_GetParagraph(item)->member.para;
@ -291,8 +291,8 @@ ME_DisplayItem *ME_SplitRun(ME_Context *c, ME_DisplayItem *item, int nVChar)
run2 = &item2->member.run;
ME_CalcRunExtent(c, para, run);
ME_CalcRunExtent(c, para, run2);
ME_CalcRunExtent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run);
ME_CalcRunExtent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run2);
run2->pt.x = run->pt.x+run->nWidth;
run2->pt.y = run->pt.y;
@ -359,6 +359,7 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags)
{
ME_DisplayItem *item = ME_MakeDI(diRun);
item->member.run.style = s;
item->member.run.ole_obj = NULL;
item->member.run.strText = strData;
item->member.run.nFlags = nFlags;
item->member.run.nCharOfs = -1;
@ -467,19 +468,6 @@ void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run)
run->nFlags &= ~(MERF_WHITESPACE | MERF_STARTWHITE | MERF_ENDWHITE);
}
/******************************************************************************
* ME_GetGraphicsSize
*
* Sets run extent for graphics runs. This functionality is just a placeholder
* for future OLE object support, and will be removed.
*/
void ME_GetGraphicsSize(ME_TextEditor *editor, ME_Run *run, SIZE *pSize)
{
assert(run->nFlags & MERF_GRAPHICS);
pSize->cx = 64;
pSize->cy = 64;
}
/******************************************************************************
* ME_CharFromPoint
*
@ -504,7 +492,7 @@ int ME_CharFromPoint(ME_Context *c, int cx, ME_Run *run)
if (run->nFlags & MERF_GRAPHICS)
{
SIZE sz;
ME_GetGraphicsSize(c->editor, run, &sz);
ME_GetOLEObjectSize(c, run, &sz);
if (cx < sz.cx)
return 0;
return 1;
@ -558,21 +546,22 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
return 0;
return 1;
}
ME_InitContext(&c, editor, GetDC(editor->hWnd));
if (run->nFlags & MERF_GRAPHICS)
{
SIZE sz;
ME_GetGraphicsSize(editor, run, &sz);
ME_GetOLEObjectSize(&c, run, &sz);
ME_DestroyContext(&c, editor->hWnd);
if (cx < sz.cx/2)
return 0;
return 1;
}
if (editor->cPasswordMask)
strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(run->strText));
else
strRunText = run->strText;
ME_InitContext(&c, editor, GetDC(editor->hWnd));
hOldFont = ME_SelectStyleFont(&c, run->style);
GetTextExtentExPointW(c.hDC, strRunText->szData, strRunText->nLen,
cx, &fit, NULL, &sz);
@ -591,7 +580,7 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
ME_DestroyString(strRunText);
ME_UnselectStyleFont(&c, run->style, hOldFont);
ReleaseDC(editor->hWnd, c.hDC);
ME_DestroyContext(&c, editor->hWnd);
return fit;
}
@ -621,19 +610,20 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
ME_String *strRunText;
/* This could point to either the run's real text, or it's masked form in a password control */
ME_InitContext(&c, editor, GetDC(editor->hWnd));
if (pRun->nFlags & MERF_GRAPHICS)
{
if (!nOffset) return 0;
ME_GetGraphicsSize(editor, pRun, &size);
return 1;
if (nOffset)
ME_GetOLEObjectSize(&c, pRun, &size);
ReleaseDC(editor->hWnd, c.hDC);
return nOffset != 0;
}
if (editor->cPasswordMask)
strRunText = ME_MakeStringR(editor->cPasswordMask,ME_StrVLen(pRun->strText));
else
strRunText = pRun->strText;
ME_InitContext(&c, editor, GetDC(editor->hWnd));
ME_GetTextExtent(&c, strRunText->szData, nOffset, pRun->style, &size);
ReleaseDC(editor->hWnd, c.hDC);
if (editor->cPasswordMask)
@ -648,7 +638,7 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
* (nLen).
*/
static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen,
int *pAscent, int *pDescent)
int startx, int *pAscent, int *pDescent)
{
SIZE size;
int nMaxLen = ME_StrVLen(run->strText);
@ -678,8 +668,8 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
if (run->nFlags & MERF_TAB)
{
int pos = 0, i = 0, ppos;
PARAFORMAT2 *pFmt = para->pFmt;
do {
if (i < pFmt->cTabCount)
{
@ -691,8 +681,8 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
pos += 720-(pos%720);
}
ppos = ME_twips2pointsX(c, pos);
if (ppos>run->pt.x) {
size.cx = ppos - run->pt.x;
if (ppos > startx + run->pt.x) {
size.cx = ppos - startx - run->pt.x;
break;
}
} while(1);
@ -701,7 +691,7 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
}
if (run->nFlags & MERF_GRAPHICS)
{
ME_GetGraphicsSize(c->editor, run, &size);
ME_GetOLEObjectSize(c, run, &size);
if (size.cy > *pAscent)
*pAscent = size.cy;
/* descent is unchanged */
@ -721,10 +711,11 @@ static SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run
* Finds width and height (but not ascent and descent) of a part of the run
* up to given character.
*/
SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen)
SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para,
ME_Run *run, int nLen, int startx)
{
int asc, desc;
return ME_GetRunSizeCommon(c, para, run, nLen, &asc, &desc);
return ME_GetRunSizeCommon(c, para, run, nLen, startx, &asc, &desc);
}
/******************************************************************************
@ -734,14 +725,15 @@ SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLe
* is calculated based on whole row's ascent and descent anyway, so no need
* to use it here.
*/
void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, ME_Run *run)
void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run)
{
if (run->nFlags & MERF_HIDDEN)
run->nWidth = 0;
else
{
int nEnd = ME_StrVLen(run->strText);
SIZE size = ME_GetRunSizeCommon(c, para, run, nEnd, &run->nAscent, &run->nDescent);
SIZE size = ME_GetRunSizeCommon(c, para, run, nEnd, startx,
&run->nAscent, &run->nDescent);
run->nWidth = size.cx;
if (!size.cx)
WARN("size.cx == 0\n");

View file

@ -74,7 +74,7 @@ CHARFORMAT2W *ME_ToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from)
void ME_CopyToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from)
{
if (ME_ToCF2W(to, from) == from)
CopyMemory(to, from, sizeof(*from));
*to = *from;
}
CHARFORMAT2W *ME_ToCFAny(CHARFORMAT2W *to, CHARFORMAT2W *from)
@ -154,7 +154,7 @@ ME_Style *ME_MakeStyle(CHARFORMAT2W *style) {
if (style->cbSize <= sizeof(CHARFORMAT2W))
CopyMemory(&s->fmt, style, style->cbSize);
else
CopyMemory(&s->fmt, style, sizeof(CHARFORMAT2W));
s->fmt = *style;
s->fmt.cbSize = sizeof(CHARFORMAT2W);
s->nSequence = -2;
@ -218,7 +218,6 @@ ME_Style *ME_ApplyStyle(ME_Style *sSrc, CHARFORMAT2W *style)
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;
}
@ -230,7 +229,7 @@ void ME_CopyCharFormat(CHARFORMAT2W *pDest, const CHARFORMAT2W *pSrc)
/* using this with non-2W structs is forbidden */
assert(pSrc->cbSize == sizeof(CHARFORMAT2W));
assert(pDest->cbSize == sizeof(CHARFORMAT2W));
CopyMemory(pDest, pSrc, sizeof(CHARFORMAT2W));
*pDest = *pSrc;
}
static void ME_DumpStyleEffect(char **p, const char *name, const CHARFORMAT2W *fmt, int mask)
@ -262,12 +261,12 @@ void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048])
p += sprintf(p, "N/A");
if (pFmt->dwMask & CFM_SIZE)
p += sprintf(p, "\nFont size: %d\n", (int)pFmt->yHeight);
p += sprintf(p, "\nFont size: %d\n", pFmt->yHeight);
else
p += sprintf(p, "\nFont size: N/A\n");
if (pFmt->dwMask & CFM_OFFSET)
p += sprintf(p, "Char offset: %d\n", (int)pFmt->yOffset);
p += sprintf(p, "Char offset: %d\n", pFmt->yOffset);
else
p += sprintf(p, "Char offset: N/A\n");
@ -304,9 +303,9 @@ ME_LogFontFromStyle(ME_Context* c, LOGFONTW *lf, const ME_Style *s)
lf->lfHeight = ME_twips2pointsY(c, -s->fmt.yHeight);
lf->lfWeight = 400;
lf->lfWeight = FW_NORMAL;
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_BOLD)
lf->lfWeight = 700;
lf->lfWeight = FW_BOLD;
if (s->fmt.dwMask & CFM_WEIGHT)
lf->lfWeight = s->fmt.wWeight;
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_ITALIC)
@ -338,7 +337,7 @@ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt)
fmt->dwMask = CFM_WEIGHT|CFM_BOLD|CFM_ITALIC|CFM_UNDERLINE|CFM_STRIKEOUT|CFM_SIZE|CFM_FACE|CFM_CHARSET;
fmt->wWeight = lf->lfWeight;
fmt->yHeight = -lf->lfHeight*1440/ry;
if (lf->lfWeight>400) fmt->dwEffects |= CFM_BOLD;
if (lf->lfWeight > FW_NORMAL) fmt->dwEffects |= CFM_BOLD;
if (lf->lfItalic) fmt->dwEffects |= CFM_ITALIC;
if (lf->lfUnderline) fmt->dwEffects |= CFM_UNDERLINE;
/* notice that if a logfont was created with underline due to CFM_LINK, this
@ -404,7 +403,7 @@ HFONT ME_SelectStyleFont(ME_Context *c, ME_Style *s)
TRACE_(richedit_style)("font created %d\n", nEmpty);
item->hFont = s->hFont;
item->nRefs = 1;
memcpy(&item->lfSpecs, &lf, sizeof(LOGFONTW));
item->lfSpecs = lf;
}
hOldFont = SelectObject(c->hDC, s->hFont);
/* should be cached too, maybe ? */

View file

@ -62,15 +62,21 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
break;
case diUndoSetParagraphFormat:
assert(pdi);
CopyMemory(&pItem->member.para, &pdi->member.para, sizeof(ME_Paragraph));
pItem->member.para = pdi->member.para;
pItem->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2);
CopyMemory(pItem->member.para.pFmt, pdi->member.para.pFmt, sizeof(PARAFORMAT2));
*pItem->member.para.pFmt = *pdi->member.para.pFmt;
break;
case diUndoInsertRun:
assert(pdi);
CopyMemory(&pItem->member.run, &pdi->member.run, sizeof(ME_Run));
pItem->member.run = pdi->member.run;
pItem->member.run.strText = ME_StrDup(pItem->member.run.strText);
ME_AddRefStyle(pItem->member.run.style);
if (pdi->member.run.ole_obj)
{
pItem->member.run.ole_obj = ALLOC_OBJ(*pItem->member.run.ole_obj);
ME_CopyReObject(pItem->member.run.ole_obj, pdi->member.run.ole_obj);
}
else pItem->member.run.ole_obj = NULL;
break;
case diUndoSetCharFormat:
case diUndoSetDefaultCharFormat:
@ -221,7 +227,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
new_para = ME_SplitParagraph(editor, tmp.pRun, tmp.pRun->member.run.style);
assert(pItem->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
CopyMemory(new_para->member.para.pFmt, pItem->member.para.pFmt, sizeof(PARAFORMAT2));
*new_para->member.para.pFmt = *pItem->member.para.pFmt;
break;
}
default:

View file

@ -47,7 +47,11 @@ static void ME_BeginRow(ME_WrapContext *wc)
wc->pRowStart = NULL;
wc->bOverflown = FALSE;
wc->pLastSplittableRun = NULL;
wc->nAvailWidth = wc->nTotalWidth - (wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
if (wc->context->editor->bWordWrap)
wc->nAvailWidth = wc->context->rcView.right - wc->context->rcView.left -
(wc->nRow ? wc->nLeftMargin : wc->nFirstMargin) - wc->nRightMargin;
else
wc->nAvailWidth = ~0u >> 1;
wc->pt.x = 0;
}
@ -117,7 +121,8 @@ static void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p)
ME_UpdateRunFlags(wc->context->editor, &p->member.run);
ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para, &p->member.run);
ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para,
wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, &p->member.run);
}
static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, int i)
@ -128,7 +133,7 @@ static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, i
return NULL;
j = ME_ReverseFindNonWhitespaceV(p->member.run.strText, i);
if (j>0) {
pp = ME_SplitRun(wc->context, piter, j);
pp = ME_SplitRun(wc, piter, j);
wc->pt.x += piter->member.run.nWidth;
return pp;
}
@ -147,7 +152,7 @@ static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, i
if (piter->member.run.nFlags & MERF_ENDWHITE)
{
j = ME_ReverseFindNonWhitespaceV(piter->member.run.strText, i);
pp = ME_SplitRun(wc->context, piter, i);
pp = ME_SplitRun(wc, piter, i);
wc->pt = pp->member.run.pt;
return pp;
}
@ -202,7 +207,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem
if (i == len)
i = ME_ReverseFindNonWhitespaceV(run->strText, len);
if (i) {
ME_DisplayItem *piter2 = ME_SplitRun(wc->context, piter, i);
ME_DisplayItem *piter2 = ME_SplitRun(wc, piter, i);
wc->pt = piter2->member.run.pt;
return piter2;
}
@ -219,7 +224,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem
TRACE("Backtracking failed, trying desperate: %s\n", debugstr_w(p->member.run.strText->szData));
/* OK, no better idea, so assume we MAY split words if we can split at all*/
if (idesp)
return ME_SplitRun(wc->context, piter, idesp);
return ME_SplitRun(wc, piter, idesp);
else
if (wc->pRowStart && piter != wc->pRowStart)
{
@ -235,7 +240,7 @@ static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem
int pos2 = ME_StrRelPos(run->strText, 0, &chars);
if (pos2 != len) {
/* the run is more than 1 char, so we may split */
return ME_SplitRun(wc->context, piter, pos2);
return ME_SplitRun(wc, piter, pos2);
}
/* the run is one char, can't split it */
return piter;
@ -272,7 +277,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
black = ME_FindNonWhitespaceV(run->strText, 0);
if (black) {
wc->bOverflown = FALSE;
pp = ME_SplitRun(wc->context, p, black);
pp = ME_SplitRun(wc, p, black);
p->member.run.nFlags |= MERF_SKIPPED;
ME_InsertRowStart(wc, pp);
return pp;
@ -282,7 +287,20 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
ME_InsertRowStart(wc, p);
return p;
}
/* simply end the current row and move on to next one */
if (run->nFlags & MERF_ENDROW)
{
p = p->next;
ME_InsertRowStart(wc, p);
return p;
}
/* we're not at the end of the row */
if (run->nFlags & MERF_TAB) {
/* force recomputation of tabs' size as it depends on position */
ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para,
wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run);
}
/* will current run fit? */
if (wc->pt.x + run->nWidth > wc->nAvailWidth)
{
@ -293,8 +311,13 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
wc->bOverflown = TRUE;
return p;
}
/* graphics or TAB - we can split before */
if (run->nFlags & (MERF_GRAPHICS|MERF_TAB)) {
/* TAB: we can split before */
if (run->nFlags & MERF_TAB) {
wc->bOverflown = TRUE;
return p;
}
/* graphics: we can split before, if run's width is smaller than row's width */
if ((run->nFlags & MERF_GRAPHICS) && run->nWidth <= wc->nAvailWidth) {
wc->bOverflown = TRUE;
return p;
}
@ -303,7 +326,7 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
{
/* we aren't sure if it's *really* necessary, it's a good start however */
int black = ME_ReverseFindNonWhitespaceV(run->strText, len);
ME_SplitRun(wc->context, p, black);
ME_SplitRun(wc, p, black);
/* handle both parts again */
return p;
}
@ -354,7 +377,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD begino
/* wc.para_style = tp->member.para.style; */
wc.style = NULL;
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.nLeftMargin = wc.nFirstMargin + ME_twips2pointsX(c, tp->member.para.pFmt->dxOffset);
wc.nRightMargin = ME_twips2pointsX(c, tp->member.para.pFmt->dxRightIndent);
wc.nRow = 0;
wc.pt.x = 0;
@ -374,8 +397,10 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp, DWORD begino
wc.pt.y += border;
}
wc.nTotalWidth = c->rcView.right - c->rcView.left;
wc.nAvailWidth = wc.nTotalWidth - wc.nFirstMargin - wc.nRightMargin;
if (c->editor->bWordWrap)
wc.nAvailWidth = c->rcView.right - c->rcView.left - wc.nFirstMargin - wc.nRightMargin;
else
wc.nAvailWidth = ~0u >> 1;
wc.pRowStart = NULL;
linespace = ME_GetParaLineSpace(c, &tp->member.para);
@ -442,14 +467,12 @@ static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
}
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
HWND hWnd = editor->hWnd;
HDC hDC = GetDC(hWnd);
ME_DisplayItem *item;
ME_Context c;
BOOL bModified = FALSE;
int yStart = -1, yEnd = -1;
ME_InitContext(&c, editor, hDC);
ME_InitContext(&c, editor, GetDC(editor->hWnd));
c.pt.x = 0;
c.pt.y = 0;
editor->nHeight = 0;
@ -485,9 +508,8 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
editor->nTotalLength = c.pt.y;
ME_DestroyContext(&c);
ReleaseDC(hWnd, hDC);
ME_DestroyContext(&c, editor->hWnd);
if (bModified || editor->nTotalLength < editor->nLastTotalLength)
ME_InvalidateMarkedParagraphs(editor);
return bModified;
@ -495,9 +517,8 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor) {
ME_Context c;
HDC hDC = GetDC(editor->hWnd);
ME_InitContext(&c, editor, hDC);
ME_InitContext(&c, editor, GetDC(editor->hWnd));
if (editor->bRedraw)
{
RECT rc = c.rcView;
@ -519,8 +540,7 @@ void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor) {
InvalidateRect(editor->hWnd, &rc, TRUE);
}
}
ME_DestroyContext(&c);
ReleaseDC(editor->hWnd, hDC);
ME_DestroyContext(&c, editor->hWnd);
}

View file

@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include "editor.h"
#include "rtf.h"
@ -711,6 +714,10 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
nChars--;
if (editor->bEmulateVersion10 && nChars)
nChars--;
} else if (p->member.run.nFlags & MERF_ENDROW) {
if (!ME_StreamOutPrint(pStream, "\\line \r\n"))
return FALSE;
nChars--;
} else {
int nEnd;