[GDIPLUS]

* Sync to Wine 1.5.4.

svn path=/trunk/; revision=56613
This commit is contained in:
Amine Khaldi 2012-05-19 10:03:40 +00:00
parent aca91a4b14
commit a87a379620
12 changed files with 1745 additions and 797 deletions

View file

@ -5,8 +5,6 @@ add_definitions(
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine)
set_rc_compiler()
spec2def(gdiplus.dll gdiplus.spec ADD_IMPORTLIB)
list(APPEND SOURCE
@ -19,12 +17,12 @@ list(APPEND SOURCE
image.c
imageattributes.c
matrix.c
metafile.c
metafile.c
pathiterator.c
pen.c
region.c
stringformat.c
gdiplus.rc
gdiplus.rc
${CMAKE_CURRENT_BINARY_DIR}/gdiplus_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/gdiplus.def)
@ -32,15 +30,5 @@ add_library(gdiplus SHARED ${SOURCE})
set_module_type(gdiplus win32dll)
target_link_libraries(gdiplus uuid wine)
add_delay_importlibs(gdiplus windowscodecs)
add_importlibs(gdiplus
msvcrt
shlwapi
oleaut32
ole32
user32
gdi32
kernel32
ntdll)
add_importlibs(gdiplus msvcrt shlwapi oleaut32 ole32 user32 gdi32 kernel32 ntdll)
add_cd_file(TARGET gdiplus DESTINATION reactos/system32 FOR all)

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Google (Evan Stade)
* Copyright (C) 2012 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -33,42 +34,121 @@ WINE_DEFAULT_DEBUG_CHANNEL (gdiplus);
#include "gdiplus.h"
#include "gdiplus_private.h"
/* PANOSE is 10 bytes in size, need to pack the structure properly */
#include "pshpack2.h"
typedef struct
{
USHORT version;
SHORT xAvgCharWidth;
USHORT usWeightClass;
USHORT usWidthClass;
SHORT fsType;
SHORT ySubscriptXSize;
SHORT ySubscriptYSize;
SHORT ySubscriptXOffset;
SHORT ySubscriptYOffset;
SHORT ySuperscriptXSize;
SHORT ySuperscriptYSize;
SHORT ySuperscriptXOffset;
SHORT ySuperscriptYOffset;
SHORT yStrikeoutSize;
SHORT yStrikeoutPosition;
SHORT sFamilyClass;
PANOSE panose;
ULONG ulUnicodeRange1;
ULONG ulUnicodeRange2;
ULONG ulUnicodeRange3;
ULONG ulUnicodeRange4;
CHAR achVendID[4];
USHORT fsSelection;
USHORT usFirstCharIndex;
USHORT usLastCharIndex;
/* According to the Apple spec, original version didn't have the below fields,
* version numbers were taken from the OpenType spec.
*/
/* version 0 (TrueType 1.5) */
USHORT sTypoAscender;
USHORT sTypoDescender;
USHORT sTypoLineGap;
USHORT usWinAscent;
USHORT usWinDescent;
/* version 1 (TrueType 1.66) */
ULONG ulCodePageRange1;
ULONG ulCodePageRange2;
/* version 2 (OpenType 1.2) */
SHORT sxHeight;
SHORT sCapHeight;
USHORT usDefaultChar;
USHORT usBreakChar;
USHORT usMaxContext;
} TT_OS2_V2;
typedef struct
{
ULONG Version;
SHORT Ascender;
SHORT Descender;
SHORT LineGap;
USHORT advanceWidthMax;
SHORT minLeftSideBearing;
SHORT minRightSideBearing;
SHORT xMaxExtent;
SHORT caretSlopeRise;
SHORT caretSlopeRun;
SHORT caretOffset;
SHORT reserved[4];
SHORT metricDataFormat;
USHORT numberOfHMetrics;
} TT_HHEA;
#include "poppack.h"
#ifdef WORDS_BIGENDIAN
#define GET_BE_WORD(x) (x)
#define GET_BE_DWORD(x) (x)
#else
#define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));
#endif
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
#define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
#define MS_HHEA_TAG MS_MAKE_TAG('h','h','e','a')
static const REAL mm_per_inch = 25.4;
static const REAL inch_per_point = 1.0/72.0;
static GpFontCollection installedFontCollection = {0};
static inline REAL get_dpi (void)
static LONG em_size_to_pixel(REAL em_size, Unit unit, LONG dpi)
{
REAL dpi;
GpGraphics *graphics;
HDC hdc = GetDC(0);
GdipCreateFromHDC (hdc, &graphics);
GdipGetDpiX(graphics, &dpi);
GdipDeleteGraphics(graphics);
ReleaseDC (0, hdc);
switch (unit)
{
default:
FIXME("Unhandled unit type: %d\n", unit);
return 0;
return dpi;
}
static inline REAL point_to_pixel (REAL point)
{
return point * get_dpi() * inch_per_point;
}
static inline REAL inch_to_pixel (REAL inch)
{
return inch * get_dpi();
}
static inline REAL document_to_pixel (REAL doc)
{
return doc * (get_dpi() / 300.0); /* Per MSDN */
}
static inline REAL mm_to_pixel (REAL mm)
{
return mm * (get_dpi() / mm_per_inch);
case UnitPixel:
case UnitWorld:
/* FIXME: Figure out when World != Pixel */
return em_size;
case UnitDisplay:
FIXME("Unknown behavior for UnitDisplay! Please report!\n");
/* FIXME: Figure out how this works...
* MSDN says that if "DISPLAY" is a monitor, then pixel should be
* used. That's not what I got. Tests on Windows revealed no output,
* and the tests in tests/font crash windows */
return 0;
case UnitPoint:
return em_size * dpi * inch_per_point;
case UnitInch:
return em_size * dpi;
case UnitDocument:
return em_size * dpi / 300.0; /* Per MSDN */
case UnitMillimeter:
return em_size * dpi / mm_per_inch;
}
}
/*******************************************************************************
@ -95,68 +175,53 @@ static inline REAL mm_to_pixel (REAL mm)
GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
REAL emSize, INT style, Unit unit, GpFont **font)
{
WCHAR facename[LF_FACESIZE];
LOGFONTW* lfw;
const NEWTEXTMETRICW* tmw;
HFONT hfont;
OUTLINETEXTMETRICW otm;
LOGFONTW lfw;
HDC hdc;
GpStatus stat;
int ret;
if (!fontFamily || !font)
if (!fontFamily || !font || emSize < 0.0)
return InvalidParameter;
TRACE("%p (%s), %f, %d, %d, %p\n", fontFamily,
debugstr_w(fontFamily->FamilyName), emSize, style, unit, font);
stat = GdipGetFamilyName (fontFamily, facename, 0);
memset(&lfw, 0, sizeof(lfw));
stat = GdipGetFamilyName(fontFamily, lfw.lfFaceName, LANG_NEUTRAL);
if (stat != Ok) return stat;
lfw.lfHeight = -em_size_to_pixel(emSize, unit, fontFamily->dpi);
lfw.lfWeight = style & FontStyleBold ? FW_BOLD : FW_REGULAR;
lfw.lfItalic = style & FontStyleItalic;
lfw.lfUnderline = style & FontStyleUnderline;
lfw.lfStrikeOut = style & FontStyleStrikeout;
hfont = CreateFontIndirectW(&lfw);
hdc = CreateCompatibleDC(0);
SelectObject(hdc, hfont);
otm.otmSize = sizeof(otm);
ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
DeleteDC(hdc);
DeleteObject(hfont);
if (!ret) return NotTrueTypeFont;
*font = GdipAlloc(sizeof(GpFont));
tmw = &fontFamily->tmw;
lfw = &((*font)->lfw);
ZeroMemory(&(*lfw), sizeof(*lfw));
lfw->lfWeight = tmw->tmWeight;
lfw->lfItalic = tmw->tmItalic;
lfw->lfUnderline = tmw->tmUnderlined;
lfw->lfStrikeOut = tmw->tmStruckOut;
lfw->lfCharSet = tmw->tmCharSet;
lfw->lfPitchAndFamily = tmw->tmPitchAndFamily;
lstrcpynW(lfw->lfFaceName, facename, LF_FACESIZE);
switch (unit)
{
case UnitWorld:
/* FIXME: Figure out when World != Pixel */
(*font)->pixel_size = emSize; break;
case UnitDisplay:
FIXME("Unknown behavior for UnitDisplay! Please report!\n");
/* FIXME: Figure out how this works...
* MSDN says that if "DISPLAY" is a monitor, then pixel should be
* used. That's not what I got. Tests on Windows revealed no output,
* and the tests in tests/font crash windows */
(*font)->pixel_size = 0; break;
case UnitPixel:
(*font)->pixel_size = emSize; break;
case UnitPoint:
(*font)->pixel_size = point_to_pixel(emSize); break;
case UnitInch:
(*font)->pixel_size = inch_to_pixel(emSize); break;
case UnitDocument:
(*font)->pixel_size = document_to_pixel(emSize); break;
case UnitMillimeter:
(*font)->pixel_size = mm_to_pixel(emSize); break;
}
lfw->lfHeight = (*font)->pixel_size * -1;
lfw->lfWeight = style & FontStyleBold ? 700 : 400;
lfw->lfItalic = style & FontStyleItalic;
lfw->lfUnderline = style & FontStyleUnderline;
lfw->lfStrikeOut = style & FontStyleStrikeout;
if (!*font) return OutOfMemory;
(*font)->unit = unit;
(*font)->emSize = emSize;
(*font)->height = tmw->ntmSizeEM;
(*font)->line_spacing = tmw->tmAscent + tmw->tmDescent + tmw->tmExternalLeading;
(*font)->otm = otm;
stat = GdipCloneFontFamily((GpFontFamily *)fontFamily, &(*font)->family);
if (stat != Ok)
{
GdipFree(*font);
return stat;
}
TRACE("<-- %p\n", *font);
@ -170,43 +235,38 @@ GpStatus WINGDIPAPI GdipCreateFontFromLogfontW(HDC hdc,
GDIPCONST LOGFONTW *logfont, GpFont **font)
{
HFONT hfont, oldfont;
TEXTMETRICW textmet;
OUTLINETEXTMETRICW otm;
GpStatus stat;
int ret;
TRACE("(%p, %p, %p)\n", hdc, logfont, font);
if(!logfont || !font)
if (!hdc || !logfont || !font)
return InvalidParameter;
if (logfont->lfFaceName[0] == 0)
return NotTrueTypeFont;
*font = GdipAlloc(sizeof(GpFont));
if(!*font) return OutOfMemory;
memcpy((*font)->lfw.lfFaceName, logfont->lfFaceName, LF_FACESIZE *
sizeof(WCHAR));
(*font)->lfw.lfHeight = logfont->lfHeight;
(*font)->lfw.lfItalic = logfont->lfItalic;
(*font)->lfw.lfUnderline = logfont->lfUnderline;
(*font)->lfw.lfStrikeOut = logfont->lfStrikeOut;
(*font)->pixel_size = (*font)->emSize = logfont->lfHeight;
(*font)->unit = UnitPixel;
hfont = CreateFontIndirectW(&(*font)->lfw);
hfont = CreateFontIndirectW(logfont);
oldfont = SelectObject(hdc, hfont);
GetTextMetricsW(hdc, &textmet);
(*font)->lfw.lfHeight = -(textmet.tmHeight-textmet.tmInternalLeading);
(*font)->lfw.lfWeight = textmet.tmWeight;
(*font)->lfw.lfCharSet = textmet.tmCharSet;
(*font)->height = 1; /* FIXME: need NEWTEXTMETRIC.ntmSizeEM here */
(*font)->line_spacing = textmet.tmAscent + textmet.tmDescent + textmet.tmExternalLeading;
otm.otmSize = sizeof(otm);
ret = GetOutlineTextMetricsW(hdc, otm.otmSize, &otm);
SelectObject(hdc, oldfont);
DeleteObject(hfont);
if (!ret) return NotTrueTypeFont;
*font = GdipAlloc(sizeof(GpFont));
if (!*font) return OutOfMemory;
(*font)->unit = UnitWorld;
(*font)->emSize = otm.otmTextMetrics.tmAscent;
(*font)->otm = otm;
stat = GdipCreateFontFamilyFromName(logfont->lfFaceName, NULL, &(*font)->family);
if (stat != Ok)
{
GdipFree(*font);
return NotTrueTypeFont;
}
TRACE("<-- %p\n", *font);
return Ok;
@ -243,6 +303,7 @@ GpStatus WINGDIPAPI GdipDeleteFont(GpFont* font)
if(!font)
return InvalidParameter;
GdipDeleteFontFamily(font->family);
GdipFree(font);
return Ok;
@ -291,7 +352,7 @@ GpStatus WINGDIPAPI GdipGetFamily(GpFont *font, GpFontFamily **family)
if (!(font && family))
return InvalidParameter;
return GdipCreateFontFamilyFromName(font->lfw.lfFaceName, NULL, family);
return GdipCloneFontFamily(font->family, family);
}
/******************************************************************************
@ -317,6 +378,7 @@ GpStatus WINGDIPAPI GdipGetFontSize(GpFont *font, REAL *size)
if (!(font && size)) return InvalidParameter;
*size = font->emSize;
TRACE("%s,%d => %f\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *size);
return Ok;
}
@ -341,15 +403,15 @@ GpStatus WINGDIPAPI GdipGetFontStyle(GpFont *font, INT *style)
if (!(font && style))
return InvalidParameter;
if (font->lfw.lfWeight > 400)
if (font->otm.otmTextMetrics.tmWeight > FW_REGULAR)
*style = FontStyleBold;
else
*style = 0;
if (font->lfw.lfItalic)
*style = FontStyleRegular;
if (font->otm.otmTextMetrics.tmItalic)
*style |= FontStyleItalic;
if (font->lfw.lfUnderline)
if (font->otm.otmTextMetrics.tmUnderlined)
*style |= FontStyleUnderline;
if (font->lfw.lfStrikeOut)
if (font->otm.otmTextMetrics.tmStruckOut)
*style |= FontStyleStrikeout;
return Ok;
@ -373,6 +435,7 @@ GpStatus WINGDIPAPI GdipGetFontUnit(GpFont *font, Unit *unit)
if (!(font && unit)) return InvalidParameter;
*unit = font->unit;
TRACE("%s,%d => %d\n", debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, *unit);
return Ok;
}
@ -412,7 +475,22 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
if(!font || !graphics || !lfw)
return InvalidParameter;
*lfw = font->lfw;
lfw->lfHeight = -font->otm.otmTextMetrics.tmAscent;
lfw->lfWidth = 0;
lfw->lfEscapement = 0;
lfw->lfOrientation = 0;
lfw->lfWeight = font->otm.otmTextMetrics.tmWeight;
lfw->lfItalic = font->otm.otmTextMetrics.tmItalic ? 1 : 0;
lfw->lfUnderline = font->otm.otmTextMetrics.tmUnderlined ? 1 : 0;
lfw->lfStrikeOut = font->otm.otmTextMetrics.tmStruckOut ? 1 : 0;
lfw->lfCharSet = font->otm.otmTextMetrics.tmCharSet;
lfw->lfOutPrecision = OUT_DEFAULT_PRECIS;
lfw->lfClipPrecision = CLIP_DEFAULT_PRECIS;
lfw->lfQuality = DEFAULT_QUALITY;
lfw->lfPitchAndFamily = 0;
strcpyW(lfw->lfFaceName, font->family->FamilyName);
TRACE("=> %s,%d\n", debugstr_w(lfw->lfFaceName), lfw->lfHeight);
return Ok;
}
@ -422,6 +500,8 @@ GpStatus WINGDIPAPI GdipGetLogFontW(GpFont *font, GpGraphics *graphics,
*/
GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
{
GpStatus stat;
TRACE("(%p, %p)\n", font, cloneFont);
if(!font || !cloneFont)
@ -431,8 +511,10 @@ GpStatus WINGDIPAPI GdipCloneFont(GpFont *font, GpFont **cloneFont)
if(!*cloneFont) return OutOfMemory;
**cloneFont = *font;
stat = GdipCloneFontFamily(font->family, &(*cloneFont)->family);
if (stat != Ok) GdipFree(*cloneFont);
return Ok;
return stat;
}
/*******************************************************************************
@ -456,12 +538,15 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
TRACE("%p %p %p\n", font, graphics, height);
stat = GdipGetDpiY((GpGraphics*)graphics, &dpi);
if (graphics)
{
stat = GdipGetDpiY((GpGraphics*)graphics, &dpi);
if (stat != Ok) return stat;
}
else
dpi = font->family->dpi;
if (stat == Ok)
stat = GdipGetFontHeightGivenDPI(font, dpi, height);
return stat;
return GdipGetFontHeightGivenDPI(font, dpi, height);
}
/*******************************************************************************
@ -481,14 +566,26 @@ GpStatus WINGDIPAPI GdipGetFontHeight(GDIPCONST GpFont *font,
*/
GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height)
{
REAL font_height;
GpStatus stat;
INT style;
UINT16 line_spacing, em_height;
REAL font_height, font_size;
if (!font || !height) return InvalidParameter;
TRACE("%p (%s), %f, %p\n", font,
debugstr_w(font->lfw.lfFaceName), dpi, height);
debugstr_w(font->family->FamilyName), dpi, height);
if (!(font && height)) return InvalidParameter;
stat = GdipGetFontSize((GpFont *)font, &font_size);
if (stat != Ok) return stat;
stat = GdipGetFontStyle((GpFont *)font, &style);
if (stat != Ok) return stat;
stat = GdipGetLineSpacing(font->family, style, &line_spacing);
if (stat != Ok) return stat;
stat = GdipGetEmHeight(font->family, style, &em_height);
if (stat != Ok) return stat;
font_height = font->line_spacing * (font->emSize / font->height);
font_height = (REAL)line_spacing * font_size / (REAL)em_height;
switch (font->unit)
{
@ -513,6 +610,9 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
return NotImplemented;
}
TRACE("%s,%d(unit %d) => %f\n",
debugstr_w(font->family->FamilyName), font->otm.otmTextMetrics.tmHeight, font->unit, *height);
return Ok;
}
@ -525,25 +625,87 @@ GpStatus WINGDIPAPI GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi,
static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf,
const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
{
if (!ntm || type == RASTER_FONTTYPE)
{
if (type != TRUETYPE_FONTTYPE)
return 1;
}
*(NEWTEXTMETRICW*)lParam = *(const NEWTEXTMETRICW*)ntm;
*(LOGFONTW *)lParam = *elf;
return 0;
}
static BOOL find_installed_font(const WCHAR *name, NEWTEXTMETRICW *ntm)
struct font_metrics
{
HDC hdc = GetDC(0);
BOOL ret = FALSE;
UINT16 em_height, ascent, descent, line_spacing; /* in font units */
int dpi;
};
if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)ntm))
ret = TRUE;
static BOOL get_font_metrics(HDC hdc, struct font_metrics *fm)
{
OUTLINETEXTMETRICW otm;
TT_OS2_V2 tt_os2;
TT_HHEA tt_hori;
LONG size;
UINT16 line_gap;
ReleaseDC(0, hdc);
otm.otmSize = sizeof(otm);
if (!GetOutlineTextMetricsW(hdc, otm.otmSize, &otm)) return FALSE;
fm->em_height = otm.otmEMSquare;
fm->dpi = GetDeviceCaps(hdc, LOGPIXELSY);
memset(&tt_hori, 0, sizeof(tt_hori));
if (GetFontData(hdc, MS_HHEA_TAG, 0, &tt_hori, sizeof(tt_hori)) != GDI_ERROR)
{
fm->ascent = GET_BE_WORD(tt_hori.Ascender);
fm->descent = -GET_BE_WORD(tt_hori.Descender);
TRACE("hhea: ascent %d, descent %d\n", fm->ascent, fm->descent);
line_gap = GET_BE_WORD(tt_hori.LineGap);
fm->line_spacing = fm->ascent + fm->descent + line_gap;
TRACE("line_gap %u, line_spacing %u\n", line_gap, fm->line_spacing);
if (fm->ascent + fm->descent != 0) return TRUE;
}
size = GetFontData(hdc, MS_OS2_TAG, 0, NULL, 0);
if (size == GDI_ERROR) return FALSE;
if (size > sizeof(tt_os2)) size = sizeof(tt_os2);
memset(&tt_os2, 0, sizeof(tt_os2));
if (GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size) != size) return FALSE;
fm->ascent = GET_BE_WORD(tt_os2.usWinAscent);
fm->descent = GET_BE_WORD(tt_os2.usWinDescent);
TRACE("usWinAscent %u, usWinDescent %u\n", fm->ascent, fm->descent);
if (fm->ascent + fm->descent == 0)
{
fm->ascent = GET_BE_WORD(tt_os2.sTypoAscender);
fm->descent = GET_BE_WORD(tt_os2.sTypoDescender);
TRACE("sTypoAscender %u, sTypoDescender %u\n", fm->ascent, fm->descent);
}
line_gap = GET_BE_WORD(tt_os2.sTypoLineGap);
fm->line_spacing = fm->ascent + fm->descent + line_gap;
TRACE("line_gap %u, line_spacing %u\n", line_gap, fm->line_spacing);
return TRUE;
}
static GpStatus find_installed_font(const WCHAR *name, struct font_metrics *fm)
{
LOGFONTW lf;
HDC hdc = CreateCompatibleDC(0);
GpStatus ret = FontFamilyNotFound;
if(!EnumFontFamiliesW(hdc, name, is_font_installed_proc, (LPARAM)&lf))
{
HFONT hfont, old_font;
hfont = CreateFontIndirectW(&lf);
old_font = SelectObject(hdc, hfont);
ret = get_font_metrics(hdc, fm) ? Ok : NotTrueTypeFont;
SelectObject(hdc, old_font);
DeleteObject(hfont);
}
DeleteDC(hdc);
return ret;
}
@ -571,8 +733,9 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
GpFontCollection *fontCollection,
GpFontFamily **FontFamily)
{
GpStatus stat;
GpFontFamily* ffamily;
NEWTEXTMETRICW ntm;
struct font_metrics fm;
TRACE("%s, %p %p\n", debugstr_w(name), fontCollection, FontFamily);
@ -581,14 +744,18 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
if (fontCollection)
FIXME("No support for FontCollections yet!\n");
if (!find_installed_font(name, &ntm))
return FontFamilyNotFound;
stat = find_installed_font(name, &fm);
if (stat != Ok) return stat;
ffamily = GdipAlloc(sizeof (GpFontFamily));
if (!ffamily) return OutOfMemory;
ffamily->tmw = ntm;
lstrcpynW(ffamily->FamilyName, name, LF_FACESIZE);
ffamily->em_height = fm.em_height;
ffamily->ascent = fm.ascent;
ffamily->descent = fm.descent;
ffamily->line_spacing = fm.line_spacing;
ffamily->dpi = fm.dpi;
*FontFamily = ffamily;
@ -613,13 +780,13 @@ GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily* FontFamily, GpFontFamily**
{
if (!(FontFamily && clonedFontFamily)) return InvalidParameter;
TRACE("stub: %p (%s), %p\n", FontFamily,
TRACE("%p (%s), %p\n", FontFamily,
debugstr_w(FontFamily->FamilyName), clonedFontFamily);
*clonedFontFamily = GdipAlloc(sizeof(GpFontFamily));
if (!*clonedFontFamily) return OutOfMemory;
(*clonedFontFamily)->tmw = FontFamily->tmw;
**clonedFontFamily = *FontFamily;
lstrcpyW((*clonedFontFamily)->FamilyName, FontFamily->FamilyName);
TRACE("<-- %p\n", *clonedFontFamily);
@ -692,7 +859,8 @@ GpStatus WINGDIPAPI GdipGetCellAscent(GDIPCONST GpFontFamily *family,
{
if (!(family && CellAscent)) return InvalidParameter;
*CellAscent = family->tmw.tmAscent;
*CellAscent = family->ascent;
TRACE("%s => %u\n", debugstr_w(family->FamilyName), *CellAscent);
return Ok;
}
@ -704,7 +872,8 @@ GpStatus WINGDIPAPI GdipGetCellDescent(GDIPCONST GpFontFamily *family,
if (!(family && CellDescent)) return InvalidParameter;
*CellDescent = family->tmw.tmDescent;
*CellDescent = family->descent;
TRACE("%s => %u\n", debugstr_w(family->FamilyName), *CellDescent);
return Ok;
}
@ -729,7 +898,8 @@ GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, U
TRACE("%p (%s), %d, %p\n", family, debugstr_w(family->FamilyName), style, EmHeight);
*EmHeight = family->tmw.ntmSizeEM;
*EmHeight = family->em_height;
TRACE("%s => %u\n", debugstr_w(family->FamilyName), *EmHeight);
return Ok;
}
@ -759,7 +929,8 @@ GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily *family,
if (style) FIXME("ignoring style\n");
*LineSpacing = family->tmw.tmAscent + family->tmw.tmDescent + family->tmw.tmExternalLeading;
*LineSpacing = family->line_spacing;
TRACE("%s => %u\n", debugstr_w(family->FamilyName), *LineSpacing);
return Ok;
}
@ -767,7 +938,7 @@ GpStatus WINGDIPAPI GdipGetLineSpacing(GDIPCONST GpFontFamily *family,
static INT CALLBACK font_has_style_proc(const LOGFONTW *elf,
const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
{
INT fontstyle=0;
INT fontstyle = FontStyleRegular;
if (!ntm) return 1;

View file

@ -265,7 +265,6 @@ COLORREF ARGB2COLORREF(ARGB color)
HBITMAP ARGB2BMP(ARGB color)
{
HDC hdc;
BITMAPINFO bi;
HBITMAP result;
RGBQUAD *bits;
@ -273,8 +272,6 @@ HBITMAP ARGB2BMP(ARGB color)
if ((color & 0xff000000) == 0xff000000) return 0;
hdc = CreateCompatibleDC(NULL);
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = 1;
bi.bmiHeader.biHeight = 1;
@ -287,15 +284,13 @@ HBITMAP ARGB2BMP(ARGB color)
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
result = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, (void*)&bits, NULL, 0);
result = CreateDIBSection(0, &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;
}

View file

@ -316,7 +316,7 @@
316 stdcall GdipGetPathGradientCenterPointI(ptr ptr)
317 stdcall GdipGetPathGradientFocusScales(ptr ptr ptr)
318 stdcall GdipGetPathGradientGammaCorrection(ptr ptr)
319 stub GdipGetPathGradientPath
319 stdcall GdipGetPathGradientPath(ptr ptr)
320 stdcall GdipGetPathGradientPointCount(ptr ptr)
321 stdcall GdipGetPathGradientPresetBlend(ptr ptr ptr long)
322 stdcall GdipGetPathGradientPresetBlendCount(ptr ptr)
@ -457,9 +457,9 @@
457 stdcall GdipResetClip(ptr)
458 stub GdipResetImageAttributes
459 stdcall GdipResetLineTransform(ptr)
460 stub GdipResetPageTransform
460 stdcall GdipResetPageTransform(ptr)
461 stdcall GdipResetPath(ptr)
462 stub GdipResetPathGradientTransform
462 stdcall GdipResetPathGradientTransform(ptr)
463 stdcall GdipResetPenTransform(ptr)
464 stdcall GdipResetTextureTransform(ptr)
465 stdcall GdipResetWorldTransform(ptr)

View file

@ -161,6 +161,7 @@ struct GpGraphics{
UINT textcontrast; /* not used yet. get/set only */
struct list containers;
GraphicsContainer contid; /* last-issued container ID */
INT origin_x, origin_y;
/* For giving the caller an HDC when we technically can't: */
HBITMAP temp_hbitmap;
int temp_hbitmap_width;
@ -170,9 +171,7 @@ struct GpGraphics{
};
struct GpBrush{
HBRUSH gdibrush;
GpBrushType bt;
LOGBRUSH lb;
};
struct GpHatch{
@ -185,12 +184,11 @@ struct GpHatch{
struct GpSolidFill{
GpBrush brush;
ARGB color;
HBITMAP bmp;
};
struct GpPathGradient{
GpBrush brush;
PathData pathdata;
GpPath* path;
ARGB centercolor;
GpWrapMode wrap;
BOOL gamma;
@ -199,6 +197,12 @@ struct GpPathGradient{
REAL* blendfac; /* blend factors */
REAL* blendpos; /* blend positions */
INT blendcount;
ARGB *surroundcolors;
INT surroundcolorcount;
ARGB* pblendcolor; /* preset blend colors */
REAL* pblendpos; /* preset blend positions */
INT pblendcount;
GpMatrix *transform;
};
struct GpLineGradient{
@ -327,7 +331,7 @@ struct color_matrix{
struct color_remap_table{
BOOL enabled;
INT mapsize;
GDIPCONST ColorMap *colormap;
ColorMap *colormap;
};
struct GpImageAttributes{
@ -342,11 +346,9 @@ struct GpImageAttributes{
};
struct GpFont{
LOGFONTW lfw;
REAL emSize;
REAL pixel_size;
UINT height;
LONG line_spacing;
GpFontFamily *family;
OUTLINETEXTMETRICW otm;
REAL emSize; /* in font units */
Unit unit;
};
@ -373,8 +375,9 @@ struct GpFontCollection{
};
struct GpFontFamily{
NEWTEXTMETRICW tmw;
WCHAR FamilyName[LF_FACESIZE];
UINT16 em_height, ascent, descent, line_spacing; /* in font units */
int dpi;
};
/* internal use */
@ -425,7 +428,8 @@ struct GpRegion{
typedef GpStatus (*gdip_format_string_callback)(HDC hdc,
GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, void *user_data);
INT lineno, const RectF *bounds, INT *underlined_indexes,
INT underlined_index_count, void *user_data);
GpStatus gdip_format_string(HDC hdc,
GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font,

File diff suppressed because it is too large Load diff

View file

@ -846,7 +846,8 @@ struct format_string_args
static GpStatus format_string_callback(HDC dc,
GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font,
GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format,
INT lineno, const RectF *bounds, void *priv)
INT lineno, const RectF *bounds, INT *underlined_indexes,
INT underlined_index_count, void *priv)
{
static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
struct format_string_args *args = priv;
@ -856,6 +857,9 @@ static GpStatus format_string_callback(HDC dc,
float y = bounds->Y;
int i;
if (underlined_index_count)
FIXME("hotkey underlines not drawn yet\n");
for (i = index; i < length; ++i)
{
GLYPHMETRICS gm;
@ -938,6 +942,7 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
{
GpFont *font;
GpStatus status;
LOGFONTW lfw;
HANDLE hfont;
HDC dc;
GpPath *backup;
@ -952,7 +957,9 @@ GpStatus WINGDIPAPI GdipAddPathString(GpPath* path, GDIPCONST WCHAR* string, INT
if (status != Ok)
return status;
hfont = CreateFontIndirectW(&font->lfw);
status = GdipGetLogFontW((GpFont *)font, NULL, &lfw);
if (status != Ok) return status;
hfont = CreateFontIndirectW(&lfw);
if (!hfont)
{
WARN("Failed to create font\n");
@ -1207,14 +1214,7 @@ GpStatus WINGDIPAPI GdipFlattenPath(GpPath *path, GpMatrix* matrix, REAL flatnes
continue;
}
/* Bezier curve always stored as 4 points */
if((path->pathdata.Types[i-1] & PathPointTypePathTypeMask) != PathPointTypeStart){
type = (path->pathdata.Types[i] & ~PathPointTypePathTypeMask) | PathPointTypeLine;
if(!add_path_list_node(node, pt.X, pt.Y, type))
goto memout;
node = node->next;
}
/* Bezier curve */
/* test for closed figure */
if(path->pathdata.Types[i+1] & PathPointTypeCloseSubpath){
@ -1659,12 +1659,222 @@ GpStatus WINGDIPAPI GdipWarpPath(GpPath *path, GpMatrix* matrix,
return NotImplemented;
}
static void add_bevel_point(const GpPointF *endpoint, const GpPointF *nextpoint,
GpPen *pen, int right_side, path_list_node_t **last_point)
{
REAL segment_dy = nextpoint->Y-endpoint->Y;
REAL segment_dx = nextpoint->X-endpoint->X;
REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
REAL distance = pen->width/2.0;
REAL bevel_dx, bevel_dy;
if (right_side)
{
bevel_dx = -distance * segment_dy / segment_length;
bevel_dy = distance * segment_dx / segment_length;
}
else
{
bevel_dx = distance * segment_dy / segment_length;
bevel_dy = -distance * segment_dx / segment_length;
}
*last_point = add_path_list_node(*last_point, endpoint->X + bevel_dx,
endpoint->Y + bevel_dy, PathPointTypeLine);
}
static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF *p3,
GpPen* pen, path_list_node_t **last_point)
{
switch (pen->join)
{
default:
case LineJoinBevel:
add_bevel_point(p2, p1, pen, 1, last_point);
add_bevel_point(p2, p3, pen, 0, last_point);
break;
}
}
static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint,
GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, int add_first_points,
int add_last_point, path_list_node_t **last_point)
{
switch (cap)
{
default:
case LineCapFlat:
if (add_first_points)
add_bevel_point(endpoint, nextpoint, pen, 1, last_point);
if (add_last_point)
add_bevel_point(endpoint, nextpoint, pen, 0, last_point);
break;
}
}
static void widen_open_figure(GpPath *path, GpPen *pen, int start, int end,
path_list_node_t **last_point)
{
int i;
if (end <= start)
return;
widen_cap(&path->pathdata.Points[start], &path->pathdata.Points[start+1],
pen, pen->startcap, pen->customstart, FALSE, TRUE, last_point);
(*last_point)->type = PathPointTypeStart;
for (i=start+1; i<end; i++)
widen_joint(&path->pathdata.Points[i-1], &path->pathdata.Points[i],
&path->pathdata.Points[i+1], pen, last_point);
widen_cap(&path->pathdata.Points[end], &path->pathdata.Points[end-1],
pen, pen->endcap, pen->customend, TRUE, TRUE, last_point);
for (i=end-1; i>start; i--)
widen_joint(&path->pathdata.Points[i+1], &path->pathdata.Points[i],
&path->pathdata.Points[i-1], pen, last_point);
widen_cap(&path->pathdata.Points[start], &path->pathdata.Points[start+1],
pen, pen->startcap, pen->customstart, TRUE, FALSE, last_point);
(*last_point)->type |= PathPointTypeCloseSubpath;
}
static void widen_closed_figure(GpPath *path, GpPen *pen, int start, int end,
path_list_node_t **last_point)
{
int i;
path_list_node_t *prev_point;
if (end <= start+1)
return;
/* left outline */
prev_point = *last_point;
widen_joint(&path->pathdata.Points[end], &path->pathdata.Points[start],
&path->pathdata.Points[start+1], pen, last_point);
for (i=start+1; i<end; i++)
widen_joint(&path->pathdata.Points[i-1], &path->pathdata.Points[i],
&path->pathdata.Points[i+1], pen, last_point);
widen_joint(&path->pathdata.Points[end-1], &path->pathdata.Points[end],
&path->pathdata.Points[start], pen, last_point);
prev_point->next->type = PathPointTypeStart;
(*last_point)->type |= PathPointTypeCloseSubpath;
/* right outline */
prev_point = *last_point;
widen_joint(&path->pathdata.Points[start], &path->pathdata.Points[end],
&path->pathdata.Points[end-1], pen, last_point);
for (i=end-1; i>start; i--)
widen_joint(&path->pathdata.Points[i+1], &path->pathdata.Points[i],
&path->pathdata.Points[i-1], pen, last_point);
widen_joint(&path->pathdata.Points[start+1], &path->pathdata.Points[start],
&path->pathdata.Points[end], pen, last_point);
prev_point->next->type = PathPointTypeStart;
(*last_point)->type |= PathPointTypeCloseSubpath;
}
GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix,
REAL flatness)
{
FIXME("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness);
GpPath *flat_path=NULL;
GpStatus status;
path_list_node_t *points=NULL, *last_point=NULL;
int i, subpath_start=0, new_length;
BYTE type;
return NotImplemented;
TRACE("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness);
if (!path || !pen)
return InvalidParameter;
if (path->pathdata.Count <= 1)
return OutOfMemory;
status = GdipClonePath(path, &flat_path);
if (status == Ok)
status = GdipFlattenPath(flat_path, matrix, flatness);
if (status == Ok && !init_path_list(&points, 314.0, 22.0))
status = OutOfMemory;
if (status == Ok)
{
last_point = points;
if (pen->endcap != LineCapFlat)
FIXME("unimplemented end cap %x\n", pen->endcap);
if (pen->startcap != LineCapFlat)
FIXME("unimplemented start cap %x\n", pen->startcap);
if (pen->dashcap != DashCapFlat)
FIXME("unimplemented dash cap %d\n", pen->dashcap);
if (pen->join != LineJoinBevel)
FIXME("unimplemented line join %d\n", pen->join);
if (pen->dash != DashStyleSolid)
FIXME("unimplemented dash style %d\n", pen->dash);
if (pen->align != PenAlignmentCenter)
FIXME("unimplemented pen alignment %d\n", pen->align);
for (i=0; i < flat_path->pathdata.Count; i++)
{
type = flat_path->pathdata.Types[i];
if ((type&PathPointTypePathTypeMask) == PathPointTypeStart)
subpath_start = i;
if ((type&PathPointTypeCloseSubpath) == PathPointTypeCloseSubpath)
{
widen_closed_figure(flat_path, pen, subpath_start, i, &last_point);
}
else if (i == flat_path->pathdata.Count-1 ||
(flat_path->pathdata.Types[i+1]&PathPointTypePathTypeMask) == PathPointTypeStart)
{
widen_open_figure(flat_path, pen, subpath_start, i, &last_point);
}
}
new_length = path_list_count(points)-1;
if (!lengthen_path(path, new_length))
status = OutOfMemory;
}
if (status == Ok)
{
path->pathdata.Count = new_length;
last_point = points->next;
for (i = 0; i < new_length; i++)
{
path->pathdata.Points[i] = last_point->pt;
path->pathdata.Types[i] = last_point->type;
last_point = last_point->next;
}
path->fill = FillModeWinding;
}
free_path_list(points);
GdipDeletePath(flat_path);
return status;
}
GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y,

View file

@ -1372,7 +1372,6 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
GpStatus stat;
HBITMAP result;
UINT width, height;
HDC hdc;
BITMAPINFOHEADER bih;
LPBYTE bits;
BitmapData lockeddata;
@ -1395,11 +1394,7 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
bih.biClrUsed = 0;
bih.biClrImportant = 0;
hdc = CreateCompatibleDC(NULL);
if (!hdc) return GenericError;
result = CreateDIBSection(hdc, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&bits,
NULL, 0);
result = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
if (result)
{
@ -1415,8 +1410,6 @@ GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
else
stat = GenericError;
DeleteDC(hdc);
if (stat != Ok && result)
{
DeleteObject(result);
@ -1694,7 +1687,6 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
BITMAPINFO* pbmi;
HBITMAP hbitmap=NULL;
INT row_size, dib_stride;
HDC hdc;
BYTE *bits=NULL, *own_bits=NULL;
REAL xres, yres;
GpStatus stat;
@ -1739,15 +1731,8 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biClrImportant = 0;
hdc = CreateCompatibleDC(NULL);
if (!hdc) {
GdipFree(pbmi);
return GenericError;
}
hbitmap = CreateDIBSection(0, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
hbitmap = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
DeleteDC(hdc);
GdipFree(pbmi);
if (!hbitmap) return GenericError;
@ -3103,6 +3088,12 @@ static GpStatus encode_image_png(GpImage *image, IStream* stream,
return encode_image_WIC(image, stream, &CLSID_WICPngEncoder, params);
}
static GpStatus encode_image_jpeg(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
{
return encode_image_WIC(image, stream, &CLSID_WICJpegEncoder, params);
}
/*****************************************************************************
* GdipSaveImageToStream [GDIPLUS.@]
*/
@ -3277,14 +3268,14 @@ static const struct image_codec codecs[NUM_CODECS] = {
/* FormatDescription */ jpeg_format,
/* FilenameExtension */ jpeg_extension,
/* MimeType */ jpeg_mimetype,
/* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
/* Flags */ ImageCodecFlagsEncoder | ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin,
/* Version */ 1,
/* SigCount */ 1,
/* SigSize */ 2,
/* SigPattern */ jpeg_sig_pattern,
/* SigMask */ jpeg_sig_mask,
},
NULL,
encode_image_jpeg,
decode_image_jpeg
},
{
@ -3520,13 +3511,53 @@ GpStatus WINGDIPAPI GdipGetEncoderParameterListSize(GpImage *image,
return NotImplemented;
}
static PixelFormat get_16bpp_format(HBITMAP hbm)
{
BITMAPV4HEADER bmh;
HDC hdc;
PixelFormat result;
hdc = CreateCompatibleDC(NULL);
memset(&bmh, 0, sizeof(bmh));
bmh.bV4Size = sizeof(bmh);
bmh.bV4Width = 1;
bmh.bV4Height = 1;
bmh.bV4V4Compression = BI_BITFIELDS;
bmh.bV4BitCount = 16;
GetDIBits(hdc, hbm, 0, 0, NULL, (BITMAPINFO*)&bmh, DIB_RGB_COLORS);
if (bmh.bV4RedMask == 0x7c00 &&
bmh.bV4GreenMask == 0x3e0 &&
bmh.bV4BlueMask == 0x1f)
{
result = PixelFormat16bppRGB555;
}
else if (bmh.bV4RedMask == 0xf800 &&
bmh.bV4GreenMask == 0x7e0 &&
bmh.bV4BlueMask == 0x1f)
{
result = PixelFormat16bppRGB565;
}
else
{
FIXME("unrecognized bitfields %x,%x,%x\n", bmh.bV4RedMask,
bmh.bV4GreenMask, bmh.bV4BlueMask);
result = PixelFormatUndefined;
}
DeleteDC(hdc);
return result;
}
/*****************************************************************************
* GdipCreateBitmapFromHBITMAP [GDIPLUS.@]
*/
GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBitmap** bitmap)
{
BITMAP bm;
DIBSECTION dib;
GpStatus retval;
PixelFormat format;
BitmapData lockeddata;
@ -3552,35 +3583,10 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBi
format = PixelFormat8bppIndexed;
break;
case 16:
{
if (GetObjectA(hbm, sizeof(dib), &dib) == sizeof(dib))
{
if (dib.dsBitfields[0] == 0x7c00 &&
dib.dsBitfields[1] == 0x3e0 &&
dib.dsBitfields[2] == 0x1f)
{
format = PixelFormat16bppRGB555;
}
else if (dib.dsBitfields[0] == 0xf800 &&
dib.dsBitfields[1] == 0x7e0 &&
dib.dsBitfields[2] == 0x1f)
{
format = PixelFormat16bppRGB565;
}
else
{
FIXME("unrecognized bitfields %x,%x,%x\n", dib.dsBitfields[0],
dib.dsBitfields[1], dib.dsBitfields[2]);
return InvalidParameter;
}
}
else
{
FIXME("unimplemented for 16-bit ddb\n");
format = get_16bpp_format(hbm);
if (format == PixelFormatUndefined)
return InvalidParameter;
}
break;
}
case 24:
format = PixelFormat24bppRGB;
break;

View file

@ -62,11 +62,16 @@ GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr)
GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes *imageattr)
{
int i;
TRACE("(%p)\n", imageattr);
if(!imageattr)
return InvalidParameter;
for (i=0; i<ColorAdjustTypeCount; i++)
GdipFree(imageattr->colorremaptables[i].colormap);
GdipFree(imageattr);
return Ok;
@ -205,6 +210,8 @@ GpStatus WINGDIPAPI GdipSetImageAttributesRemapTable(GpImageAttributes *imageAtt
ColorAdjustType type, BOOL enableFlag, UINT mapSize,
GDIPCONST ColorMap *map)
{
ColorMap *new_map;
TRACE("(%p,%u,%i,%u,%p)\n", imageAttr, type, enableFlag, mapSize, map);
if(!imageAttr || type >= ColorAdjustTypeCount)
@ -215,8 +222,22 @@ GpStatus WINGDIPAPI GdipSetImageAttributesRemapTable(GpImageAttributes *imageAtt
if(!map || !mapSize)
return InvalidParameter;
new_map = GdipAlloc(sizeof(*map) * mapSize);
if (!new_map)
return OutOfMemory;
memcpy(new_map, map, sizeof(*map) * mapSize);
GdipFree(imageAttr->colorremaptables[type].colormap);
imageAttr->colorremaptables[type].mapsize = mapSize;
imageAttr->colorremaptables[type].colormap = map;
imageAttr->colorremaptables[type].colormap = new_map;
}
else
{
GdipFree(imageAttr->colorremaptables[type].colormap);
imageAttr->colorremaptables[type].colormap = NULL;
}
imageAttr->colorremaptables[type].enabled = enableFlag;

View file

@ -554,6 +554,9 @@ GpStatus WINGDIPAPI GdipGetPathGradientCenterPoint(GpPathGradient*,GpPointF*);
GpStatus WINGDIPAPI GdipGetPathGradientCenterPointI(GpPathGradient*,GpPoint*);
GpStatus WINGDIPAPI GdipGetPathGradientFocusScales(GpPathGradient*,REAL*,REAL*);
GpStatus WINGDIPAPI GdipGetPathGradientGammaCorrection(GpPathGradient*,BOOL*);
GpStatus WINGDIPAPI GdipGetPathGradientPath(GpPathGradient*,GpPath*);
GpStatus WINGDIPAPI GdipGetPathGradientPresetBlend(GpPathGradient*,ARGB*,REAL*,INT);
GpStatus WINGDIPAPI GdipGetPathGradientPresetBlendCount(GpPathGradient*,INT*);
GpStatus WINGDIPAPI GdipGetPathGradientPointCount(GpPathGradient*,INT*);
GpStatus WINGDIPAPI GdipSetPathGradientPresetBlend(GpPathGradient*,
GDIPCONST ARGB*,GDIPCONST REAL*,INT);

View file

@ -61,7 +61,7 @@ reactos/dll/win32/dbghelp # Synced to Wine-1.3.37
reactos/dll/win32/dciman32 # Synced to Wine-1.3.37
reactos/dll/win32/dwmapi # Synced to Wine-1.3.37
reactos/dll/win32/fusion # Synced to Wine-1.5.4
reactos/dll/win32/gdiplus # Synced to Wine-1.3.37
reactos/dll/win32/gdiplus # Synced to Wine-1.5.4
reactos/dll/win32/hhctrl.ocx # Autosync
reactos/dll/win32/hlink # Synced to Wine-1.3.37
reactos/dll/win32/hnetcfg # Synced to Wine-1.3.37