When OLE object provides IViewObject::Draw, Richedit can draw it even though the OLE object does not support CF_BITMAP nor CF_ENHMETAFILE.
Signed-off-by: Dongwan Kim kdw6485@gmail.com --- dlls/riched20/richole.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 03572511ff7..1a62f0b9f36 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -5653,6 +5653,7 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) STGMEDIUM stgm; DIBSECTION dibsect; ENHMETAHEADER emh; + int pixs;
assert(run->nFlags & MERF_GRAPHICS); assert(run->reobj); @@ -5691,8 +5692,13 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) { - FIXME("unsupported format\n"); - pSize->cx = pSize->cy = 0; + if( IOleObject_GetExtent(run->reobj->obj.poleobj, DVASPECT_CONTENT, pSize) != S_OK){ + FIXME("unsupported format\n"); + pSize->cx = pSize->cy = 0; + } + pixs = GetDeviceCaps(c->hDC, LOGPIXELSX); + pSize->cx = MulDiv(pSize->cx, pixs , 2540); + pSize->cy = MulDiv(pSize->cy, pixs , 2540); IDataObject_Release(ido); return; } @@ -5735,6 +5741,8 @@ void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected ) BOOL has_size; HBITMAP old_bm; RECT rc; + HRESULT hr; + int pixs;
assert(run->nFlags & MERF_GRAPHICS); assert(run->reobj); @@ -5755,7 +5763,17 @@ void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected ) fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK) { - FIXME("Couldn't get storage medium\n"); + IOleObject_GetExtent(run->reobj->obj.poleobj, DVASPECT_CONTENT, &sz); + pixs = GetDeviceCaps(c->hDC, LOGPIXELSX); + rc.left = x; + rc.top = y - MulDiv(sz.cy, pixs, 2540); + rc.right = x + MulDiv(sz.cx, pixs, 2540); + rc.bottom = y ; + hr = OleDraw(run->reobj->obj.poleobj, DVASPECT_CONTENT, c->hDC, &rc); + if (FAILED(hr)) + { + FIXME("Couldn't draw ole object\n"); + } IDataObject_Release(ido); return; }
The character position should be filled in REOBJECT which IRichEditOle::GetObject returns.
Signed-off-by: Dongwan Kim kdw6485@gmail.com --- dlls/riched20/caret.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index beac8af50a1..9e1bb17b7f4 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -462,6 +462,7 @@ void editor_insert_oleobj(ME_TextEditor *editor, const REOBJECT *reo) struct re_object *reobj_prev = NULL; ME_Cursor *cursor, cursor_from_ofs; ME_Style *style; + LONG cp = 0;
if (reo->cp == REO_CP_SELECTION) cursor = editor->pCursors; @@ -482,12 +483,16 @@ void editor_insert_oleobj(ME_TextEditor *editor, const REOBJECT *reo) prev = run; while ((prev = run_prev_all_paras( prev ))) { + cp += prev->len; if (prev->reobj) { reobj_prev = prev->reobj; + cp += prev->reobj->obj.cp; break; } } + if(run->reobj->obj.cp == REO_CP_SELECTION) + run->reobj->obj.cp = cp; if (reobj_prev) list_add_after(&reobj_prev->entry, &run->reobj->entry); else
Signed-off-by: Dongwan Kim kdw6485@gmail.com --- dlls/riched20/tests/richole.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index 9449c6b58cc..d68bf1149ae 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -3296,6 +3296,11 @@ static void test_InsertObject(void) CHECK_REOBJECT_STRUCT(reole, 1, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo3.polesite, 3); CHECK_REOBJECT_STRUCT(reole, 2, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL, reo2.polesite, 2);
+ received_reo.cbStruct = sizeof(received_reo); + hr = IRichEditOle_GetObject(reole, 1, &received_reo, REO_GETOBJ_ALL_INTERFACES); + ok( received_reo.cp == 1 , "IRichEditOle_GetObject should fill the cp of structure REOBJ."); + + hr = IRichEditOle_GetObject(reole, 2, NULL, REO_GETOBJ_ALL_INTERFACES); ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
The font collection saves the facename, while is_font_installed_proc returns fullname. It can be a trouble to some fonts. For example, The font '맑은 고딕', which is the basic korean font in windows, has the fullname 'Malgun Gothic'. In that case, GdipCreateFontFamilyFromName failed even though the font was installed.
Signed-off-by: Dongwan Kim kdw6485@gmail.com --- dlls/gdiplus/font.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/gdiplus/font.c b/dlls/gdiplus/font.c index 44431ea2ac8..565089b722e 100644 --- a/dlls/gdiplus/font.c +++ b/dlls/gdiplus/font.c @@ -1581,6 +1581,7 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, HFONT hfont, old_hfont; struct font_metrics fm; int i; + const ENUMLOGFONTW *elfW = (const ENUMLOGFONTW*)lfw;
param->stat = Ok;
@@ -1655,7 +1656,7 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm, family->installed = param->is_system; family->ref = 1;
- lstrcpyW(family->FamilyName, lfw->lfFaceName); + lstrcpynW(family->FamilyName, elfW->elfFullName, LF_FACESIZE);
fonts->FontFamilies[fonts->count++] = family;
I would like to see some tests for this. The existing test_long_name function should be a good place to add them.
I'd like the tests to verify that GdipCreateFontFamilyFromName works now, and that GdipGetFamilyName and GdipGetLogFontW return the correct names, since all of these are affected by changing the stored FamilyName.
It turned out that it was my mistake. I found this issue on wine-6.7 and gdiplus/font.c file has not been changed for the font collection. I assumed that It would happen on latest wine too. But it does not. I guess some patches on win32u/font.c solved the problem.
I will drop this patch at the next submission.
I want other pathces to be reviewed.
Thanks.
Dongwan Kim.
It turned out that it was my mistake. I found this issue on wine-6.7 and the gdiplus/font.c file has not been changed for the font collection. I assumed that It would happen on the latest wine too. But it does not. I guess some patches on win32u/font.c solved the problem.
I will drop this patch at the next submission.
I want other patches to be reviewed.
Thanks.
Dongwan Kim.
On 11/22/21 17:32, Dongwan Kim wrote:
When OLE object provides IViewObject::Draw, Richedit can draw it even though the OLE object does not support CF_BITMAP nor CF_ENHMETAFILE.
Signed-off-by: Dongwan Kim kdw6485@gmail.com
Would you resubmit patches with following feedback applied? Conformance tests would be appreciated too (hint: use OleCreateDefaultHandler to reduce the amount of work to fake an OLE object).
dlls/riched20/richole.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 03572511ff7..1a62f0b9f36 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -5653,6 +5653,7 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) STGMEDIUM stgm; DIBSECTION dibsect; ENHMETAHEADER emh;
int pixs;
assert(run->nFlags & MERF_GRAPHICS); assert(run->reobj);
@@ -5691,8 +5692,13 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
I suppose native would prefer IViewObject over IDataObject; however, this needs tests for what native actually does.
{
FIXME("unsupported format\n");
pSize->cx = pSize->cy = 0;
if( IOleObject_GetExtent(run->reobj->obj.poleobj, DVASPECT_CONTENT, pSize) != S_OK){
Maybe prefer IViewObject2::GetExtent if available? This needs tests as well. Also, use the FAILED() macro.
FIXME("unsupported format\n");
pSize->cx = pSize->cy = 0;
}
pixs = GetDeviceCaps(c->hDC, LOGPIXELSX);
pSize->cx = MulDiv(pSize->cx, pixs , 2540);
pSize->cy = MulDiv(pSize->cy, pixs , 2540);
You can use the convert_sizel() helper instead.
IDataObject_Release(ido); return; }
@@ -5735,6 +5741,8 @@ void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected ) BOOL has_size; HBITMAP old_bm; RECT rc;
HRESULT hr;
int pixs;
assert(run->nFlags & MERF_GRAPHICS); assert(run->reobj);
@@ -5755,7 +5763,17 @@ void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected ) fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
Also here, IViewObject preference (if native does it).
{
FIXME("Couldn't get storage medium\n");
IOleObject_GetExtent(run->reobj->obj.poleobj, DVASPECT_CONTENT, &sz);
pixs = GetDeviceCaps(c->hDC, LOGPIXELSX);
rc.left = x;
rc.top = y - MulDiv(sz.cy, pixs, 2540);
rc.right = x + MulDiv(sz.cx, pixs, 2540);
rc.bottom = y ;
Use convert_sizel() here as well.
hr = OleDraw(run->reobj->obj.poleobj, DVASPECT_CONTENT, c->hDC, &rc);
if (FAILED(hr))
{
FIXME("Couldn't draw ole object\n");
}} IDataObject_Release(ido); return;
On 3/31/22 01:37, Jinoh Kang wrote:
On 11/22/21 17:32, Dongwan Kim wrote:
When OLE object provides IViewObject::Draw, Richedit can draw it even though the OLE object does not support CF_BITMAP nor CF_ENHMETAFILE.
Signed-off-by: Dongwan Kim kdw6485@gmail.com
Would you resubmit patches with following feedback applied? Conformance tests would be appreciated too (hint: use OleCreateDefaultHandler to reduce the amount of work to fake an OLE object).
Also, put this line just before signoff:
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52752
dlls/riched20/richole.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 03572511ff7..1a62f0b9f36 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -5653,6 +5653,7 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) STGMEDIUM stgm; DIBSECTION dibsect; ENHMETAHEADER emh;
int pixs;
assert(run->nFlags & MERF_GRAPHICS); assert(run->reobj);
@@ -5691,8 +5692,13 @@ void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
I suppose native would prefer IViewObject over IDataObject; however, this needs tests for what native actually does.
{
FIXME("unsupported format\n");
pSize->cx = pSize->cy = 0;
if( IOleObject_GetExtent(run->reobj->obj.poleobj, DVASPECT_CONTENT, pSize) != S_OK){
Maybe prefer IViewObject2::GetExtent if available? This needs tests as well. Also, use the FAILED() macro.
FIXME("unsupported format\n");
pSize->cx = pSize->cy = 0;
}
pixs = GetDeviceCaps(c->hDC, LOGPIXELSX);
pSize->cx = MulDiv(pSize->cx, pixs , 2540);
pSize->cy = MulDiv(pSize->cy, pixs , 2540);
You can use the convert_sizel() helper instead.
IDataObject_Release(ido); return; }
@@ -5735,6 +5741,8 @@ void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected ) BOOL has_size; HBITMAP old_bm; RECT rc;
HRESULT hr;
int pixs;
assert(run->nFlags & MERF_GRAPHICS); assert(run->reobj);
@@ -5755,7 +5763,17 @@ void draw_ole( ME_Context *c, int x, int y, ME_Run *run, BOOL selected ) fmt.tymed = TYMED_ENHMF; if (IDataObject_GetData(ido, &fmt, &stgm) != S_OK)
Also here, IViewObject preference (if native does it).
{
FIXME("Couldn't get storage medium\n");
IOleObject_GetExtent(run->reobj->obj.poleobj, DVASPECT_CONTENT, &sz);
pixs = GetDeviceCaps(c->hDC, LOGPIXELSX);
rc.left = x;
rc.top = y - MulDiv(sz.cy, pixs, 2540);
rc.right = x + MulDiv(sz.cx, pixs, 2540);
rc.bottom = y ;
Use convert_sizel() here as well.
hr = OleDraw(run->reobj->obj.poleobj, DVASPECT_CONTENT, c->hDC, &rc);
if (FAILED(hr))
{
FIXME("Couldn't draw ole object\n");
}} IDataObject_Release(ido); return;