diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/CMakeLists.txt | 5 | ||||
-rw-r--r-- | intern/SConscript | 1 | ||||
-rw-r--r-- | intern/ghost/CMakeLists.txt | 4 | ||||
-rw-r--r-- | intern/ghost/SConscript | 1 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_DropTargetWin32.cpp | 17 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemPathsWin32.cpp | 26 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 77 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.cpp | 22 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.h | 4 | ||||
-rw-r--r-- | intern/utfconv/CMakeLists.txt | 24 | ||||
-rw-r--r-- | intern/utfconv/SConscript | 12 | ||||
-rw-r--r-- | intern/utfconv/utf_winfunc.c | 156 | ||||
-rw-r--r-- | intern/utfconv/utf_winfunc.h | 44 | ||||
-rw-r--r-- | intern/utfconv/utfconv.c | 232 | ||||
-rw-r--r-- | intern/utfconv/utfconv.h | 102 |
15 files changed, 674 insertions, 53 deletions
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index 9f5217e68e3..5637fa383a1 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -66,3 +66,8 @@ if(WITH_CYCLES) add_subdirectory(cycles) endif() + +#Only Windows needs utf16 converter +if(WIN32) + add_subdirectory(utfconv) +endif()
\ No newline at end of file diff --git a/intern/SConscript b/intern/SConscript index bb19426263a..196a80433c9 100644 --- a/intern/SConscript +++ b/intern/SConscript @@ -3,6 +3,7 @@ Import ('env') SConscript(['audaspace/SConscript', 'string/SConscript', + 'utfconv/SConscript', 'ghost/SConscript', 'guardedalloc/SConscript', 'moto/SConscript', diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 5693aea0865..5c653ac92c0 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -281,6 +281,10 @@ elseif(WIN32) ${WINTAB_INC} ) + list(APPEND INC + ../utfconv + ) + list(APPEND SRC intern/GHOST_DisplayManagerWin32.cpp intern/GHOST_SystemWin32.cpp diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 3410f11a971..2265daa8fff 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -110,6 +110,7 @@ else: if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'): incs = env['BF_WINTAB_INC'] + ' ' + incs + incs += ' ../utfconv' if window_system in ('win32-vc', 'win64-vc'): env.BlenderLib ('bf_intern_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15]) #, cc_compileflags=env['CCFLAGS'].append('/WX') ) diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp index 4c9072d2ce6..c13c242bc7e 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp +++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp @@ -34,6 +34,9 @@ #include "GHOST_DropTargetWin32.h" #include <ShellApi.h> +#include "utf_winfunc.h" +#include "utfconv.h" + #ifdef GHOST_DEBUG // utility void printLastError(void); @@ -267,20 +270,12 @@ void * GHOST_DropTargetWin32::getDropDataAsFilenames(IDataObject * pDataObject) { if ( ::DragQueryFileW ( hdrop, nfile, fpath, MAX_PATH ) > 0 ) { - if ( !WideCharToANSI(fpath, temp_path) ) + if ( !(temp_path = alloc_utf_8_from_16(fpath, 0)) ) { continue; } // Just ignore paths that could not be converted verbatim. - if (strpbrk(temp_path, "?")) - { -#ifdef GHOST_DEBUG - ::printf("\ndiscarding path that contains illegal characters: %s", temp_path); -#endif // GHOST_DEBUG - ::free(temp_path); - temp_path = NULL; - continue; - } + strArray->strings[nvalid] = (GHOST_TUns8*) temp_path; strArray->count = nvalid+1; nvalid++; @@ -309,7 +304,7 @@ void * GHOST_DropTargetWin32::getDropDataAsString(IDataObject * pDataObject) if(pDataObject->GetData(&fmtetc, &stgmed) == S_OK) { LPCWSTR wstr = (LPCWSTR)::GlobalLock(stgmed.hGlobal); - if ( !WideCharToANSI(wstr, tmp_string) ) + if ( !(tmp_string = alloc_utf_8_from_16((wchar_t*)wstr, 0)) ) { ::GlobalUnlock(stgmed.hGlobal); return NULL; diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp index 379e1963c40..29c2e9c0227 100644 --- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp @@ -35,6 +35,7 @@ #define _WIN32_IE 0x0501 #endif #include <shlobj.h> +#include "utfconv.h" #if defined(__MINGW32__) || defined(__CYGWIN__) @@ -70,11 +71,14 @@ GHOST_SystemPathsWin32::~GHOST_SystemPathsWin32() const GHOST_TUns8* GHOST_SystemPathsWin32::getSystemDir() const { - static char knownpath[MAX_PATH]; - HRESULT hResult = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath); + static char knownpath[MAX_PATH*3] = {0}; /* 1 utf-16 might translante into 3 utf-8. 2 utf-16 translates into 4 utf-8*/ + wchar_t knownpath_16[MAX_PATH]; + + HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); if (hResult == S_OK) { + conv_utf_16_to_8(knownpath_16,knownpath,MAX_PATH*3); return (GHOST_TUns8*)knownpath; } @@ -83,11 +87,14 @@ const GHOST_TUns8* GHOST_SystemPathsWin32::getSystemDir() const const GHOST_TUns8* GHOST_SystemPathsWin32::getUserDir() const { - static char knownpath[MAX_PATH]; - HRESULT hResult = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath); + static char knownpath[MAX_PATH*3] = {0}; + wchar_t knownpath_16[MAX_PATH]; + + HRESULT hResult = SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, knownpath_16); if (hResult == S_OK) { + conv_utf_16_to_8(knownpath_16,knownpath,MAX_PATH*3); return (GHOST_TUns8*)knownpath; } @@ -96,8 +103,11 @@ const GHOST_TUns8* GHOST_SystemPathsWin32::getUserDir() const const GHOST_TUns8* GHOST_SystemPathsWin32::getBinaryDir() const { - static char fullname[MAX_PATH]; - if(GetModuleFileName(0, fullname, MAX_PATH)) { + static char fullname[MAX_PATH*3] = {0}; + wchar_t fullname_16[MAX_PATH*3]; + + if(GetModuleFileNameW(0, fullname_16, MAX_PATH)) { + conv_utf_16_to_8(fullname_16,fullname,MAX_PATH*3); return (GHOST_TUns8*)fullname; } @@ -107,5 +117,7 @@ const GHOST_TUns8* GHOST_SystemPathsWin32::getBinaryDir() const void GHOST_SystemPathsWin32::addToSystemRecentFiles(const char* filename) const { /* SHARD_PATH resolves to SHARD_PATHA for non-UNICODE build */ - SHAddToRecentDocs(SHARD_PATH,filename); + UTF16_ENCODE(filename) + SHAddToRecentDocs(SHARD_PATHW,filename_16); + UTF16_UN_ENCODE(filename) } diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index b478fea706c..b79185b1637 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -60,6 +60,8 @@ #endif #endif +#include "utfconv.h" + #include "GHOST_DisplayManagerWin32.h" #include "GHOST_EventButton.h" #include "GHOST_EventCursor.h" @@ -292,8 +294,8 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent) } // Process all the events waiting for us - while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0) { - ::DispatchMessage(&msg); + while (::PeekMessageW(&msg, 0, 0, 0, PM_REMOVE) != 0) { + ::DispatchMessageW(&msg); anyProcessed = true; } } while (waitForEvent && !anyProcessed); @@ -394,7 +396,7 @@ GHOST_TSuccess GHOST_SystemWin32::init() } if (success) { - WNDCLASS wc; + WNDCLASSW wc; wc.style= CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc= s_wndProc; wc.cbClsExtra= 0; @@ -408,10 +410,10 @@ GHOST_TSuccess GHOST_SystemWin32::init() wc.hCursor = ::LoadCursor(0, IDC_ARROW); wc.hbrBackground= (HBRUSH)::GetStockObject(BLACK_BRUSH); wc.lpszMenuName = 0; - wc.lpszClassName= GHOST_WindowWin32::getWindowClassName(); + wc.lpszClassName= L"GHOST_WindowClass"; // Use RegisterClassEx for setting small icon - if (::RegisterClass(&wc) == 0) { + if (::RegisterClassW(&wc) == 0) { success = GHOST_kFailure; } } @@ -719,15 +721,17 @@ GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINP char utf8_char[6] = {0}; char ascii = 0; - wchar_t utf16[2]={0}; + wchar_t utf16[3]={0}; BYTE state[256] ={0}; - GetKeyboardState(state); + int r; + GetKeyboardState((PBYTE)state); + + if(r = ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout)) - if(ToUnicodeEx(vk, 0, state, utf16, 2, 0, system->m_keylayout)) - WideCharToMultiByte(CP_UTF8, 0, - (wchar_t*)utf16, 1, - (LPSTR) utf8_char, 5, - NULL,NULL); else *utf8_char = 0; + if((r>0 && r<3)){utf16[r]=0; + + conv_utf_16_to_8(utf16,utf8_char,6);} + else if (r==-1) utf8_char[0] = '\0'; @@ -1189,8 +1193,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * DefWindowProc returns. */ break; - - //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// // Other events //////////////////////////////////////////////////////////////////////// case WM_GETTEXT: @@ -1239,17 +1242,17 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } if (!eventHandled) - lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); + lResult = ::DefWindowProcW(hwnd, msg, wParam, lParam); return lResult; } GHOST_TUns8* GHOST_SystemWin32::getClipboard(bool selection) const { - wchar_t *buffer; char *temp_buff; if ( IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL) ) { + wchar_t *buffer; size_t len = 0; HANDLE hData = GetClipboardData( CF_UNICODETEXT ); if (hData == NULL) { @@ -1262,9 +1265,32 @@ GHOST_TUns8* GHOST_SystemWin32::getClipboard(bool selection) const return NULL; } - len = WideCharToMultiByte(CP_UTF8, 0, buffer, -1, NULL, 0, NULL, NULL); - temp_buff = (char*) malloc(len); - WideCharToMultiByte(CP_UTF8, 0, buffer, -1, temp_buff, len, NULL, NULL); + temp_buff = alloc_utf_8_from_16(buffer,0); + + /* Buffer mustn't be accessed after CloseClipboard + it would like accessing free-d memory */ + GlobalUnlock( hData ); + CloseClipboard(); + + return (GHOST_TUns8*)temp_buff; + } else if ( IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL) ) { + char *buffer; + size_t len = 0; + HANDLE hData = GetClipboardData( CF_TEXT ); + if (hData == NULL) { + CloseClipboard(); + return NULL; + } + buffer = (char*)GlobalLock( hData ); + if (!buffer) { + CloseClipboard(); + return NULL; + } + + len = strlen(buffer); + temp_buff = (char*) malloc(len+1); + strncpy(temp_buff, buffer, len); + temp_buff[len] = '\0'; /* Buffer mustn't be accessed after CloseClipboard it would like accessing free-d memory */ @@ -1281,20 +1307,19 @@ void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const { if(selection) {return;} // for copying the selection, used on X11 - if (OpenClipboard(NULL)) { + if(OpenClipboard(NULL)) { HLOCAL clipbuffer; wchar_t *data; if (buffer) { + size_t len = count_utf_16_from_8(buffer); EmptyClipboard(); - int wlen = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, NULL, 0); - - clipbuffer = LocalAlloc(LMEM_FIXED, wlen * sizeof(wchar_t)); + clipbuffer = LocalAlloc(LMEM_FIXED,sizeof(wchar_t) * len); data = (wchar_t*)GlobalLock(clipbuffer); - - MultiByteToWideChar(CP_UTF8, 0, buffer, -1, data, wlen); - + + conv_utf_8_to_16(buffer, data, len); + LocalUnlock(clipbuffer); SetClipboardData(CF_UNICODETEXT,clipbuffer); } diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 8e37d1832df..9d105748095 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -41,6 +41,8 @@ #include "GHOST_WindowWin32.h" #include "GHOST_SystemWin32.h" #include "GHOST_DropTargetWin32.h" +#include "utfconv.h" +#include "utf_winfunc.h" // Need glew for some defines #include <GL/glew.h> @@ -64,7 +66,7 @@ #endif #endif -LPCSTR GHOST_WindowWin32::s_windowClassName = "GHOST_WindowClass"; +wchar_t* GHOST_WindowWin32::s_windowClassName = L"GHOST_WindowClass"; const int GHOST_WindowWin32::s_maxTitleLength = 128; HGLRC GHOST_WindowWin32::s_firsthGLRc = NULL; HDC GHOST_WindowWin32::s_firstHDC = NULL; @@ -234,9 +236,10 @@ GHOST_WindowWin32::GHOST_WindowWin32( height = rect.bottom - rect.top; } - m_hWnd = ::CreateWindow( + wchar_t * title_16 = alloc_utf16_from_8((char*)(const char*)title,0); + m_hWnd = ::CreateWindowW( s_windowClassName, // pointer to registered class name - title, // pointer to window name + title_16, // pointer to window name wintype, // window style left, // horizontal position of window top, // vertical position of window @@ -246,11 +249,13 @@ GHOST_WindowWin32::GHOST_WindowWin32( 0, // handle to menu or child-window identifier ::GetModuleHandle(0), // handle to application instance 0); // pointer to window-creation data + free(title_16); } else { - m_hWnd = ::CreateWindow( + wchar_t * title_16 = alloc_utf16_from_8((char*)(const char*)title,0); + m_hWnd = ::CreateWindowW( s_windowClassName, // pointer to registered class name - title, // pointer to window name + title_16, // pointer to window name WS_POPUP | WS_MAXIMIZE, // window style left, // horizontal position of window top, // vertical position of window @@ -260,6 +265,7 @@ GHOST_WindowWin32::GHOST_WindowWin32( 0, // handle to menu or child-window identifier ::GetModuleHandle(0), // handle to application instance 0); // pointer to window-creation data + free(title_16); } if (m_hWnd) { // Register this window as a droptarget. Requires m_hWnd to be valid. @@ -433,13 +439,15 @@ HWND GHOST_WindowWin32::getHWND() const void GHOST_WindowWin32::setTitle(const STR_String& title) { - ::SetWindowText(m_hWnd, title); + wchar_t * title_16 = alloc_utf16_from_8((char*)(const char*)title, 0); + ::SetWindowTextW(m_hWnd, (wchar_t*)title_16); + free(title_16); } void GHOST_WindowWin32::getTitle(STR_String& title) const { - char buf[s_maxTitleLength]; + char buf[s_maxTitleLength];/*CHANGE + never used yet*/ ::GetWindowText(m_hWnd, buf, s_maxTitleLength); STR_String temp (buf); title = buf; diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 6eb17affdbf..c8e88c8d844 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -236,7 +236,7 @@ public: * Returns the name of the window class. * @return The name of the window class. */ - static LPCSTR getWindowClassName() { return s_windowClassName; } + static wchar_t* getWindowClassName() { return s_windowClassName; } /** * Register a mouse click event (should be called @@ -351,7 +351,7 @@ protected: /** ITaskbarList3 structure for progress bar*/ ITaskbarList3 * m_Bar; - static LPCSTR s_windowClassName; + static wchar_t* s_windowClassName; static const int s_maxTitleLength; /** WinTab dll handle */ diff --git a/intern/utfconv/CMakeLists.txt b/intern/utfconv/CMakeLists.txt new file mode 100644 index 00000000000..9dd41c28406 --- /dev/null +++ b/intern/utfconv/CMakeLists.txt @@ -0,0 +1,24 @@ +set(INC + . +) + +set(INC_SYS + ${GLEW_INCLUDE_PATH} +) + +set(SRC + utfconv.c + + utfconv.h + #utf_func.h +) + + +if(WIN32) + list(APPEND SRC + utf_winfunc.c + utf_winfunc.h + ) +endif() + +blender_add_lib(bf_intern_utfconv "${SRC}" "${INC}" "${INC_SYS}")
\ No newline at end of file diff --git a/intern/utfconv/SConscript b/intern/utfconv/SConscript new file mode 100644 index 00000000000..1f0fab330d3 --- /dev/null +++ b/intern/utfconv/SConscript @@ -0,0 +1,12 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') + +incs = '.' +defs = '' + + + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + env.BlenderLib ('bf_utfconv', sources, Split(incs), Split(defs), libtype=['intern','player'], priority=[0,0] ) diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c new file mode 100644 index 00000000000..09f5dfff67e --- /dev/null +++ b/intern/utfconv/utf_winfunc.c @@ -0,0 +1,156 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifdef WIN32 + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0501 +#endif + +#include "utf_winfunc.h" +#include <io.h> +#include <Windows.h> +#include <wchar.h> + + +FILE * ufopen(const char * filename, const char * mode) +{ + FILE * f = NULL; + UTF16_ENCODE(filename); + UTF16_ENCODE (mode); + + if(filename_16 && mode_16) f = _wfopen(filename_16, mode_16); + + UTF16_UN_ENCODE(mode); + UTF16_UN_ENCODE(filename); + + if(!f) + { + if(f=fopen(filename,mode)) + printf("WARNING: %s is not utf path. Please update it.\n",filename); + } + + return f; +} + +int uopen(const char *filename, int oflag, int pmode) +{ + int f = -1; + UTF16_ENCODE(filename); + + if(filename_16) f = _wopen(filename_16, oflag, pmode); + + UTF16_UN_ENCODE(filename); + + if(f==-1) + { + if((f=open(filename,oflag, pmode))!=-1) + printf("WARNING: %s is not utf path. Please update it.\n",filename); + } + + return f; +} + +int urename(const char *oldname, const char *newname ) +{ + int r = -1; + UTF16_ENCODE(oldname); + UTF16_ENCODE (newname); + + if(oldname_16 && newname_16) r = _wrename(oldname_16, newname_16); + + UTF16_UN_ENCODE(newname); + UTF16_UN_ENCODE(oldname); + return r; +} + +int umkdir(const char *pathname) +{ + + BOOL r = 0; + UTF16_ENCODE(pathname); + + if(pathname_16) r = CreateDirectoryW(pathname_16, NULL); + + UTF16_UN_ENCODE(pathname); + + return r?0:-1; +} + +char * u_alloc_getenv(const char *varname) +{ + char * r = 0; + wchar_t * str; + UTF16_ENCODE(varname); + if(varname_16){ str = _wgetenv(varname_16); + r = alloc_utf_8_from_16(str,0);} + UTF16_UN_ENCODE(varname); + + return r; +} +void u_free_getenv(char *val) +{ + free(val); +} + +int uput_getenv(const char *varname, char * value, size_t buffsize) +{ + int r = 0; + wchar_t * str; + if(!buffsize) return r; + + UTF16_ENCODE(varname); + if(varname_16) + { + str = _wgetenv(varname_16); + conv_utf_16_to_8(str, value, buffsize); + r = 1; + } + UTF16_UN_ENCODE(varname); + + if(!r) value[0] = 0; + + return r; +} + + + +int uputenv(const char *name, const char *value) +{ + int r = -1; + UTF16_ENCODE(name) + UTF16_ENCODE(value) + if(name_16 && value_16) { + if(SetEnvironmentVariableW(name_16,value_16)!=0) + r =0; + else r = -1; + } + UTF16_UN_ENCODE(value) + UTF16_UN_ENCODE(name) + + return r; +} + +#endif
\ No newline at end of file diff --git a/intern/utfconv/utf_winfunc.h b/intern/utfconv/utf_winfunc.h new file mode 100644 index 00000000000..5e88d2de901 --- /dev/null +++ b/intern/utfconv/utf_winfunc.h @@ -0,0 +1,44 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifdef WIN32 + + +#include "utfconv.h" +#include <stdio.h> + +FILE * ufopen(const char * filename, const char * mode); +int uopen(const char *filename, int oflag, int pmode); +int urename(const char *oldname, const char *newname ); + +char * u_alloc_getenv(const char *varname); +void u_free_getenv(char *val); + +int uput_getenv(const char *varname, char * value, size_t buffsize); +int uputenv(const char *name, const char *value); + +int umkdir(const char *pathname); + +#endif
\ No newline at end of file diff --git a/intern/utfconv/utfconv.c b/intern/utfconv/utfconv.c new file mode 100644 index 00000000000..9aeca36e55a --- /dev/null +++ b/intern/utfconv/utfconv.c @@ -0,0 +1,232 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "utfconv.h" + +size_t count_utf_8_from_16(wchar_t * string16) +{ + int i; + size_t count = 0; + wchar_t u = 0; + if(!string16) return 0; + + for(i=0;u = string16[i];i++) + { + if(u < 0x0080) count+=1; else + if(u < 0x0800) count+=2; else + if(u < 0xD800) count+=3; else + if(u < 0xDC00) { + i++; + if((u = string16[i])==0) break; + if(u >= 0xDC00 && u < 0xE000)count+=4; + } else + if(u < 0xE000) /*illigal*/; else + count+=3; + } + + return ++count; +} + + +size_t count_utf_16_from_8(char * string8) +{ + size_t count = 0; + char u; + char type = 0; + unsigned int u32 = 0; + + if(!string8) return 0; + + for(;(u = *string8);string8++) + { + if(type==0) + { + if((u&0x01<<7) == 0) {count++; u32 = 0; continue;} //1 utf-8 char + if((u&0x07<<5) == 0xC0) {type=1; u32 = u & 0x1F; continue;} //2 utf-8 char + if((u&0x0F<<4) == 0xE0) {type=2; u32 = u & 0x0F; continue;} //3 utf-8 char + if((u&0x1F<<3) == 0xF0) {type=3; u32 = u & 0x07; continue;} //4 utf-8 char + continue; + } else + { + if((u & 0xC0) == 0x80) {u32=(u32<<6) | (u&0x3F); type--;} else + {u32 = 0; type = 0;}; + } + if(type==0) + { + if((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000)) count++; else + if(0x10000 <= u32 && u32 < 0x110000) count+=2; + u32 = 0; + } + + } + + return ++count; +} + + + + +int conv_utf_16_to_8(wchar_t * in16, char * out8, size_t size8) +{ + char * out8end = out8+size8; + wchar_t u = 0; + int err = 0; + if(!size8 || !in16 || !out8) return UTF_ERROR_NULL_IN; + out8end--; + + for(; out8 < out8end && (u=*in16); in16++, out8++) + { + if(u < 0x0080) *out8 = u; else + if(u < 0x0800) { + if(out8 + 1 >= out8end) break; + *out8++=(0x3<<6) | (0x1F & (u>>6)); + *out8 =(0x1<<7) | (0x3F & (u)); + }else + if(u < 0xD800 || u >= 0xE000) { + if(out8 + 2 >= out8end) break; + *out8++=(0x7<<5) | (0xF & (u>>12)); + *out8++=(0x1<<7) | (0x3F & (u>>6));; + *out8 =(0x1<<7) | (0x3F & (u)); + }else + if(u < 0xDC00) { + wchar_t u2 = *++in16; + + if(!u2) break; + if(u2 >= 0xDC00 && u2 < 0xE000) + { + if(out8 + 3 >= out8end) break; else { + unsigned int uc = 0x10000 + (u2 - 0xDC00) + ((u - 0xD800)<<10); + + *out8++=(0xF<<4) | (0x7 & (uc>>18)); + *out8++=(0x1<<7) | (0x3F & (uc>>12)); + *out8++=(0x1<<7) | (0x3F & (uc>>6)); + *out8 =(0x1<<7) | (0x3F & (uc)); + } + } else {out8--; err|=UTF_ERROR_ILLCHAR;}; + } else + if(u < 0xE000) {out8--; err|=UTF_ERROR_ILLCHAR;} + + + } + + *out8=*out8end=0; + + if(*in16) err|=UTF_ERROR_SMALL; + + return err; +} + + +int conv_utf_8_to_16(char * in8, wchar_t * out16, size_t size16) +{ + char u; + char type = 0; + wchar_t u32 = 0; + wchar_t * out16end = out16+size16; + int err = 0; + if(!size16 || !in8 || !out16) return UTF_ERROR_NULL_IN; + out16end--; + + for(;out16<out16end && (u = *in8);in8++) + { + if(type==0) + { + if((u&0x01<<7) == 0) {*out16=u; out16++; u32 = 0; continue;} //1 utf-8 char + if((u&0x07<<5) == 0xC0) {type=1; u32 = u & 0x1F; continue;} //2 utf-8 char + if((u&0x0F<<4) == 0xE0) {type=2; u32 = u & 0x0F; continue;} //3 utf-8 char + if((u&0x1F<<3) == 0xF0) {type=3; u32 = u & 0x07; continue;} //4 utf-8 char + err|=UTF_ERROR_ILLCHAR; continue; + } else + { + if((u & 0xC0) == 0x80) {u32=(u32<<6) | (u&0x3F); type--;} else + {u32 = 0; type = 0; err|=UTF_ERROR_ILLSEQ;}; + } + if(type==0) + { + if((0 < u32 && u32 < 0xD800) || (0xE000 <= u32 && u32 < 0x10000)) {*out16=u32; out16++;}else + if(0x10000 <= u32 && u32 < 0x110000) { + if(out16 + 1 >= out16end) break; + u32-=0x10000; + *out16 = 0xD800 + (u32 >> 10); + out16++; + *out16 = 0xDC00 + (u32 & 0x3FF); + out16++; + }; + u32 = 0; + } + + } + + *out16=*out16end=0; + + if(*in8) err|=UTF_ERROR_SMALL; + + return err; +} + +int is_ascii(char * in8) +{ + for(in8; *in8; in8++) + if(0x80 & *in8) return 0; + + return 1; +} + +void utf_8_cut_end(char * inout8, size_t maxcutpoint) +{ + const char * start = inout8; + char * cur = inout8 + maxcutpoint; + char cc; + if(!inout8) return; + + cc = *cur; + + + + +} + + + +char * alloc_utf_8_from_16(wchar_t * in16, size_t add) +{ + size_t bsize = count_utf_8_from_16(in16); + char * out8 = NULL; + if(!bsize) return NULL; + out8 = (char*)malloc(sizeof(char) * (bsize + add)); + conv_utf_16_to_8(in16,out8, bsize); + return out8; +} + +wchar_t * alloc_utf16_from_8(char * in8, size_t add) +{ + size_t bsize = count_utf_16_from_8(in8); + wchar_t * out16 = NULL; + if(!bsize) return NULL; + out16 =(wchar_t*) malloc(sizeof(wchar_t) * (bsize + add)); + conv_utf_8_to_16(in8,out16, bsize); + return out16; +} + diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h new file mode 100644 index 00000000000..185c76422e2 --- /dev/null +++ b/intern/utfconv/utfconv.h @@ -0,0 +1,102 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Alexandr Kuznetsov, Andrea Weikert + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <wchar.h> +#include <stdio.h> +#include <stdlib.h> + + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Counts how many bytes is requered for for future utf-8 string using utf-16 + * @param string-16 pointer to working utf-16 string + * @return How many bytes must be allocated includeng NULL. + */ +size_t count_utf_8_from_16(wchar_t * string16); + +/** + * Counts how many wchar_t (two byte) is requered for for future utf-16 string using utf-8 + * @param string-8 pointer to working utf-8 string + * @return How many bytes must be allocated includeng NULL. + */ +size_t count_utf_16_from_8(char * string8); + +/** + * conv_utf_*** errors + */ +#define UTF_ERROR_NULL_IN 1<<0 /* Error occures when requered parameter is missing*/ +#define UTF_ERROR_ILLCHAR 1<<1 /* Error if character is in illigal UTF rage*/ +#define UTF_ERROR_SMALL 1<<2 /* Passed size is to small. It gives legal string with character missing at the end*/ +#define UTF_ERROR_ILLSEQ 1<<3 /* Error if sequence is broken and doesn't finish*/ + +/** + * Converts utf-16 string to allocated utf-8 string + * @params in16 utf-16 string to convert + * @params out8 utf-8 string to string the conversion + * @params size8 the allocated size in bytes of out8 + * @return Returns any errors occured during conversion. See the block above, + */ +int conv_utf_16_to_8(wchar_t * in16, char * out8, size_t size8); + +/** + * Converts utf-8 string to allocated utf-16 string + * @params in8 utf-8 string to convert + * @params out16 utf-16 string to string the conversion + * @params size16 the allocated size in wchar_t (two byte) of out16 + * @return Returns any errors occured during conversion. See the block above, + */ +int conv_utf_8_to_16(char * in8, wchar_t * out16, size_t size16); + + +/** + * Allocates and converts the utf-8 string from utf-16 + * @params in16 utf-16 string to convert + * @params add any additional size which will be allocated for new utf-8 string in bytes + * @return New allocated and converted utf-8 string or NULL if in16 is 0. + */ +char * alloc_utf_8_from_16(wchar_t * in16, size_t add); + +/** + * Allocates and converts the utf-16 string from utf-8 + * @params in8 utf-8 string to convert + * @params add any additional size which will be allocated for new utf-16 string in wchar_t (two bytes) + * @return New allocated and converted utf-16 string or NULL if in8 is 0. + */ +wchar_t * alloc_utf16_from_8(char * in8, size_t add); + +/* Easy allocation and conversion of new utf-16 string. New string has _16 suffix. Must be deallocated with UTF16_UN_ENCODE in right order*/ +#define UTF16_ENCODE(in8str) if(1){\ + wchar_t * in8str ## _16 = alloc_utf16_from_8((char*)in8str, 0); + +#define UTF16_UN_ENCODE(in8str) \ + free(in8str ## _16 ); }; + +#ifdef __cplusplus +} +#endif
\ No newline at end of file |