[GDIPLUS]

* Sync with Wine 1.7.1.

svn path=/trunk/; revision=60204
This commit is contained in:
Amine Khaldi 2013-09-19 15:10:19 +00:00
parent 6af8ca5475
commit 6df5eb8a4a
14 changed files with 508 additions and 107 deletions

View file

@ -22,11 +22,10 @@ list(APPEND SOURCE
pen.c
region.c
stringformat.c
gdiplus.rc
${CMAKE_CURRENT_BINARY_DIR}/gdiplus_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/gdiplus.def)
add_library(gdiplus SHARED ${SOURCE})
add_library(gdiplus SHARED ${SOURCE} gdiplus.rc)
set_module_type(gdiplus win32dll)
target_link_libraries(gdiplus uuid wine)
add_delay_importlibs(gdiplus windowscodecs)

View file

@ -221,17 +221,16 @@ GpStatus WINGDIPAPI GdipSetCustomLineCapStrokeJoin(GpCustomLineCap* custom,
return Ok;
}
GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap* custom,
REAL width)
GpStatus WINGDIPAPI GdipSetCustomLineCapWidthScale(GpCustomLineCap* custom, REAL width)
{
static int calls;
TRACE("(%p,%0.2f)\n", custom, width);
if(!(calls++))
FIXME("not implemented\n");
if(!custom)
return InvalidParameter;
return NotImplemented;
custom->scale = width;
return Ok;
}
GpStatus WINGDIPAPI GdipGetCustomLineCapBaseCap(GpCustomLineCap *customCap, GpLineCap *baseCap)

View file

@ -1138,111 +1138,324 @@ GpStatus WINGDIPAPI GdipPrivateAddFontFile(GpFontCollection* fontCollection,
return NotImplemented;
}
/* Copied from msi/font.c */
#define TT_PLATFORM_APPLE_UNICODE 0
#define TT_PLATFORM_MACINTOSH 1
#define TT_PLATFORM_MICROSOFT 3
typedef struct _tagTT_OFFSET_TABLE {
USHORT uMajorVersion;
USHORT uMinorVersion;
USHORT uNumOfTables;
USHORT uSearchRange;
USHORT uEntrySelector;
USHORT uRangeShift;
} TT_OFFSET_TABLE;
#define TT_APPLE_ID_DEFAULT 0
#define TT_APPLE_ID_ISO_10646 2
#define TT_APPLE_ID_UNICODE_2_0 3
typedef struct _tagTT_TABLE_DIRECTORY {
char szTag[4]; /* table name */
ULONG uCheckSum; /* Check sum */
ULONG uOffset; /* Offset from beginning of file */
ULONG uLength; /* length of the table in bytes */
} TT_TABLE_DIRECTORY;
#define TT_MS_ID_SYMBOL_CS 0
#define TT_MS_ID_UNICODE_CS 1
typedef struct _tagTT_NAME_TABLE_HEADER {
USHORT uFSelector; /* format selector. Always 0 */
USHORT uNRCount; /* Name Records count */
USHORT uStorageOffset; /* Offset for strings storage,
* from start of the table */
} TT_NAME_TABLE_HEADER;
#define TT_MAC_ID_SIMPLIFIED_CHINESE 25
#define NAME_ID_FULL_FONT_NAME 4
#define NAME_ID_VERSION 5
typedef struct _tagTT_NAME_RECORD {
USHORT uPlatformID;
USHORT uEncodingID;
USHORT uLanguageID;
USHORT uNameID;
USHORT uStringLength;
USHORT uStringOffset; /* from start of storage area */
} TT_NAME_RECORD;
typedef struct {
USHORT major_version;
USHORT minor_version;
USHORT tables_no;
USHORT search_range;
USHORT entry_selector;
USHORT range_shift;
} tt_header;
#define SWAPWORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x) MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))
typedef struct {
char tag[4]; /* table name */
ULONG check_sum; /* Check sum */
ULONG offset; /* Offset from beginning of file */
ULONG length; /* length of the table in bytes */
} tt_table_directory;
/*
* Code based off of code located here
* http://www.codeproject.com/gdi/fontnamefromfile.asp
*/
static WCHAR *load_ttf_name_id( const char *mem, DWORD_PTR size, DWORD id, WCHAR *ret, DWORD len )
typedef struct {
USHORT format; /* format selector. Always 0 */
USHORT count; /* Name Records count */
USHORT string_offset; /* Offset for strings storage, * from start of the table */
} tt_name_table;
typedef struct {
USHORT platform_id;
USHORT encoding_id;
USHORT language_id;
USHORT name_id;
USHORT length;
USHORT offset; /* from start of storage area */
} tt_name_record;
/* Copied from gdi32/freetype.c */
static const LANGID mac_langid_table[] =
{
const TT_TABLE_DIRECTORY *tblDir;
TT_OFFSET_TABLE ttOffsetTable;
TT_NAME_TABLE_HEADER ttNTHeader;
TT_NAME_RECORD ttRecord;
DWORD ofs, pos;
int i;
MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ENGLISH */
MAKELANGID(LANG_FRENCH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_FRENCH */
MAKELANGID(LANG_GERMAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_GERMAN */
MAKELANGID(LANG_ITALIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ITALIAN */
MAKELANGID(LANG_DUTCH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_DUTCH */
MAKELANGID(LANG_SWEDISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SWEDISH */
MAKELANGID(LANG_SPANISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SPANISH */
MAKELANGID(LANG_DANISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_DANISH */
MAKELANGID(LANG_PORTUGUESE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_PORTUGUESE */
MAKELANGID(LANG_NORWEGIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_NORWEGIAN */
MAKELANGID(LANG_HEBREW,SUBLANG_DEFAULT), /* TT_MAC_LANGID_HEBREW */
MAKELANGID(LANG_JAPANESE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_JAPANESE */
MAKELANGID(LANG_ARABIC,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ARABIC */
MAKELANGID(LANG_FINNISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_FINNISH */
MAKELANGID(LANG_GREEK,SUBLANG_DEFAULT), /* TT_MAC_LANGID_GREEK */
MAKELANGID(LANG_ICELANDIC,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ICELANDIC */
MAKELANGID(LANG_MALTESE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MALTESE */
MAKELANGID(LANG_TURKISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TURKISH */
MAKELANGID(LANG_CROATIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_CROATIAN */
MAKELANGID(LANG_CHINESE_TRADITIONAL,SUBLANG_DEFAULT), /* TT_MAC_LANGID_CHINESE_TRADITIONAL */
MAKELANGID(LANG_URDU,SUBLANG_DEFAULT), /* TT_MAC_LANGID_URDU */
MAKELANGID(LANG_HINDI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_HINDI */
MAKELANGID(LANG_THAI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_THAI */
MAKELANGID(LANG_KOREAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_KOREAN */
MAKELANGID(LANG_LITHUANIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_LITHUANIAN */
MAKELANGID(LANG_POLISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_POLISH */
MAKELANGID(LANG_HUNGARIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_HUNGARIAN */
MAKELANGID(LANG_ESTONIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ESTONIAN */
MAKELANGID(LANG_LATVIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_LETTISH */
MAKELANGID(LANG_SAMI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SAAMISK */
MAKELANGID(LANG_FAEROESE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_FAEROESE */
MAKELANGID(LANG_FARSI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_FARSI */
MAKELANGID(LANG_RUSSIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_RUSSIAN */
MAKELANGID(LANG_CHINESE_SIMPLIFIED,SUBLANG_DEFAULT), /* TT_MAC_LANGID_CHINESE_SIMPLIFIED */
MAKELANGID(LANG_DUTCH,SUBLANG_DUTCH_BELGIAN), /* TT_MAC_LANGID_FLEMISH */
MAKELANGID(LANG_IRISH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_IRISH */
MAKELANGID(LANG_ALBANIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ALBANIAN */
MAKELANGID(LANG_ROMANIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ROMANIAN */
MAKELANGID(LANG_CZECH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_CZECH */
MAKELANGID(LANG_SLOVAK,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SLOVAK */
MAKELANGID(LANG_SLOVENIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SLOVENIAN */
0, /* TT_MAC_LANGID_YIDDISH */
MAKELANGID(LANG_SERBIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SERBIAN */
MAKELANGID(LANG_MACEDONIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MACEDONIAN */
MAKELANGID(LANG_BULGARIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_BULGARIAN */
MAKELANGID(LANG_UKRAINIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_UKRAINIAN */
MAKELANGID(LANG_BELARUSIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_BYELORUSSIAN */
MAKELANGID(LANG_UZBEK,SUBLANG_DEFAULT), /* TT_MAC_LANGID_UZBEK */
MAKELANGID(LANG_KAZAK,SUBLANG_DEFAULT), /* TT_MAC_LANGID_KAZAKH */
MAKELANGID(LANG_AZERI,SUBLANG_AZERI_CYRILLIC), /* TT_MAC_LANGID_AZERBAIJANI */
0, /* TT_MAC_LANGID_AZERBAIJANI_ARABIC_SCRIPT */
MAKELANGID(LANG_ARMENIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ARMENIAN */
MAKELANGID(LANG_GEORGIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_GEORGIAN */
0, /* TT_MAC_LANGID_MOLDAVIAN */
MAKELANGID(LANG_KYRGYZ,SUBLANG_DEFAULT), /* TT_MAC_LANGID_KIRGHIZ */
MAKELANGID(LANG_TAJIK,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TAJIKI */
MAKELANGID(LANG_TURKMEN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TURKMEN */
MAKELANGID(LANG_MONGOLIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MONGOLIAN */
MAKELANGID(LANG_MONGOLIAN,SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA), /* TT_MAC_LANGID_MONGOLIAN_CYRILLIC_SCRIPT */
MAKELANGID(LANG_PASHTO,SUBLANG_DEFAULT), /* TT_MAC_LANGID_PASHTO */
0, /* TT_MAC_LANGID_KURDISH */
MAKELANGID(LANG_KASHMIRI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_KASHMIRI */
MAKELANGID(LANG_SINDHI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SINDHI */
MAKELANGID(LANG_TIBETAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TIBETAN */
MAKELANGID(LANG_NEPALI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_NEPALI */
MAKELANGID(LANG_SANSKRIT,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SANSKRIT */
MAKELANGID(LANG_MARATHI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MARATHI */
MAKELANGID(LANG_BENGALI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_BENGALI */
MAKELANGID(LANG_ASSAMESE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ASSAMESE */
MAKELANGID(LANG_GUJARATI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_GUJARATI */
MAKELANGID(LANG_PUNJABI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_PUNJABI */
MAKELANGID(LANG_ORIYA,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ORIYA */
MAKELANGID(LANG_MALAYALAM,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MALAYALAM */
MAKELANGID(LANG_KANNADA,SUBLANG_DEFAULT), /* TT_MAC_LANGID_KANNADA */
MAKELANGID(LANG_TAMIL,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TAMIL */
MAKELANGID(LANG_TELUGU,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TELUGU */
MAKELANGID(LANG_SINHALESE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SINHALESE */
0, /* TT_MAC_LANGID_BURMESE */
MAKELANGID(LANG_KHMER,SUBLANG_DEFAULT), /* TT_MAC_LANGID_KHMER */
MAKELANGID(LANG_LAO,SUBLANG_DEFAULT), /* TT_MAC_LANGID_LAO */
MAKELANGID(LANG_VIETNAMESE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_VIETNAMESE */
MAKELANGID(LANG_INDONESIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_INDONESIAN */
0, /* TT_MAC_LANGID_TAGALOG */
MAKELANGID(LANG_MALAY,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MALAY_ROMAN_SCRIPT */
0, /* TT_MAC_LANGID_MALAY_ARABIC_SCRIPT */
MAKELANGID(LANG_AMHARIC,SUBLANG_DEFAULT), /* TT_MAC_LANGID_AMHARIC */
MAKELANGID(LANG_TIGRIGNA,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TIGRINYA */
0, /* TT_MAC_LANGID_GALLA */
0, /* TT_MAC_LANGID_SOMALI */
MAKELANGID(LANG_SWAHILI,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SWAHILI */
0, /* TT_MAC_LANGID_RUANDA */
0, /* TT_MAC_LANGID_RUNDI */
0, /* TT_MAC_LANGID_CHEWA */
MAKELANGID(LANG_MALAGASY,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MALAGASY */
MAKELANGID(LANG_ESPERANTO,SUBLANG_DEFAULT), /* TT_MAC_LANGID_ESPERANTO */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 95-111 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 112-127 */
MAKELANGID(LANG_WELSH,SUBLANG_DEFAULT), /* TT_MAC_LANGID_WELSH */
MAKELANGID(LANG_BASQUE,SUBLANG_DEFAULT), /* TT_MAC_LANGID_BASQUE */
MAKELANGID(LANG_CATALAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_CATALAN */
0, /* TT_MAC_LANGID_LATIN */
MAKELANGID(LANG_QUECHUA,SUBLANG_DEFAULT), /* TT_MAC_LANGID_QUECHUA */
0, /* TT_MAC_LANGID_GUARANI */
0, /* TT_MAC_LANGID_AYMARA */
MAKELANGID(LANG_TATAR,SUBLANG_DEFAULT), /* TT_MAC_LANGID_TATAR */
MAKELANGID(LANG_UIGHUR,SUBLANG_DEFAULT), /* TT_MAC_LANGID_UIGHUR */
0, /* TT_MAC_LANGID_DZONGKHA */
0, /* TT_MAC_LANGID_JAVANESE */
0, /* TT_MAC_LANGID_SUNDANESE */
MAKELANGID(LANG_GALICIAN,SUBLANG_DEFAULT), /* TT_MAC_LANGID_GALICIAN */
MAKELANGID(LANG_AFRIKAANS,SUBLANG_DEFAULT), /* TT_MAC_LANGID_AFRIKAANS */
MAKELANGID(LANG_BRETON,SUBLANG_DEFAULT), /* TT_MAC_LANGID_BRETON */
MAKELANGID(LANG_INUKTITUT,SUBLANG_DEFAULT), /* TT_MAC_LANGID_INUKTITUT */
MAKELANGID(LANG_SCOTTISH_GAELIC,SUBLANG_DEFAULT), /* TT_MAC_LANGID_SCOTTISH_GAELIC */
MAKELANGID(LANG_MANX_GAELIC,SUBLANG_DEFAULT), /* TT_MAC_LANGID_MANX_GAELIC */
MAKELANGID(LANG_IRISH,SUBLANG_IRISH_IRELAND), /* TT_MAC_LANGID_IRISH_GAELIC */
0, /* TT_MAC_LANGID_TONGAN */
0, /* TT_MAC_LANGID_GREEK_POLYTONIC */
MAKELANGID(LANG_GREENLANDIC,SUBLANG_DEFAULT), /* TT_MAC_LANGID_GREELANDIC */
MAKELANGID(LANG_AZERI,SUBLANG_AZERI_LATIN), /* TT_MAC_LANGID_AZERBAIJANI_ROMAN_SCRIPT */
};
if (sizeof(TT_OFFSET_TABLE) > size)
return NULL;
ttOffsetTable = *(TT_OFFSET_TABLE*)mem;
ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);
static inline WORD get_mac_code_page( const tt_name_record *name )
{
WORD encoding_id = GET_BE_WORD(name->encoding_id);
if (encoding_id == TT_MAC_ID_SIMPLIFIED_CHINESE) return 10008; /* special case */
return 10000 + encoding_id;
}
if (ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
return NULL;
static int match_name_table_language( const tt_name_record *name, LANGID lang )
{
LANGID name_lang;
pos = sizeof(ttOffsetTable);
for (i = 0; i < ttOffsetTable.uNumOfTables; i++)
switch (GET_BE_WORD(name->platform_id))
{
tblDir = (const TT_TABLE_DIRECTORY*)&mem[pos];
pos += sizeof(*tblDir);
if (memcmp(tblDir->szTag,"name",4)==0)
case TT_PLATFORM_MICROSOFT:
switch (GET_BE_WORD(name->encoding_id))
{
ofs = SWAPLONG(tblDir->uOffset);
case TT_MS_ID_UNICODE_CS:
case TT_MS_ID_SYMBOL_CS:
name_lang = GET_BE_WORD(name->language_id);
break;
default:
return 0;
}
break;
case TT_PLATFORM_MACINTOSH:
if (!IsValidCodePage( get_mac_code_page( name ))) return 0;
name_lang = GET_BE_WORD(name->language_id);
if (name_lang >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
name_lang = mac_langid_table[name_lang];
break;
case TT_PLATFORM_APPLE_UNICODE:
switch (GET_BE_WORD(name->encoding_id))
{
case TT_APPLE_ID_DEFAULT:
case TT_APPLE_ID_ISO_10646:
case TT_APPLE_ID_UNICODE_2_0:
name_lang = GET_BE_WORD(name->language_id);
if (name_lang >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
name_lang = mac_langid_table[name_lang];
break;
default:
return 0;
}
break;
default:
return 0;
}
if (name_lang == lang) return 3;
if (PRIMARYLANGID( name_lang ) == PRIMARYLANGID( lang )) return 2;
if (name_lang == MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT )) return 1;
return 0;
}
static WCHAR *copy_name_table_string( const tt_name_record *name, const BYTE *data, WCHAR *ret, DWORD len )
{
WORD name_len = GET_BE_WORD(name->length);
WORD codepage;
switch (GET_BE_WORD(name->platform_id))
{
case TT_PLATFORM_APPLE_UNICODE:
case TT_PLATFORM_MICROSOFT:
if (name_len >= len*sizeof(WCHAR))
return NULL;
for (len = 0; len < name_len / 2; len++)
ret[len] = (data[len * 2] << 8) | data[len * 2 + 1];
ret[len] = 0;
return ret;
case TT_PLATFORM_MACINTOSH:
codepage = get_mac_code_page( name );
len = MultiByteToWideChar( codepage, 0, (char *)data, name_len, ret, len-1 );
if (!len)
return NULL;
ret[len] = 0;
return ret;
}
return NULL;
}
static WCHAR *load_ttf_name_id( const BYTE *mem, DWORD_PTR size, DWORD id, WCHAR *ret, DWORD len )
{
LANGID lang = GetSystemDefaultLangID();
const tt_header *header;
const tt_name_table *name_table;
const tt_name_record *name_record;
DWORD pos, ofs, count;
int i, res, best_lang = 0, best_index = -1;
if (sizeof(tt_header) > size)
return NULL;
header = (const tt_header*)mem;
count = GET_BE_WORD(header->tables_no);
if (GET_BE_WORD(header->major_version) != 1 || GET_BE_WORD(header->minor_version) != 0)
return NULL;
pos = sizeof(*header);
for (i = 0; i < count; i++)
{
const tt_table_directory *table_directory = (const tt_table_directory*)&mem[pos];
pos += sizeof(*table_directory);
if (memcmp(table_directory->tag, "name", 4) == 0)
{
ofs = GET_BE_DWORD(table_directory->offset);
break;
}
}
if (i >= ttOffsetTable.uNumOfTables)
if (i >= count)
return NULL;
pos = ofs + sizeof(ttNTHeader);
if (ofs >= size)
return NULL;
pos = ofs + sizeof(*name_table);
if (pos > size)
return NULL;
ttNTHeader = *(TT_NAME_TABLE_HEADER*)&mem[ofs];
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
for(i=0; i<ttNTHeader.uNRCount; i++)
name_table = (const tt_name_table*)&mem[ofs];
count = GET_BE_WORD(name_table->count);
if (GET_BE_WORD(name_table->string_offset) >= size - ofs) return NULL;
ofs += GET_BE_WORD(name_table->string_offset);
for (i=0; i<count; i++)
{
ttRecord = *(TT_NAME_RECORD*)&mem[pos];
pos += sizeof(ttRecord);
name_record = (const tt_name_record*)&mem[pos];
pos += sizeof(*name_record);
if (pos > size)
return NULL;
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
if (ttRecord.uNameID == id)
{
const char *buf;
if (GET_BE_WORD(name_record->name_id) != id) continue;
if (GET_BE_WORD(name_record->offset) >= size - ofs) return NULL;
if (GET_BE_WORD(name_record->length) > size - ofs - GET_BE_WORD(name_record->offset)) return NULL;
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
if (ofs + ttRecord.uStringOffset + ttNTHeader.uStorageOffset + ttRecord.uStringLength > size)
return NULL;
buf = mem + ofs + ttRecord.uStringOffset + ttNTHeader.uStorageOffset;
len = MultiByteToWideChar(CP_ACP, 0, buf, ttRecord.uStringLength, ret, len-1);
ret[len] = 0;
return ret;
res = match_name_table_language( name_record, lang );
if (res > best_lang)
{
best_lang = res;
best_index = i;
}
}
if (best_lang)
{
name_record = (const tt_name_record*)(name_table + 1) + best_index;
ret = copy_name_table_string( name_record, mem+ofs+GET_BE_WORD(name_record->offset), ret, len );
TRACE( "name %u found platform %u lang %04x %s\n", GET_BE_WORD(name_record->name_id),
GET_BE_WORD(name_record->platform_id), GET_BE_WORD(name_record->language_id), debugstr_w( ret ));
return ret;
}
return NULL;
}

View file

@ -66,6 +66,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
free_installed_fonts();
break;
}

View file

@ -190,12 +190,12 @@
190 stdcall GdipDrawString(ptr wstr long ptr ptr ptr ptr)
191 stdcall GdipEmfToWmfBits(ptr long ptr long long)
192 stdcall GdipEndContainer(ptr ptr)
193 stub GdipEnumerateMetafileDestPoint
194 stub GdipEnumerateMetafileDestPointI
193 stdcall GdipEnumerateMetafileDestPoint(ptr ptr ptr ptr ptr ptr)
194 stdcall GdipEnumerateMetafileDestPointI(ptr ptr ptr ptr ptr ptr)
195 stub GdipEnumerateMetafileDestPoints
196 stub GdipEnumerateMetafileDestPointsI
197 stub GdipEnumerateMetafileDestRect
198 stub GdipEnumerateMetafileDestRectI
197 stdcall GdipEnumerateMetafileDestRect(ptr ptr ptr ptr ptr ptr)
198 stdcall GdipEnumerateMetafileDestRectI(ptr ptr ptr ptr ptr ptr)
199 stub GdipEnumerateMetafileSrcRectDestPoint
200 stub GdipEnumerateMetafileSrcRectDestPointI
201 stdcall GdipEnumerateMetafileSrcRectDestPoints(ptr ptr ptr long ptr long ptr ptr ptr)
@ -455,7 +455,7 @@
455 stdcall GdipReleaseDC(ptr ptr)
456 stdcall GdipRemovePropertyItem(ptr long)
457 stdcall GdipResetClip(ptr)
458 stub GdipResetImageAttributes
458 stdcall GdipResetImageAttributes(ptr long)
459 stdcall GdipResetLineTransform(ptr)
460 stdcall GdipResetPageTransform(ptr)
461 stdcall GdipResetPath(ptr)

View file

@ -170,7 +170,7 @@ struct GpGraphics{
REAL xres, yres;
GpMatrix worldtrans; /* world transform */
BOOL busy; /* hdc handle obtained by GdipGetDC */
GpRegion *clip;
GpRegion *clip; /* in device coords */
UINT textcontrast; /* not used yet. get/set only */
struct list containers;
GraphicsContainer contid; /* last-issued container ID */

View file

@ -68,6 +68,9 @@ static GpStatus draw_driver_string(GpGraphics *graphics, GDIPCONST UINT16 *text,
GDIPCONST GpBrush *brush, GDIPCONST PointF *positions,
INT flags, GDIPCONST GpMatrix *matrix);
static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space,
GpCoordinateSpace src_space, GpMatrix *matrix);
/* Converts from gdiplus path point type to gdi path point type. */
static BYTE convert_path_point_type(BYTE type)
{
@ -300,9 +303,6 @@ static void restore_dc(GpGraphics *graphics, INT state)
RestoreDC(graphics->hdc, state);
}
static GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space,
GpCoordinateSpace src_space, GpMatrix *matrix);
/* This helper applies all the changes that the points listed in ptf need in
* order to be drawn on the device context. In the end, this should include at
* least:
@ -366,6 +366,7 @@ static void gdi_alpha_blend(GpGraphics *graphics, INT dst_x, INT dst_y, INT dst_
static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn)
{
/* clipping region is in device coords */
return GdipGetRegionHRgn(graphics->clip, NULL, hrgn);
}
@ -2116,7 +2117,7 @@ static void get_font_hfont(GpGraphics *graphics, GDIPCONST GpFont *font,
(pt[2].X-pt[0].X)*(pt[2].X-pt[0].X));
get_log_fontW(font, graphics, &lfw);
lfw.lfHeight = gdip_round(font_height * rel_height);
lfw.lfHeight = -gdip_round(font_height * rel_height);
unscaled_font = CreateFontIndirectW(&lfw);
SelectObject(hdc, unscaled_font);
@ -4063,6 +4064,9 @@ GpStatus WINGDIPAPI GdipFlush(GpGraphics *graphics, GpFlushIntention intention)
*/
GpStatus WINGDIPAPI GdipGetClipBounds(GpGraphics *graphics, GpRectF *rect)
{
GpStatus status;
GpRegion *clip;
TRACE("(%p, %p)\n", graphics, rect);
if(!graphics)
@ -4071,7 +4075,15 @@ GpStatus WINGDIPAPI GdipGetClipBounds(GpGraphics *graphics, GpRectF *rect)
if(graphics->busy)
return ObjectBusy;
return GdipGetRegionBounds(graphics->clip, graphics, rect);
status = GdipCreateRegion(&clip);
if (status != Ok) return status;
status = GdipGetClip(graphics, clip);
if (status == Ok)
status = GdipGetRegionBounds(clip, graphics, rect);
GdipDeleteRegion(clip);
return status;
}
/*****************************************************************************
@ -5005,7 +5017,8 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string
if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23;
if (!(format_flags & StringFormatFlagsNoClip) &&
scaled_rect.Width != 1 << 23 && scaled_rect.Height != 1 << 23)
scaled_rect.Width != 1 << 23 && scaled_rect.Height != 1 << 23 &&
rect->Width > 0.0 && rect->Height > 0.0)
{
/* FIXME: If only the width or only the height is 0, we should probably still clip */
rgn = CreatePolygonRgn(corners, 4, ALTERNATE);
@ -5414,11 +5427,15 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode
if(!graphics)
return InvalidParameter;
if(graphics->busy)
return ObjectBusy;
/* hrgn is already in device units */
status = GdipCreateRegionHrgn(hrgn, &region);
if(status != Ok)
return status;
status = GdipSetClipRegion(graphics, region, mode);
status = GdipCombineRegionRegion(graphics->clip, region, mode);
GdipDeleteRegion(region);
return status;
@ -5426,6 +5443,9 @@ GpStatus WINGDIPAPI GdipSetClipHrgn(GpGraphics *graphics, HRGN hrgn, CombineMode
GpStatus WINGDIPAPI GdipSetClipPath(GpGraphics *graphics, GpPath *path, CombineMode mode)
{
GpStatus status;
GpPath *clip_path;
TRACE("(%p, %p, %d)\n", graphics, path, mode);
if(!graphics)
@ -5434,14 +5454,29 @@ GpStatus WINGDIPAPI GdipSetClipPath(GpGraphics *graphics, GpPath *path, CombineM
if(graphics->busy)
return ObjectBusy;
return GdipCombineRegionPath(graphics->clip, path, mode);
status = GdipClonePath(path, &clip_path);
if (status == Ok)
{
GpMatrix world_to_device;
get_graphics_transform(graphics, CoordinateSpaceDevice,
CoordinateSpaceWorld, &world_to_device);
status = GdipTransformPath(clip_path, &world_to_device);
if (status == Ok)
GdipCombineRegionPath(graphics->clip, clip_path, mode);
GdipDeletePath(clip_path);
}
return status;
}
GpStatus WINGDIPAPI GdipSetClipRect(GpGraphics *graphics, REAL x, REAL y,
REAL width, REAL height,
CombineMode mode)
{
GpStatus status;
GpRectF rect;
GpRegion *region;
TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %d)\n", graphics, x, y, width, height, mode);
@ -5455,8 +5490,19 @@ GpStatus WINGDIPAPI GdipSetClipRect(GpGraphics *graphics, REAL x, REAL y,
rect.Y = y;
rect.Width = width;
rect.Height = height;
status = GdipCreateRegionRect(&rect, &region);
if (status == Ok)
{
GpMatrix world_to_device;
return GdipCombineRegionRect(graphics->clip, &rect, mode);
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
status = GdipTransformRegion(region, &world_to_device);
if (status == Ok)
status = GdipCombineRegionRegion(graphics->clip, region, mode);
GdipDeleteRegion(region);
}
return status;
}
GpStatus WINGDIPAPI GdipSetClipRectI(GpGraphics *graphics, INT x, INT y,
@ -5477,6 +5523,9 @@ GpStatus WINGDIPAPI GdipSetClipRectI(GpGraphics *graphics, INT x, INT y,
GpStatus WINGDIPAPI GdipSetClipRegion(GpGraphics *graphics, GpRegion *region,
CombineMode mode)
{
GpStatus status;
GpRegion *clip;
TRACE("(%p, %p, %d)\n", graphics, region, mode);
if(!graphics || !region)
@ -5485,7 +5534,19 @@ GpStatus WINGDIPAPI GdipSetClipRegion(GpGraphics *graphics, GpRegion *region,
if(graphics->busy)
return ObjectBusy;
return GdipCombineRegionRegion(graphics->clip, region, mode);
status = GdipCloneRegion(region, &clip);
if (status == Ok)
{
GpMatrix world_to_device;
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &world_to_device);
status = GdipTransformRegion(clip, &world_to_device);
if (status == Ok)
status = GdipCombineRegionRegion(graphics->clip, clip, mode);
GdipDeleteRegion(clip);
}
return status;
}
GpStatus WINGDIPAPI GdipSetMetafileDownLevelRasterizationLimit(GpMetafile *metafile,
@ -5743,6 +5804,7 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
{
GpRegion *clip;
GpStatus status;
GpMatrix device_to_world;
TRACE("(%p, %p)\n", graphics, region);
@ -5755,6 +5817,14 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
if((status = GdipCloneRegion(graphics->clip, &clip)) != Ok)
return status;
get_graphics_transform(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &device_to_world);
status = GdipTransformRegion(clip, &device_to_world);
if (status != Ok)
{
GdipDeleteRegion(clip);
return status;
}
/* free everything except root node and header */
delete_element(&region->node);
memcpy(region, clip, sizeof(GpRegion));

View file

@ -270,3 +270,20 @@ GpStatus WINGDIPAPI GdipSetImageAttributesToIdentity(GpImageAttributes *imageAtt
return NotImplemented;
}
GpStatus WINGDIPAPI GdipResetImageAttributes(GpImageAttributes *imageAttr,
ColorAdjustType type)
{
TRACE("(%p,%u)\n", imageAttr, type);
if(!imageAttr || type >= ColorAdjustTypeCount)
return InvalidParameter;
memset(&imageAttr->colorkeys[type], 0, sizeof(imageAttr->colorkeys[type]));
memset(&imageAttr->colormatrices[type], 0, sizeof(imageAttr->colormatrices[type]));
memset(&imageAttr->colorremaptables[type], 0, sizeof(imageAttr->colorremaptables[type]));
memset(&imageAttr->gamma_enabled[type], 0, sizeof(imageAttr->gamma_enabled[type]));
memset(&imageAttr->gamma[type], 0, sizeof(imageAttr->gamma[type]));
return Ok;
}

View file

@ -551,6 +551,69 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics *graphics,
return stat;
}
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRect(GpGraphics *graphics,
GDIPCONST GpMetafile *metafile, GDIPCONST GpRectF *dest,
EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
{
GpPointF points[3];
if (!graphics || !metafile || !dest) return InvalidParameter;
points[0].X = points[2].X = dest->X;
points[0].Y = points[1].Y = dest->Y;
points[1].X = dest->X + dest->Width;
points[2].Y = dest->Y + dest->Height;
return GdipEnumerateMetafileSrcRectDestPoints(graphics, metafile, points, 3,
&metafile->bounds, metafile->unit, callback, cb_data, attrs);
}
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRectI(GpGraphics *graphics,
GDIPCONST GpMetafile *metafile, GDIPCONST GpRect *dest,
EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
{
GpRectF destf;
if (!graphics || !metafile || !dest) return InvalidParameter;
destf.X = dest->X;
destf.Y = dest->Y;
destf.Width = dest->Width;
destf.Height = dest->Height;
return GdipEnumerateMetafileDestRect(graphics, metafile, &destf, callback, cb_data, attrs);
}
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPoint(GpGraphics *graphics,
GDIPCONST GpMetafile *metafile, GDIPCONST GpPointF *dest,
EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
{
GpRectF destf;
if (!graphics || !metafile || !dest) return InvalidParameter;
destf.X = dest->X;
destf.Y = dest->Y;
destf.Width = units_to_pixels(metafile->bounds.Width, metafile->unit, metafile->image.xres);
destf.Height = units_to_pixels(metafile->bounds.Height, metafile->unit, metafile->image.yres);
return GdipEnumerateMetafileDestRect(graphics, metafile, &destf, callback, cb_data, attrs);
}
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPointI(GpGraphics *graphics,
GDIPCONST GpMetafile *metafile, GDIPCONST GpPoint *dest,
EnumerateMetafileProc callback, VOID *cb_data, GDIPCONST GpImageAttributes *attrs)
{
GpPointF ptf;
if (!graphics || !metafile || !dest) return InvalidParameter;
ptf.X = dest->X;
ptf.Y = dest->Y;
return GdipEnumerateMetafileDestPoint(graphics, metafile, &ptf, callback, cb_data, attrs);
}
static int CALLBACK get_metafile_type_proc(HDC hDC, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR,
int nObj, LPARAM lpData)
{

View file

@ -87,6 +87,8 @@ static GpPenType bt_to_pt(GpBrushType bt)
GpStatus WINGDIPAPI GdipClonePen(GpPen *pen, GpPen **clonepen)
{
GpStatus stat;
TRACE("(%p, %p)\n", pen, clonepen);
if(!pen || !clonepen)
@ -97,9 +99,34 @@ GpStatus WINGDIPAPI GdipClonePen(GpPen *pen, GpPen **clonepen)
**clonepen = *pen;
GdipCloneCustomLineCap(pen->customstart, &(*clonepen)->customstart);
GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend);
GdipCloneBrush(pen->brush, &(*clonepen)->brush);
(*clonepen)->customstart = NULL;
(*clonepen)->customend = NULL;
(*clonepen)->brush = NULL;
(*clonepen)->dashes = NULL;
stat = GdipCloneBrush(pen->brush, &(*clonepen)->brush);
if (stat == Ok && pen->customstart)
stat = GdipCloneCustomLineCap(pen->customstart, &(*clonepen)->customstart);
if (stat == Ok && pen->customend)
stat = GdipCloneCustomLineCap(pen->customend, &(*clonepen)->customend);
if (stat == Ok && pen->dashes)
{
(*clonepen)->dashes = GdipAlloc(pen->numdashes * sizeof(REAL));
if ((*clonepen)->dashes)
memcpy((*clonepen)->dashes, pen->dashes, pen->numdashes * sizeof(REAL));
else
stat = OutOfMemory;
}
if (stat != Ok)
{
GdipDeletePen(*clonepen);
*clonepen = NULL;
return stat;
}
TRACE("<-- %p\n", *clonepen);

View file

@ -716,7 +716,7 @@ GpStatus WINGDIPAPI GdipGetRegionBoundsI(GpRegion *region, GpGraphics *graphics,
status = GdipGetRegionBounds(region, graphics, &rectf);
if(status == Ok){
rect->X = gdip_round(rectf.X);
rect->Y = gdip_round(rectf.X);
rect->Y = gdip_round(rectf.Y);
rect->Width = gdip_round(rectf.Width);
rect->Height = gdip_round(rectf.Height);
}

View file

@ -704,6 +704,8 @@ enum EmfPlusRecordType {
EmfPlusRecordTypeMin = EmfPlusRecordTypeHeader
};
#define FlatnessDefault 0.25f
#ifndef __cplusplus
typedef enum Unit Unit;

View file

@ -206,6 +206,14 @@ GpStatus WINGDIPAPI GdipDrawRectanglesI(GpGraphics*,GpPen*,GDIPCONST GpRect*,INT
GpStatus WINGDIPAPI GdipDrawString(GpGraphics*,GDIPCONST WCHAR*,INT,
GDIPCONST GpFont*,GDIPCONST RectF*, GDIPCONST GpStringFormat*,
GDIPCONST GpBrush*);
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPoint(GpGraphics*,GDIPCONST GpMetafile*,
GDIPCONST GpPointF*,EnumerateMetafileProc,VOID*,GDIPCONST GpImageAttributes*);
GpStatus WINGDIPAPI GdipEnumerateMetafileDestPointI(GpGraphics*,GDIPCONST GpMetafile*,
GDIPCONST GpPoint*,EnumerateMetafileProc,VOID*,GDIPCONST GpImageAttributes*);
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRect(GpGraphics*,GDIPCONST GpMetafile*,
GDIPCONST GpRectF*,EnumerateMetafileProc,VOID*,GDIPCONST GpImageAttributes*);
GpStatus WINGDIPAPI GdipEnumerateMetafileDestRectI(GpGraphics*,GDIPCONST GpMetafile*,
GDIPCONST GpRect*,EnumerateMetafileProc,VOID*,GDIPCONST GpImageAttributes*);
GpStatus WINGDIPAPI GdipEnumerateMetafileSrcRectDestPoints(GpGraphics*,
GDIPCONST GpMetafile*,GDIPCONST GpPointF*,INT,GDIPCONST GpRectF*,Unit,
EnumerateMetafileProc,VOID*,GDIPCONST GpImageAttributes*);
@ -450,6 +458,8 @@ GpStatus WINGDIPAPI GdipSetImageAttributesToIdentity(GpImageAttributes*,
ColorAdjustType);
GpStatus WINGDIPAPI GdipSetImageAttributesWrapMode(GpImageAttributes*,WrapMode,
ARGB,BOOL);
GpStatus WINGDIPAPI GdipResetImageAttributes(GpImageAttributes*,
ColorAdjustType);
/* LinearGradientBrush */
GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF*,GDIPCONST GpPointF*,

View file

@ -73,7 +73,7 @@ reactos/dll/win32/dciman32 # Synced to Wine-1.7.1
reactos/dll/win32/dwmapi # Synced to Wine-1.7.1
reactos/dll/win32/faultrep # Synced to Wine-1.7.1
reactos/dll/win32/fusion # Synced to Wine-1.7.1
reactos/dll/win32/gdiplus # Synced to Wine-1.5.26
reactos/dll/win32/gdiplus # Synced to Wine-1.7.1
reactos/dll/win32/hhctrl.ocx # Synced to Wine-1.5.26
reactos/dll/win32/hlink # Synced to Wine-1.5.4
reactos/dll/win32/hnetcfg # Synced to Wine-1.5.4