mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
Sync to Wine-20050524:
Alexandre Julliard <[email protected]> - Added rules for building import libraries in the individual dll makefiles, and added support for building a .def.a static import library too. Michael Stefaniuc <[email protected]> - Reimplement VarMul(). It can multiply now all variants that the native (WinXP) function supports too. - Fix VariantChangeType: calls to VarDecFromCy and VarDecFromDisp had source and destination swapped. Richard Cohen <[email protected]> - Remove unused macro. - Check for VT_I8 before testing it. - VarMod returns DISP_E_OVERFLOW not E_INVALIDARG. Robert Shearman <[email protected]> - Use I_RpcGetBuffer instead of HeapReAlloc for getting the Buffer memory. Vincent Beron <[email protected]> - Use SUBLANG_NEUTRAL for French resources. Alex Villacis Lasso <[email protected]> - Fix leftover negative sign in height parameter for transparent bitmap. - Properly announce whether bitmap is transparent in get_Attributes. - GIF transparency is now palette-index based, instead of RGB based. - Keep original bitmap and XOR mask separate, so that get_Handle returns original bitmap. svn path=/trunk/; revision=15563
This commit is contained in:
@@ -4,6 +4,7 @@ TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
MODULE = oleaut32.dll
|
||||
IMPORTLIB = liboleaut32.$(IMPLIBEXT)
|
||||
IMPORTS = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll
|
||||
DELAYIMPORTS = comctl32 urlmon
|
||||
EXTRALIBS = $(LIBUNICODE) -luuid
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT
|
||||
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
{
|
||||
|
||||
@@ -132,6 +132,7 @@ typedef struct OLEPictureImpl {
|
||||
|
||||
/* Bitmap transparency mask */
|
||||
HBITMAP hbmMask;
|
||||
HBITMAP hbmXor;
|
||||
COLORREF rgbTrans;
|
||||
|
||||
/* data */
|
||||
@@ -262,6 +263,7 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
|
||||
newObject->keepOrigFormat = TRUE;
|
||||
|
||||
newObject->hbmMask = NULL;
|
||||
newObject->hbmXor = NULL;
|
||||
newObject->loadtime_magic = 0xdeadbeef;
|
||||
newObject->loadtime_format = 0;
|
||||
newObject->bIsDirty = FALSE;
|
||||
@@ -320,6 +322,8 @@ static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
|
||||
switch(Obj->desc.picType) {
|
||||
case PICTYPE_BITMAP:
|
||||
DeleteObject(Obj->desc.u.bmp.hbitmap);
|
||||
if (Obj->hbmMask != NULL) DeleteObject(Obj->hbmMask);
|
||||
if (Obj->hbmXor != NULL) DeleteObject(Obj->hbmXor);
|
||||
break;
|
||||
case PICTYPE_METAFILE:
|
||||
DeleteMetaFile(Obj->desc.u.wmf.hmeta);
|
||||
@@ -588,12 +592,12 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
|
||||
SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
|
||||
SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
|
||||
|
||||
hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
|
||||
|
||||
if (This->hbmMask) {
|
||||
HDC hdcMask = CreateCompatibleDC(0);
|
||||
HBITMAP hOldbm = SelectObject(hdcMask, This->hbmMask);
|
||||
|
||||
hbmpOld = SelectObject(hdcBmp, This->hbmXor);
|
||||
|
||||
SetMapMode(hdcMask, MM_ANISOTROPIC);
|
||||
SetWindowOrgEx(hdcMask, 0, 0, NULL);
|
||||
SetWindowExtEx(hdcMask, This->himetricWidth, This->himetricHeight, NULL);
|
||||
@@ -607,8 +611,10 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
|
||||
|
||||
SelectObject(hdcMask, hOldbm);
|
||||
DeleteDC(hdcMask);
|
||||
} else
|
||||
} else {
|
||||
hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
|
||||
StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
|
||||
}
|
||||
|
||||
SelectObject(hdcBmp, hbmpOld);
|
||||
DeleteDC(hdcBmp);
|
||||
@@ -739,7 +745,7 @@ static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
|
||||
TRACE("(%p)->(%p).\n", This, pdwAttr);
|
||||
*pdwAttr = 0;
|
||||
switch (This->desc.picType) {
|
||||
case PICTYPE_BITMAP: break; /* not 'truly' scalable, see MSDN. */
|
||||
case PICTYPE_BITMAP: if (This->hbmMask) *pdwAttr = PICTURE_TRANSPARENT; break; /* not 'truly' scalable, see MSDN. */
|
||||
case PICTYPE_ICON: *pdwAttr = PICTURE_TRANSPARENT;break;
|
||||
case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break;
|
||||
default:FIXME("Unknown pictype %d\n",This->desc.picType);break;
|
||||
@@ -1175,15 +1181,60 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
|
||||
HBITMAP hOldbitmap;
|
||||
HBITMAP hOldbitmapmask;
|
||||
|
||||
This->hbmMask = CreateBitmap(bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 1, 1, NULL);
|
||||
unsigned int monopadding = (((unsigned)(gif->SWidth + 31)) >> 5) << 2;
|
||||
HBITMAP hTempMask;
|
||||
|
||||
hOldbitmap = SelectObject(hdc,This->desc.u.bmp.hbitmap);
|
||||
This->hbmXor = CreateDIBitmap(
|
||||
hdcref,
|
||||
&bmi->bmiHeader,
|
||||
CBM_INIT,
|
||||
bytes,
|
||||
bmi,
|
||||
DIB_RGB_COLORS
|
||||
);
|
||||
|
||||
bmi->bmiColors[0].rgbRed = 0;
|
||||
bmi->bmiColors[0].rgbGreen = 0;
|
||||
bmi->bmiColors[0].rgbBlue = 0;
|
||||
bmi->bmiColors[1].rgbRed = 255;
|
||||
bmi->bmiColors[1].rgbGreen = 255;
|
||||
bmi->bmiColors[1].rgbBlue = 255;
|
||||
|
||||
bmi->bmiHeader.biBitCount = 1;
|
||||
bmi->bmiHeader.biSizeImage = monopadding*gif->SHeight;
|
||||
bmi->bmiHeader.biClrUsed = 2;
|
||||
|
||||
for (i = 0; i < gif->SHeight; i++) {
|
||||
unsigned char * colorPointer = bytes + padding * i;
|
||||
unsigned char * monoPointer = bytes + monopadding * i;
|
||||
for (j = 0; j < gif->SWidth; j++) {
|
||||
unsigned char pixel = colorPointer[j];
|
||||
if ((j & 7) == 0) monoPointer[j >> 3] = 0;
|
||||
if (pixel == (transparent & 0x000000FFU)) monoPointer[j >> 3] |= 1 << (7 - (j & 7));
|
||||
}
|
||||
}
|
||||
hdcref = GetDC(0);
|
||||
hTempMask = CreateDIBitmap(
|
||||
hdcref,
|
||||
&bmi->bmiHeader,
|
||||
CBM_INIT,
|
||||
bytes,
|
||||
bmi,
|
||||
DIB_RGB_COLORS
|
||||
);
|
||||
DeleteDC(hdcref);
|
||||
|
||||
bmi->bmiHeader.biHeight = -bmi->bmiHeader.biHeight;
|
||||
This->hbmMask = CreateBitmap(bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, 1, 1, NULL);
|
||||
hOldbitmap = SelectObject(hdc, hTempMask);
|
||||
hOldbitmapmask = SelectObject(hdcMask, This->hbmMask);
|
||||
SetBkColor(hdc, This->rgbTrans);
|
||||
|
||||
SetBkColor(hdc, RGB(255, 255, 255));
|
||||
BitBlt(hdcMask, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, hdc, 0, 0, SRCCOPY);
|
||||
|
||||
/* We no longer need the original bitmap, so we apply the first
|
||||
transformation with the mask to speed up the rendering */
|
||||
SelectObject(hdc, This->hbmXor);
|
||||
SetBkColor(hdc, RGB(0,0,0));
|
||||
SetTextColor(hdc, RGB(255,255,255));
|
||||
BitBlt(hdc, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight,
|
||||
@@ -1193,6 +1244,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
|
||||
SelectObject(hdcMask, hOldbitmapmask);
|
||||
DeleteDC(hdcMask);
|
||||
DeleteDC(hdc);
|
||||
DeleteObject(hTempMask);
|
||||
}
|
||||
|
||||
DeleteDC(hdcref);
|
||||
|
||||
@@ -1979,7 +1979,8 @@ TMStubImpl_Invoke(
|
||||
|
||||
memset(&buf,0,sizeof(buf));
|
||||
buf.size = xmsg->cbBuffer;
|
||||
buf.base = xmsg->Buffer;
|
||||
buf.base = HeapAlloc(GetProcessHeap(), 0, xmsg->cbBuffer);
|
||||
memcpy(buf.base, xmsg->Buffer, xmsg->cbBuffer);
|
||||
buf.curoff = 0;
|
||||
buf.iid = IID_IUnknown;
|
||||
|
||||
@@ -2173,9 +2174,9 @@ afterserialize:
|
||||
if (hres != S_OK)
|
||||
return hres;
|
||||
|
||||
/* might need to use IRpcChannelBuffer_GetBuffer ? */
|
||||
xmsg->cbBuffer = buf.curoff;
|
||||
xmsg->Buffer = buf.base;
|
||||
I_RpcGetBuffer((RPC_MESSAGE *)xmsg);
|
||||
memcpy(xmsg->Buffer, buf.base, buf.curoff);
|
||||
HeapFree(GetProcessHeap(),0,args);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
+154
-44
@@ -493,8 +493,8 @@ static inline HRESULT VARIANT_Coerce(VARIANTARG* pd, LCID lcid, USHORT wFlags,
|
||||
case VT_R4: return VarDecFromR4(V_R4(ps), &V_DECIMAL(pd));
|
||||
case VT_R8: return VarDecFromR8(V_R8(ps), &V_DECIMAL(pd));
|
||||
case VT_DATE: return VarDecFromDate(V_DATE(ps), &V_DECIMAL(pd));
|
||||
case VT_CY: return VarDecFromCy(V_CY(pd), &V_DECIMAL(ps));
|
||||
case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(ps));
|
||||
case VT_CY: return VarDecFromCy(V_CY(ps), &V_DECIMAL(pd));
|
||||
case VT_DISPATCH: return VarDecFromDisp(V_DISPATCH(ps), lcid, &V_DECIMAL(pd));
|
||||
case VT_BSTR: return VarDecFromStr(V_BSTR(ps), lcid, dwFlags, &V_DECIMAL(pd));
|
||||
}
|
||||
break;
|
||||
@@ -2914,58 +2914,168 @@ HRESULT WINAPI VarAdd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
||||
/**********************************************************************
|
||||
* VarMul [OLEAUT32.156]
|
||||
*
|
||||
* Multiply two variants.
|
||||
*
|
||||
* PARAMS
|
||||
* left [I] First variant
|
||||
* right [I] Second variant
|
||||
* result [O] Result variant
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK.
|
||||
* Failure: An HRESULT error code indicating the error.
|
||||
*
|
||||
* NOTES
|
||||
* Native VarMul up to and including WinXP dosn't like as input variants
|
||||
* I1, UI2, UI4, UI8, INT and UINT. But it can multiply apples with oranges.
|
||||
*
|
||||
* Native VarMul dosn't check for NULL in/out pointers and crashes. We do the
|
||||
* same here.
|
||||
*
|
||||
* FIXME
|
||||
* Overflow checking for R8 (double) overflow. Return DISP_E_OVERFLOW in that
|
||||
* case.
|
||||
*/
|
||||
HRESULT WINAPI VarMul(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
||||
{
|
||||
HRESULT rc = E_FAIL;
|
||||
VARTYPE lvt,rvt,resvt;
|
||||
VARIANT lv,rv;
|
||||
BOOL found;
|
||||
HRESULT hres;
|
||||
VARTYPE lvt, rvt, resvt, tvt;
|
||||
VARIANT lv, rv, tv;
|
||||
double r8res;
|
||||
|
||||
/* Variant priority for coercion. Sorted from lowest to highest.
|
||||
VT_ERROR shows an invalid input variant type. */
|
||||
enum coerceprio { vt_UI1 = 0, vt_I2, vt_I4, vt_I8, vt_CY, vt_R4, vt_R8,
|
||||
vt_DECIMAL, vt_NULL, vt_ERROR };
|
||||
/* Mapping from priority to variant type. Keep in sync with coerceprio! */
|
||||
VARTYPE prio2vt[] = { VT_UI1, VT_I2, VT_I4, VT_I8, VT_CY, VT_R4, VT_R8,
|
||||
VT_DECIMAL, VT_NULL, VT_ERROR };
|
||||
|
||||
/* Mapping for coercion from input variant to priority of result variant. */
|
||||
static VARTYPE coerce[] = {
|
||||
/* VT_EMPTY, VT_NULL, VT_I2, VT_I4, VT_R4 */
|
||||
vt_UI1, vt_NULL, vt_I2, vt_I4, vt_R4,
|
||||
/* VT_R8, VT_CY, VT_DATE, VT_BSTR, VT_DISPATCH */
|
||||
vt_R8, vt_CY, vt_R8, vt_R8, vt_ERROR,
|
||||
/* VT_ERROR, VT_BOOL, VT_VARIANT, VT_UNKNOWN, VT_DECIMAL */
|
||||
vt_ERROR, vt_I2, vt_ERROR, vt_ERROR, vt_DECIMAL,
|
||||
/* 15, VT_I1, VT_UI1, VT_UI2, VT_UI4 VT_I8 */
|
||||
vt_ERROR, vt_ERROR, vt_UI1, vt_ERROR, vt_ERROR, vt_I8
|
||||
};
|
||||
|
||||
TRACE("(%p->(%s%s),%p->(%s%s),%p)\n", left, debugstr_VT(left),
|
||||
debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right), result);
|
||||
debugstr_VF(left), right, debugstr_VT(right), debugstr_VF(right),
|
||||
result);
|
||||
|
||||
VariantInit(&lv);VariantInit(&rv);
|
||||
VariantInit(&lv);
|
||||
VariantInit(&rv);
|
||||
VariantInit(&tv);
|
||||
lvt = V_VT(left)&VT_TYPEMASK;
|
||||
rvt = V_VT(right)&VT_TYPEMASK;
|
||||
found = FALSE;resvt=VT_VOID;
|
||||
if (((1<<lvt) | (1<<rvt)) & (VTBIT_R4|VTBIT_R8)) {
|
||||
found = TRUE;
|
||||
resvt = VT_R8;
|
||||
|
||||
/* If we have any flag set (VT_ARRAY, VT_VECTOR, etc.) bail out.
|
||||
Same for any input variant type > VT_I8 */
|
||||
if (V_VT(left) & ~VT_TYPEMASK || V_VT(right) & ~VT_TYPEMASK ||
|
||||
lvt > VT_I8 || rvt > VT_I8) {
|
||||
hres = DISP_E_BADVARTYPE;
|
||||
goto end;
|
||||
}
|
||||
if (!found && (((1<<lvt) | (1<<rvt)) & (VTBIT_I1|VTBIT_I2|VTBIT_UI1|VTBIT_UI2|VTBIT_I4|VTBIT_UI4|(1<<VT_INT)|(1<<VT_UINT)))) {
|
||||
found = TRUE;
|
||||
resvt = VT_I4;
|
||||
}
|
||||
if (!found) {
|
||||
FIXME("can't expand vt %d vs %d to a target type.\n",lvt,rvt);
|
||||
return E_FAIL;
|
||||
}
|
||||
rc = VariantChangeType(&lv, left, 0, resvt);
|
||||
if (FAILED(rc)) {
|
||||
FIXME("Could not convert 0x%x to %d?\n",V_VT(left),resvt);
|
||||
return rc;
|
||||
}
|
||||
rc = VariantChangeType(&rv, right, 0, resvt);
|
||||
if (FAILED(rc)) {
|
||||
FIXME("Could not convert 0x%x to %d?\n",V_VT(right),resvt);
|
||||
return rc;
|
||||
|
||||
/* Determine the variant type to coerce to. */
|
||||
if (coerce[lvt] > coerce[rvt]) {
|
||||
resvt = prio2vt[coerce[lvt]];
|
||||
tvt = prio2vt[coerce[rvt]];
|
||||
} else {
|
||||
resvt = prio2vt[coerce[rvt]];
|
||||
tvt = prio2vt[coerce[lvt]];
|
||||
}
|
||||
|
||||
/* Special cases where the result variant type is defined by both
|
||||
input variants and not only that with the highest priority */
|
||||
if (resvt == VT_R4 && (tvt == VT_CY || tvt == VT_I8 || tvt == VT_I4))
|
||||
resvt = VT_R8;
|
||||
if (lvt == VT_EMPTY && rvt == VT_EMPTY)
|
||||
resvt = VT_I2;
|
||||
|
||||
/* For overflow detection use the biggest compatible type for the
|
||||
multiplication */
|
||||
switch (resvt) {
|
||||
case VT_R8:
|
||||
V_VT(result) = resvt;
|
||||
V_R8(result) = V_R8(&lv) * V_R8(&rv);
|
||||
rc = S_OK;
|
||||
break;
|
||||
case VT_I4:
|
||||
V_VT(result) = resvt;
|
||||
V_I4(result) = V_I4(&lv) * V_I4(&rv);
|
||||
rc = S_OK;
|
||||
break;
|
||||
case VT_ERROR:
|
||||
hres = DISP_E_BADVARTYPE;
|
||||
goto end;
|
||||
case VT_NULL:
|
||||
hres = S_OK;
|
||||
V_VT(result) = VT_NULL;
|
||||
goto end;
|
||||
case VT_UI1:
|
||||
case VT_I2:
|
||||
case VT_I4:
|
||||
case VT_I8:
|
||||
tvt = VT_I8;
|
||||
break;
|
||||
case VT_R4:
|
||||
tvt = VT_R8;
|
||||
break;
|
||||
default:
|
||||
tvt = resvt;
|
||||
}
|
||||
TRACE("returning 0x%8lx (%s%s),%g\n", rc, debugstr_VT(result),
|
||||
debugstr_VF(result), V_VT(result) == VT_R8 ? V_R8(result) : (double)V_I4(result));
|
||||
return rc;
|
||||
|
||||
/* Now coerce the variants */
|
||||
hres = VariantChangeType(&lv, left, 0, tvt);
|
||||
if (FAILED(hres))
|
||||
goto end;
|
||||
hres = VariantChangeType(&rv, right, 0, tvt);
|
||||
if (FAILED(hres))
|
||||
goto end;
|
||||
|
||||
/* Do the math */
|
||||
hres = S_OK;
|
||||
V_VT(&tv) = tvt;
|
||||
V_VT(result) = resvt;
|
||||
switch (tvt) {
|
||||
case VT_DECIMAL:
|
||||
hres = VarDecMul(&V_DECIMAL(&lv), &V_DECIMAL(&rv),
|
||||
&V_DECIMAL(result));
|
||||
goto end;
|
||||
case VT_CY:
|
||||
hres = VarCyMul(V_CY(&lv), V_CY(&rv), &V_CY(result));
|
||||
goto end;
|
||||
case VT_I8:
|
||||
/* Overflow detection */
|
||||
r8res = (double)V_I8(&lv) * (double)V_I8(&rv);
|
||||
if (r8res > (double)I8_MAX || r8res < (double)I8_MIN) {
|
||||
V_VT(result) = VT_R8;
|
||||
V_R8(result) = r8res;
|
||||
goto end;
|
||||
} else
|
||||
V_I8(&tv) = V_I8(&lv) * V_I8(&rv);
|
||||
break;
|
||||
case VT_R8:
|
||||
/* FIXME: overflow detection */
|
||||
V_R8(&tv) = V_R8(&lv) * V_R8(&rv);
|
||||
break;
|
||||
default:
|
||||
ERR("We shouldn't get here! tvt = %d!\n", tvt);
|
||||
break;
|
||||
}
|
||||
if (rvt != tvt) {
|
||||
while ((hres = VariantChangeType(result, &tv, 0, resvt)) != S_OK) {
|
||||
/* Overflow! Change to the vartype with the next higher priority */
|
||||
resvt = prio2vt[coerce[resvt] + 1];
|
||||
}
|
||||
} else
|
||||
hres = VariantCopy(result, &tv);
|
||||
|
||||
end:
|
||||
if (hres != S_OK) {
|
||||
V_VT(result) = VT_EMPTY;
|
||||
V_I4(result) = 0; /* No V_EMPTY */
|
||||
}
|
||||
VariantClear(&lv);
|
||||
VariantClear(&rv);
|
||||
VariantClear(&tv);
|
||||
TRACE("returning 0x%8lx (variant type %s)\n", hres, debugstr_VT(result));
|
||||
return hres;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
@@ -4267,7 +4377,7 @@ HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
||||
return DISP_E_TYPEMISMATCH;
|
||||
case VT_DECIMAL:
|
||||
V_VT(result) = VT_EMPTY;
|
||||
return E_INVALIDARG;
|
||||
return DISP_E_OVERFLOW;
|
||||
case VT_ERROR:
|
||||
return DISP_E_TYPEMISMATCH;
|
||||
case VT_RECORD:
|
||||
@@ -4352,7 +4462,7 @@ HRESULT WINAPI VarMod(LPVARIANT left, LPVARIANT right, LPVARIANT result)
|
||||
} else
|
||||
{
|
||||
V_VT(result) = VT_EMPTY;
|
||||
return E_INVALIDARG;
|
||||
return DISP_E_OVERFLOW;
|
||||
}
|
||||
case VT_ERROR:
|
||||
return DISP_E_TYPEMISMATCH;
|
||||
|
||||
Reference in New Issue
Block a user