selectInfo.dwSize = sizeof(selectInfo);
selectInfo.parent = hwnd;
selectInfo.dwFlags = CRYPTUI_ENABLE_SHOW_PHYSICAL_STORE;
- selectInfo.pwszTitle = selectInfo.pwszTitle = NULL;
+ selectInfo.pwszTitle = NULL;
selectInfo.pEnumData = &enumData;
selectInfo.pfnSelectedStoreCallback = NULL;
if ((store = CryptUIDlgSelectStoreW(&selectInfo)))
return S_OK;
}
-HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme)
-{
- /* FIXME */
- return S_OK;
-}
-
static BYTE *assembly_get_blob(ASSEMBLY *assembly, WORD index, ULONG *size)
{
return GetData(&assembly->blobs[index], size);
return E_NOTIMPL;
}
-/******************************************************************
- * CompareAssemblyIdentity (FUSION.@)
- */
-HRESULT WINAPI CompareAssemblyIdentity(LPCWSTR pwzAssemblyIdentity1, BOOL fUnified1,
- LPCWSTR pwzAssemblyIdentity2, BOOL fUnified2,
- BOOL *pfEquivalent, AssemblyComparisonResult *pResult)
-{
- FIXME("(%s, %d, %s, %d, %p, %p) stub!\n", debugstr_w(pwzAssemblyIdentity1),
- fUnified1, debugstr_w(pwzAssemblyIdentity2), fUnified2, pfEquivalent, pResult);
-
- return E_NOTIMPL;
-}
-
/******************************************************************
* CreateInstallReferenceEnum (FUSION.@)
*/
return E_NOTIMPL;
}
-/******************************************************************
- * GetAssemblyIdentityFromFile (FUSION.@)
- */
-HRESULT WINAPI GetAssemblyIdentityFromFile(LPCWSTR pwzFilePath, REFIID riid,
- IUnknown **ppIdentity)
-{
- FIXME("(%s, %s, %p) stub!\n", debugstr_w(pwzFilePath), debugstr_guid(riid),
- ppIdentity);
-
- return E_NOTIMPL;
-}
-
static HRESULT (WINAPI *pGetCORVersion)(LPWSTR pbuffer, DWORD cchBuffer,
DWORD *dwLength);
HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name);
HRESULT assembly_get_path(ASSEMBLY *assembly, LPWSTR *path);
HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version);
-HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme);
HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token);
static inline LPWSTR strdupW(LPCWSTR src)
switch(brush->bt){
case BrushTypeSolidColor:
+ {
+ GpSolidFill *fill;
*clone = GdipAlloc(sizeof(GpSolidFill));
if (!*clone) return OutOfMemory;
+ fill = (GpSolidFill*)*clone;
+
memcpy(*clone, brush, sizeof(GpSolidFill));
(*clone)->gdibrush = CreateBrushIndirect(&(*clone)->lb);
+ fill->bmp = ARGB2BMP(fill->color);
break;
+ }
case BrushTypeHatchFill:
*clone = GdipAlloc(sizeof(GpHatch));
if (!*clone) return OutOfMemory;
(*sf)->brush.gdibrush = CreateSolidBrush(col);
(*sf)->brush.bt = BrushTypeSolidColor;
(*sf)->color = color;
+ (*sf)->bmp = ARGB2BMP(color);
return Ok;
}
GdipFree(((GpPathGradient*) brush)->blendpos);
break;
case BrushTypeSolidColor:
+ if (((GpSolidFill*)brush)->bmp)
+ DeleteObject(((GpSolidFill*)brush)->bmp);
break;
case BrushTypeLinearGradient:
GdipFree(((GpLineGradient*)brush)->blendfac);
(*fontCollection)->FontFamilies = NULL;
(*fontCollection)->count = 0;
+ (*fontCollection)->allocated = 0;
return Ok;
}
return Ok;
}
+void free_installed_fonts(void)
+{
+ while (installedFontCollection.count)
+ GdipDeleteFontFamily(installedFontCollection.FontFamilies[--installedFontCollection.count]);
+ HeapFree(GetProcessHeap(), 0, installedFontCollection.FontFamilies);
+ installedFontCollection.FontFamilies = NULL;
+ installedFontCollection.allocated = 0;
+}
+
+static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
+ DWORD type, LPARAM lParam)
+{
+ GpFontCollection* fonts = (GpFontCollection*)lParam;
+ int i;
+
+ /* skip duplicates */
+ for (i=0; i<fonts->count; i++)
+ if (strcmpiW(lfw->lfFaceName, fonts->FontFamilies[i]->FamilyName) == 0)
+ return 1;
+
+ if (fonts->allocated == fonts->count)
+ {
+ INT new_alloc_count = fonts->allocated+50;
+ GpFontFamily** new_family_list = HeapAlloc(GetProcessHeap(), 0, new_alloc_count*sizeof(void*));
+
+ if (!new_family_list)
+ return 0;
+
+ memcpy(new_family_list, fonts->FontFamilies, fonts->count*sizeof(void*));
+ HeapFree(GetProcessHeap(), 0, fonts->FontFamilies);
+ fonts->FontFamilies = new_family_list;
+ fonts->allocated = new_alloc_count;
+ }
+
+ if (GdipCreateFontFamilyFromName(lfw->lfFaceName, NULL, &fonts->FontFamilies[fonts->count]) == Ok)
+ fonts->count++;
+ else
+ return 0;
+
+ return 1;
+}
+
GpStatus WINGDIPAPI GdipNewInstalledFontCollection(
GpFontCollection** fontCollection)
{
- FIXME("stub: %p\n",fontCollection);
+ TRACE("(%p)\n",fontCollection);
if (!fontCollection)
return InvalidParameter;
+ if (installedFontCollection.count == 0)
+ {
+ HDC hdc;
+ LOGFONTW lfw;
+
+ hdc = GetDC(0);
+
+ lfw.lfCharSet = DEFAULT_CHARSET;
+ lfw.lfFaceName[0] = 0;
+ lfw.lfPitchAndFamily = 0;
+
+ if (!EnumFontFamiliesExW(hdc, &lfw, add_font_proc, (LPARAM)&installedFontCollection, 0))
+ {
+ free_installed_fonts();
+ ReleaseDC(0, hdc);
+ return OutOfMemory;
+ }
+
+ ReleaseDC(0, hdc);
+ }
+
*fontCollection = &installedFontCollection;
return Ok;
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls( hinst );
break;
+
+ case DLL_PROCESS_DETACH:
+ free_installed_fonts();
+ break;
}
return TRUE;
}
((color & 0xff0000) >> 16);
}
+HBITMAP ARGB2BMP(ARGB color)
+{
+ HDC hdc;
+ BITMAPINFO bi;
+ HBITMAP result;
+ RGBQUAD *bits;
+ int alpha;
+
+ if ((color & 0xff000000) == 0xff000000) return 0;
+
+ hdc = CreateCompatibleDC(NULL);
+
+ bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
+ bi.bmiHeader.biWidth = 1;
+ bi.bmiHeader.biHeight = 1;
+ bi.bmiHeader.biPlanes = 1;
+ bi.bmiHeader.biBitCount = 32;
+ bi.bmiHeader.biCompression = BI_RGB;
+ bi.bmiHeader.biSizeImage = 0;
+ bi.bmiHeader.biXPelsPerMeter = 0;
+ bi.bmiHeader.biYPelsPerMeter = 0;
+ bi.bmiHeader.biClrUsed = 0;
+ bi.bmiHeader.biClrImportant = 0;
+
+ result = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void*)&bits, NULL, 0);
+
+ bits[0].rgbReserved = alpha = (color>>24)&0xff;
+ bits[0].rgbRed = ((color>>16)&0xff)*alpha/255;
+ bits[0].rgbGreen = ((color>>8)&0xff)*alpha/255;
+ bits[0].rgbBlue = (color&0xff)*alpha/255;
+
+ DeleteDC(hdc);
+
+ return result;
+}
+
/* Like atan2, but puts angle in correct quadrant if dx is 0. */
REAL gdiplus_atan2(REAL dy, REAL dx)
{
break;
}
}
+
+const char *debugstr_rectf(CONST RectF* rc)
+{
+ if (!rc) return "(null)";
+ return wine_dbg_sprintf("(%0.2f,%0.2f,%0.2f,%0.2f)", rc->X, rc->Y, rc->Width, rc->Height);
+}
@ stdcall GdipTranslateWorldTransform(ptr long long long)
@ stdcall GdipVectorTransformMatrixPoints(ptr ptr long)
@ stdcall GdipVectorTransformMatrixPointsI(ptr ptr long)
-@ stub GdipWarpPath
-@ stub GdipWidenPath
+@ stdcall GdipWarpPath(ptr ptr ptr long long long long long long long)
+@ stdcall GdipWidenPath(ptr ptr ptr long)
@ stub GdipWindingModeOutline
@ stdcall GdiplusNotificationHook(ptr)
@ stdcall GdiplusNotificationUnhook(ptr)
#define TENSION_CONST (0.3)
COLORREF ARGB2COLORREF(ARGB color);
+HBITMAP ARGB2BMP(ARGB color);
extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
REAL startAngle, REAL sweepAngle);
extern REAL gdiplus_atan2(REAL dy, REAL dx);
extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
REAL tension, REAL *x, REAL *y);
+extern void free_installed_fonts(void);
+
extern BOOL lengthen_path(GpPath *path, INT len);
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path);
return M_PI * degrees / 180.0;
}
+extern const char *debugstr_rectf(CONST RectF* rc);
+
struct GpPen{
UINT style;
GpUnit unit;
struct GpSolidFill{
GpBrush brush;
ARGB color;
+ HBITMAP bmp;
};
struct GpPathGradient{
struct GpFontCollection{
GpFontFamily **FontFamilies;
INT count;
+ INT allocated;
};
struct GpFontFamily{
}
break;
}
+ case BrushTypeSolidColor:
+ {
+ GpSolidFill *fill = (GpSolidFill*)brush;
+ if (fill->bmp)
+ {
+ RECT rc;
+ /* partially transparent fill */
+
+ SelectClipPath(graphics->hdc, RGN_AND);
+ if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
+ {
+ HDC hdc = CreateCompatibleDC(NULL);
+ HBITMAP oldbmp;
+ BLENDFUNCTION bf;
+
+ if (!hdc) break;
+
+ oldbmp = SelectObject(hdc, fill->bmp);
+
+ bf.BlendOp = AC_SRC_OVER;
+ bf.BlendFlags = 0;
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+
+ GdiAlphaBlend(graphics->hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hdc, 0, 0, 1, 1, bf);
+
+ SelectObject(hdc, oldbmp);
+ DeleteDC(hdc);
+ }
+
+ break;
+ }
+ /* else fall through */
+ }
default:
SelectObject(graphics->hdc, brush->gdibrush);
FillPath(graphics->hdc);
SIZE size;
RECT drawcoord;
+ TRACE("(%p, %s, %i, %p, %s, %p, %p)\n", graphics, debugstr_wn(string, length),
+ length, font, debugstr_rectf(rect), format, brush);
+
if(!graphics || !string || !font || !brush || !rect)
return InvalidParameter;
nheight;
SIZE size;
+ TRACE("(%p, %s, %i, %p, %s, %p, %p, %p, %p)\n", graphics,
+ debugstr_wn(string, length), length, font, debugstr_rectf(rect), format,
+ bounds, codepointsfitted, linesfilled);
+
if(!graphics || !string || !font || !rect)
return InvalidParameter;
GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace dst_space,
GpCoordinateSpace src_space, GpPointF *points, INT count)
{
+ GpMatrix *matrix;
+ GpStatus stat;
+ REAL unitscale;
+
if(!graphics || !points || count <= 0)
return InvalidParameter;
if(graphics->busy)
return ObjectBusy;
- FIXME("(%p, %d, %d, %p, %d): stub\n", graphics, dst_space, src_space, points, count);
+ TRACE("(%p, %d, %d, %p, %d)\n", graphics, dst_space, src_space, points, count);
- return NotImplemented;
+ if (src_space == dst_space) return Ok;
+
+ stat = GdipCreateMatrix(&matrix);
+ if (stat == Ok)
+ {
+ unitscale = convert_unit(graphics->hdc, graphics->unit);
+
+ if(graphics->unit != UnitDisplay)
+ unitscale *= graphics->scale;
+
+ /* transform from src_space to CoordinateSpacePage */
+ switch (src_space)
+ {
+ case CoordinateSpaceWorld:
+ GdipMultiplyMatrix(matrix, graphics->worldtrans, MatrixOrderAppend);
+ break;
+ case CoordinateSpacePage:
+ break;
+ case CoordinateSpaceDevice:
+ GdipScaleMatrix(matrix, 1.0/unitscale, 1.0/unitscale, MatrixOrderAppend);
+ break;
+ }
+
+ /* transform from CoordinateSpacePage to dst_space */
+ switch (dst_space)
+ {
+ case CoordinateSpaceWorld:
+ {
+ GpMatrix *inverted_transform;
+ stat = GdipCloneMatrix(graphics->worldtrans, &inverted_transform);
+ if (stat == Ok)
+ {
+ stat = GdipInvertMatrix(inverted_transform);
+ if (stat == Ok)
+ GdipMultiplyMatrix(matrix, inverted_transform, MatrixOrderAppend);
+ GdipDeleteMatrix(inverted_transform);
+ }
+ break;
+ }
+ case CoordinateSpacePage:
+ break;
+ case CoordinateSpaceDevice:
+ GdipScaleMatrix(matrix, unitscale, unitscale, MatrixOrderAppend);
+ break;
+ }
+
+ if (stat == Ok)
+ stat = GdipTransformMatrixPoints(matrix, points, count);
+
+ GdipDeleteMatrix(matrix);
+ }
+
+ return stat;
}
GpStatus WINGDIPAPI GdipTransformPointsI(GpGraphics *graphics, GpCoordinateSpace dst_space,
GpCoordinateSpace src_space, GpPoint *points, INT count)
{
- FIXME("(%p, %d, %d, %p, %d): stub\n", graphics, dst_space, src_space, points, count);
+ GpPointF *pointsF;
+ GpStatus ret;
+ INT i;
- return NotImplemented;
+ TRACE("(%p, %d, %d, %p, %d)\n", graphics, dst_space, src_space, points, count);
+
+ if(count <= 0)
+ return InvalidParameter;
+
+ pointsF = GdipAlloc(sizeof(GpPointF) * count);
+ if(!pointsF)
+ return OutOfMemory;
+
+ for(i = 0; i < count; i++){
+ pointsF[i].X = (REAL)points[i].X;
+ pointsF[i].Y = (REAL)points[i].Y;
+ }
+
+ ret = GdipTransformPoints(graphics, dst_space, src_space, pointsF, count);
+
+ if(ret == Ok)
+ for(i = 0; i < count; i++){
+ points[i].X = roundr(pointsF[i].X);
+ points[i].Y = roundr(pointsF[i].Y);
+ }
+ GdipFree(pointsF);
+
+ return ret;
}
HPALETTE WINGDIPAPI GdipCreateHalftonePalette(void)
path->pathdata.Count);
}
+GpStatus WINGDIPAPI GdipWarpPath(GpPath *path, GpMatrix* matrix,
+ GDIPCONST GpPointF *points, INT count, REAL x, REAL y, REAL width,
+ REAL height, WarpMode warpmode, REAL flatness)
+{
+ FIXME("(%p,%p,%p,%i,%0.2f,%0.2f,%0.2f,%0.2f,%i,%0.2f)\n", path, matrix,
+ points, count, x, y, width, height, warpmode, flatness);
+
+ return NotImplemented;
+}
+
+GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
+ REAL flatness)
+{
+ FIXME("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness);
+
+ return NotImplemented;
+}
+
GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y,
REAL width, REAL height)
{
GpStatus WINGDIPAPI GdipCreateStringFormat(INT attr, LANGID lang,
GpStringFormat **format)
{
+ TRACE("(%i, %x, %p)\n", attr, lang, format);
+
if(!format)
return InvalidParameter;
GpStatus WINGDIPAPI GdipSetStringFormatAlign(GpStringFormat *format,
StringAlignment align)
{
+ TRACE("(%p, %i)\n", format, align);
+
if(!format)
return InvalidParameter;
GpStatus WINGDIPAPI GdipSetStringFormatDigitSubstitution(GpStringFormat *format,
LANGID language, StringDigitSubstitute substitute)
{
+ TRACE("(%p, %x, %i)\n", format, language, substitute);
+
if(!format)
return InvalidParameter;
GpStatus WINGDIPAPI GdipSetStringFormatHotkeyPrefix(GpStringFormat *format,
INT hkpx)
{
+ TRACE("(%p, %i)\n", format, hkpx);
+
if(!format || hkpx < 0 || hkpx > 2)
return InvalidParameter;
GpStatus WINGDIPAPI GdipSetStringFormatLineAlign(GpStringFormat *format,
StringAlignment align)
{
+ TRACE("(%p, %i)\n", format, align);
+
if(!format)
return InvalidParameter;
GpStatus WINGDIPAPI GdipSetStringFormatTabStops(GpStringFormat *format, REAL firsttab,
INT count, GDIPCONST REAL *tabs)
{
+ TRACE("(%p, %0.2f, %i, %p)\n", format, firsttab, count, tabs);
+
if(!format || !tabs)
return InvalidParameter;
GpStatus WINGDIPAPI GdipSetStringFormatTrimming(GpStringFormat *format,
StringTrimming trimming)
{
+ TRACE("(%p, %i)\n", format, trimming);
+
if(!format)
return InvalidParameter;
GpStatus WINGDIPAPI GdipSetStringFormatFlags(GpStringFormat *format, INT flags)
{
+ TRACE("(%p, %x)\n", format, flags);
+
if(!format)
return InvalidParameter;