From d17757a7338f69f1f280d0871a492cdcc0cd9a84 Mon Sep 17 00:00:00 2001 From: Daniel Reimer Date: Fri, 16 Jul 2010 12:52:37 +0000 Subject: [PATCH] [PATCH] user32: DrawText: CJK and Thai line-wrapping [PATCH] appwiz: check if path is valid Both by Katayama Hirofumi svn path=/trunk/; revision=48077 --- reactos/dll/cpl/appwiz/createlink.c | 18 +++++++----- reactos/dll/win32/user32/windows/font.c | 37 +++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/reactos/dll/cpl/appwiz/createlink.c b/reactos/dll/cpl/appwiz/createlink.c index faceb8fd0fa..609eb2342d1 100644 --- a/reactos/dll/cpl/appwiz/createlink.c +++ b/reactos/dll/cpl/appwiz/createlink.c @@ -324,6 +324,7 @@ ShowCreateShortcutWizard(HWND hwndCPl, LPWSTR szPath) PROPSHEETPAGE psp; UINT nPages = 0; UINT nLength; + DWORD attrs; PCREATE_LINK_CONTEXT pContext = (PCREATE_LINK_CONTEXT) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CREATE_LINK_CONTEXT)); if (!pContext) @@ -337,10 +338,13 @@ ShowCreateShortcutWizard(HWND hwndCPl, LPWSTR szPath) /* no directory given */ return FALSE; } - /// - /// FIXME - /// check if path is valid - /// + + attrs = GetFileAttributesW(szPath); + if (attrs == INVALID_FILE_ATTRIBUTES || (attrs & FILE_ATTRIBUTE_DIRECTORY)) + { + /* invalid path */ + return FALSE; + } wcscpy(pContext->szLinkName, szPath); if (pContext->szLinkName[nLength-1] != L'\\') @@ -389,7 +393,7 @@ NewLinkHere(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { WCHAR szFile[MAX_PATH]; - if (MultiByteToWideChar(CP_ACP, 0, (char*)lParam1, strlen((char*)lParam1)+1, szFile, MAX_PATH)) + if (MultiByteToWideChar(CP_ACP, 0, (LPSTR) lParam1, -1, szFile, MAX_PATH)) { return ShowCreateShortcutWizard(hwndCPl, szFile); } @@ -401,7 +405,7 @@ LONG CALLBACK NewLinkHereW(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { - return ShowCreateShortcutWizard(hwndCPl, (LPWSTR)lParam1); + return ShowCreateShortcutWizard(hwndCPl, (LPWSTR) lParam1); } LONG @@ -410,7 +414,7 @@ NewLinkHereA(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { WCHAR szFile[MAX_PATH]; - if (MultiByteToWideChar(CP_ACP, 0, (char*)lParam1, strlen((char*)lParam1)+1, szFile, MAX_PATH)) + if (MultiByteToWideChar(CP_ACP, 0, (LPSTR) lParam1, -1, szFile, MAX_PATH)) { return ShowCreateShortcutWizard(hwndCPl, szFile); } diff --git a/reactos/dll/win32/user32/windows/font.c b/reactos/dll/win32/user32/windows/font.c index 4d1ac982db8..a0fede9dbb6 100644 --- a/reactos/dll/win32/user32/windows/font.c +++ b/reactos/dll/win32/user32/windows/font.c @@ -495,6 +495,38 @@ static void TEXT_PathEllipsify (HDC hdc, WCHAR *str, unsigned int max_len, } } +/* Check the character is Chinese, Japanese, Korean and/or Thai */ +inline BOOL IsCJKT(WCHAR wch) +{ + if (0x0E00 <= wch && wch <= 0x0E7F) + return TRUE; /* Thai */ + + if (0x3000 <= wch && wch <= 0x9FFF) + return TRUE; /* CJK */ + + if (0xAC00 <= wch && wch <= 0xD7FF) + return TRUE; /* Korean */ + + if (0xFF00 <= wch && wch <= 0xFFEF) + return TRUE; /* CJK */ + + return FALSE; +} + +/* See http://en.wikipedia.org/wiki/Kinsoku_shori */ +static const WCHAR KinsokuClassA[] = +{ + 0x2010, 0x2013, 0x2019, 0x201D, 0x203C, 0x2047, 0x2048, 0x2049, 0x3001, + 0x3002, 0x3005, 0x3009, 0x300B, 0x300D, 0x300F, 0x3011, 0x3015, 0x3017, + 0x3019, 0x301C, 0x301F, 0x303B, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049, + 0x3063, 0x3083, 0x3085, 0x3087, 0x308E, 0x3095, 0x3096, 0x30A0, 0x30A1, + 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30C3, 0x30E3, 0x30E5, 0x30E7, 0x30EE, + 0x30F5, 0x30F6, 0x30FB, 0x30FC, 0x30FD, 0x30FE, 0x31F0, 0x31F1, 0x31F2, + 0x31F3, 0x31F4, 0x31F5, 0x31F6, 0x31F7, 0x31F8, 0x31F9, 0x31FA, 0x31FB, + 0x31FC, 0x31FD, 0x31FE, 0x31FF, 0xFF01, 0xFF09, 0xFF0C, 0xFF0E, 0xFF1A, + 0xFF1B, 0xFF1F, 0xFF3D, 0xFF5D, 0xFF60, 0 +}; + /********************************************************************* * TEXT_WordBreak (static) * @@ -576,9 +608,10 @@ static void TEXT_WordBreak (HDC hdc, WCHAR *str, unsigned int max_str, p--; /* the word just fitted */ else { - while (p > str && *(--p) != SPACE) + while (p > str && *(--p) != SPACE && (!IsCJKT(p[1]) || + p[1] == L'\0' || wcschr(KinsokuClassA, p[1]) != NULL)) ; - word_fits = (p != str || *p == SPACE); + word_fits = (p != str || *p == SPACE || IsCJKT(p[1])); } /* If there was one or the first character didn't fit then */ if (word_fits)