From 34ff69130826ac72f1481f82ef7f0fda0cce0a3e Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Thu, 2 Dec 2021 12:03:19 +0100 Subject: [PATCH] sizeof(wchar) is changed to 4 (32 bits) to support non BMP unicode characters This might bring some incompatibilities in the code that expects wchar to be 16 bit, which escpecially involves dealing with Win32 (and to lesser extend MacOS) APIs, so if your application is doing that, please check all instances of WCHAR (UniChar on MacOS) or even wchar especially type casts. To support host APIs, char16 is introduced (but there is no 16-bit String varian). Use ToSystemCharsetW, FromSystemCharsetW to convert texts to Win32 API. - Support of drawing non-BMP characters in GUI - Vastly improved character font replacement code (when drawing characters missing with requested font, replacement font is used) - Last instances of Win32 ANSI calls (those ending with A) are removed - UTF handling routines are refactored and their's naming is unified - RTF is now being able to handle non-BMP characters (RTF is used as clipboard format for RichText) Other minor changes: - fixed TryRealloc issue - improved MemoryCheck - Removed MemoryAlloc48/MemoryFree48 - In theide Background parsing should less often cause delays in the main thread --- autotest/UnicodeInfo/UnicodeInfo.cpp | 2 +- autotest/WStringSerialize/Etalon.log | 238 ++++++----- .../WStringSerialize/WStringSerialize.cpp | 2 +- autotest/WStringSerialize/wstring.bin | Bin 10213 -> 36175 bytes autotest/std_wstring/std_wstring.cpp | 25 ++ autotest/std_wstring/std_wstring.upp | 9 + .../GetMemoryBlockSize/GetMemoryBlockSize.cpp | 17 + .../GetMemoryBlockSize/GetMemoryBlockSize.upp | 9 + examples/MemorySize/MemorySize.cpp | 17 + examples/MemorySize/MemorySize.upp | 9 + examples/WeirdBug/WeirdBug.cpp | 13 + examples/WeirdBug/WeirdBug.upp | 9 + rainbow/WinAlt/DrawTextWinAlt.cpp | 5 +- rainbow/WinAlt/TopWinAlt.cpp | 2 +- reference/OpenGL/OpenGL.upp | 2 +- uppbox/FontMaps2/TypeReader.cpp | 130 +++--- uppbox/FontMaps2/TypeReader.h | 13 +- uppbox/FontMaps2/main.cpp | 114 ++++- uppsrc/CodeEditor/FindReplace.cpp | 4 +- uppsrc/Core/App.cpp | 50 +-- uppsrc/Core/Bom.cpp | 2 +- uppsrc/Core/CharSet.cpp | 22 +- uppsrc/Core/CharSet.h | 239 +++++------ uppsrc/Core/Core.h | 10 +- uppsrc/Core/Cpu.cpp | 6 +- uppsrc/Core/CvFlt.cpp | 38 +- uppsrc/Core/Defs.h | 6 +- uppsrc/Core/FileMapping.cpp | 2 +- uppsrc/Core/Format.cpp | 2 +- uppsrc/Core/Heap.h | 3 - uppsrc/Core/HeapImp.h | 32 +- uppsrc/Core/Lang.h | 4 +- uppsrc/Core/LangInfo.cpp | 6 +- uppsrc/Core/LocalProcess.cpp | 12 +- uppsrc/Core/Mem.h | 18 + uppsrc/Core/NetNode.cpp | 45 +- uppsrc/Core/Ops.h | 2 - uppsrc/Core/Path.cpp | 24 +- uppsrc/Core/Path.h | 19 +- uppsrc/Core/SSL/InitExit.cpp | 56 +-- uppsrc/Core/Speller.cpp | 2 +- uppsrc/Core/SplitMerge.cpp | 2 +- uppsrc/Core/StrUtil.cpp | 19 +- uppsrc/Core/Stream.cpp | 69 ++-- uppsrc/Core/Stream.h | 7 +- uppsrc/Core/String.cpp | 25 +- uppsrc/Core/String.h | 39 +- uppsrc/Core/StringFind.cpp | 4 +- uppsrc/Core/UnicodeInfo.cpp | 60 +-- uppsrc/Core/Utf.cpp | 144 +++---- uppsrc/Core/Utf.hpp | 42 +- uppsrc/Core/Util.cpp | 68 +-- uppsrc/Core/Util.h | 14 +- uppsrc/Core/ValueUtil.cpp | 8 - uppsrc/Core/WString.cpp | 68 ++- uppsrc/Core/Win32Util.cpp | 10 +- uppsrc/Core/Xmlize.cpp | 4 +- uppsrc/Core/config.h | 2 + uppsrc/Core/heap.cpp | 30 +- uppsrc/Core/heapdbg.cpp | 2 - uppsrc/Core/lheap.cpp | 18 +- uppsrc/Core/sheap.cpp | 27 +- uppsrc/Core/src.tpp/Heap_en-us.tpp | 12 - uppsrc/Core/src.tpp/StreamFn_en-us.tpp | 11 +- uppsrc/Core/src.tpp/Stream_en-us.tpp | 31 -- uppsrc/Core/src.tpp/String_en-us.tpp | 3 +- uppsrc/CppBase/ppfile.cpp | 15 +- uppsrc/CtrlCore/CocoClip.mm | 7 +- uppsrc/CtrlCore/CocoDnD.cpp | 7 +- uppsrc/CtrlCore/CocoDrawText.mm | 21 +- uppsrc/CtrlCore/CtrlCore.h | 31 +- uppsrc/CtrlCore/CtrlKbd.cpp | 2 +- uppsrc/CtrlCore/CtrlMt.cpp | 13 +- uppsrc/CtrlCore/CtrlTimer.cpp | 8 + uppsrc/CtrlCore/DrawTextWin32.cpp | 5 +- uppsrc/CtrlCore/DrawTextX11.cpp | 2 +- uppsrc/CtrlCore/DrawWin32.cpp | 8 +- uppsrc/CtrlCore/EncodeRTF.cpp | 10 +- uppsrc/CtrlCore/GtkClip.cpp | 4 +- uppsrc/CtrlCore/GtkEvent.cpp | 4 +- uppsrc/CtrlCore/ImageWin32.cpp | 7 +- uppsrc/CtrlCore/ParseRTF.cpp | 15 +- uppsrc/CtrlCore/TopWin32.cpp | 10 +- uppsrc/CtrlCore/Win32Clip.cpp | 13 +- uppsrc/CtrlCore/Win32DnD.cpp | 5 +- uppsrc/CtrlCore/Win32Gui.h | 2 +- uppsrc/CtrlCore/Win32Proc.cpp | 17 +- uppsrc/CtrlCore/Win32Wnd.cpp | 111 ++--- uppsrc/CtrlLib/AKeys.cpp | 2 +- uppsrc/CtrlLib/ChWin32.cpp | 11 +- uppsrc/CtrlLib/CtrlUtil.h | 38 +- uppsrc/CtrlLib/DocEdit.cpp | 4 +- uppsrc/CtrlLib/DropList.cpp | 2 +- uppsrc/CtrlLib/EditField.cpp | 2 +- uppsrc/CtrlLib/FileList.cpp | 2 +- uppsrc/CtrlLib/FileSel.cpp | 18 +- uppsrc/CtrlLib/Help.cpp | 2 +- uppsrc/CtrlLib/LineEdit.cpp | 31 +- uppsrc/CtrlLib/PopupTable.cpp | 1 + uppsrc/CtrlLib/SuggestCtrl.cpp | 2 +- uppsrc/CtrlLib/Text.cpp | 30 +- uppsrc/CtrlLib/TextEdit.h | 5 +- uppsrc/CtrlLib/TrayIconWin32.cpp | 66 ++- uppsrc/CtrlLib/TreeCtrl.cpp | 2 +- uppsrc/CtrlLib/Win32.cpp | 56 +-- uppsrc/Draw/Draw.h | 4 +- uppsrc/Draw/Draw.upp | 3 +- uppsrc/Draw/DrawText.cpp | 8 +- uppsrc/Draw/DrawTextUtil.cpp | 2 +- uppsrc/Draw/Drawing.cpp | 56 +-- uppsrc/Draw/Font.cpp | 46 ++- uppsrc/Draw/FontCR.cpp | 268 +++++++++--- uppsrc/Draw/FontCoco.mm | 55 ++- uppsrc/Draw/FontFc.cpp | 85 ++-- uppsrc/Draw/FontInt.h | 11 +- uppsrc/Draw/FontWin32.cpp | 110 ++++- uppsrc/Draw/Fonts.i | 388 ++++++++++++++++++ uppsrc/Draw/Image.cpp | 2 +- uppsrc/Draw/src.tpp/Font_en-us.tpp | 12 +- uppsrc/Esc/Esc.cpp | 4 +- uppsrc/GLCtrl/GLCtrl.cpp | 4 + uppsrc/HexView/HexView.cpp | 2 +- uppsrc/ODBC/ODBC.cpp | 5 +- uppsrc/Painter/DrawOp.cpp | 2 +- uppsrc/Painter/Painter.cpp | 4 +- uppsrc/RichEdit/Kbd.cpp | 2 +- uppsrc/RichText/ParaData.cpp | 4 +- uppsrc/RichText/ParseQtf.cpp | 25 +- uppsrc/ide/About.cpp | 6 +- uppsrc/ide/Browser/Base.cpp | 19 + uppsrc/ide/Browser/Browser.h | 2 + uppsrc/ide/Builders/Build.cpp | 17 +- uppsrc/ide/Builders/Build.h | 1 + uppsrc/ide/Calc.cpp | 2 +- uppsrc/ide/Core/Util.cpp | 3 +- uppsrc/ide/Debug.cpp | 2 +- uppsrc/ide/Debuggers/Sym.cpp | 15 +- uppsrc/ide/Errors.cpp | 4 +- uppsrc/ide/FindInFiles.cpp | 2 +- uppsrc/ide/Help.cpp | 2 +- uppsrc/ide/LayDes/laydes.cpp | 1 + uppsrc/ide/LayDes/textprop.cpp | 2 +- uppsrc/ide/Navigator.cpp | 2 + uppsrc/ide/ide.cpp | 4 +- uppsrc/ide/ide.h | 4 +- uppsrc/ide/idefile.cpp | 20 +- upptst/CJK/CJK.upp | 12 + upptst/CJK/main.cpp | 37 ++ upptst/FileSel/main.cpp | 30 +- 149 files changed, 2373 insertions(+), 1446 deletions(-) create mode 100644 autotest/std_wstring/std_wstring.cpp create mode 100644 autotest/std_wstring/std_wstring.upp create mode 100644 examples/GetMemoryBlockSize/GetMemoryBlockSize.cpp create mode 100644 examples/GetMemoryBlockSize/GetMemoryBlockSize.upp create mode 100644 examples/MemorySize/MemorySize.cpp create mode 100644 examples/MemorySize/MemorySize.upp create mode 100644 examples/WeirdBug/WeirdBug.cpp create mode 100644 examples/WeirdBug/WeirdBug.upp create mode 100644 uppsrc/Draw/Fonts.i create mode 100644 upptst/CJK/CJK.upp create mode 100644 upptst/CJK/main.cpp diff --git a/autotest/UnicodeInfo/UnicodeInfo.cpp b/autotest/UnicodeInfo/UnicodeInfo.cpp index 70a36d106..7245c394f 100644 --- a/autotest/UnicodeInfo/UnicodeInfo.cpp +++ b/autotest/UnicodeInfo/UnicodeInfo.cpp @@ -82,7 +82,7 @@ CONSOLE_APP_MAIN ASSERT(comb == UnicodeDecompose(code)); - Vector h = UnicodeDecompose(code, true); + WString h = UnicodeDecompose(code, true); if(h.GetCount() > 1) { DUMP(h); ASSERT(code == UnicodeCompose(h)); diff --git a/autotest/WStringSerialize/Etalon.log b/autotest/WStringSerialize/Etalon.log index 4f161b6c1..26eb9be16 100644 --- a/autotest/WStringSerialize/Etalon.log +++ b/autotest/WStringSerialize/Etalon.log @@ -1,103 +1,139 @@ -* C:\upp\out\autotest\CLANGx64.Debug.Debug_Full\WStringSerialize.exe 13.10.2021 09:17:22, user: cxl +* C:\upp\out\wchar_autotest\CLANGx64.Debug.Debug_Full\WStringSerialize.exe 13.10.2021 10:00:28, user: cxl x: - [0] = x - [1] = xx - [2] = xxx - [3] = xxxx - [4] = xxxxx - [5] = xxxxxx - [6] = xxxxxxx - [7] = xxxxxxxx - [8] = xxxxxxxxx - [9] = xxxxxxxxxx - [10] = xxxxxxxxxxx - [11] = xxxxxxxxxxxx - [12] = xxxxxxxxxxxxx - [13] = xxxxxxxxxxxxxx - [14] = xxxxxxxxxxxxxxx - [15] = xxxxxxxxxxxxxxxx - [16] = xxxxxxxxxxxxxxxxx - [17] = xxxxxxxxxxxxxxxxxx - [18] = xxxxxxxxxxxxxxxxxxx - [19] = xxxxxxxxxxxxxxxxxxxx - [20] = xxxxxxxxxxxxxxxxxxxxx - [21] = xxxxxxxxxxxxxxxxxxxxxx - [22] = xxxxxxxxxxxxxxxxxxxxxxx - [23] = xxxxxxxxxxxxxxxxxxxxxxxx - [24] = xxxxxxxxxxxxxxxxxxxxxxxxx - [25] = xxxxxxxxxxxxxxxxxxxxxxxxxx - [26] = xxxxxxxxxxxxxxxxxxxxxxxxxxx - [27] = xxxxxxxxxxxxxxxxxxxxxxxxxxxx - [28] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [29] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [30] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [31] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [32] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [33] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [34] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [35] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [36] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [37] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [38] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [39] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [40] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [41] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [42] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [43] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [44] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [45] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [46] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [47] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [48] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [49] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [50] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [51] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [52] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [53] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [54] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [55] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [56] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [57] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [58] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [59] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [60] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [61] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [62] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [63] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [64] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [65] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [66] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [67] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [68] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [69] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [70] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [71] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [72] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [73] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [74] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [75] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [76] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [77] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [78] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [79] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [80] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [81] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [82] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [83] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [84] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [85] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [86] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [87] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [88] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [89] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [90] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [91] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [92] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [93] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [94] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [95] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [96] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [97] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [98] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - [99] = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + [0] = 0 + [1] = 01 + [2] = 012 + [3] = 0123 + [4] = 01234 + [5] = 012345 + [6] = 0123456 + [7] = 01234567 + [8] = 012345678 + [9] = 0123456789 + [10] = 012345678910 + [11] = 01234567891011 + [12] = 0123456789101112 + [13] = 012345678910111213 + [14] = 01234567891011121314 + [15] = 0123456789101112131415 + [16] = 012345678910111213141516 + [17] = 01234567891011121314151617 + [18] = 0123456789101112131415161718 + [19] = 012345678910111213141516171819 + [20] = 01234567891011121314151617181920 + [21] = 0123456789101112131415161718192021 + [22] = 012345678910111213141516171819202122 + [23] = 01234567891011121314151617181920212223 + [24] = 0123456789101112131415161718192021222324 + [25] = 012345678910111213141516171819202122232425 + [26] = 01234567891011121314151617181920212223242526 + [27] = 0123456789101112131415161718192021222324252627 + [28] = 012345678910111213141516171819202122232425262728 + [29] = 01234567891011121314151617181920212223242526272829 + [30] = 0123456789101112131415161718192021222324252627282930 + [31] = 012345678910111213141516171819202122232425262728293031 + [32] = 01234567891011121314151617181920212223242526272829303132 + [33] = 0123456789101112131415161718192021222324252627282930313233 + [34] = 012345678910111213141516171819202122232425262728293031323334 + [35] = 01234567891011121314151617181920212223242526272829303132333435 + [36] = 0123456789101112131415161718192021222324252627282930313233343536 + [37] = 012345678910111213141516171819202122232425262728293031323334353637 + [38] = 01234567891011121314151617181920212223242526272829303132333435363738 + [39] = 0123456789101112131415161718192021222324252627282930313233343536373839 + [40] = 012345678910111213141516171819202122232425262728293031323334353637383940 + [41] = 01234567891011121314151617181920212223242526272829303132333435363738394041 + [42] = 0123456789101112131415161718192021222324252627282930313233343536373839404142 + [43] = 012345678910111213141516171819202122232425262728293031323334353637383940414243 + [44] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344 + [45] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445 + [46] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546 + [47] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647 + [48] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 + [49] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 + [50] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 + [51] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 + [52] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 + [53] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 + [54] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 + [55] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 + [56] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 + [57] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 + [58] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 + [59] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 + [60] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 + [61] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 + [62] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 + [63] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 + [64] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 + [65] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 + [66] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 + [67] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 + [68] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 + [69] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 + [70] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 + [71] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 + [72] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 + [73] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 + [74] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 + [75] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 + [76] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 + [77] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 + [78] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 + [79] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 + [80] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 + [81] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 + [82] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 + [83] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 + [84] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 + [85] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 + [86] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 + [87] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 + [88] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 + [89] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 + [90] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 + [91] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 + [92] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 + [93] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 + [94] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 + [95] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 + [96] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 + [97] = 012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 + [98] = 01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 + [99] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 + [100] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 + [101] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 + [102] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 + [103] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 + [104] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 + [105] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 + [106] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 + [107] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 + [108] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 + [109] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 + [110] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 + [111] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 + [112] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 + [113] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 + [114] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 + [115] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 + [116] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 + [117] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 + [118] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 + [119] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 + [120] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 + [121] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 + [122] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 + [123] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 + [124] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 + [125] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 + [126] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 + [127] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 + [128] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 + [129] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 + [130] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 + [131] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 + [132] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 + [133] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 + [134] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 + [135] = 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 diff --git a/autotest/WStringSerialize/WStringSerialize.cpp b/autotest/WStringSerialize/WStringSerialize.cpp index 8fa95af27..cf077102e 100644 --- a/autotest/WStringSerialize/WStringSerialize.cpp +++ b/autotest/WStringSerialize/WStringSerialize.cpp @@ -7,6 +7,6 @@ CONSOLE_APP_MAIN Vector x; LoadFromFile(x, GetDataFile("wstring.bin")); DDUMPC(x); + ASSERT(StoreAsString(x) == LoadDataFile("wstring.bin")); CheckLogEtalon(); - RLOG("================= OK"); } diff --git a/autotest/WStringSerialize/wstring.bin b/autotest/WStringSerialize/wstring.bin index 6f7659b26187d21defcf0e520586ee141062f9ed..024b4d8dd184a52581bdc97e60ea26920810288c 100644 GIT binary patch literal 36175 zcmeHQ4Ww0B82$R0>LpWBNhMQKd6Ikn&q@>ulKq?=iYmMmcx7Zp1aT9-(G9&Z-4vzd}m(wu8pn#^X!ZNKKM57{l~z@fA}S|2_JurtndFjVw*U0S7MVswbQYheL36@ z4h)gNhL=GnAH3OVN6j7AGO7TC;Y3Og3stY!~zEV4PR9OPJRb6Y*ovBbV= z=U^AC&TqE@7wj*{q7oM>S(sHtF4VL*%gS7+u0QJvU8r+OCn|NJ;-#Ic*oE3_ovhr& zsBk;p07j4BjYd3-vankXc^HjxHyiUXYL|7pK@X#Qc`q9E;00Fns$mb_Vr4HI_uy4l z_1XXr-e+|ljPT&4zRrsw9=zE%c{0X_*ISb}gM4_$b$K+(hZkL+SHpaG+YNa(&WBh2 zHtz=d@ZKAXV5AQ(zo{sO`j`zi7s*&3v&NR98SG>UgdJ?yPQCqqOT`>N8>5Yfo~Ds?tQ)N-I|9S#xQ9IRreLqtJ`s@m}o(bC~6 zcRoZ^b)@P5gowV53WNlMp=QSfL>-6-(cE!?@g9r_QQt`c@-ZM0qQg@HWhf{SqR5{F z%%_2g5N)0jIKzVzAu2s9fJO!=!i0TJAblRB2vP2N0o52#5u)J>0;_SbVnods1z2-{ z#fYvi3AE-x!+pATS-`ahT#RV_iok0fyckjaRRP!@fH9)~YXY%-5M!(ot_#R)fQ+%4 zxFImJ12e{|<7WYyEub-0CpQIZ_Mj$M#oQ9GodGt%YUj4V?HsrXRz<%E;LZY^VDBn}cY)nKuoJA>?g;Si0?yX%3iR%So?sRDhk)-5@CjCne+vBG zfzK>PHTz2x^qK+^;n+P9kq;tBhimsmN1o^)DV{wLDfuIX)cE#L)Z~>K5){}Y5tMI& zNK0B+>EVWUFfBeGNo-jczQy1{*0q*6-cR%rsGkmWCvsE+aBr_H9 zd1~GS&)W)EiW^@P!`B=zDKt|yGJy{tALf1Bywc5@Sc)6pIKaHi%y!6}HhfZ+w;}Vg zD_dhtEX9p!jhQ5nDPH(MDDR-<)jwLq)>souabsRRW;@|CkG%1dm!D`gEn;h|iKVzP z=?5R_t1A6-Gt>qe|t$d5LS7MTm z%52hEsZqKrw@P<4W;tJ-T`p7`AU)Mb$i*Z=k<8D3W7 d#+O3u3&>jhE6DnOSVD^XV-4B(R^&%7`~(&ZSFiv8 diff --git a/autotest/std_wstring/std_wstring.cpp b/autotest/std_wstring/std_wstring.cpp new file mode 100644 index 000000000..15d9ad1bc --- /dev/null +++ b/autotest/std_wstring/std_wstring.cpp @@ -0,0 +1,25 @@ +#include + +using namespace Upp; + +CONSOLE_APP_MAIN +{ + StdLogSetup(LOG_COUT|LOG_FILE); + + DDUMP(sizeof(wchar_t)); + + WString x; + x.Cat(48); + x.Cat(48000); + x.Cat(70000); + + std::wstring w = x; + + DDUMP(w.size()); + + WString y = w; + + ASSERT(x == y); + + DLOG("============= OK"); +} diff --git a/autotest/std_wstring/std_wstring.upp b/autotest/std_wstring/std_wstring.upp new file mode 100644 index 000000000..d8e70fde2 --- /dev/null +++ b/autotest/std_wstring/std_wstring.upp @@ -0,0 +1,9 @@ +uses + Core; + +file + std_wstring.cpp; + +mainconfig + "" = ""; + diff --git a/examples/GetMemoryBlockSize/GetMemoryBlockSize.cpp b/examples/GetMemoryBlockSize/GetMemoryBlockSize.cpp new file mode 100644 index 000000000..9f3deb37b --- /dev/null +++ b/examples/GetMemoryBlockSize/GetMemoryBlockSize.cpp @@ -0,0 +1,17 @@ +#include + +using namespace Upp; + +// TEST IN RELEASE MODE! + +CONSOLE_APP_MAIN +{ + for(int q = 5; q < 500*1024*1024; q = q + 1 + q / 10) { + size_t sz = q; + void *ptr = MemoryAllocSz(sz); + DLOG("Requested " << q << ", allocated " << sz << ", GetMemoryBlockSize " << GetMemoryBlockSize(ptr)); + if(sz != GetMemoryBlockSize(ptr)) + Panic("FAILED!"); + MemoryFree(ptr); + } +} diff --git a/examples/GetMemoryBlockSize/GetMemoryBlockSize.upp b/examples/GetMemoryBlockSize/GetMemoryBlockSize.upp new file mode 100644 index 000000000..9001499b9 --- /dev/null +++ b/examples/GetMemoryBlockSize/GetMemoryBlockSize.upp @@ -0,0 +1,9 @@ +uses + Core; + +file + GetMemoryBlockSize.cpp; + +mainconfig + "" = "DEBUGCODE"; + diff --git a/examples/MemorySize/MemorySize.cpp b/examples/MemorySize/MemorySize.cpp new file mode 100644 index 000000000..9f3deb37b --- /dev/null +++ b/examples/MemorySize/MemorySize.cpp @@ -0,0 +1,17 @@ +#include + +using namespace Upp; + +// TEST IN RELEASE MODE! + +CONSOLE_APP_MAIN +{ + for(int q = 5; q < 500*1024*1024; q = q + 1 + q / 10) { + size_t sz = q; + void *ptr = MemoryAllocSz(sz); + DLOG("Requested " << q << ", allocated " << sz << ", GetMemoryBlockSize " << GetMemoryBlockSize(ptr)); + if(sz != GetMemoryBlockSize(ptr)) + Panic("FAILED!"); + MemoryFree(ptr); + } +} diff --git a/examples/MemorySize/MemorySize.upp b/examples/MemorySize/MemorySize.upp new file mode 100644 index 000000000..c4a2da96c --- /dev/null +++ b/examples/MemorySize/MemorySize.upp @@ -0,0 +1,9 @@ +uses + Core; + +file + MemorySize.cpp; + +mainconfig + "" = "DEBUGCODE"; + diff --git a/examples/WeirdBug/WeirdBug.cpp b/examples/WeirdBug/WeirdBug.cpp new file mode 100644 index 000000000..023ae5afa --- /dev/null +++ b/examples/WeirdBug/WeirdBug.cpp @@ -0,0 +1,13 @@ +#include + +using namespace Upp; + +Vector g_turbine_data; // one for turbine*scenario + +CONSOLE_APP_MAIN +{ + String data = LoadFile("D:/xxx/td.bin"); + RDUMP(data.GetCount()); + LoadFromString(g_turbine_data, data); + RDUMP(g_turbine_data); +} diff --git a/examples/WeirdBug/WeirdBug.upp b/examples/WeirdBug/WeirdBug.upp new file mode 100644 index 000000000..87e4f8712 --- /dev/null +++ b/examples/WeirdBug/WeirdBug.upp @@ -0,0 +1,9 @@ +uses + Core; + +file + WeirdBug.cpp; + +mainconfig + "" = "DEBUGCODE"; + diff --git a/rainbow/WinAlt/DrawTextWinAlt.cpp b/rainbow/WinAlt/DrawTextWinAlt.cpp index 0e040b7e7..3a8ec6272 100644 --- a/rainbow/WinAlt/DrawTextWinAlt.cpp +++ b/rainbow/WinAlt/DrawTextWinAlt.cpp @@ -34,10 +34,11 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon double sina, cosa; Draw::SinCos(angle, sina, cosa); Size offset; - ::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, (const WCHAR *)text, n, dx); + ::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, + ToSystemCharsetW(text), n, dx); } else - ::ExtTextOutW(handle, x, y + ascent, 0, NULL, (const WCHAR *)text, + ::ExtTextOutW(handle, x, y + ascent, 0, NULL, ToSystemCharsetW(text), n, dx); ::SelectObject(handle, orgfont); } diff --git a/rainbow/WinAlt/TopWinAlt.cpp b/rainbow/WinAlt/TopWinAlt.cpp index 55426e7df..729c3f8e3 100644 --- a/rainbow/WinAlt/TopWinAlt.cpp +++ b/rainbow/WinAlt/TopWinAlt.cpp @@ -78,7 +78,7 @@ void TopWindow::SyncTitle0() #ifndef PLATFORM_WINCE if(hwnd) if(IsWindowUnicode(hwnd)) - ::SetWindowTextW(hwnd, (const WCHAR*)~title); + ::SetWindowTextW(hwnd, ToSystemCharsetW(title)); else #endif ::SetWindowText(hwnd, ToSystemCharset(title.ToString())); diff --git a/reference/OpenGL/OpenGL.upp b/reference/OpenGL/OpenGL.upp index 942c9e3b8..d28b6c5a8 100644 --- a/reference/OpenGL/OpenGL.upp +++ b/reference/OpenGL/OpenGL.upp @@ -2,7 +2,7 @@ description "GLCtrl widget example\377"; uses GLCtrl, - CodeEditor; + CtrlLib; file main.cpp; diff --git a/uppbox/FontMaps2/TypeReader.cpp b/uppbox/FontMaps2/TypeReader.cpp index 08136ad7f..18a18cde2 100644 --- a/uppbox/FontMaps2/TypeReader.cpp +++ b/uppbox/FontMaps2/TypeReader.cpp @@ -1,21 +1,31 @@ #include "TypeReader.h" #define LLOG(x) // LOG(x) -#define LDUMP(x) // LLOG(#x << " = " << x); +#define LDUMP(x) // LOG(#x << " = " << x); + +int FontTypeReader::Error() +{ + throw Fail(); return 0; +} + +int FontTypeReader::Error() +{ + throw Fail(); return 0; +} int FontTypeReader::Peek8(const char *s) { - return s + 1 < font.end() ? (byte)*s : Error(); + return s + 1 < data.end() ? (byte)*s : Error(); } int FontTypeReader::Peek16(const char *s) { - return s + 2 < font.end() ? Peek16be(s) : Error(); + return s + 2 < data.end() ? Peek16be(s) : Error(); } int FontTypeReader::Peek32(const char *s) { - return s + 4 < font.end() ? Peek32be(s) : Error(); + return s + 4 < data.end() ? Peek32be(s) : Error(); } int FontTypeReader::Peek8(const char *s, int i) @@ -54,45 +64,11 @@ int FontTypeReader::Read32(const char *&s) return q; } -const char *FontTypeReader::Seek(const char *tab, int& len) -{ - ASSERT(strlen(tab) == 4); - int q = table.Find(tab); - if(q < 0) - Error(); - len = table[q].length; - return ~font + table[q].offset; -} - -const char *FontTypeReader::Seek(const char *tab) -{ - int dummy; - return Seek(tab, dummy); -} - -bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck) +bool FontTypeReader::Open(Font font, bool symbol, bool justcheck) { // DDUMP(fnt.GetCount()); try { int i; - table.Clear(); - font = fnt; - const char *s = fnt; - int q = Read32(s); - if(q != 0x74727565 && q != 0x00010000) - Error(); - int n = Read16(s); - s += 6; - while(n--) { -// DDUMP(String(s, 4)); - Table& t = table.Add(String(s, 4)); - s += 8; // skip checksum - t.offset = Read32(s); -// DDUMP(t.offset); - t.length = Read32(s); -// DDUMP(t.length); -// DLOG("----"); - } #if 0 for(i = 0; i < table.GetCount(); i++) LLOG("table: " << table.GetKey(i) << " offset: " << table[i].offset << " length: " << table[i].length); @@ -124,35 +100,40 @@ bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck) << ", offset: " << glyphinfo[i].offset << ", size: " << glyphinfo[i].size); #endif + data = font.GetData("OS/2"); + panose.Clear(); + if(data.GetCount() > 32 + 10) + panose = data.Mid(32, 10); + bool found = false; + data = font.GetData("cmap"); for(int pass = 0; pass < 2; pass++) { - const char *s = Seek("cmap"); - const char *p = s; + const char *p = data; // LOGHEXDUMP(p, 256); p += 2; - n = Read16(p); + int n = Read16(p); // DDUMP(n); while(n--) { int pid = Read16(p); int psid = Read16(p); int offset = Read32(p); - if(offset < 0 || offset > font.GetLength()) + if(offset < 0 || offset > data.GetCount()) Error(); - int format = Peek16(s + offset); + int format = Peek16(~data + offset); LLOG("cmap pid: " << pid << " psid: " << psid << " format: " << format); //Test with Symbol font !!!; improve - Unicode first, 256 bytes later..., symbol... if(symbol) { - if(pid == 1 && psid == 0 && Peek16(s + offset) == 0) { + if(pid == 1 && psid == 0 && Peek16(~data + offset) == 0) { LLOG("Reading symbol table"); - p = s + offset + 6; + p = ~data + offset + 6; for(int i = 0; i < 256; i++); //SetGlyph(i, (byte)p[i]); goto done; } } else - if(pid == 3 && psid == 10 && format == 12 && pass == 0) { - const char *p = s + offset; + if((pid == 3 && psid == 10) || (pid == 0 && psid == 4) && format == 12 && pass == 0) { + const char *p = ~data + offset; int ngroups = Peek32(p + 12); p += 16; // pointer to groups table for(int i = 0; i < ngroups; i++) { @@ -163,8 +144,8 @@ bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck) goto done; } else - if(pid == 3 && psid == 1 && format == 4 && pass == 1) { - const char *p = s + offset; + if((pid == 3 && psid == 1) || (pid == 0 && psid == 3) && format == 4 && pass == 1) { + const char *p = ~data + offset; int n = Peek16(p + 6) >> 1; LLOG("Found UNICODE encoding, offset " << offset << ", segments " << n); const char *seg_end = p + 14; @@ -199,35 +180,38 @@ bool FontTypeReader::Open(const String& fnt, bool symbol, bool justcheck) } } } - done: - - int len; - const char *strings = Seek("name", len); - s = strings + 2; - int count = Read16(s); - strings += (word)Read16(s); - for(int i = 0; i < count; i++) { - int platform = Read16(s); - s += 4; - if(Read16(s) == 6) { - int len = Read16(s); - int offset = Read16(s); - if(platform == 1) - ps_name = String(strings + offset, len); - else { - s = strings + offset; - len >>= 1; - while(len--) - ps_name.Cat(Read16(s)); + done:; + #if 0 + String names = font.GetData("name"); + if(names.GetCount()) { + const char *strings = names; + const char *s = strings + 2; + int count = Read16(s); + strings += (word)Read16(s); + for(int i = 0; i < count; i++) { + int platform = Read16(s); + s += 4; + if(Read16(s) == 6) { + int len = Read16(s); + int offset = Read16(s); + if(platform == 1) + ps_name = String(strings + offset, len); + else { + s = strings + offset; + len >>= 1; + while(len--) + ps_name.Cat(Read16(s)); + } + break; } - break; + s += 4; } - s += 4; } DDUMP(ps_name); + #endif } catch(Fail) { - DLOG("ERROR"); + LLOG("ERROR"); return false; } diff --git a/uppbox/FontMaps2/TypeReader.h b/uppbox/FontMaps2/TypeReader.h index b153cebf0..52d2ec541 100644 --- a/uppbox/FontMaps2/TypeReader.h +++ b/uppbox/FontMaps2/TypeReader.h @@ -6,7 +6,7 @@ using namespace Upp; class FontTypeReader { - String font; + String data; struct Table : Moveable { int offset; @@ -15,7 +15,7 @@ class FontTypeReader { VectorMap table; struct Fail {}; - static int Error() { throw Fail(); return 0; } + static int Error(); int Peek8(const char *s); int Peek16(const char *s); @@ -27,17 +27,14 @@ class FontTypeReader { int Read16(const char *&s); int Read32(const char *&s); - const char *Seek(const char *tab, int& len); - const char *Seek(const char *tab); -// void Seek(const char *tab, TTFStreamIn& s); - String GetTable(const char *tab); - public: String ps_name; Array> ranges; + + String panose; - bool Open(const String& fnt, bool symbol = false, bool justcheck = false); + bool Open(Font font, bool symbol = false, bool justcheck = false); }; #endif diff --git a/uppbox/FontMaps2/main.cpp b/uppbox/FontMaps2/main.cpp index ee8890956..978841ed3 100644 --- a/uppbox/FontMaps2/main.cpp +++ b/uppbox/FontMaps2/main.cpp @@ -8,6 +8,8 @@ using namespace Upp; #define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p')) +#ifdef PLATFORM_WIN32 + namespace Upp { HFONT GetWin32Font(Font fnt, int angle); }; @@ -34,20 +36,70 @@ String GetFontDataSys(Font font, dword table) return r; } +#endif + +String ReadFontTable(Stream& in, const char *table, int fonti = 0) +{ + in.Seek(0); + int q = in.Get32be(); + if(q == 0x74746366) { // true type collection + in.Get32(); // skip major/minor version + int nfonts = in.Get32be(); + if(fonti >= nfonts) + return Null; + in.SeekCur(fonti * 4); + int offset = in.Get32be(); + if(offset < 0 || offset >= in.GetSize()) + return Null; + in.Seek(offset); + q = in.Get32be(); + } + if(q != 0x74727565 && q != 0x00010000) + return Null; + int n = in.Get16be(); + in.Get32(); + in.Get16(); + while(n--) { + if(in.IsError() || in.IsEof()) return Null; + String tab = in.Get(4); + in.Get32(); + int offset = in.Get32be(); + int length = in.Get32be(); + if(tab == table) { + if(offset < 0 || length < 0 || offset + length > in.GetSize()) + return Null; + in.Seek(offset); + return in.Get(length); + } + } + return Null; +} + GUI_APP_MAIN { +// FileIn in("C:/Windows/Fonts/arial.ttf"); +/* + FileIn in("D:\\xxx\\msyh.ttc"); + DDUMPHEX(ReadFontTable(in, "cmap", 0)); + DDUMPHEX(ReadFontTable(in, "cmap", 1)); + DDUMPHEX(ReadFontTable(in, "cmap", 2)); + return; +*/ #if 0 -// Font font(Font::FindFaceNameIndex("Microsoft JhengHei"), 20); - Font font = StdFont(); + Font font(Font::FindFaceNameIndex("Noto Serif CJK KR"), 20); + +// Font font = Roman(20); // SaveFile("d:/xxx/font.bin", GetFontDataSys(font, 0)); - String cmap = GetFontDataSys(font, CMAP); - LOGHEXDUMP(~cmap, 256); +// String cmap = GetFontDataSys(font, CMAP); +// LOGHEXDUMP(~cmap, 256); FontTypeReader r; // r.Open(Arial(20).GetData()); - r.Open(font.GetData()); + DDUMP(font.GetFaceName()); + r.Open(font); + DDUMPHEX(r.panose); return; @@ -55,34 +107,52 @@ GUI_APP_MAIN #endif Progress pi; pi.SetTotal(Font::GetFaceCount()); - for(int i = 0; i < Font::GetFaceCount(); i++) { + Vector name; + for(int i = 0; i < Font::GetFaceCount(); i++) + name.Add(Font::GetFaceName(i)); + for(int i : GetSortOrder(name)) { String f = Font::GetFaceName(i); pi.SetText(f); if(pi.StepCanceled()) break; Font fnt; fnt.FaceName(f); - DLOG("==========="); - DDUMP(f); FontTypeReader r; // r.Open(Arial(20).GetData()); - r.Open(fnt.GetData()); - Sort(r.ranges, [](Tuple a, Tuple b) { return a.a < b.a; }); - DDUMP(r.ranges); - while(r.ranges.GetCount() > 8) { - int mini = 0; - int mind = INT_MAX; - for(int i = 0; i < r.ranges.GetCount() - 1; i++) { - int d = r.ranges[i + 1].a - r.ranges[i].b; - if(d < mind) { - mind = d; - mini = i; + r.Open(fnt); + if(r.panose.GetCount() == 10) { + dword h[8] = {0}; + for(auto r : r.ranges) { + for(int c = r.a; c <= r.b; c++) { + c = max(c, 0); + if(c < 2048) + h[0] |= 0x80000000 >> (c >> 6); + else { + int bi = clamp(c - 2048, 0, 7*32*1024 - 1) >> 10; + ASSERT((bi >> 5) + 1 < 8); + h[(bi >> 5) + 1] |= 0x80000000 >> (bi & 31); + } } } - r.ranges[mini].b = r.ranges[mini + 1].b; - r.ranges.Remove(mini + 1); + String l; + l << "{ " << AsCString(f); + l << ", { "; + bool first = true; + for(int h : r.panose) { + if(first) + first = false; + else + l << ","; + l << h; + } + l << " }, { "; + for(int i = 0; i < 8; i++) { + if(i) l << ","; + l << Format("0x%08x", (int)h[i]); + } + l << " } },"; + LOG(l); } - DDUMP(r.ranges); } // r.Open(Font(Font::FindFaceNameIndex("Segoe UI Emoji"), 20).GetData()); diff --git a/uppsrc/CodeEditor/FindReplace.cpp b/uppsrc/CodeEditor/FindReplace.cpp index c59f3b81f..3ae8ef322 100644 --- a/uppsrc/CodeEditor/FindReplace.cpp +++ b/uppsrc/CodeEditor/FindReplace.cpp @@ -218,8 +218,8 @@ bool CodeEditor::RegExpFind(int64 pos, bool block) for(int i = 0; i < regex.GetCount(); i++) SetFound(i, WILDANY, regex.GetString(i).ToWString()); int off = regex.GetOffset(); - int len = utf8len(~ln + off, regex.GetLength()); - pos = GetPos64(line, utf8len(~ln, off) + (int)pos); + int len = Utf32Len(~ln + off, regex.GetLength()); + pos = GetPos64(line, Utf32Len(~ln, off) + (int)pos); foundtext = GetW(pos, len); if(!block) { foundsel = true; diff --git a/uppsrc/Core/App.cpp b/uppsrc/Core/App.cpp index 9383eaee5..37bd0299f 100644 --- a/uppsrc/Core/App.cpp +++ b/uppsrc/Core/App.cpp @@ -59,7 +59,7 @@ String GetHomeDirectory() { String GetEnv(const char *id) { - return WString(_wgetenv(WString(id))).ToString(); + return WString(_wgetenv(ToSystemCharsetW(id))).ToString(); } String GetExeFilePath() @@ -500,27 +500,27 @@ void AppInitEnvironment__() int nArgs; LPWSTR *szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); if(szArglist) { - strcpy(Argv0__, WString(szArglist[0]).ToString()); + strcpy(Argv0__, FromSystemCharsetW(szArglist[0])); for(int i = 1; i < nArgs; i++) - coreCmdLine__().Add(szArglist[i]); + coreCmdLine__().Add(FromSystemCharsetW(szArglist[i]).ToWString()); LocalFree(szArglist); } - wchar *env = GetEnvironmentStringsW(); - for(wchar *ptr = env; *ptr; ptr++) + WCHAR *env = GetEnvironmentStringsW(); + for(WCHAR *ptr = env; *ptr; ptr++) { - const wchar *b = ptr; + const WCHAR *b = ptr; if(*ptr) ptr++; while(*ptr && *ptr != '=') ptr++; - WString varname(b, ptr); + WString varname = ToUtf32(b, int(ptr - b)); if(*ptr) ptr++; b = ptr; while(*ptr) ptr++; - EnvMap().GetAdd(ToUpper(varname)) = WString(b, ptr); + EnvMap().GetAdd(ToUpper(varname)) = ToUtf32(b, int(ptr - b)); } FreeEnvironmentStringsW(env); @@ -556,16 +556,16 @@ void LaunchWebBrowser(const String& url) #if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE) static auxthread_t auxthread__ sShellExecuteOpen(void *str) { - ShellExecuteW(NULL, L"open", (wchar *)str, NULL, L".", SW_SHOWDEFAULT); + ShellExecuteW(NULL, L"open", (WCHAR *)str, NULL, L".", SW_SHOWDEFAULT); free(str); return 0; } void LaunchWebBrowser(const String& url) { - WString wurl = ToSystemCharsetW(url); + Vector wurl = ToSystemCharsetW(url); if ((int64)(ShellExecuteW(NULL, L"open", wurl, NULL, L".", SW_SHOWDEFAULT)) <= 32) { - int l = sizeof(wchar) * wurl.GetLength() + 1; + int l = sizeof(wchar) * wurl.GetCount() + 1; char *curl = (char *)malloc(l); memcpy(curl, wurl, l); StartAuxThread(sShellExecuteOpen, curl); @@ -619,27 +619,29 @@ String LoadDataFile(const char *filename) String GetComputerName() { - char temp[256]; - *temp = 0; #if defined(PLATFORM_WIN32) + WCHAR temp[256]; + *temp = 0; dword w = 255; - ::GetComputerNameA(temp, &w); + ::GetComputerNameW(temp, &w); #else + char temp[256]; gethostname(temp, sizeof(temp)); #endif - return FromSystemCharset(temp); + return temp; } String GetUserName() { - char temp[256]; - *temp = 0; #if defined(PLATFORM_WIN32) + WCHAR temp[256]; + *temp = 0; dword w = 255; - ::GetUserNameA(temp, &w); - return FromSystemCharset(temp); + ::GetUserNameW(temp, &w); + return temp; #else - return Nvl(GetEnv("USER"), "boot"); + char temp[256]; + return Nvl(GetEnv("USER"), "root"); #endif } @@ -652,7 +654,7 @@ String GetDesktopManager() if(GetEnv("GNOME_DESKTOP_SESSION_ID").GetCount()) return "gnome"; if(GetEnv("KDE_FULL_SESSION").GetCount() || GetEnv("KDEDIR").GetCount()) - return "kde"; + return "kde"; return GetEnv("DESKTOP_SESSION"); #endif } @@ -661,9 +663,9 @@ String GetDesktopManager() String GetShellFolder(int clsid) { - wchar path[MAX_PATH]; + WCHAR path[MAX_PATH]; if(SHGetFolderPathW(NULL, clsid, NULL, /*SHGFP_TYPE_CURRENT*/0, path) == S_OK) - return FromUnicodeBuffer(path); + return FromSystemCharsetW(path); return Null; } @@ -691,7 +693,7 @@ String GetDownloadFolder() if(SHGetKnownFolderPath) { PWSTR path = NULL; if(SHGetKnownFolderPath(&MY_FOLDERID_Downloads, 0, NULL, &path) == S_OK && path) { - String s = FromUnicodeBuffer(path, wstrlen(path)); + String s = FromSystemCharsetW(path); CoTaskMemFree(path); return s; } diff --git a/uppsrc/Core/Bom.cpp b/uppsrc/Core/Bom.cpp index ef5abb71b..25384f187 100644 --- a/uppsrc/Core/Bom.cpp +++ b/uppsrc/Core/Bom.cpp @@ -35,7 +35,7 @@ static void sLoadBom(Stream& in, String *t, WString *wt, byte def_charset) byte *h = (byte *)&header; if(h[0] == 0xef && h[1] == 0xbb && c == 0xbf) { if(wt) - *wt = FromUtf8(LoadStream(in)); + *wt = ToUtf32(LoadStream(in)); else *t = ToCharset(CHARSET_DEFAULT, LoadStream(in), CHARSET_UTF8); return; diff --git a/uppsrc/Core/CharSet.cpp b/uppsrc/Core/CharSet.cpp index a6839e385..2d1ab8502 100644 --- a/uppsrc/Core/CharSet.cpp +++ b/uppsrc/Core/CharSet.cpp @@ -1998,12 +1998,6 @@ int ToAscii(int c, byte charset) return cs.FromUnicode(ToAscii(cs.ToUnicode(c))); } -word UnicodeCombine(word chr, word combine) -{ - dword h[2] = { chr, combine }; - return (word)UnicodeCompose(h, 2); -} - void ToUpper(char *t, const char *s, int len, byte charset) { charset = ResolveCharset(charset); @@ -2050,7 +2044,7 @@ WString ToUnicode(const char *src, int l, byte charset) { charset = ResolveCharset(charset); if(charset == CHARSET_UTF8) - return FromUtf8(src, l); + return ToUtf32(src, l); WStringBuffer result(l); ToUnicode(result, src, l, charset); return WString(result); @@ -2073,7 +2067,7 @@ String FromUnicodeBuffer(const wchar *src, int len, byte charset, int defchar) String FromUnicodeBuffer(const wchar *src) { - return FromUnicodeBuffer(src, wstrlen(src)); + return FromUnicodeBuffer(src, strlen__(src)); } String FromUnicode(const WString& src, byte charset, int defchar) @@ -2089,7 +2083,7 @@ String ToCharset(byte charset, const String& src, byte scharset, int def) return src; int slen = src.GetLength(); if(scharset == CHARSET_UTF8) - return FromUnicode(FromUtf8(src, slen), charset, def); + return FromUnicode(ToUtf32(src, slen), charset, def); if(charset == CHARSET_UTF8) return ToUtf8(ToUnicode(src, scharset)); StringBuffer result(slen); @@ -2161,7 +2155,7 @@ String ToUpper(const char *s, byte charset) { charset = ResolveCharset(charset); if(charset == CHARSET_UTF8) - return ToUtf8(ToUpper(FromUtf8(s))); + return ToUtf8(ToUpper(ToUtf32(s))); int l = (int)strlen(s); StringBuffer r(l); ToUpper(r, s, l, charset); @@ -2172,7 +2166,7 @@ String ToLower(const char *s, byte charset) { charset = ResolveCharset(charset); if(charset == CHARSET_UTF8) - return ToUtf8(ToLower(FromUtf8(s))); + return ToUtf8(ToLower(ToUtf32(s))); int l = (int)strlen(s); StringBuffer r(l); ToLower(r, s, l, charset); @@ -2183,7 +2177,7 @@ String ToAscii(const char *s, byte charset) { charset = ResolveCharset(charset); if(charset == CHARSET_UTF8) - return ToUtf8(ToAscii(FromUtf8(s))); + return ToUtf8(ToAscii(ToUtf32(s))); int l = (int)strlen(s); StringBuffer r(l); ToAscii(r, s, l, charset); @@ -2194,7 +2188,7 @@ String ToUpper(const String& s, byte charset) { charset = ResolveCharset(charset); if(charset == CHARSET_UTF8) - return ToUtf8(ToUpper(FromUtf8(s))); + return ToUtf8(ToUpper(ToUtf32(s))); int l = s.GetLength(); StringBuffer r(l); ToUpper(r, s, l, charset); @@ -2205,7 +2199,7 @@ String ToLower(const String& s, byte charset) { charset = ResolveCharset(charset); if(charset == CHARSET_UTF8) - return ToUtf8(ToLower(FromUtf8(s))); + return ToUtf8(ToLower(ToUtf32(s))); int l = s.GetLength(); StringBuffer r(l); ToLower(r, s, l, charset); diff --git a/uppsrc/Core/CharSet.h b/uppsrc/Core/CharSet.h index e8d19a28b..f3d953cd1 100644 --- a/uppsrc/Core/CharSet.h +++ b/uppsrc/Core/CharSet.h @@ -8,6 +8,7 @@ enum { #undef CHRSET_ #define CHARSET_TOASCII 253 +#define CHARSET_UTF32 254 // auxilary #define CHARSET_UTF8 255 #define CHARSET_UNICODE 255 @@ -23,86 +24,83 @@ enum { #include "Utf.hpp" -int strlen32(const dword *s); +inline bool IsUtf8Lead(int c) { return (c & 0xc0) != 0x80; } -inline bool IsUtf8Lead(int c) -{ - return (c & 0xc0) != 0x80; -} +wchar ReadSurrogatePair(const char16 *s, const char16 *lim); -dword FetchUtf8(const char *&s, const char *lim, bool& ok); -inline dword FetchUtf8(const char *&s, const char *lim) { bool ok; return FetchUtf8(s, lim, ok); } +wchar FetchUtf8(const char *&s, const char *lim, bool& ok); +inline wchar FetchUtf8(const char *&s, const char *lim) { bool ok; return FetchUtf8(s, lim, ok); } + +dword FetchUtf8(const char *&s, bool& ok); +inline wchar FetchUtf8(const char *&s) { bool ok; return FetchUtf8(s, ok); } bool CheckUtf8(const char *s, int len); -inline bool CheckUtf8(const char *s) { return CheckUtf8(s, (int)strlen(s)); } +inline bool CheckUtf8(const char *s) { return CheckUtf8(s, (int)strlen8(s)); } inline bool CheckUtf8(const String& s) { return CheckUtf8(~s, s.GetCount()); } -int Utf8Len(const dword *s, int len); -inline int Utf8Len(const dword *s) { return Utf8Len(s, strlen32(s)); } -inline int Utf8Len(const Vector& s) { return Utf8Len(s, s.GetCount()); } -inline int Utf8Len(dword code) { return Utf8Len(&code, 1); } - int Utf8Len(const wchar *s, int len); -inline int Utf8Len(const wchar *s) { return Utf8Len(s, wstrlen(s)); } +inline int Utf8Len(const wchar *s) { return Utf8Len(s, strlen32(s)); } +inline int Utf8Len(wchar code) { return Utf8Len(&code, 1); } inline int Utf8Len(const WString& s) { return Utf8Len(~s, s.GetCount()); } -void ToUtf8(char *t, const dword *s, int len); -String ToUtf8(const dword *s, int len); -inline String ToUtf8(const dword *s) { return ToUtf8(s, strlen32(s)); } -inline String ToUtf8(const Vector& s) { return ToUtf8(s, s.GetCount()); } -inline String ToUtf8(dword code) { return ToUtf8(&code, 1); } +int Utf8Len(const char16 *s, int len); +inline int Utf8Len(const char16 *s) { return Utf8Len(s, strlen16(s)); } +inline int Utf8Len(const Vector& s) { return Utf8Len(s, s.GetCount()); } void ToUtf8(char *t, const wchar *s, int len); String ToUtf8(const wchar *s, int len); -inline String ToUtf8(const wchar *s) { return ToUtf8(s, wstrlen(s)); } +inline String ToUtf8(const wchar *s) { return ToUtf8(s, strlen32(s)); } +inline String ToUtf8(wchar code) { return ToUtf8(&code, 1); } inline String ToUtf8(const WString& s) { return ToUtf8(~s, s.GetCount()); } -int Utf16Len(const dword *s, int len); -inline int Utf16Len(const dword *s) { return Utf16Len(s, strlen32(s)); } -inline int Utf16Len(const Vector& s) { return Utf16Len(s, s.GetCount()); } -inline int Utf16Len(dword code) { return Utf16Len(&code, 1); } +void ToUtf8(char *t, const char16 *s, int len); +String ToUtf8(const char16 *s, int len); +inline String ToUtf8(const char16 *s) { return ToUtf8(s, strlen16(s)); } +inline String ToUtf8(const Vector& s) { return ToUtf8(s, s.GetCount()); } + +int Utf16Len(const wchar *s, int len); +inline int Utf16Len(const wchar *s) { return Utf16Len(s, strlen32(s)); } +inline int Utf16Len(const WString& s) { return Utf16Len(s, s.GetCount()); } +inline int Utf16Len(wchar code) { return Utf16Len(&code, 1); } int Utf16Len(const char *s, int len); -inline int Utf16Len(const char *s) { return Utf16Len(s, (int)strlen(s)); } +inline int Utf16Len(const char *s) { return Utf16Len(s, (int)strlen8(s)); } inline int Utf16Len(const String& s) { return Utf16Len(~s, s.GetCount()); } -void ToUtf16(wchar *t, const dword *s, int len); -WString ToUtf16(const dword *s, int len); -inline WString ToUtf16(const dword *s) { return ToUtf16(s, strlen32(s)); } -inline WString ToUtf16(const Vector& s) { return ToUtf16(s, s.GetCount()); } -inline WString ToUtf16(dword code) { return ToUtf16(&code, 1); } +int ToUtf16(char16 *t, const wchar *s, int len); +Vector ToUtf16(const wchar *s, int len); +inline Vector ToUtf16(const wchar *s) { return ToUtf16(s, strlen32(s)); } +inline Vector ToUtf16(const WString& s) { return ToUtf16(s, s.GetCount()); } +inline Vector ToUtf16(wchar code) { return ToUtf16(&code, 1); } -void ToUtf16(wchar *t, const char *s, int len); -WString ToUtf16(const char *s, int len); -inline WString ToUtf16(const char *s) { return ToUtf16(s, (int)strlen(s)); } -inline WString ToUtf16(const String& s) { return ToUtf16(~s, s.GetCount()); } +int ToUtf16(char16 *t, const char *s, int len); +Vector ToUtf16(const char *s, int len); +inline Vector ToUtf16(const char *s) { return ToUtf16(s, (int)strlen8(s)); } +inline Vector ToUtf16(const String& s) { return ToUtf16(~s, s.GetCount()); } -int Utf32Len(const wchar *s, int len); -inline int Utf32Len(const wchar *s) { return Utf32Len(s, wstrlen(s)); } -inline int Utf32Len(const WString& s) { return Utf32Len(~s, s.GetCount()); } +int Utf32Len(const char16 *s, int len); +inline int Utf32Len(const char16 *s) { return Utf32Len(s, strlen16(s)); } +inline int Utf32Len(const Vector& s) { return Utf32Len(s, s.GetCount()); } int Utf32Len(const char *s, int len); -inline int Utf32Len(const char *s) { return Utf32Len(s, (int)strlen(s)); } +inline int Utf32Len(const char *s) { return Utf32Len(s, (int)strlen8(s)); } inline int Utf32Len(const String& s) { return Utf32Len(~s, s.GetCount()); } -dword ReadSurrogatePair(const wchar *s, const wchar *lim); +void ToUtf32(wchar *t, const char16 *s, int len); +WString ToUtf32(const char16 *s, int len); +inline WString ToUtf32(const char16 *s) { return ToUtf32(s, strlen16(s)); } +inline WString ToUtf32(const Vector& s) { return ToUtf32(s, s.GetCount()); } -void ToUtf32(dword *t, const wchar *s, int len); -Vector ToUtf32(const wchar *s, int len); -inline Vector ToUtf32(const wchar *s) { return ToUtf32(s, wstrlen(s)); } -inline Vector ToUtf32(const WString& s) { return ToUtf32(~s, s.GetCount()); } - -void ToUtf32(dword *t, const char *s, int len); -Vector ToUtf32(const char *s, int len); -inline Vector ToUtf32(const char *s) { return ToUtf32(s, (int)strlen(s)); } -inline Vector ToUtf32(const String& s) { return ToUtf32(~s, s.GetCount()); } +void ToUtf32(wchar *t, const char *s, int len); +WString ToUtf32(const char *s, int len); +inline WString ToUtf32(const char *s) { return ToUtf32(s, (int)strlen8(s)); } +inline WString ToUtf32(const String& s) { return ToUtf32(~s, s.GetCount()); } enum { MAX_DECOMPOSED = 18 }; -int UnicodeDecompose(dword codepoint, dword t[MAX_DECOMPOSED], bool only_canonical = false); -Vector UnicodeDecompose(dword codepoint, bool only_canonical = false); -dword UnicodeCompose(const dword *t, int count); -inline dword UnicodeCompose(const Vector& t) { return UnicodeCompose(t, t.GetCount()); } +int UnicodeDecompose(wchar codepoint, wchar t[MAX_DECOMPOSED], bool only_canonical = false); +WString UnicodeDecompose(wchar codepoint, bool only_canonical = false); +wchar UnicodeCompose(const WString& t); void SetDefaultCharset(byte charset); byte GetDefaultCharset(); @@ -127,62 +125,62 @@ extern byte unicode_fast_info__[2048]; extern byte unicode_fast_upper_ascii__[]; extern byte unicode_fast_lower_ascii__[]; -dword ToUpperRest_(dword c); -dword ToLowerRest_(dword c); -char ToAsciiRest_(dword c); -bool IsRTL_(dword c); -bool IsMark_(dword c); -bool IsLetter_(dword c); -bool IsUpper_(dword c); -bool IsLower_(dword c); +wchar ToUpperRest_(wchar c); +wchar ToLowerRest_(wchar c); +char ToAsciiRest_(wchar c); +bool IsRTL_(wchar c); +bool IsMark_(wchar c); +bool IsLetter_(wchar c); +bool IsUpper_(wchar c); +bool IsLower_(wchar c); -inline dword ToUpper(dword c) { return c < 2048 ? unicode_fast_upper__[c] : ToUpperRest_(c); } -inline dword ToLower(dword c) { return c < 2048 ? unicode_fast_lower__[c] : ToLowerRest_(c); } -inline char ToAscii(dword c) { return c < 2048 ? unicode_fast_ascii__[c] : ToAsciiRest_(c); } -inline char ToUpperAscii(dword c){ return c < 2048 ? unicode_fast_upper_ascii__[c] : (char)ToUpper(ToAsciiRest_(c)); } -inline char ToLowerAscii(dword c){ return c < 2048 ? unicode_fast_lower_ascii__[c] : (char)ToLower(ToAsciiRest_(c)); } -inline bool IsLower(dword c) { return c < 2048 ? unicode_fast_info__[c] & 1 : IsLower_(c); } -inline bool IsUpper(dword c) { return c < 2048 ? unicode_fast_info__[c] & 2 : IsUpper_(c); } -inline bool IsLetter(dword c) { return c < 2048 ? unicode_fast_info__[c] & 4 : IsLetter_(c); } +inline wchar ToUpper(wchar c) { return c < 2048 ? unicode_fast_upper__[c] : ToUpperRest_(c); } +inline wchar ToLower(wchar c) { return c < 2048 ? unicode_fast_lower__[c] : ToLowerRest_(c); } +inline char ToAscii(wchar c) { return c < 2048 ? unicode_fast_ascii__[c] : ToAsciiRest_(c); } +inline char ToUpperAscii(wchar c){ return c < 2048 ? unicode_fast_upper_ascii__[c] : (char)ToUpper(ToAsciiRest_(c)); } +inline char ToLowerAscii(wchar c){ return c < 2048 ? unicode_fast_lower_ascii__[c] : (char)ToLower(ToAsciiRest_(c)); } +inline bool IsLower(wchar c) { return c < 2048 ? unicode_fast_info__[c] & 1 : IsLower_(c); } +inline bool IsUpper(wchar c) { return c < 2048 ? unicode_fast_info__[c] & 2 : IsUpper_(c); } +inline bool IsLetter(wchar c) { return c < 2048 ? unicode_fast_info__[c] & 4 : IsLetter_(c); } -inline bool IsRTL(dword c) { return (dword)c >= 1470 && IsRTL_(c); } -inline bool IsMark(dword c) { return c < 0x300 ? false : c <= 0x36f ? true : IsMark_(c); } +inline bool IsRTL(wchar c) { return (wchar)c >= 1470 && IsRTL_(c); } +inline bool IsMark(wchar c) { return c < 0x300 ? false : c <= 0x36f ? true : IsMark_(c); } -inline bool IsLetter(int c) { return IsLetter((dword) c); } -inline bool IsUpper(int c) { return IsUpper((dword) c); } -inline bool IsLower(int c) { return IsLower((dword) c); } -inline int ToUpper(int c) { return ToUpper((dword) c); } -inline int ToLower(int c) { return ToLower((dword) c); } -inline char ToAscii(int c) { return ToAscii((dword) c); } -inline char ToUpperAscii(int c) { return ToUpperAscii((dword) c); } -inline char ToLowerAscii(int c) { return ToUpperAscii((dword) c); } +inline bool IsLetter(int c) { return IsLetter((wchar) c); } +inline bool IsUpper(int c) { return IsUpper((wchar) c); } +inline bool IsLower(int c) { return IsLower((wchar) c); } +inline int ToUpper(int c) { return ToUpper((wchar) c); } +inline int ToLower(int c) { return ToLower((wchar) c); } +inline char ToAscii(int c) { return ToAscii((wchar) c); } +inline char ToUpperAscii(int c) { return ToUpperAscii((wchar) c); } +inline char ToLowerAscii(int c) { return ToUpperAscii((wchar) c); } -inline bool IsLetter(char c) { return IsLetter((dword)(byte) c); } -inline bool IsUpper(char c) { return IsUpper((dword)(byte) c); } -inline bool IsLower(char c) { return IsLower((dword)(byte) c); } -inline dword ToUpper(char c) { return ToUpper((dword)(byte) c); } -inline dword ToLower(char c) { return ToLower((dword)(byte) c); } -inline char ToAscii(char c) { return ToAscii((dword)(byte) c); } -inline char ToUpperAscii(char c) { return ToUpperAscii((dword)(byte) c); } -inline char ToLowerAscii(char c) { return ToLowerAscii((dword)(byte) c); } +inline bool IsLetter(char c) { return IsLetter((wchar)(byte) c); } +inline bool IsUpper(char c) { return IsUpper((wchar)(byte) c); } +inline bool IsLower(char c) { return IsLower((wchar)(byte) c); } +inline wchar ToUpper(char c) { return ToUpper((wchar)(byte) c); } +inline wchar ToLower(char c) { return ToLower((wchar)(byte) c); } +inline char ToAscii(char c) { return ToAscii((wchar)(byte) c); } +inline char ToUpperAscii(char c) { return ToUpperAscii((wchar)(byte) c); } +inline char ToLowerAscii(char c) { return ToLowerAscii((wchar)(byte) c); } -inline bool IsLetter(signed char c) { return IsLetter((dword)(byte) c); } -inline bool IsUpper(signed char c) { return IsUpper((dword)(byte) c); } -inline bool IsLower(signed char c) { return IsLower((dword)(byte) c); } -inline dword ToUpper(signed char c) { return ToUpper((dword)(byte) c); } -inline dword ToLower(signed char c) { return ToLower((dword)(byte) c); } -inline char ToAscii(signed char c) { return ToAscii((dword)(byte) c); } -inline char ToUpperAscii(signed char c) { return ToUpperAscii((dword)(byte) c); } -inline char ToLowerAscii(signed char c) { return ToLowerAscii((dword)(byte) c); } +inline bool IsLetter(signed char c) { return IsLetter((wchar)(byte) c); } +inline bool IsUpper(signed char c) { return IsUpper((wchar)(byte) c); } +inline bool IsLower(signed char c) { return IsLower((wchar)(byte) c); } +inline wchar ToUpper(signed char c) { return ToUpper((wchar)(byte) c); } +inline wchar ToLower(signed char c) { return ToLower((wchar)(byte) c); } +inline char ToAscii(signed char c) { return ToAscii((wchar)(byte) c); } +inline char ToUpperAscii(signed char c) { return ToUpperAscii((wchar)(byte) c); } +inline char ToLowerAscii(signed char c) { return ToLowerAscii((wchar)(byte) c); } -inline bool IsLetter(wchar c) { return IsLetter((dword) c); } -inline bool IsUpper(wchar c) { return IsUpper((dword) c); } -inline bool IsLower(wchar c) { return IsLower((dword) c); } -inline dword ToUpper(wchar c) { return ToUpper((dword) c); } -inline dword ToLower(wchar c) { return ToLower((dword) c); } -inline char ToAscii(wchar c) { return ToAscii((dword) c); } -inline char ToUpperAscii(wchar c) { return ToUpperAscii((dword) c); } -inline char ToLowerAscii(wchar c) { return ToLowerAscii((dword) c); } +inline bool IsLetter(char16 c) { return IsLetter((wchar) c); } +inline bool IsUpper(char16 c) { return IsUpper((wchar) c); } +inline bool IsLower(char16 c) { return IsLower((wchar) c); } +inline wchar ToUpper(char16 c) { return ToUpper((wchar) c); } +inline wchar ToLower(char16 c) { return ToLower((wchar) c); } +inline char ToAscii(char16 c) { return ToAscii((wchar) c); } +inline char ToUpperAscii(char16 c) { return ToUpperAscii((wchar) c); } +inline char ToLowerAscii(char16 c) { return ToLowerAscii((wchar) c); } inline bool IsDigit(int c) { return c >= '0' && c <= '9'; } inline bool IsAlpha(int c) { return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z'; } @@ -198,13 +196,13 @@ String Utf8ToAscii(const String& src); String Utf8ToUpperAscii(const String& src); String Utf8ToLowerAscii(const String& src); -void ToUpper(wchar *t, const wchar *s, int len); -void ToLower(wchar *t, const wchar *s, int len); -void ToAscii(wchar *t, const wchar *s, int len); +void ToUpper(char16 *t, const char16 *s, int len); +void ToLower(char16 *t, const char16 *s, int len); +void ToAscii(char16 *t, const char16 *s, int len); -void ToUpper(wchar *s, int len); -void ToLower(wchar *s, int len); -void ToAscii(wchar *s, int len); +void ToUpper(char16 *s, int len); +void ToLower(char16 *s, int len); +void ToAscii(char16 *s, int len); bool IsLetter(int c, byte charset); bool IsUpper(int c, byte charset); @@ -253,32 +251,11 @@ bool SaveFileBOMUtf8(const char *path, const String& data); bool Utf8BOM(Stream& in); - -// Deprecated - -word UnicodeCombine(word chr, word combine); - -inline bool IsCJKIdeograph(int c) { return c >= 0x2e80 && c <= 0xdfaf || c >= 0xf900 && c <= 0xfaff; } - -int ToUnicode(int chr, byte charset); -int FromUnicode(wchar wchr, byte charset, int defchar = DEFAULTCHAR); - -void ToUnicode(wchar *ws, const char *s, int n, byte charset); -void FromUnicode(char *s, const wchar *ws, int n, byte charset, int defchar = DEFAULTCHAR); - WString ToUnicode(const String& src, byte charset); WString ToUnicode(const char *src, int n, byte charset); String FromUnicodeBuffer(const wchar *src, int len, byte charset = CHARSET_DEFAULT, int defchar = DEFAULTCHAR); String FromUnicodeBuffer(const wchar *src); String FromUnicode(const WString& src, byte charset = CHARSET_DEFAULT, int defchar = DEFAULTCHAR); -inline WString FromUtf8(const char *s, int len) { return ToUtf16(s, len); } -inline WString FromUtf8(const char *s) { return ToUtf16(s); } -inline WString FromUtf8(const String& s) { return ToUtf16(s); } - -inline bool utf8check(const char *s, int len) { return CheckUtf8(s, len); } - -inline int utf8len(const char *s, int len) { return Utf16Len(s, len); } -inline int utf8len(const char *s) { return Utf16Len(s); } -inline int lenAsUtf8(const wchar *s, int len) { return Utf8Len(s, len); } -inline int lenAsUtf8(const wchar *s) { return Utf8Len(s); } +int ToUnicode(int chr, byte charset); +int FromUnicode(wchar wchr, byte charset, int defchar = DEFAULTCHAR); diff --git a/uppsrc/Core/Core.h b/uppsrc/Core/Core.h index 5965f7955..0c3c34d2c 100644 --- a/uppsrc/Core/Core.h +++ b/uppsrc/Core/Core.h @@ -1,7 +1,7 @@ #ifndef CORE_H #define CORE_H -#define UPP_VERSION 0x20200200 +#define UPP_VERSION 0x20210900 #ifndef flagMT #define flagMT // MT is now always on @@ -63,6 +63,11 @@ #ifdef CPU_X86 #include + +#ifdef PLATFORM_WIN32 +#include +#endif + #endif #if defined(PLATFORM_POSIX) @@ -306,7 +311,6 @@ class JsonIO; #include "String.h" #include "TimeDate.h" -#include "Path.h" #include "Stream.h" #include "Diag.h" @@ -324,6 +328,8 @@ class JsonIO; #include "CharSet.h" +#include "Path.h" + #include "SplitMerge.h" #include "Other.h" diff --git a/uppsrc/Core/Cpu.cpp b/uppsrc/Core/Cpu.cpp index 99707a2ed..a5c785a9c 100644 --- a/uppsrc/Core/Cpu.cpp +++ b/uppsrc/Core/Cpu.cpp @@ -1,12 +1,8 @@ #include "Core.h" -#ifdef CPU_X86 -#ifdef COMPILER_MSC -#include -#else +#if !(defined(CPU_X86) && defined(COMPILER_MSC)) #include #endif -#endif #ifdef PLATFORM_FREEBSD #include diff --git a/uppsrc/Core/CvFlt.cpp b/uppsrc/Core/CvFlt.cpp index b69feec44..ee5a9adcf 100644 --- a/uppsrc/Core/CvFlt.cpp +++ b/uppsrc/Core/CvFlt.cpp @@ -167,7 +167,7 @@ int FormatDoubleDigits(const sF128& w, char *digits, int precision) } }; - auto D1 = [&](dword u) { *digits++ = u + '0'; }; + auto D1 = [&](dword u) { *digits++ = char(u + '0'); }; auto D2 = [&](dword u) { memcpy(digits, s100 + 2 * u, 2); digits += 2; }; auto D3 = [&](dword u) { int q = (5243 * u) >> 19; D1(q); D2(u - 100 * q); }; // bit faster than / % here @@ -182,24 +182,24 @@ int FormatDoubleDigits(const sF128& w, char *digits, int precision) auto U16 = [&] { u1 = u / 10000000000000000; u = u % 10000000000000000; }; switch(precision) { - case 1: FP(10); D1(u); break; - case 2: FP(100); D2(u); break; - case 3: FP(1000); D3(u); break; - case 4: FP(10000); D4(u); break; - case 5: FP(100000); D5(u); break; - case 6: FP(1000000); D6(u); break; - case 7: FP(10000000); D7(u); break; - case 8: FP(100000000); D8(u); break; - case 9: FP(1000000000); U8(); D1(u1); D8(u); break; - case 10: FP(10000000000); U8(); D2(u1); D8(u); break; - case 11: FP(100000000000); U8(); D3(u1); D8(u); break; - case 12: FP(1000000000000); U8(); D4(u1); D8(u); break; - case 13: FP(10000000000000); U8(); D5(u1); D8(u); break; - case 14: FP(100000000000000); U8(); D6(u1); D8(u); break; - case 15: FP(1000000000000000); U8(); D7(u1); D8(u); break; - case 16: FP(10000000000000000); U8(); D8(u1); D8(u); break; - case 17: FP(100000000000000000); U16(); D1(u1); U8(); D8(u1); D8(u); break; - case 18: FP(1000000000000000000u); U16(); D2(u1); U8(); D8(u1); D8(u); break; + case 1: FP(10); D1((dword)u); break; + case 2: FP(100); D2((dword)u); break; + case 3: FP(1000); D3((dword)u); break; + case 4: FP(10000); D4((dword)u); break; + case 5: FP(100000); D5((dword)u); break; + case 6: FP(1000000); D6((dword)u); break; + case 7: FP(10000000); D7((dword)u); break; + case 8: FP(100000000); D8((dword)u); break; + case 9: FP(1000000000); U8(); D1((dword)u1); D8((dword)u); break; + case 10: FP(10000000000); U8(); D2((dword)u1); D8((dword)u); break; + case 11: FP(100000000000); U8(); D3((dword)u1); D8((dword)u); break; + case 12: FP(1000000000000); U8(); D4((dword)u1); D8((dword)u); break; + case 13: FP(10000000000000); U8(); D5((dword)u1); D8((dword)u); break; + case 14: FP(100000000000000); U8(); D6((dword)u1); D8((dword)u); break; + case 15: FP(1000000000000000); U8(); D7((dword)u1); D8((dword)u); break; + case 16: FP(10000000000000000); U8(); D8((dword)u1); D8((dword)u); break; + case 17: FP(100000000000000000); U16(); D1((dword)u1); U8(); D8((dword)u1); D8((dword)u); break; + case 18: FP(1000000000000000000u); U16(); D2((dword)u1); U8(); D8((dword)u1); D8((dword)u); break; } return -e10; } diff --git a/uppsrc/Core/Defs.h b/uppsrc/Core/Defs.h index 6c05e0551..b5ef1149d 100644 --- a/uppsrc/Core/Defs.h +++ b/uppsrc/Core/Defs.h @@ -145,14 +145,16 @@ typedef short unsigned uint16; typedef unsigned long dword; typedef long int32; typedef unsigned long uint32; -typedef WCHAR wchar; +typedef WCHAR char16; + #else typedef unsigned int dword; typedef int int32; typedef unsigned int uint32; -typedef word wchar; +typedef word char16; #endif +typedef uint32 wchar; #ifdef COMPILER_MSC typedef __int64 int64; diff --git a/uppsrc/Core/FileMapping.cpp b/uppsrc/Core/FileMapping.cpp index 53941a2d5..05f2d9090 100644 --- a/uppsrc/Core/FileMapping.cpp +++ b/uppsrc/Core/FileMapping.cpp @@ -47,7 +47,7 @@ bool FileMapping::Open(const char *file, bool delete_share) write = false; #ifdef PLATFORM_WIN32 hfile = CreateFileW(ToSystemCharsetW(file), GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | (delete_share && IsWinNT() ? FILE_SHARE_DELETE : 0), + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(hfile == INVALID_HANDLE_VALUE) return false; diff --git a/uppsrc/Core/Format.cpp b/uppsrc/Core/Format.cpp index e9e0c2e29..420f90573 100644 --- a/uppsrc/Core/Format.cpp +++ b/uppsrc/Core/Format.cpp @@ -559,7 +559,7 @@ String DoubleFormatter(const Formatting& f) dword n; bool overflow = false; s = ScanUint(n, s, overflow); - if(overflow || !s || n > (wd ? 1000 : 100)) + if(overflow || !s || n > (wd ? 1000u : 100u)) return Null; (wd ? width : precision) = n; } diff --git a/uppsrc/Core/Heap.h b/uppsrc/Core/Heap.h index c3d343a9e..e1554b627 100644 --- a/uppsrc/Core/Heap.h +++ b/uppsrc/Core/Heap.h @@ -23,9 +23,6 @@ void *MemoryAlloc(size_t size); void MemoryFree(void *ptr); void *MemoryAlloc32(); void MemoryFree32(void *ptr); -void *MemoryAlloc48(); -void MemoryFree48(void *ptr); -void MemoryFreeThread(); void MemoryCheck(); void MemoryDumpLarge(); void MemoryDumpHuge(); diff --git a/uppsrc/Core/HeapImp.h b/uppsrc/Core/HeapImp.h index dcb103e22..12128ae7a 100644 --- a/uppsrc/Core/HeapImp.h +++ b/uppsrc/Core/HeapImp.h @@ -215,11 +215,11 @@ template bool BlkHeap::TryRealloc(void *ptr, size_t count, size_t& n) { ASSERT(count); - + BlkHeader *h = (BlkHeader *)ptr; if(h->size == 0) return false; - + word sz = h->GetSize(); if(sz != count) { if(!JoinNext(h, (word)count) && count > sz) @@ -271,7 +271,7 @@ struct Heap : BlkHeap { REMOTE_OUT_SZ = 2000, // maximum size of remote frees to be buffered to flush at once }; - + // allocator options: static word HPAGE; // size of master page, in 4KB units static int max_free_hpages; // maximum free master pages kept in reserve (if more, they are returned to the system) @@ -294,7 +294,7 @@ struct Heap : BlkHeap { static_assert(__countof(sz) == 23, "NKLASS mismatch"); return sz[k]; } - + struct FreeLink { FreeLink *next; }; @@ -316,16 +316,16 @@ struct Heap : BlkHeap { byte *End() { return (byte *)this + 4096; } int Count() { return (int)(uintptr_t)(End() - Begin()) / Ksz(klass); } }; - + struct LargeHeapDetail { BlkHeader_ freelist[25][1]; void LinkFree(BlkHeader_ *h); }; - + struct LargeHeap : BlkHeap {}; - + typedef LargeHeap::BlkHeader LBlkHeader; - + struct DLink : BlkPrefix { // Large Page header / big block header DLink *next; DLink *prev; @@ -339,7 +339,7 @@ struct Heap : BlkHeap { void LinkSelf() { Dbl_Self(this); } void Unlink() { Dbl_Unlink(this); } void Link(DLink *lnk) { Dbl_LinkAfter(this, lnk); } - + LargeHeap::BlkHeader *GetFirst() { return (LargeHeap::BlkHeader *)((byte *)this + LOFFSET); } // pointer to data area }; @@ -349,7 +349,7 @@ struct Heap : BlkHeap { static_assert(sizeof(BlkPrefix) == 16, "Wrong sizeof(BlkPrefix)"); static_assert(sizeof(DLink) == 64, "Wrong sizeof(DLink)"); - + static StaticMutex mutex; Page work[NKLASS][1]; // circular list of pages that contain some empty blocks @@ -363,7 +363,7 @@ struct Heap : BlkHeap { LargeHeap lheap; DLink large[1]; // all large 64KB chunks that belong to this heap int free_lpages; // empty large pages (in reserve) - + void *out[REMOTE_OUT_SZ / 8 + 1]; void **out_ptr; int out_size; @@ -377,9 +377,9 @@ struct Heap : BlkHeap { void *page; HugePage *next; }; - + static HugePage *huge_pages; - + static DLink big[1]; // List of all big blocks static Heap aux; // Single global auxiliary heap to store orphans and global list of free pages @@ -410,11 +410,11 @@ struct Heap : BlkHeap { void Init(); - static int CheckFree(FreeLink *l, int k); + static int CheckFree(FreeLink *l, int k, bool page = true); void Check(); static void DblCheck(Page *p); static void AssertLeaks(bool b); - + static bool IsSmall(void *ptr) { return (((dword)(uintptr_t)ptr) & 16) == 0; } static Page *GetPage(void *ptr) { return (Page *)((uintptr_t)ptr & ~(uintptr_t)4095); } @@ -546,4 +546,4 @@ void Heap::LargeFreeRemote() } LargeFreeRemoteRaw(list); } -} +} \ No newline at end of file diff --git a/uppsrc/Core/Lang.h b/uppsrc/Core/Lang.h index 673fffe6e..dcd91e3c0 100644 --- a/uppsrc/Core/Lang.h +++ b/uppsrc/Core/Lang.h @@ -68,9 +68,9 @@ public: WString GetIndexLetter(const wchar *text) const { return (*getindexletter)(text, language); } int Compare(const wchar *a, int alen, const wchar *b, int blen) const { return (*compare)(a, alen, b, blen, language); } - int Compare(const wchar *a, const wchar *b) const { return Compare(a, wstrlen(a), b, wstrlen(b)); } + int Compare(const wchar *a, const wchar *b) const { return Compare(a, strlen__(a), b, strlen__(b)); } int Compare(WString a, WString b) const { return Compare(a, a.GetLength(), b, b.GetLength()); } - int Compare(const char *a, const char *b) const { return Compare(ToUnicode(a, CHARSET_DEFAULT), ToUnicode(b, CHARSET_DEFAULT)); } + int Compare(const char *a, const char *b) const { return Compare(ToUtf32(a), ToUtf32(b)); } int Compare(String a, String b) const { return Compare(a.ToWString(), b.ToWString()); } bool operator()(const wchar *a, const wchar *b) const { return Compare(a, b) < 0; } diff --git a/uppsrc/Core/LangInfo.cpp b/uppsrc/Core/LangInfo.cpp index 35e668ebc..2cd362f57 100644 --- a/uppsrc/Core/LangInfo.cpp +++ b/uppsrc/Core/LangInfo.cpp @@ -193,14 +193,14 @@ int CSCZLanguageCompare(const wchar *a, int a_length, const wchar *b, int b_leng String GetLocaleInfoA(LCID lcid, LCTYPE lctype) { - wchar cbuf[1000]; + WCHAR cbuf[1000]; ::GetLocaleInfoW(lcid, lctype, cbuf, __countof(cbuf)); - return FromSystemCharsetW(cbuf); + return cbuf; } WString GetLocaleInfoW(LCID lcid, LCTYPE lctype) { - wchar wbuf[1000]; + WCHAR wbuf[1000]; Zero(wbuf); if(::GetLocaleInfoW(lcid, lctype, (WCHAR *)wbuf, __countof(wbuf))) return wbuf; diff --git a/uppsrc/Core/LocalProcess.cpp b/uppsrc/Core/LocalProcess.cpp index 95c53b622..c3839de92 100644 --- a/uppsrc/Core/LocalProcess.cpp +++ b/uppsrc/Core/LocalProcess.cpp @@ -68,14 +68,11 @@ static void sNoBlock(int fd) #ifdef PLATFORM_WIN32 bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& si, PROCESS_INFORMATION& pi, const char *cd) { // provides conversion of charset for cmdline and envptr - WString wcmd(command); - int n = wcmd.GetCount() + 1; - WString wcd(cd); - Buffer cmd(n); - memcpy(cmd, wcmd, n * sizeof(wchar)); + Vector cmd = ToSystemCharsetW(command); + cmd.Add(0); #if 0 // unicode environment not necessary for now wchar wenvptr = NULL; - Buffer env(n); + Buffer env(n); if(envptr) { int len = 0; while(envptr[len] || envptr[len + 1]) @@ -85,7 +82,8 @@ bool Win32CreateProcess(const char *command, const char *envptr, STARTUPINFOW& s memcpy(env, wenv, (len + 2) * sizeof(wchar)); } #endif - return CreateProcessW(NULL, cmd, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, (void *)envptr, cd ? ~wcd : NULL, &si, &pi); + return CreateProcessW(NULL, cmd, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, (void *)envptr, + cd ? ToSystemCharsetW(cd).begin() : NULL, &si, &pi); } #endif diff --git a/uppsrc/Core/Mem.h b/uppsrc/Core/Mem.h index 5db192468..16b488073 100644 --- a/uppsrc/Core/Mem.h +++ b/uppsrc/Core/Mem.h @@ -641,4 +641,22 @@ int inline_memcmp_aligned(const char *a, const char *b, size_t count) } #endif +template +bool memeq_t(const T *p, const T *q, size_t count) +{ + if((sizeof(T) & 15) == 0) + return memeq128(p, q, count * (sizeof(T) >> 4)); + else + if((sizeof(T) & 7) == 0) + return memeq64(p, q, count * (sizeof(T) >> 3)); + else + if((sizeof(T) & 3) == 0) + return memeq32(p, q, count * (sizeof(T) >> 2)); + else + if((sizeof(T) & 1) == 0) + return memeq16(p, q, count * (sizeof(T) >> 1)); + else + return memeq8(p, q, count * sizeof(T)); +} + hash_t memhash(const void *ptr, size_t count); diff --git a/uppsrc/Core/NetNode.cpp b/uppsrc/Core/NetNode.cpp index 9aa47ab26..9532aa977 100644 --- a/uppsrc/Core/NetNode.cpp +++ b/uppsrc/Core/NetNode.cpp @@ -12,10 +12,10 @@ NetNode::NetNode() NetNode& NetNode::operator=(const NetNode& s) { net = s.net; - local = s.local; - remote = s.remote; - comment = s.comment; - provider = s.provider; + local = clone(s.local); + remote = clone(s.remote); + comment = clone(s.comment); + provider = clone(s.provider); name = s.name; path = s.path; SetPtrs(); @@ -30,25 +30,23 @@ String DosInitCaps(const char *name) return InitCaps(name); } -void NetNode::SetPtr(String& s, char *& ptr) -{ - if(ptr) ptr = (char *)~s; -} - void NetNode::SetPtrs() { + auto SetPtr = [](Vector& s, char16 *& ptr) { if(ptr) ptr = s; }; SetPtr(local, net.lpLocalName); SetPtr(remote, net.lpRemoteName); SetPtr(comment, net.lpComment); SetPtr(provider, net.lpProvider); } +/* void NetNode::Serialize(Stream& s) { s % net.dwScope % net.dwType % net.dwDisplayType % net.dwUsage; s % local % remote % comment % provider % name % path; SetPtrs(); } +*/ Array NetNode::Enum() const { @@ -78,34 +76,35 @@ Array NetNode::Enum0(HANDLE hEnum) { Array r; DWORD cEntries = (DWORD)-1, cbBuffer = 0x4000; - Buffer lpnr(cbBuffer); - while(::WNetEnumResource(hEnum, &cEntries, lpnr, &cbBuffer) == 0) { + Buffer lpnr(cbBuffer); + while(::WNetEnumResourceW(hEnum, &cEntries, lpnr, &cbBuffer) == 0) { for(int i = 0; i < (int)cEntries; i++) { - NETRESOURCE& sn = lpnr[i]; - const char *s = sn.lpRemoteName; + NETRESOURCEW& sn = lpnr[i]; + const WCHAR *s = sn.lpRemoteName; NetNode& nn = r.Add(); - NETRESOURCE& n = nn.net; + NETRESOURCEW& n = nn.net; n = sn; - nn.local = n.lpLocalName; - nn.remote = n.lpRemoteName; - nn.comment = n.lpComment; - nn.provider = n.lpProvider; + auto get = [](const char16 *s) { Vector x; while(s && *s) x.Add(*s++); x.Add(0); return x; }; + nn.local = get(n.lpLocalName); + nn.remote = get(n.lpRemoteName); + nn.comment = get(n.lpComment); + nn.provider = get(n.lpProvider); nn.SetPtrs(); if(s) { if(s[0] == '\\' && s[1] == '\\') - nn.name = FromSystemCharset(DosInitCaps(GetFileName(s))); + nn.name = DosInitCaps(GetFileName(FromSystemCharsetW(s))); else - nn.name = FromSystemCharset(s); + nn.name = FromSystemCharsetW(s); } if(n.lpComment && *n.lpComment) { if(nn.name.GetCount()) - nn.name = String().Cat() << FromSystemCharset(n.lpComment) + nn.name = String().Cat() << FromSystemCharsetW(n.lpComment) << " (" << nn.name << ")"; else - nn.name = FromSystemCharset(n.lpComment); + nn.name = FromSystemCharsetW(n.lpComment); } if(!(n.dwUsage & RESOURCEUSAGE_CONTAINER)) - nn.path = FromSystemCharset(n.lpRemoteName); + nn.path = FromSystemCharsetW(n.lpRemoteName); } } ::WNetCloseEnum(hEnum); diff --git a/uppsrc/Core/Ops.h b/uppsrc/Core/Ops.h index a993a3260..f7b3c99c5 100644 --- a/uppsrc/Core/Ops.h +++ b/uppsrc/Core/Ops.h @@ -233,8 +233,6 @@ byte addc64(uint64& result, const uint64& value, byte carry) { #elif defined(COMPILER_MSC) && defined(CPU_64) -#include - inline uint64 mul64(uint64 a, uint64 b, uint64& hi) { diff --git a/uppsrc/Core/Path.cpp b/uppsrc/Core/Path.cpp index 17904ae71..c098b2006 100644 --- a/uppsrc/Core/Path.cpp +++ b/uppsrc/Core/Path.cpp @@ -187,7 +187,7 @@ bool PathIsEqual(const char *p1, const char *p2) #ifndef PLATFORM_WINCE String GetCurrentDirectory() { #if defined(PLATFORM_WIN32) - wchar h[MAX_PATH]; + WCHAR h[MAX_PATH]; GetCurrentDirectoryW(MAX_PATH, h); return FromSystemCharsetW(h); #elif defined(PLATFORM_POSIX) @@ -211,7 +211,7 @@ bool SetCurrentDirectory(const char *path) String GetTempPath() { - wchar h[MAX_PATH]; + WCHAR h[MAX_PATH]; GetTempPathW(MAX_PATH, h); return FromSystemCharsetW(h); } @@ -253,7 +253,7 @@ String ToUnixName(const char* fn, const char* stop = NULL) { String GetFullPath(const char *file) { #ifdef PLATFORM_WIN32 String ufn = FromUnixName(file); - wchar h[MAX_PATH]; + WCHAR h[MAX_PATH]; GetFullPathNameW(ToSystemCharsetW(ufn), MAX_PATH, h, 0); return FromSystemCharsetW(h); #else @@ -364,10 +364,10 @@ static bool sGetSymLinkPath0(const char *linkpath, String *path) { bool ret = false; HRESULT hres; - IShellLink* psl; + IShellLinkW* psl; IPersistFile* ppf; CoInitialize(NULL); - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (PVOID *) &psl); if(SUCCEEDED(hres)) { hres = psl->QueryInterface(IID_IPersistFile, (PVOID *) &ppf); @@ -375,9 +375,9 @@ static bool sGetSymLinkPath0(const char *linkpath, String *path) hres = ppf->Load(ToSystemCharsetW(linkpath), STGM_READ); if(SUCCEEDED(hres)) { if(path) { - char fileW[_MAX_PATH] = {0}; + WCHAR fileW[_MAX_PATH] = {0}; psl->GetPath(fileW, _MAX_PATH, NULL, 0); - *path = FromSystemCharset(fileW); + *path = fileW; } else ret = true; @@ -950,20 +950,20 @@ Array FileSystemInfo::Find(String mask, int max_count, f.filename = "\\"; f.root_style = ROOT_FIXED; #elif defined(PLATFORM_WIN32) - char drive[4] = "?:\\"; + WCHAR drive[4] = L"?:\\"; for(int c = 'A'; c <= 'Z'; c++) { *drive = c; - int n = GetDriveType(drive); + int n = GetDriveTypeW(drive); if(n == DRIVE_NO_ROOT_DIR) continue; FileInfo& f = fi.Add(); f.filename = drive; - char name[256], system[256]; + WCHAR name[256], system[256]; DWORD d; if(c != 'A' && c != 'B' && n != DRIVE_UNKNOWN) { - bool b = GetVolumeInformation(drive, name, 256, &d, &d, &d, system, 256); + bool b = GetVolumeInformationW(drive, name, 256, &d, &d, &d, system, 256); if(b) { - if(*name) f.root_desc << " " << FromSystemCharset(name); + if(*name) f.root_desc << " " << FromSystemCharsetW(name); } else if(n == DRIVE_REMOVABLE || n == DRIVE_CDROM) { if(unmounted) { diff --git a/uppsrc/Core/Path.h b/uppsrc/Core/Path.h index 8f8922c82..50c608282 100644 --- a/uppsrc/Core/Path.h +++ b/uppsrc/Core/Path.h @@ -315,15 +315,14 @@ FileSystemInfo& StdFileSystemInfo(); #ifdef PLATFORM_WIN32 class NetNode : Moveable { - NETRESOURCE net; - String local, remote, comment, provider; + NETRESOURCEW net; + Vector local, remote, comment, provider; - String name; - String path; + String name; + String path; static void Copy(String& t, char *s); static Array Enum0(HANDLE hEnum); - static void SetPtr(String& s, char *& ptr); void SetPtrs(); @@ -334,14 +333,12 @@ public: String GetName() const { return name; } String GetPath() const { return path; } int GetDisplayType() const; - String GetRemote() const { return remote; } - String GetLocal() const { return local; } - String GetProvider() const { return provider; } - String GetComment() const { return comment; } + String GetRemote() const { return ToUtf8(remote); } + String GetLocal() const { return ToUtf8(local); } + String GetProvider() const { return ToUtf8(provider); } + String GetComment() const { return ToUtf8(comment); } Array Enum() const; - void Serialize(Stream& s); - static Array EnumRoot(); static Array EnumRemembered(); diff --git a/uppsrc/Core/SSL/InitExit.cpp b/uppsrc/Core/SSL/InitExit.cpp index 8ea5227f8..8923c0413 100644 --- a/uppsrc/Core/SSL/InitExit.cpp +++ b/uppsrc/Core/SSL/InitExit.cpp @@ -6,28 +6,25 @@ namespace Upp { static int64 UPP_SSL_alloc = 0; -static void *SslAlloc0(size_t size) -{ - LLOG("Alloc " << size); - size_t alloc = size + sizeof(int64); - int64 *aptr = (int64 *)MemoryAllocSz(alloc); - *aptr++ = (int64)alloc; - UPP_SSL_alloc += alloc; - LLOG("UPP_SSL_MALLOC(" << (int64)size << ", alloc " << alloc << ") -> " << FormatIntHex(aptr) << ", total = " << UPP_SSL_alloc); - return aptr; -} - #if OPENSSL_VERSION_NUMBER >= 0x10100000L -static void *SslAlloc(size_t size, const char *, int) +static void *SslAlloc(size_t size, const char *file, int line) #else static void *SslAlloc(size_t size) #endif { - return SslAlloc0(size); + size_t alloc = size + sizeof(int64); + int64 *aptr = (int64 *)MemoryAllocSz(alloc); + *aptr++ = (int64)alloc; + UPP_SSL_alloc += alloc; + LLOG("UPP_SSL_MALLOC(" << (int64)size << ", size " << size + << ", " << file << " " << line + << ") -> " << aptr << ", MemorySize: " << GetMemoryBlockSize(aptr) + << ", total = " << UPP_SSL_alloc << ", thread: " << Thread::GetCurrentId()); + return aptr; } #if OPENSSL_VERSION_NUMBER >= 0x10100000L -static void SslFree(void *ptr, const char *, int) +static void SslFree(void *ptr, const char *file, int line) #else static void SslFree(void *ptr) #endif @@ -36,35 +33,46 @@ static void SslFree(void *ptr) return; int64 *aptr = (int64 *)ptr - 1; UPP_SSL_alloc -= *aptr; - LLOG("UPP_SSL_FREE(" << ptr << ", alloc " << *aptr << "), total = " << UPP_SSL_alloc); + LLOG("UPP_SSL_FREE(" << ptr << ", size " << *aptr + << ", " << file << " " << line + << "), MemorySize: " << GetMemoryBlockSize(aptr) << ", total = " << UPP_SSL_alloc << ", thread: " << Thread::GetCurrentId()); + if(*aptr != GetMemoryBlockSize(aptr)) + Panic("SslFree corrupted"); MemoryFree(aptr); } #if OPENSSL_VERSION_NUMBER >= 0x10100000L -static void *SslRealloc(void *ptr, size_t size, const char *, int) +static void *SslRealloc(void *ptr, size_t size, const char *file, int line) #else static void *SslRealloc(void *ptr, size_t size) #endif { LLOG("SslRealloc " << ptr << ", " << size); - if(!ptr) - return SslAlloc0(size); + if(!ptr) { + LLOG("UPP_SSL_REALLOC by Alloc:"); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + return SslAlloc(size, file, line); +#else + return SslAlloc(size); +#endif + } int64 *aptr = (int64 *)ptr - 1; - if((int64)(size + sizeof(int64)) <= *aptr) { - LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << *aptr << ") -> keep same block"); + if((int64)(size + sizeof(int64)) <= *aptr) { // TODO: Do we really want this? + LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << *aptr << ") -> keep same block" << ", thread: " << Thread::GetCurrentId()); return ptr; } size_t newalloc = size + sizeof(int64); int64 *newaptr = (int64 *)MemoryAllocSz(newalloc); if(!newaptr) { - LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc << ") -> fail"); + LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc << ") -> fail" << ", thread: " << Thread::GetCurrentId()); return NULL; } *newaptr++ = newalloc; memcpy(newaptr, ptr, min((int)(*aptr - sizeof(int64)), (int)size)); UPP_SSL_alloc += newalloc - *aptr; - LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc << ") -> " - << FormatIntHex(newaptr) << ", total = " << UPP_SSL_alloc); + LLOG("UPP_SSL_REALLOC(" << ptr << ", " << (int64)size << ", alloc " << newalloc + << ", " << file << " " << line + << ") -> " << newaptr << ", total = " << UPP_SSL_alloc << ", thread: " << Thread::GetCurrentId()); MemoryFree(aptr); return newaptr; } @@ -74,7 +82,7 @@ void TcpSocketInit(); INITIALIZER(SSL) { MemoryIgnoreLeaksBlock __; - LLOG("SSL init"); + LLOG("SslInit"); TcpSocketInit(); CRYPTO_set_mem_functions(SslAlloc, SslRealloc, SslFree); SSL_library_init(); diff --git a/uppsrc/Core/Speller.cpp b/uppsrc/Core/Speller.cpp index 09d8a58c5..2efb96ca5 100644 --- a/uppsrc/Core/Speller.cpp +++ b/uppsrc/Core/Speller.cpp @@ -167,7 +167,7 @@ Speller *sGetSpeller(int lang) while(!user.IsEof()) { String s = user.GetLine(); if(!s.IsEmpty()) - f.user.Add(FromUtf8(s)); + f.user.Add(ToUtf32(s)); } if(in.Get() != 255) f.SetOld(LoadFile(path)); diff --git a/uppsrc/Core/SplitMerge.cpp b/uppsrc/Core/SplitMerge.cpp index 7f201381f..ec830d545 100644 --- a/uppsrc/Core/SplitMerge.cpp +++ b/uppsrc/Core/SplitMerge.cpp @@ -138,7 +138,7 @@ Vector Split(int maxcount, const wchar *s, const wchar *text, bool igno { SplitDelimWText delim; delim.ds = text; - delim.l = wstrlen(text); + delim.l = strlen__(text); return delim.l ? SplitGeneric(maxcount, delim, s, ignoreempty) : Vector(); } diff --git a/uppsrc/Core/StrUtil.cpp b/uppsrc/Core/StrUtil.cpp index 6951fd669..283102d15 100644 --- a/uppsrc/Core/StrUtil.cpp +++ b/uppsrc/Core/StrUtil.cpp @@ -2,11 +2,20 @@ namespace Upp { -int wstrlen(const wchar *s) +int strlen16(const char16 *s) { - const wchar *q = s; - while(*q) q++; - return (int)(q - s); + if(!s) return 0; + const char16 *s0 = s; + while(*s) s++; + return int(s - s0); +} + +int strlen32(const wchar *s) +{ + if(!s) return 0; + const wchar *s0 = s; + while(*s) s++; + return int(s - s0); } unsigned ctoi(int c) @@ -32,7 +41,7 @@ int CharFilterAscii128(int c) int CharFilterUnicode(int c) { - return c >= 32 && c < 65536 ? c : 0; + return c >= 32 && c < 0x10FFFF ? c : 0; } int CharFilterDigit(int c) diff --git a/uppsrc/Core/Stream.cpp b/uppsrc/Core/Stream.cpp index 92e9df196..716fe5f15 100644 --- a/uppsrc/Core/Stream.cpp +++ b/uppsrc/Core/Stream.cpp @@ -629,36 +629,29 @@ Stream& Stream::operator/(String& s) { return *this; } -Stream& Stream::operator%(WString& s) { +Stream& Stream::operator%(WString& s) +{ // we do not support BE here anymore if(IsError()) return *this; if(IsLoading()) { - dword len; - Pack(len); - if(len < 256 * 1024) { - WStringBuffer sb(len); - SerializeRaw((byte*)~sb, len * sizeof(wchar)); - s = sb; - } - else { - String h = GetAll(len * sizeof(wchar)); - if(h.IsVoid()) - LoadError(); - else { - WStringBuffer sb(len); - memcpy8(~sb, ~h, len * sizeof(wchar)); - s = sb; - } - } + dword len = Get(); + if(len == 0xff) + len = Get32le(); + String h = GetAll(len * sizeof(char16)); + if(h.IsVoid()) + LoadError(); + else + s = ToUtf32((const char16 *)~h, len); } else { - dword len = s.GetLength(); + Vector x = ToUtf16(s); + dword len = x.GetCount(); if(len < 0xff) Put(len); else { Put(0xff); Put32le(len); } - SerializeRaw((byte*)~s, len * sizeof(wchar)); + SerializeRaw((byte*)x.begin(), len * sizeof(char16)); } return *this; } @@ -667,7 +660,7 @@ Stream& Stream::operator/(WString& s) { if(IsError()) return *this; String h = ToUtf8(s); *this / h; - s = FromUtf8(h); + s = ToUtf32(h); return *this; } @@ -1082,32 +1075,28 @@ Stream& NilStream() return Single(); } -#ifdef PLATFORM_WIN32 -bool IsCoutUTF8; -#endif - -void CoutUTF8() -{ -#ifdef PLATFORM_WIN32 - IsCoutUTF8 = true; - SetConsoleOutputCP(65001); -#endif -} - #ifndef PLATFORM_WINCE class CoutStream : public Stream { +#ifdef PLATFORM_WIN32 String buffer; + void Flush() { + ONCELOCK { + SetConsoleOutputCP(65001); // set console to UTF8 mode + } + static HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + dword dummy; + WriteFile(h, ~buffer, buffer.GetCount(), &dummy, NULL); + buffer.Clear(); + } +#endif + + void Put0(int w) { #ifdef PLATFORM_WIN32 buffer.Cat(w); - if(CheckUtf8(buffer)) { // TODO: Use W api - String ws = ToSystemCharset(buffer, GetConsoleOutputCP()); - static HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); - dword dummy; - WriteFile(h, ~ws, ws.GetCount(), &dummy, NULL); - buffer.Clear(); - } + if(CheckUtf8(buffer) || buffer.GetCount() > 8) + Flush(); #else putchar(w); #endif diff --git a/uppsrc/Core/Stream.h b/uppsrc/Core/Stream.h index 2a00b971f..9c171a1ba 100644 --- a/uppsrc/Core/Stream.h +++ b/uppsrc/Core/Stream.h @@ -178,10 +178,6 @@ public: void PutLine(const char *s); void PutLine(const String& s); - void PutW(const wchar *s, int count) { Put(s, count * 2); } - dword GetW(wchar *s, int count) { return Get(s, count * 2) / 2; } - bool GetAllW(wchar *s, int count) { return GetAll(s, count * 2); } - void Put(Stream& s, int64 size = INT64_MAX, dword click = 4096); // Stream as serialization streamer @@ -253,6 +249,9 @@ public: void PutIL(int c) { Put32le(c); } void PutMW(int c) { Put16be(c); } void PutML(int c) { Put32be(c); } + void PutW(const char16 *s, int count) { Put(s, count * 2); } + dword GetW(char16 *s, int count) { return Get(s, count * 2) / 2; } + bool GetAllW(char16 *s, int count) { return GetAll(s, count * 2); } #endif private: // No copy Stream(const Stream& s); diff --git a/uppsrc/Core/String.cpp b/uppsrc/Core/String.cpp index eb71cc6ed..8013d7872 100644 --- a/uppsrc/Core/String.cpp +++ b/uppsrc/Core/String.cpp @@ -216,9 +216,12 @@ WString String::ToWString() const int String::GetCharCount() const { - return GetDefaultCharset() == CHARSET_UTF8 ? utf8len(Begin(), GetCount()) : GetCount(); + return GetDefaultCharset() == CHARSET_UTF8 ? Utf32Len(Begin(), GetCount()) : GetCount(); } +String::String(char16 *s) : String(ToUtf8(s)) {} +String::String(wchar *s) : String(ToUtf8(s)) {} + String::String(StringBuffer& b) { Zero(); @@ -354,26 +357,14 @@ struct StringICompare__ StringICompare__(int e) : encoding(e) {} }; -int CompareNoCase(const String& a, const String& b, byte encoding) +int CompareNoCase(const String& a, const String& b) { - if(encoding == CHARSET_DEFAULT) encoding = GetDefaultCharset(); - if(encoding == CHARSET_UTF8) return CompareNoCase(FromUtf8(a), FromUtf8(b)); -#ifdef DEPRECATED - return IterCompare(a.Begin(), a.End(), b.Begin(), b.End(), StringICompare__(encoding)); -#else - return CompareRanges(a, b, StringICompare__(encoding)); -#endif + return CompareNoCase(ToUtf32(a), ToUtf32(b)); } -int CompareNoCase(const String& a, const char *b, byte encoding) +int CompareNoCase(const String& a, const char *b) { - if(encoding == CHARSET_DEFAULT) encoding = GetDefaultCharset(); - if(encoding == CHARSET_UTF8) return CompareNoCase(FromUtf8(a), FromUtf8(b, (int)strlen(b))); -#ifdef DEPRECATED - return IterCompare(a.Begin(), a.End(), b, b + strlen(b), StringICompare__(encoding)); -#else - return CompareRanges(a, SubRange(b, b + strlen(b)), StringICompare__(encoding)); -#endif + return CompareNoCase(ToUtf32(a), ToUtf32(b, (int)strlen(b))); } } diff --git a/uppsrc/Core/String.h b/uppsrc/Core/String.h index dc8d6af8e..9a59c7369 100644 --- a/uppsrc/Core/String.h +++ b/uppsrc/Core/String.h @@ -1,6 +1,8 @@ class Nuller; -int wstrlen(const wchar *s); +inline int strlen8(const char *s) { return s ? (int)strlen(s) : 0; } +int strlen16(const char16 *s); +int strlen32(const wchar *s); #ifdef PLATFORM_POSIX inline int stricmp(const char *a, const char *b) { return strcasecmp(a, b); } @@ -12,12 +14,11 @@ inline int stricmp(const char *a, const char *b) { return _stricmp(a, b) inline int strnicmp(const char *a, const char *b, int n) { return _strnicmp(a, b, n); } #endif -force_inline int strlen__(const char *s) { return s ? (int)strlen(s) : 0; } - -inline int strlen__(const wchar *s) { return s ? (int)wstrlen(s) : 0; } +force_inline int strlen__(const char *s) { return strlen8(s); } +inline int strlen__(const wchar *s) { return strlen32(s); } inline int cmpval__(char x) { return (byte)x; } -inline int cmpval__(wchar x) { return (word)x; } +inline int cmpval__(wchar x) { return x; } int find(const char *text, int len, const char *needle, int nlen, int from); int find(const wchar *text, int len, const wchar *needle, int nlen, int from); @@ -391,6 +392,10 @@ public: String(int chr, int count) { String0::Zero(); Cat(chr, count); } String(StringBuffer& b); + + String(char16 *s); + String(wchar *s); + WString ToWString() const; const String& ToString() const { return *this; } @@ -618,12 +623,12 @@ inline String AsString(const String& s) { return s; } template<> inline hash_t GetHashValue(const String& s) { return s.GetHashValue(); } -int CompareNoCase(const String& a, const String& b, byte encoding = 0); -int CompareNoCase(const String& a, const char *b, byte encoding = 0); +int CompareNoCase(const String& a, const String& b); +int CompareNoCase(const String& a, const char *b); inline -int CompareNoCase(const char *a, const String& b, byte encoding = 0) { - return -CompareNoCase(b, a, encoding); +int CompareNoCase(const char *a, const String& b) { + return -CompareNoCase(b, a); } String TrimLeft(const String& s); @@ -774,8 +779,8 @@ public: int GetAlloc() const { return alloc; } hash_t GetHashValue() const { return memhash(ptr, length * sizeof(wchar)); } - bool IsEqual(const WString0& s) const { return s.length == length && memeq16(ptr, s.ptr, length); } - bool IsEqual(const wchar *s) const { int l = wstrlen(s); return l == GetCount() && memeq16(begin(), s, l); } + bool IsEqual(const WString0& s) const { return s.length == length && memeq_t(ptr, s.ptr, length); } + bool IsEqual(const wchar *s) const { int l = strlen__(s); return l == GetCount() && memeq_t(begin(), s, l); } int Compare(const WString0& s) const; void Remove(int pos, int count = 1); @@ -835,6 +840,8 @@ public: WString(const char *s, int n); WString(const char *s, const char *lim); + WString(const char16 *s); + static WString GetVoid(); bool IsVoid() const { return alloc < 0; } @@ -845,13 +852,13 @@ public: #ifndef _HAVE_NO_STDWSTRING WString(const std::wstring& s); - operator std::wstring() const; - std::wstring ToStd() const { return std::wstring(Begin(), End()); } + operator std::wstring() const { return ToStd(); } + std::wstring ToStd() const; #endif }; #ifndef _HAVE_NO_STDWSTRING -inline std::wstring to_string(const WString& s) { return std::wstring(s.Begin(), s.End()); } +inline std::wstring to_string(const WString& s) { return s.ToStd(); } #endif class WStringBuffer : NoCopy { @@ -885,7 +892,7 @@ public: void SetCount(int l) { SetLength(l); } int GetLength() const { return (int)(pend - pbegin); } int GetCount() const { return GetLength(); } - void Strlen() { SetLength(wstrlen(pbegin)); } + void Strlen() { SetLength(strlen__(pbegin)); } void Clear() { Free(); Zero(); } void Reserve(int r) { int l = GetLength(); SetLength(l + r); SetLength(l); } @@ -893,7 +900,7 @@ public: void Cat(int c, int count); void Cat(const wchar *s, int l); void Cat(const wchar *s, const wchar *e) { Cat(s, int(e - s)); } - void Cat(const wchar *s) { Cat(s, wstrlen(s)); } + void Cat(const wchar *s) { Cat(s, strlen__(s)); } void Cat(const WString& s) { Cat(s, s.GetLength()); } void Cat(const char *s) { Cat(WString(s)); } diff --git a/uppsrc/Core/StringFind.cpp b/uppsrc/Core/StringFind.cpp index ef5f25abf..d717259f4 100644 --- a/uppsrc/Core/StringFind.cpp +++ b/uppsrc/Core/StringFind.cpp @@ -123,8 +123,8 @@ int find(const char *text, int len, const char *needle, int nlen, int from) int find(const wchar *text, int len, const wchar *needle, int nlen, int from) { - int q = t_find<2>((const char *)text, 2 * len, (const char *)needle, 2 * nlen, 2 * from); - return q < 0 ? q : q / 2; + int q = t_find((const char *)text, sizeof(wchar) * len, (const char *)needle, sizeof(wchar) * nlen, sizeof(wchar) * from); + return q < 0 ? q : q / sizeof(wchar); } #else diff --git a/uppsrc/Core/UnicodeInfo.cpp b/uppsrc/Core/UnicodeInfo.cpp index bafeb392a..9cb32af78 100644 --- a/uppsrc/Core/UnicodeInfo.cpp +++ b/uppsrc/Core/UnicodeInfo.cpp @@ -76,12 +76,12 @@ struct UnicodeInfo { } }; - Index composed; - Index decomposed; // using String as the vessel for dwords + Index composed; + Index decomposed; int canonical_count; - Index lower; - Index upper; + Index lower; + Index upper; CharBits rtl; CharBits letter; CharBits islower; @@ -130,8 +130,8 @@ UnicodeInfo::UnicodeInfo() count += data[1]; for(int i = 0; i < count; i++) { composed.Add(data[i + 2]); - String h; - auto put = [&](dword c) { if(c) h.Cat((char *)&c, 4); }; + WString h; + auto put = [&](dword c) { if(c) h.Cat(c); }; put(data[i + count + 2]); put(data[i + 2 * count + 2]); put(data[i + 3 * count + 2]); @@ -143,11 +143,11 @@ UnicodeInfo::UnicodeInfo() int offset = 4 * count + 2; while(data[offset]) { - dword code = data[offset++]; + wchar code = data[offset++]; int ii = composed.Find(code); - String h = decomposed[ii]; + WString h = decomposed[ii]; while(data[offset]) - h.Cat((char *)&data[offset++], 4); + h.Cat(data[offset++]); decomposed.Set(ii, h); offset++; } @@ -169,54 +169,54 @@ UnicodeInfo::UnicodeInfo() Load(data, ismark, offset); } -static int sUnicodeDecompose(dword codepoint, dword *t, Vector *r, bool only_canonical) +static int sUnicodeDecompose(wchar codepoint, wchar *t, WString *r, bool only_canonical) { // TODO: Add hangul support const UnicodeInfo& f = Single(); int q = f.composed.Find(codepoint); if(q >= 0 && (!only_canonical || q < f.canonical_count)) { - String s = f.decomposed[q]; + const WString& s = f.decomposed[q]; if(r) - r->SetCount(s.GetCount() >> 2); - int i; - for(i = 0; 4 * i < s.GetCount(); i++) - (r ? (*r)[i] : t[i]) = ((const dword *)~s)[i]; - return i; + *r = s; + if(t) + memcpy(t, s, sizeof(wchar) * s.GetCount()); + return s.GetCount(); } return 0; } -int UnicodeDecompose(dword codepoint, dword t[MAX_DECOMPOSED], bool only_canonical) +int UnicodeDecompose(wchar codepoint, wchar t[MAX_DECOMPOSED], bool only_canonical) { return sUnicodeDecompose(codepoint, t, NULL, only_canonical); } -Vector UnicodeDecompose(dword codepoint, bool only_canonical) +WString UnicodeDecompose(wchar codepoint, bool only_canonical) { - Vector r; + WString r; sUnicodeDecompose(codepoint, NULL, &r, only_canonical); return r; } -dword UnicodeCompose(const dword *t, int count) +wchar UnicodeCompose(const WString& s) { + int count = s.GetCount(); if(count < 1 || count > 3) return 0; if(count == 1) - return t[0]; - String s((byte *)t, sizeof(dword) * count); + return *s; + const UnicodeInfo& f = Single(); int q = f.decomposed.Find(s); return q >= 0 && q < f.canonical_count ? f.composed[q] : 0; } -dword ToUpperRest_(dword c) +wchar ToUpperRest_(wchar c) { const UnicodeInfo& f = Single(); int q = f.lower.Find(c); return q >= 0 ? f.upper[q] : c; } -dword ToLowerRest_(dword c) +wchar ToLowerRest_(wchar c) { if(c == 0x1e9e) // Capital sharp S -> small sharp S (but not reverse direction) return 0xdf; @@ -233,7 +233,7 @@ dword ToLowerRest_(dword c) return q >= 0 ? f.lower[q] : c; } -char ToAsciiRest_(dword c) +char ToAsciiRest_(wchar c) { const UnicodeInfo& f = Single(); int q = f.composed.Find(c); @@ -243,27 +243,27 @@ char ToAsciiRest_(dword c) return ch >= ' ' && ch < 128 ? ch : ' '; } -bool IsRTL_(dword c) +bool IsRTL_(wchar c) { return Single().rtl.Get(c); } -bool IsLetter_(dword c) +bool IsLetter_(wchar c) { return Single().letter.Get(c); } -bool IsLower_(dword c) +bool IsLower_(wchar c) { return c != (dword)ToUpper((int)c) || Single().islower.Get(c); } -bool IsUpper_(dword c) +bool IsUpper_(wchar c) { return c != (dword)ToLower((int)c) || Single().isupper.Get(c); } -bool IsMark_(dword c) +bool IsMark_(wchar c) { return Single().ismark.Get(c); } diff --git a/uppsrc/Core/Utf.cpp b/uppsrc/Core/Utf.cpp index 3acf1bd32..4844c6c8c 100644 --- a/uppsrc/Core/Utf.cpp +++ b/uppsrc/Core/Utf.cpp @@ -2,138 +2,142 @@ namespace Upp { -int strlen32(const dword *s) -{ - const dword *s0 = s; - while(*s) s++; - return int(s - s0); -} - bool CheckUtf8(const char *s, int len) { - return FromUtf8_([](const byte *, dword){}, s, len); -} - -int Utf8Len(const dword *s, int len) -{ - int rlen = 0; - for(const dword *lim = s + len; s < lim; s++) - ToUtf8_([&](char) { rlen++; }, *s); - return rlen; -} - -void ToUtf8(char *t, const dword *s, int len) -{ - for(const dword *lim = s + len; s < lim; s++) - ToUtf8_([&](char c) { *t++ = c; }, *s); -} - -String ToUtf8(const dword *s, int len) -{ - String r; - for(const dword *lim = s + len; s < lim; s++) - ToUtf8_([&](char c) { r.Cat(c); }, *s); - return r; + return FromUtf8_([](wchar) {}, s, len); } int Utf8Len(const wchar *s, int len) { int rlen = 0; - FromUtf16_([&](const wchar *, dword code) { ToUtf8_([&](char c) { rlen++; }, code); }, s, len); + for(const wchar *lim = s + len; s < lim; s++) + ToUtf8_([&](char) { rlen++; }, *s); return rlen; } void ToUtf8(char *t, const wchar *s, int len) { - FromUtf16_([&](const wchar *, dword code) { ToUtf8_([&](char c) { *t++ = c; }, code); }, s, len); + for(const wchar *lim = s + len; s < lim; s++) + ToUtf8_([&](char c) { *t++ = c; }, *s); } String ToUtf8(const wchar *s, int len) { - StringBuffer r; - r.Reserve(len); - FromUtf16_([&](const wchar *, dword code) { ToUtf8_([&](char c) { r.Cat(c); }, code); }, s, len); - return String(r); + String r; + for(const wchar *lim = s + len; s < lim; s++) + ToUtf8_([&](char c) { r.Cat(c); }, *s); + return r; } -int Utf16Len(const dword *s, int len) +int Utf8Len(const char16 *s, int len) { int rlen = 0; - for(const dword *lim = s + len; s < lim; s++) - ToUtf16_([&](wchar) { rlen++; }, *s); + FromUtf16_([&](wchar code) { ToUtf8_([&](char c) { rlen++; }, code); }, s, len); return rlen; } -void ToUtf16(wchar *t, const dword *s, int len) +void ToUtf8(char *t, const char16 *s, int len) { - for(const dword *lim = s + len; s < lim; s++) - ToUtf16_([&](wchar c) { *t++ = c; }, *s); + FromUtf16_([&](wchar code) { ToUtf8_([&](char c) { *t++ = c; }, code); }, s, len); } -WString ToUtf16(const dword *s, int len) +String ToUtf8(const char16 *s, int len) { - WStringBuffer r; + StringBuffer r; r.Reserve(len); - for(const dword *lim = s + len; s < lim; s++) - ToUtf16_([&](wchar c) { r.Cat(c); }, *s); - return WString(r); + FromUtf16_([&](wchar code) { ToUtf8_([&](char c) { r.Cat(c); }, code); }, s, len); + return String(r); +} + +int Utf16Len(const wchar *s, int len) +{ + int rlen = 0; + for(const wchar *lim = s + len; s < lim; s++) + ToUtf16_([&](char16) { rlen++; }, *s); + return rlen; +} + +int ToUtf16(char16 *t, const wchar *s, int len) +{ + char16 *t0 = t; + for(const wchar *lim = s + len; s < lim; s++) + ToUtf16_([&](char16 c) { *t++ = c; }, *s); + return int(t - t0); +} + +Vector ToUtf16(const wchar *s, int len) +{ + Vector r; + r.Reserve(len); + for(const wchar *lim = s + len; s < lim; s++) + ToUtf16_([&](char16 c) { r.Add(c); }, *s); + return r; } int Utf16Len(const char *s, int len) { int rlen = 0; - FromUtf8_([&](const byte *, dword code) { ToUtf16_([&](wchar c) { rlen++; }, code); }, s, len); + FromUtf8_([&](wchar code) { + ToUtf16_([&](char16) { rlen++; }, code); + }, s, len); return rlen; } -void ToUtf16(wchar *t, const char *s, int len) +int ToUtf16(char16 *t, const char *s, int len) { - FromUtf8_([&](const byte *, dword code) { ToUtf16_([&](wchar c) { *t++ = c; }, code); }, s, len); + char16 *t0 = t; + FromUtf8_([&](wchar code) { + ToUtf16_([&](char16 c) { *t++ = c; }, code); + }, s, len); + return int(t - t0); } -WString ToUtf16(const char *s, int len) +Vector ToUtf16(const char *s, int len) { - WStringBuffer r; - FromUtf8_([&](const byte *, dword code) { ToUtf16_([&](wchar c) { r.Cat(c); }, code); }, s, len); - return WString(r); + Vector r; + FromUtf8_([&](wchar code) { + ToUtf16_([&](char16 c) { r.Add(c); } , code); + }, s, len); + return r; } int Utf32Len(const char *s, int len) { int rlen = 0; - FromUtf8_([&](const byte *, dword) { rlen++; }, s, len); + FromUtf8_([&](wchar) { rlen++; }, s, len); return rlen; } -void ToUtf32(dword *t, const char *s, int len) +void ToUtf32(wchar *t, const char *s, int len) { - FromUtf8_([&](const byte *, dword c) { *t++ = c; }, s, len); + FromUtf8_([&](wchar c) { *t++ = c; }, s, len); } -Vector ToUtf32(const char *s, int len) +WString ToUtf32(const char *s, int len) { - Vector r; - FromUtf8_([&](const byte *, dword c) { r.Add(c); }, s, len); - return r; + WStringBuffer r; + FromUtf8_([&](wchar c) { r.Cat(c); }, s, len); + return WString(r); } -int Utf32Len(const wchar *s, int len) +int Utf32Len(const char16 *s, int len) { int rlen = 0; - FromUtf16_([&](const wchar *, dword) { rlen++; }, s, len); + FromUtf16_([&](wchar) { rlen++; }, s, len); return rlen; } -void ToUtf32(dword *t, const wchar *s, int len) +void ToUtf32(wchar *t, const char16 *s, int len) { - FromUtf16_([&](const wchar *, dword c) { *t++ = c; }, s, len); + FromUtf16_([&](wchar c) { *t++ = c; }, s, len); } -Vector ToUtf32(const wchar *s, int len) +WString ToUtf32(const char16 *s, int len) { - Vector r; - FromUtf16_([&](const wchar *, dword c) { r.Add(c); }, s, len); - return r; + WStringBuffer r; + r.Reserve(len); + FromUtf16_([&](wchar c) { r.Cat(c); }, s, len); + return WString(r); } String Utf8ToAscii(const String& src) @@ -176,4 +180,4 @@ String Utf8ToLowerAscii(const String& src) return String(r); } -}; +}; \ No newline at end of file diff --git a/uppsrc/Core/Utf.hpp b/uppsrc/Core/Utf.hpp index 19b8dc319..099fceabd 100644 --- a/uppsrc/Core/Utf.hpp +++ b/uppsrc/Core/Utf.hpp @@ -1,5 +1,5 @@ template -force_inline bool ToUtf8_(Target t, dword codepoint) +force_inline bool ToUtf8_(Target t, wchar codepoint) { if(codepoint < 0x80) t((char)codepoint); @@ -29,7 +29,7 @@ force_inline bool ToUtf8_(Target t, dword codepoint) return true; } -force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok) +force_inline dword FetchUtf8(const char *&_s, bool nolim, const char *_lim, bool& ok) { const byte *s = (const byte *)_s; const byte *lim = (const byte *)_lim; @@ -41,14 +41,14 @@ force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok) else if(code >= 0xC2) { dword c; - if(code < 0xE0 && s + 1 < lim && + if(code < 0xE0 && (nolim || s + 1 < lim) && s[1] >= 0x80 && s[1] < 0xc0 && (c = ((code - 0xC0) << 6) + s[1] - 0x80) >= 0x80 && c < 0x800) { _s += 2; return c; } else - if(code < 0xF0 && s + 2 < lim && + if(code < 0xF0 && (nolim || s + 2 < lim) && s[1] >= 0x80 && s[1] < 0xc0 && s[2] >= 0x80 && s[2] < 0xc0 && (c = ((code - 0xE0) << 12) + ((s[1] - 0x80) << 6) + s[2] - 0x80) >= 0x800 && !(c >= 0xEE00 && c <= 0xEEFF)) { @@ -56,7 +56,7 @@ force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok) return c; } else - if(code < 0xF8 && s + 3 < lim && + if(code < 0xF8 && (nolim || s + 3 < lim) && s[1] >= 0x80 && s[1] < 0xc0 && s[2] >= 0x80 && s[2] < 0xc0 && s[3] >= 0x80 && s[3] < 0xc0 && (c = ((code - 0xF0) << 18) + ((s[1] - 0x80) << 12) + ((s[2] - 0x80) << 6) + s[3] - 0x80) >= 0x10000 && c < 0x110000) { @@ -69,13 +69,23 @@ force_inline dword FetchUtf8(const char *&_s, const char *_lim, bool& ok) return 0xEE00 + code; // ERROR ESCAPE } +force_inline dword FetchUtf8(const char *&s, const char *lim, bool& ok) +{ + return FetchUtf8(s, false, lim, ok); +} + +force_inline dword FetchUtf8(const char *&s, bool& ok) +{ + return FetchUtf8(s, true, NULL, ok); +} + template force_inline bool FromUtf8_(Target t, const char *s, size_t len) { bool ok = true; const char *lim = s + len; while(s < lim) - t((const byte *)s, FetchUtf8(s, lim, ok)); + t(FetchUtf8(s, lim, ok)); return ok; } @@ -83,36 +93,36 @@ template force_inline bool ToUtf16_(Target t, size_t codepoint) { if(codepoint < 0x10000) - t((wchar)codepoint); + t((char16)codepoint); else if(codepoint < 0x110000) { codepoint -= 0x10000; - t(wchar(0xD800 + (0x3ff & (codepoint >> 10)))); - t(wchar(0xDC00 + (0x3ff & codepoint))); + t(char16(0xD800 + (0x3ff & (codepoint >> 10)))); + t(char16(0xDC00 + (0x3ff & codepoint))); } else return false; return true; } -force_inline dword ReadSurrogatePair(const wchar *s, const wchar *lim) +force_inline wchar ReadSurrogatePair(const char16 *s, const char16 *lim) { return (*s & 0XFC00) == 0xD800 && s + 1 < lim && (s[1] & 0xFC00) == 0xDC00 ? - ((dword(s[0] & 0x3ff) << 10) | (s[1] & 0x3ff)) + 0x10000 : 0; + ((wchar(s[0] & 0x3ff) << 10) | (s[1] & 0x3ff)) + 0x10000 : 0; } template -force_inline void FromUtf16_(Target t, const wchar *s, size_t len) +force_inline void FromUtf16_(Target t, const char16 *s, size_t len) { - const wchar *lim = s + len; + const char16 *lim = s + len; while(s < lim) { - dword c = ReadSurrogatePair(s, lim); + wchar c = ReadSurrogatePair(s, lim); if(c) { - t(s, c); + t(c); s += 2; } else { - t(s, *s); + t(*s); s++; } } diff --git a/uppsrc/Core/Util.cpp b/uppsrc/Core/Util.cpp index 555badfeb..8a27d9f24 100644 --- a/uppsrc/Core/Util.cpp +++ b/uppsrc/Core/Util.cpp @@ -577,25 +577,13 @@ int ChNoInvalid(int c) return c == DEFAULTCHAR ? '_' : c; } -#ifdef PLATFORM_WINCE -WString ToSystemCharset(const String& src) -{ - return src.ToWString(); -} - -String FromSystemCharset(const WString& src) -{ - return src.ToString(); -} -#else - #ifdef PLATFORM_WIN32 String ToSystemCharset(const String& src, int cp) { - WString s = src.ToWString(); - int l = s.GetLength() * 5; + Vector s = ToUtf16(src); + int l = s.GetCount() * 8; StringBuffer b(l); - int q = WideCharToMultiByte(cp, 0, (const WCHAR *)~s, s.GetLength(), b, l, NULL, NULL); + int q = WideCharToMultiByte(cp, 0, s, s.GetCount(), b, l, NULL, NULL); if(q <= 0) return src; b.SetCount(q); @@ -609,12 +597,11 @@ String ToSystemCharset(const String& src) String FromWin32Charset(const String& src, int cp) { - WStringBuffer b(src.GetLength()); - int q = MultiByteToWideChar(cp, MB_PRECOMPOSED, ~src, src.GetLength(), (WCHAR*)~b, src.GetLength()); + Buffer b(src.GetLength()); + int q = MultiByteToWideChar(cp, MB_PRECOMPOSED, ~src, src.GetLength(), b, src.GetLength()); if(q <= 0) return src; - b.SetCount(q); - return WString(b).ToString(); + return ToUtf8(b, q); } String FromOEMCharset(const String& src) @@ -627,16 +614,6 @@ String FromSystemCharset(const String& src) return FromWin32Charset(src, CP_ACP); } -WString ToSystemCharsetW(const char *src) -{ - return String(src).ToWString(); -} - -String FromSystemCharsetW(const wchar *src) -{ - return WString(src).ToString(); -} - #else String ToSystemCharset(const String& src) { @@ -649,8 +626,39 @@ String FromSystemCharset(const String& src) return IsMainRunning() ? Filter(ToCharset(CHARSET_DEFAULT, src, GetLNGCharset(GetSystemLNG())), ChNoInvalid) : src; } #endif -#endif +Vector ToSystemCharsetW(const WString& src) +{ + Vector h = ToUtf16(src); + h.Add(0); + return h; +} + +Vector ToSystemCharsetW(const String& src) +{ + Vector h = ToUtf16(src); + h.Add(0); + return h; +} + +Vector ToSystemCharsetW(const wchar *src) +{ + Vector h = ToUtf16(src); + h.Add(0); + return h; +} + +Vector ToSystemCharsetW(const char *src) +{ + Vector h = ToUtf16(src); + h.Add(0); + return h; +} + +String FromSystemCharsetW(const char16 *src) +{ + return ToUtf8(src); +} static StaticMutex sGCfgLock; diff --git a/uppsrc/Core/Util.h b/uppsrc/Core/Util.h index 6884128a3..c2b8b71a2 100644 --- a/uppsrc/Core/Util.h +++ b/uppsrc/Core/Util.h @@ -158,17 +158,17 @@ String HexDecode(const char *s, const char *lim); inline String HexDecode(const char *s, int len) { return HexDecode(s, s + len); } inline String HexDecode(const String& s) { return HexDecode(~s, s.GetCount()); } -#ifdef PLATFORM_WINCE -WString ToSystemCharset(const String& src); -String FromSystemCharset(const WString& src); -#else String ToSystemCharset(const String& src, int cp); String ToSystemCharset(const String& src); String FromWin32Charset(const String& src, int cp); String FromSystemCharset(const String& src); -WString ToSystemCharsetW(const char *src); -String FromSystemCharsetW(const wchar *src); -#endif + +Vector ToSystemCharsetW(const WString& src); +Vector ToSystemCharsetW(const String& src); +Vector ToSystemCharsetW(const wchar *src); +Vector ToSystemCharsetW(const char *src); + +String FromSystemCharsetW(const char16 *src); #ifdef PLATFORM_WIN32 String FromOEMCharset(const String& src); diff --git a/uppsrc/Core/ValueUtil.cpp b/uppsrc/Core/ValueUtil.cpp index 5a3984aeb..8d2ef2285 100644 --- a/uppsrc/Core/ValueUtil.cpp +++ b/uppsrc/Core/ValueUtil.cpp @@ -289,21 +289,13 @@ bool ValueMap::Data::IsNull() const { } void ValueMap::Data::Serialize(Stream& s) { -#if !defined(_MSC_VER) || _MSC_VER > 1310 s % key % value; -#else - throw 0; -#endif } void ValueMap::Data::Xmlize(XmlIO& xio) { -#if !defined(_MSC_VER) || _MSC_VER > 1310 Upp::Xmlize(xio, key); Upp::Xmlize(xio, value); -#else - throw 0; -#endif } void ValueMap::Data::Jsonize(JsonIO& jio) diff --git a/uppsrc/Core/WString.cpp b/uppsrc/Core/WString.cpp index 71f539610..f9d6dade7 100644 --- a/uppsrc/Core/WString.cpp +++ b/uppsrc/Core/WString.cpp @@ -6,13 +6,13 @@ wchar *WString0::Alloc(int& count) { if(count <= SMALL) { count = SMALL; - wchar *p = (wchar *)MemoryAlloc48(); + wchar *p = (wchar *)MemoryAlloc((SMALL + 1) * sizeof(wchar)); return p; } size_t sz = sizeof(Atomic) + ((size_t)count + 1) * sizeof(wchar); Atomic *rc = (Atomic *)MemoryAllocSz(sz); if(count != INT_MAX) - count = int(((sz - sizeof(Atomic)) >> 1) - 1); + count = int(((sz - sizeof(Atomic)) / sizeof(wchar)) - 1); *rc = 1; return (wchar *)(rc + 1); } @@ -26,7 +26,7 @@ void WString0::Free() MemoryFree(&rc); } else - MemoryFree48(ptr); + MemoryFree(ptr); } } @@ -94,15 +94,8 @@ void WString0::Set0(const WString0& src) AtomicInc(Rc()); } else { - ptr = (wchar *)MemoryAlloc48(); - qword *t = (qword *)ptr; - qword *s = (qword *)src.ptr; - t[0] = s[0]; - t[1] = s[1]; - t[2] = s[2]; - t[3] = s[3]; - t[4] = s[4]; - t[5] = s[5]; + ptr = (wchar *)MemoryAlloc((SMALL + 1) * sizeof(wchar)); + memcpy(ptr, src.ptr, sizeof(wchar) * (SMALL + 1)); } Dsyn(); } @@ -224,6 +217,11 @@ WString::WString(const char *s) { *this = ToUnicode(s, s ? (int)strlen(s) : 0, CHARSET_DEFAULT); } +WString::WString(const char16 *s) { + Zero(); + *this = ToUtf32(s); +} + WString::WString(const char *s, int n) { Zero(); *this = ToUnicode(s, n, CHARSET_DEFAULT); @@ -249,30 +247,26 @@ WString WString::GetVoid() } #ifndef _HAVE_NO_STDWSTRING +static_assert(sizeof(wchar_t) == 4 || sizeof(wchar_t) == 2, "Invalid wchar_t size"); + WString::WString(const std::wstring& s) { - if(sizeof(std::wstring::value_type) == sizeof(wchar)) { - WString0::Set0((wchar *)s.c_str(), (int)s.length()); - } - else { - WString0::Zero(); - std::wstring::const_iterator i = s.begin(); - while(i < s.end()) - Cat(*i++); - } + WString0::Zero(); + if(sizeof(wchar_t) == 4) + *this = WString((const wchar *)s.c_str(), (int)s.size()); + if(sizeof(wchar_t) == 2) + *this = ToUtf32((char16 *)s.c_str(), (int)s.size()); } -WString::operator std::wstring() const +std::wstring WString::ToStd() const { - if(sizeof(std::wstring::value_type) == sizeof(wchar)) - return std::wstring((std::wstring::value_type *)Begin(), - (std::wstring::value_type *)End()); - else { - std::wstring r; - const wchar *s = Begin(); - while(s < End()) - r += *s++; - return r; + if(sizeof(wchar_t) == 4) { + const wchar *s = begin(); + return std::wstring((const wchar_t *)begin(), GetCount()); + } + if(sizeof(wchar_t) == 2) { + Vector h = ToUtf16(*this); + return std::wstring((const wchar_t *)h.begin(), h.GetCount()); } } #endif @@ -286,14 +280,14 @@ void WStringBuffer::Zero() wchar *WStringBuffer::Alloc(int count, int& alloc) { if(count <= 23) { - wchar *s = (wchar *)MemoryAlloc48(); + wchar *s = (wchar *)MemoryAlloc(24 * sizeof(wchar)); alloc = WString0::SMALL; return s; } else { size_t sz = sizeof(Atomic) + ((size_t)count + 1) * sizeof(wchar); Atomic *rc = (Atomic *)MemoryAlloc(sz); - alloc = (int)min((size_t)INT_MAX, ((sz - sizeof(Atomic)) >> 1) - 1); + alloc = (int)min((size_t)INT_MAX, ((sz - sizeof(Atomic)) / sizeof(wchar)) - 1); ASSERT(alloc >= 0); *rc = 1; return (wchar *)(rc + 1); @@ -304,7 +298,7 @@ void WStringBuffer::Free() { int all = (int)(limit - pbegin); if(all == WString0::SMALL) - MemoryFree48(pbegin); + MemoryFree(pbegin); if(all > WString0::SMALL) MemoryFree((Atomic *)pbegin - 1); } @@ -357,7 +351,7 @@ void WStringBuffer::Cat(int c, int l) { if(pend + l > limit) Expand(max(GetLength(), l) + GetLength(), NULL, l); - memset16(pend, c, l); + memset32(pend, c, l); pend += l; } @@ -408,9 +402,9 @@ int CompareNoCase(const WString& a, const WString& b) int CompareNoCase(const WString& a, const wchar *b) { #ifdef DEPRECATED - return IterCompare(a.Begin(), a.End(), b, b + wstrlen(b), WStringICompare__()); + return IterCompare(a.Begin(), a.End(), b, b + strlen__(b), WStringICompare__()); #else - return CompareRanges(a, SubRange(b, b + wstrlen(b)), WStringICompare__()); + return CompareRanges(a, SubRange(b, b + strlen__(b)), WStringICompare__()); #endif } diff --git a/uppsrc/Core/Win32Util.cpp b/uppsrc/Core/Win32Util.cpp index b2aeebc62..57fc986a5 100644 --- a/uppsrc/Core/Win32Util.cpp +++ b/uppsrc/Core/Win32Util.cpp @@ -158,14 +158,14 @@ void DeleteWinReg(const String& key, HKEY base, dword wow) { } String GetSystemDirectory() { - char temp[MAX_PATH]; + WCHAR temp[MAX_PATH]; *temp = 0; - ::GetSystemDirectory(temp, sizeof(temp)); - return FromSystemCharset(temp); + ::GetSystemDirectoryW(temp, sizeof(temp)); + return FromSystemCharsetW(temp); } String GetWindowsDirectory() { - wchar temp[MAX_PATH]; + WCHAR temp[MAX_PATH]; *temp = 0; GetWindowsDirectoryW(temp, sizeof(temp)); return FromSystemCharsetW(temp); @@ -179,7 +179,7 @@ void *GetDllFn(const char *dll, const char *fn) } String GetModuleFileName(HINSTANCE instance) { - wchar h[_MAX_PATH]; + WCHAR h[_MAX_PATH]; GetModuleFileNameW(instance, h, _MAX_PATH); return FromSystemCharsetW(h); } diff --git a/uppsrc/Core/Xmlize.cpp b/uppsrc/Core/Xmlize.cpp index 7d038a60c..d5e2c67fe 100644 --- a/uppsrc/Core/Xmlize.cpp +++ b/uppsrc/Core/Xmlize.cpp @@ -31,12 +31,12 @@ void Xmlize(XmlIO& xml, WString& var) h = ToUtf8(var); Xmlize(xml, h); if(xml.IsLoading()) - var = FromUtf8(h); + var = ToUtf32(h); } template<> void XmlAttrLoad(WString& var, const String& text) { - var = FromUtf8(text); + var = ToUtf32(text); } template<> String XmlAttrStore(const WString& var) diff --git a/uppsrc/Core/config.h b/uppsrc/Core/config.h index 2267fa730..3a4f44deb 100644 --- a/uppsrc/Core/config.h +++ b/uppsrc/Core/config.h @@ -185,4 +185,6 @@ #define CPP_11 #endif +#define WCHAR32 1 // this version of U++ has 32 bit wchar + #endif diff --git a/uppsrc/Core/heap.cpp b/uppsrc/Core/heap.cpp index b0bd6252a..24787e07d 100644 --- a/uppsrc/Core/heap.cpp +++ b/uppsrc/Core/heap.cpp @@ -125,11 +125,37 @@ void Heap::DblCheck(Page *p) while(p != l); } -int Heap::CheckFree(FreeLink *l, int k) +int Heap::CheckFree(FreeLink *l, int k, bool pg) { + char h[200]; int n = 0; + + Page *page = GetPage(l); + + if(l && page->klass != k) { + sprintf(h, "Invalid freelist block at 0x%p sz: %d (klass mismatch)", l, Ksz(k)); + Panic(h); + } + while(l) { + if(l->next) { + Page *lp = GetPage(l->next); + if(pg && lp != page) { + sprintf(h, "Invalid freelist block at 0x%p sz: %d (out of page) (-> 0x%p)", l, Ksz(k), l->next); + Panic(h); + } + if((4096 - ((uintptr_t)(l->next) & (uintptr_t)4095)) % Ksz(k) != 0) { + sprintf(h, "Invalid freelist block at 0x%p sz: %d (invalid address)", l, Ksz(k)); + Panic(h); + } + if(lp->klass != k) { + sprintf(h, "Invalid freelist block at 0x%p sz: %d (next klass mismatch)", l, Ksz(k)); + Panic(h); + } + } + DbgFreeCheckK(l, k); + l = l->next; n++; } @@ -167,7 +193,7 @@ void Heap::Check() { break; p = p->next; } - CheckFree(cache[i], i); + CheckFree(cache[i], i, false); } DLink *l = large->next; diff --git a/uppsrc/Core/heapdbg.cpp b/uppsrc/Core/heapdbg.cpp index a89be21b7..6b14d2073 100644 --- a/uppsrc/Core/heapdbg.cpp +++ b/uppsrc/Core/heapdbg.cpp @@ -174,8 +174,6 @@ size_t GetMemoryBlockSize(void *ptr) void *MemoryAlloc32() { return MemoryAlloc(32); } void MemoryFree32(void *ptr) { return MemoryFree(ptr); } -void *MemoryAlloc48() { return MemoryAlloc(48); } -void MemoryFree48(void *ptr) { return MemoryFree(ptr); } void MemoryCheckDebug() { diff --git a/uppsrc/Core/lheap.cpp b/uppsrc/Core/lheap.cpp index 8a5264533..8894ed008 100644 --- a/uppsrc/Core/lheap.cpp +++ b/uppsrc/Core/lheap.cpp @@ -203,7 +203,7 @@ bool Heap::TryRealloc(void *ptr, size_t& newsize) return true; } } - + Mutex::Lock __(mutex); if(h->heap == NULL) { // this is big block LTIMING("Big realloc"); @@ -211,7 +211,7 @@ bool Heap::TryRealloc(void *ptr, size_t& newsize) DLink *d = (DLink *)h - 1; size_t count = (newsize + sizeof(DLink) + sizeof(BlkPrefix) + 4095) >> 12; - + if(HugeTryRealloc(d, count)) { big_size -= d->size; d->size = newsize = (count << 12) - sizeof(DLink) - sizeof(BlkPrefix); @@ -220,21 +220,23 @@ bool Heap::TryRealloc(void *ptr, size_t& newsize) } } + // TODO: When small block fits, we could still return true + return false; } size_t Heap::LGetBlockSize(void *ptr) { - LBlkHeader *h = (LBlkHeader *)ptr - 1; + BlkPrefix *h = (BlkPrefix *)ptr - 1; if(h->heap == NULL) { // huge block Mutex::Lock __(mutex); - DLink *h = (DLink *)ptr - 1; - return h->size; + DLink *hh = (DLink *)h - 1; + return hh->size; } - - return h->GetSize(); + + return ((int)h->GetSize() * LUNIT) - sizeof(BlkPrefix); } #endif -} +} \ No newline at end of file diff --git a/uppsrc/Core/sheap.cpp b/uppsrc/Core/sheap.cpp index dd67b46e8..454da0f49 100644 --- a/uppsrc/Core/sheap.cpp +++ b/uppsrc/Core/sheap.cpp @@ -388,6 +388,8 @@ struct HeapMutexLock { ~HeapMutexLock() { LeaveHeapMutex(); } }; +void MemoryFreeThread(); + struct HeapExitThreadGuard { void Used() {} ~HeapExitThreadGuard() { MemoryFreeThread(); } @@ -608,31 +610,6 @@ void MemoryFree32_i(void *ptr) void MemoryFree32(void *ptr) { MemoryFree32_i(ptr); } -void *MemoryAlloc48() -{ - LTIMING("MemoryAlloc48"); - Heap *heap = heap_tls__; - if(heap) - return LogAlloc(heap->Alloc48(), 48); - else { - HeapMutexLock __; - return LogAlloc(MakeHeap()->Alloc48(), 48); - } -} - -void MemoryFree48(void *ptr) -{ - LTIMING("MemoryFree48"); - LogFree(ptr); - Heap *heap = heap_tls__; - if(heap) - heap->Free48(ptr); - else { - HeapMutexLock __; - MakeHeap()->Free48(ptr); - } -} - #endif void MemoryFreeThread() diff --git a/uppsrc/Core/src.tpp/Heap_en-us.tpp b/uppsrc/Core/src.tpp/Heap_en-us.tpp index 0cd439ae9..efb4c5ced 100644 --- a/uppsrc/Core/src.tpp/Heap_en-us.tpp +++ b/uppsrc/Core/src.tpp/Heap_en-us.tpp @@ -58,18 +58,6 @@ This has the same functionality as MemoryFree([%-*@3 ptr]), but is slightly faster.&] [s3;%% &] [s4; &] -[s5;:Upp`:`:MemoryAlloc48`(`): [@(0.0.255) void]_`*[* MemoryAlloc48]()&] -[s2;%% Allocates memory block of exactly 48 bytes. This has the same -functionality as MemoryAlloc(32), but is slightly faster.&] -[s3; &] -[s4; &] -[s5;:Upp`:`:MemoryFree48`(void`*`): [@(0.0.255) void]_[* MemoryFree48]([@(0.0.255) void]_`* -[*@3 ptr])&] -[s2;%% Frees a memory block previously allocated by MemoryAlloc48. -This has the same functionality as MemoryFree([%-*@3 ptr]), but -is slightly faster.&] -[s3;%% &] -[s4; &] [s5;:Upp`:`:MemoryTryRealloc`(void`*`,size`_t`&`): [@(0.0.255) bool]_[* MemoryTryRealloc]( [@(0.0.255) void]_`*[*@3 ptr], [_^size`_t^ size`_t][@(0.0.255) `&]_[*@3 newsize])&] [s2;%% Attempts to change the size of block at [%-*@3 ptr] to something diff --git a/uppsrc/Core/src.tpp/StreamFn_en-us.tpp b/uppsrc/Core/src.tpp/StreamFn_en-us.tpp index ffd56d5f4..97d2edce4 100644 --- a/uppsrc/Core/src.tpp/StreamFn_en-us.tpp +++ b/uppsrc/Core/src.tpp/StreamFn_en-us.tpp @@ -1,5 +1,4 @@ topic "Stream utilities"; -[2 $$0,0#00000000000000000000000000000000:Default] [i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class] [l288;2 $$2,0#27521748481378242620020725143825:desc] [0 $$3,0#96390100711032703541132217272105:end] @@ -9,6 +8,7 @@ topic "Stream utilities"; [l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param] [i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam] [b42;2 $$9,9#13035079074754324216151401829390:normal] +[2 $$0,0#00000000000000000000000000000000:Default] [{_} [ {{10000@(113.42.0) [s0;%% [*@2;4 Stream helpers]]}}&] [s0;%% &] @@ -40,16 +40,9 @@ stream. Returns the actual number of bytes copied. With default [%-*@3 count] value it copies all data from [%-*@3 src] until EOF.&] [s3; &] [s4; &] -[s5;:CoutUTF8`(`): [@(0.0.255) void]_[* CoutUTF8]()&] -[s2;%% In Win32, setups console output for UTF8. NOP in POSIX.&] -[s3; &] -[s4; &] [s5;:Cout`(`): [_^Stream^ Stream][@(0.0.255) `&]_[* Cout]()&] [s2;%% Returns special output stream representing console output. -Data written to this stream are displayed as characters in console. -In Win32, encoding is converted to default console encoding, -or is not convereted at all if CoutUTF8 was called.&] -[s7;%% [*/ Return value]-|Console stream.&] +Data written to this stream are displayed as characters in console.&] [s3; &] [s4; &] [s5;:Cerr`(`): [_^Stream^ Stream][@(0.0.255) `&]_[* Cerr]()&] diff --git a/uppsrc/Core/src.tpp/Stream_en-us.tpp b/uppsrc/Core/src.tpp/Stream_en-us.tpp index 0876db3ae..ea2a36be6 100644 --- a/uppsrc/Core/src.tpp/Stream_en-us.tpp +++ b/uppsrc/Core/src.tpp/Stream_en-us.tpp @@ -704,37 +704,6 @@ as 0 is considered as NULL pointer too...&] [s7; [%-*C@3 count]-|Repeat count.&] [s3; &] [s4;%- &] -[s5;:Stream`:`:PutW`(const wchar`*`,int`):%- [@(0.0.255) void]_[* PutW]([@(0.0.255) const]_ -[_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:wchar`:`:typedef^ wchar -]_`*[*@3 s], [@(0.0.255) int]_[*@3 count])&] -[s2; Writes a specified number of wchars (16`-bit character values) -to the stream in platform specific format (little`-endian or -big`-endian).&] -[s7; [%-*C@3 s]-|String to write.&] -[s7; [%-*C@3 count]-|Length of string.&] -[s3; &] -[s4;%- &] -[s5;:Stream`:`:GetW`(wchar`*`,int`):%- [_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:dword`:`:typedef^ d -word]_[* GetW]([_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:wchar`:`:typedef^ w -char]_`*[*@3 s], [@(0.0.255) int]_[*@3 count])&] -[s2; Reads a specified number of wchars (16`-bit character values) -from the stream in platform specific format.&] -[s7; [%-*C@3 s]-|Pointer to buffer to receive wchars.&] -[s7; [%-*C@3 count]-|Number of wchars.&] -[s7; [*/ Return value]-|Number of wchars actually read.&] -[s3; &] -[s4;%- &] -[s5;:Stream`:`:GetAllW`(wchar`*`,int`):%- [@(0.0.255) bool]_[* GetAllW]([_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:wchar`:`:typedef^ w -char]_`*[*@3 s], [@(0.0.255) int]_[*@3 count])&] -[s2; Reads a specified number of wchars (16`-bit character values) -from the stream in platform specific format. If there is not -enough data in the stream, LoadError is invoked (that in turn -might throw an exception).&] -[s7; [%-*C@3 s]-|&] -[s7; [%-*C@3 count]-|&] -[s7; [*/ Return value]-|&] -[s3; &] -[s4;%- &] [s5;:Stream`:`:PutCrLf`(`):%- [@(0.0.255) void]_[* PutCrLf]()&] [s2; Writes CR`-LF pair to the stream. &] [s3; &] diff --git a/uppsrc/Core/src.tpp/String_en-us.tpp b/uppsrc/Core/src.tpp/String_en-us.tpp index 27d18d1bf..f4a8bd64f 100644 --- a/uppsrc/Core/src.tpp/String_en-us.tpp +++ b/uppsrc/Core/src.tpp/String_en-us.tpp @@ -109,7 +109,8 @@ td`::string][@(0.0.255) `&]_[*@3 s])&] st]&] [s2; Returns a number of characters contained in String. This is equal GetCount() if default charset is not UTF`-8, but different -for UTF`-8. It is faster equivalent of ToWString().GetCount().&] +for UTF`-8 where it returns a number of unicode codepoints. It +is faster equivalent of ToWString().GetCount().&] [s3;%- &] [s4;%- &] [s5;:String`:`:ToWString`(`)const:%- [_^WString^ WString]_[* ToWString]()_[@(0.0.255) const diff --git a/uppsrc/CppBase/ppfile.cpp b/uppsrc/CppBase/ppfile.cpp index e2723bbb8..9f10b0f7b 100644 --- a/uppsrc/CppBase/ppfile.cpp +++ b/uppsrc/CppBase/ppfile.cpp @@ -411,12 +411,17 @@ void InvalidateFileTimeCache(const String& path) Time GetFileTimeCached(const String& p) { LTIMING("GetFileTimeCached"); - Mutex::Lock __(s_PathFileTimeMutex); - int q = s_PathFileTime.Find(p); - if(q >= 0) - return s_PathFileTime[q]; + { + Mutex::Lock __(s_PathFileTimeMutex); + int q = s_PathFileTime.Find(p); + if(q >= 0) + return s_PathFileTime[q]; + } Time m = FileGetTime(p); - s_PathFileTime.Put(p, m); + { + Mutex::Lock __(s_PathFileTimeMutex); + s_PathFileTime.Put(p, m); + } return m; } diff --git a/uppsrc/CtrlCore/CocoClip.mm b/uppsrc/CtrlCore/CocoClip.mm index b853ddec9..a51893d0e 100644 --- a/uppsrc/CtrlCore/CocoClip.mm +++ b/uppsrc/CtrlCore/CocoClip.mm @@ -479,12 +479,7 @@ Image MakeDragImage(const Image& arrow, Image sample); Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample) { -#ifdef PLATFORM_WIN32 - if(IsWin2K()) - return MakeDragImage(arrow, sample); - else -#endif - return arrow98; + return MakeDragImage(arrow, sample); } }; diff --git a/uppsrc/CtrlCore/CocoDnD.cpp b/uppsrc/CtrlCore/CocoDnD.cpp index 43ac54046..7f278e6e9 100644 --- a/uppsrc/CtrlCore/CocoDnD.cpp +++ b/uppsrc/CtrlCore/CocoDnD.cpp @@ -12,12 +12,7 @@ Image MakeDragImage(const Image& arrow, Image sample); Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample) { -#ifdef PLATFORM_WIN32 - if(IsWin2K()) - return MakeDragImage(arrow, sample); - else -#endif - return arrow98; + return MakeDragImage(arrow, sample); } END_UPP_NAMESPACE diff --git a/uppsrc/CtrlCore/CocoDrawText.mm b/uppsrc/CtrlCore/CocoDrawText.mm index 2150ed73a..37ff39479 100644 --- a/uppsrc/CtrlCore/CocoDrawText.mm +++ b/uppsrc/CtrlCore/CocoDrawText.mm @@ -1,5 +1,7 @@ #include "CocoMM.h" +#include + #ifdef GUI_COCOA #define LLOG(x) @@ -15,9 +17,13 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon Set(ink); bool synth; - CFRef cgFont = CTFontCopyGraphicsFont(CT_Font(font, synth), NULL); - CGContextSetFont(cgHandle, cgFont); + CTFontRef ct_font = CT_Font(font, synth); + + static void (*CTFontDrawGlyphs)(CTFontRef, const CGGlyph[], const CGPoint[], size_t, CGContextRef); + ONCELOCK { + *reinterpret_cast(&CTFontDrawGlyphs) = dlsym(RTLD_DEFAULT, "CTFontDrawGlyphs"); + } Point off = GetOffset(); CGAffineTransform tm = CGAffineTransformMakeTranslation(x + off.x, y + off.y); @@ -52,7 +58,16 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon } CGContextSetFontSize(cgHandle, font.GetHeight()); - CGContextShowGlyphsAtPositions(cgHandle, g, p, nn); } + + if(CTFontDrawGlyphs) + CTFontDrawGlyphs(ct_font, g, p, nn, cgHandle); + else { + CFRef cgFont = CTFontCopyGraphicsFont(ct_font, NULL); + CGContextSetFont(cgHandle, cgFont); + CGContextShowGlyphsAtPositions(cgHandle, g, p, nn); + } }; +} + #endif \ No newline at end of file diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 1574ea86c..194317ac5 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -83,30 +83,31 @@ void SetSurface(Draw& w, const Rect& dest, const RGBA *pixels, Size srcsz, Point void SetSurface(Draw& w, int x, int y, int cx, int cy, const RGBA *pixels); enum { - K_DELTA = 0x010000, + K_DELTA = 0x200000, + K_CHAR_LIM = 0x200000, // lower that this, key in Key is Unicode codepoint - K_ALT = 0x080000, - K_SHIFT = 0x040000, - K_CTRL = 0x020000, + K_ALT = 0x1000000, + K_SHIFT = 0x800000, + K_CTRL = 0x400000, +#ifdef PLATFORM_COCOA + K_OPTION = 0x2000000, +#endif - K_KEYUP = 0x100000, + K_KEYUP = 0x4000000, - K_MOUSEMIDDLE = 0x200000, - K_MOUSERIGHT = 0x400000, - K_MOUSELEFT = 0x800000, - K_MOUSEDOUBLE = 0x1000000, - K_MOUSETRIPLE = 0x2000000, + K_MOUSEMIDDLE = 0x2, + K_MOUSERIGHT = 0x4, + K_MOUSELEFT = 0x8, + K_MOUSEDOUBLE = 0x10, + K_MOUSETRIPLE = 0x20, K_SHIFT_CTRL = K_SHIFT|K_CTRL, -#ifdef PLATFORM_COCOA - K_OPTION = 0x4000000, -#endif - K_PEN = 0x8000000, + K_PEN = 0x80, IK_DBL_CLICK = 0x40000001, // this is just to get the info that the entry is equal to dbl-click to the menu - + K_MOUSE_FORWARD = 0x80000001, K_MOUSE_BACKWARD = 0x80000002, }; diff --git a/uppsrc/CtrlCore/CtrlKbd.cpp b/uppsrc/CtrlCore/CtrlKbd.cpp index c1bfa2076..2044c4721 100644 --- a/uppsrc/CtrlCore/CtrlKbd.cpp +++ b/uppsrc/CtrlCore/CtrlKbd.cpp @@ -68,7 +68,7 @@ bool Ctrl::DispatchKey(dword keycode, int count) String kl; dword k = keycode; const char *l = ""; - if(k < 65536) { + if(k < K_CHAR_LIM) { kl << "CHAR \'" << ToUtf8((wchar)keycode) << "\' (" << keycode << ')'; l = " "; } diff --git a/uppsrc/CtrlCore/CtrlMt.cpp b/uppsrc/CtrlCore/CtrlMt.cpp index 0b36432e9..3628b7e84 100644 --- a/uppsrc/CtrlCore/CtrlMt.cpp +++ b/uppsrc/CtrlCore/CtrlMt.cpp @@ -6,13 +6,24 @@ namespace Upp { static StaticMutex sGLock; +// #define DELAY_WATCH 1000 _DBG_ + static thread_local int sGLockLevel = 0; void EnterGuiMutex() { LLOG(">EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread()); - if(sGLockLevel++ == 0) + if(sGLockLevel++ == 0) { +#if DELAY_WATCH + for(int i = 0; i < DELAY_WATCH; i++) { + if(sGLock.TryEnter()) return; + Sleep(1); + } + Panic("Long timer procedure detected!"); +#else sGLock.Enter(); +#endif + } LLOG("EnterGuiMutex " << sGLockLevel << ' ' << IsMainThread()); } diff --git a/uppsrc/CtrlCore/CtrlTimer.cpp b/uppsrc/CtrlCore/CtrlTimer.cpp index d97361647..32bd2e06b 100644 --- a/uppsrc/CtrlCore/CtrlTimer.cpp +++ b/uppsrc/CtrlCore/CtrlTimer.cpp @@ -4,6 +4,7 @@ namespace Upp { // #define LOG_QUEUE #define LLOG(x) // LOG(x) +// #define DELAY_WATCH 1000 _DBG_ int MemoryProbeInt; @@ -120,7 +121,14 @@ void Ctrl::TimerProc(dword time) else delete todo; sTimerLock.Leave(); + #if DELAY_WATCH + int tm = msecs(); + #endif cb(); + #if DELAY_WATCH + if(msecs() - tm > DELAY_WATCH) + Panic("Long timer procedure detected!"); + #endif sTimerLock.Enter(); } time = msecs(); diff --git a/uppsrc/CtrlCore/DrawTextWin32.cpp b/uppsrc/CtrlCore/DrawTextWin32.cpp index 85ffae095..8b2e902e6 100644 --- a/uppsrc/CtrlCore/DrawTextWin32.cpp +++ b/uppsrc/CtrlCore/DrawTextWin32.cpp @@ -21,14 +21,15 @@ void SystemDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font fon Mutex::Lock ___(sFontLock); // need this because of GetWin32Font HGDIOBJ orgfont = ::SelectObject(handle, GetWin32Font(font, angle)); int ascent = font.Info().GetAscent(); + Vector text16 = ToUtf16(text, n); if(angle) { double sina, cosa; Draw::SinCos(angle, sina, cosa); Size offset; - ::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, (const WCHAR *)text, n, dx); + ::ExtTextOutW(handle, x + fround(ascent * sina), y + fround(ascent * cosa), 0, NULL, text16.begin(), text16.GetCount(), dx); } else - ::ExtTextOutW(handle, x, y + ascent, 0, NULL, (const WCHAR *)text, n, dx); + ::ExtTextOutW(handle, x, y + ascent, 0, NULL, text16.begin(), text16.GetCount(), dx); ::SelectObject(handle, orgfont); } diff --git a/uppsrc/CtrlCore/DrawTextX11.cpp b/uppsrc/CtrlCore/DrawTextX11.cpp index cfba78501..951b4478b 100644 --- a/uppsrc/CtrlCore/DrawTextX11.cpp +++ b/uppsrc/CtrlCore/DrawTextX11.cpp @@ -135,7 +135,7 @@ GlyphInfo XftGetGlyphInfoSys(Font font, int chr) { wchar h = chr; XGlyphInfo info; - XftTextExtents16(Xdisplay, GetXftMetricFont(font, 0), &h, 1, &info); + XftTextExtents32(Xdisplay, GetXftMetricFont(font, 0), &h, 1, &info); GlyphInfo gi; gi.width = info.xOff; gi.lspc = -info.x; diff --git a/uppsrc/CtrlCore/DrawWin32.cpp b/uppsrc/CtrlCore/DrawWin32.cpp index 699c0e8ff..4ff32563e 100644 --- a/uppsrc/CtrlCore/DrawWin32.cpp +++ b/uppsrc/CtrlCore/DrawWin32.cpp @@ -464,12 +464,12 @@ PrintDraw::PrintDraw(HDC hdc, const char *docname) : SystemDraw(hdc) { GuiLock __; - DOCINFO di; + DOCINFOW di; memset(&di, 0, sizeof(di)); di.cbSize = sizeof(di); - String sys_docname = ToSystemCharset(docname); - di.lpszDocName = ~sys_docname; - if(::StartDoc(hdc, &di) <= 0) + Vector sys_docname = ToSystemCharsetW(docname); + di.lpszDocName = sys_docname; + if(::StartDocW(hdc, &di) <= 0) aborted = true; else InitPrinter(); diff --git a/uppsrc/CtrlCore/EncodeRTF.cpp b/uppsrc/CtrlCore/EncodeRTF.cpp index cf48424e5..3d036f7eb 100644 --- a/uppsrc/CtrlCore/EncodeRTF.cpp +++ b/uppsrc/CtrlCore/EncodeRTF.cpp @@ -223,8 +223,14 @@ void RTFEncoder::Command(const char *cmd, int param) void RTFEncoder::PutText(const wchar *text) { for(; *text; text++) - if((uint16)*text >= 128) - stream.Put(Format("\\u%d?", (int16)*text)); + if(*text >= 128) { + if(*text >= 65536) { + Vector h = ToUtf16(*text); + stream << "\\uc0 \\u" << (unsigned)h[0] << "\\uc1 \\u" << (unsigned)h[1]; + } + else + stream.Put(Format("\\u%d?", (int16)*text)); + } else { if(*text == '{' || *text == '}' || *text == '\\') stream.Put('\\'); diff --git a/uppsrc/CtrlCore/GtkClip.cpp b/uppsrc/CtrlCore/GtkClip.cpp index bce4744b4..4456d03d8 100644 --- a/uppsrc/CtrlCore/GtkClip.cpp +++ b/uppsrc/CtrlCore/GtkClip.cpp @@ -240,7 +240,7 @@ WString GetWString(PasteClip& clip) { GuiLock __; if(clip.IsAvailable("text")) - return FromUtf8(clip.Get("text")); + return ToUtf32(clip.Get("text")); return Null; } @@ -286,7 +286,7 @@ String ReadClipboardText() WString ReadClipboardUnicodeText() { - return FromUtf8(Ctrl::gclipboard().Get("text")); + return ToUtf32(Ctrl::gclipboard().Get("text")); } bool IsClipboardAvailable(const char *id) diff --git a/uppsrc/CtrlCore/GtkEvent.cpp b/uppsrc/CtrlCore/GtkEvent.cpp index acb9e1f84..55b56d254 100644 --- a/uppsrc/CtrlCore/GtkEvent.cpp +++ b/uppsrc/CtrlCore/GtkEvent.cpp @@ -325,7 +325,7 @@ void Ctrl::AddEvent(gpointer user_data, int type, const Value& value, GdkEvent * void Ctrl::IMCommit(GtkIMContext *context, gchar *str, gpointer user_data) { GuiLock __; - AddEvent(user_data, EVENT_TEXT, FromUtf8(str), NULL); + AddEvent(user_data, EVENT_TEXT, ToUtf32(str), NULL); } bool Ctrl::ProcessInvalids() @@ -525,7 +525,7 @@ void Ctrl::Proc() case GDK_KEY_RELEASE: kv = CurrentEvent.value[0]; hw = CurrentEvent.value[1]; - if(kv >= 0 && kv < 65536) { + if(kv >= 0 && kv < K_CHAR_LIM) { LLOG("keyval " << FormatIntHex(kv) << ' ' << (char)kv); if(kv >= 'a' && kv <= 'z') kv = kv - 'a' + 'A'; diff --git a/uppsrc/CtrlCore/ImageWin32.cpp b/uppsrc/CtrlCore/ImageWin32.cpp index c05e49051..36b1100e7 100644 --- a/uppsrc/CtrlCore/ImageWin32.cpp +++ b/uppsrc/CtrlCore/ImageWin32.cpp @@ -329,7 +329,7 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, const Rect& src, sz = Ctrl::GetVirtualScreenArea().GetSize(); m.img = IsPrinter() && GetDeviceCaps(GetHandle(), NUMCOLORS) == 2 ? Dither(img, 360) : img; // If printer does not support color, dither cache.Get(m).Paint(*this, x, y, src, color); - cache.Shrink(4 * sz.cx * sz.cy, IsWinNT() ? 1000 : 100); + cache.Shrink(4 * sz.cx * sz.cy, 1000); } void ImageDraw::Section::Init(int cx, int cy) @@ -567,12 +567,9 @@ HICON SystemDraw::IconWin32(const Image& img, bool cursor) Point p = img.GetHotSpot(); iconinfo.xHotspot = p.x; iconinfo.yHotspot = p.y; - static Size cursor_size(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); Size tsz = sz; - if(!IsWin2K() && cursor) - tsz = cursor_size; Size csz = Size(min(tsz.cx, sz.cx), min(tsz.cy, sz.cy)); - if(IsWinXP() && !ImageFallBack) { + if(!ImageFallBack) { RGBA *pixels; BitmapInfo32__ bi(tsz.cx, tsz.cy); HDC dcMem = ::CreateCompatibleDC(NULL); diff --git a/uppsrc/CtrlCore/ParseRTF.cpp b/uppsrc/CtrlCore/ParseRTF.cpp index c4208bcd6..dc3ddf85c 100644 --- a/uppsrc/CtrlCore/ParseRTF.cpp +++ b/uppsrc/CtrlCore/ParseRTF.cpp @@ -500,8 +500,19 @@ RTFParser::TOKEN RTFParser::Fetch() break; } } - if(c && !skip) + if(c && !skip) { text.Cat(c); + if(text.GetCount() >= 2) { + char16 h[2]; + h[0] = text[text.GetCount() - 2]; + h[1] = text[text.GetCount() - 1]; + wchar c = ReadSurrogatePair(h, h + 2); + if(c) { + text.TrimLast(2); + text.Cat(c); + } + } + } skip = nskip; } @@ -1080,7 +1091,7 @@ String RTFParser::ReadBinHex(char& odd) const byte v = ctoi(odd); String out; for(const wchar *s = text.Begin(); *s; s++) { - byte w = (*s >= '0' && *s <= '9' ? *s - '0' + byte w = (byte)(*s >= '0' && *s <= '9' ? *s - '0' : *s >= 'A' && *s <= 'F' ? *s - 'A' + 10 : *s >= 'a' && *s <= 'f' ? *s - 'a' + 10 : 255); diff --git a/uppsrc/CtrlCore/TopWin32.cpp b/uppsrc/CtrlCore/TopWin32.cpp index ac924b9b7..f69a24c79 100644 --- a/uppsrc/CtrlCore/TopWin32.cpp +++ b/uppsrc/CtrlCore/TopWin32.cpp @@ -75,12 +75,8 @@ void TopWindow::SyncTitle() GuiLock __; LLOG("TopWindow::SyncTitle0 " << UPP::Name(this)); HWND hwnd = GetHWND(); - if(hwnd) { - if(IsWindowUnicode(hwnd)) - ::SetWindowTextW(hwnd, (const WCHAR*)~title); - else - ::SetWindowText(hwnd, ToSystemCharset(title.ToString())); - } + if(hwnd) + ::SetWindowTextW(hwnd, ToSystemCharsetW(title)); } void TopWindow::DeleteIco() @@ -250,7 +246,7 @@ void TopWindow::Open(HWND hwnd) if(dokeys && (!GUI_AKD_Conservative() || GetAccessKeysDeep() <= 1)) DistributeAccessKeys(); USRLOG(" OPEN " << Desc(this)); - LLOG("TopWindow::Open, owner HWND = " << FormatIntHex((int)hwnd, 8) << ", Active = " << FormatIntHex((int)::GetActiveWindow(), 8)); + LLOG("TopWindow::Open, owner HWND = " << hwnd << ", Active = " << hwnd); IgnoreMouseUp(); SyncCaption(); LLOG("WindowStyles: " << WindowStyleAsString(style, exstyle)); diff --git a/uppsrc/CtrlCore/Win32Clip.cpp b/uppsrc/CtrlCore/Win32Clip.cpp index de303db5a..0189ded6e 100644 --- a/uppsrc/CtrlCore/Win32Clip.cpp +++ b/uppsrc/CtrlCore/Win32Clip.cpp @@ -55,7 +55,7 @@ bool DebugClipboard() void ClipboardLog(const char *txt) { - if(!DebugClipboard()) + if(!DebugClipboard()) return; FileAppend f(GetExeDirFile("clip.log")); f << GetSysTime() << ": " << txt << "\n"; @@ -232,7 +232,8 @@ void AppendClipboardText(const String& s) void AppendClipboardUnicodeText(const WString& s) { - AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength()); + Vector ws = ToUtf16(s); + AppendClipboard("wtext", (const byte *)ws.begin(), 2 * ws.GetCount()); } const char *ClipFmtsText() @@ -245,7 +246,7 @@ String GetString(PasteClip& clip) GuiLock __; if(clip.Accept("wtext")) { String s = ~clip; - return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString(); + return ToUtf8((const char16 *)~s, strlen16((const char16 *)~s)); } if(clip.Accept("text")) return ~clip; @@ -257,7 +258,7 @@ WString GetWString(PasteClip& clip) GuiLock __; if(clip.Accept("wtext")) { String s = ~clip; - return WString((const wchar *)~s, wstrlen((const wchar *)~s)); + return ToUtf32((const char16 *)~s, strlen16((const char16 *)~s)); } if(clip.Accept("text")) return (~clip).ToWString(); @@ -326,7 +327,7 @@ String ReadClipboardText() WString ReadClipboardUnicodeText() { String s = ReadClipboard((const char *)CF_UNICODETEXT); - return WString((const wchar *)~s, wstrlen((const wchar *)~s)); + return ToUtf32((const char16 *)~s, strlen16((const char16 *)~s)); } bool IsClipboardAvailable(const char *id) @@ -475,7 +476,7 @@ Vector GetClipFiles(const String& data) const sDROPFILES *df = (const sDROPFILES *)~data; const char *s = ((const char *)df + df->offset); if(df->unicode) { - const wchar *ws = (wchar *)s; + const char16 *ws = (char16 *)s; while(*ws) { WString fn; while(*ws) diff --git a/uppsrc/CtrlCore/Win32DnD.cpp b/uppsrc/CtrlCore/Win32DnD.cpp index 66336477e..37a5749f5 100644 --- a/uppsrc/CtrlCore/Win32DnD.cpp +++ b/uppsrc/CtrlCore/Win32DnD.cpp @@ -484,10 +484,7 @@ Image MakeDragImage(const Image& arrow, Image sample); Image MakeDragImage(const Image& arrow, const Image& arrow98, Image sample) { - if(IsWin2K()) - return MakeDragImage(arrow, sample); - else - return arrow98; + return MakeDragImage(arrow, sample); } int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, diff --git a/uppsrc/CtrlCore/Win32Gui.h b/uppsrc/CtrlCore/Win32Gui.h index 6cf156c70..21e57eb9a 100644 --- a/uppsrc/CtrlCore/Win32Gui.h +++ b/uppsrc/CtrlCore/Win32Gui.h @@ -142,7 +142,7 @@ public: SystemDraw(HDC hdc); virtual ~SystemDraw(); - bool CanSetSurface() { return Pixels() && IsWinNT(); } + bool CanSetSurface() { return Pixels(); } }; #ifndef PLATFORM_WINCE diff --git a/uppsrc/CtrlCore/Win32Proc.cpp b/uppsrc/CtrlCore/Win32Proc.cpp index a7e946213..a18a72d83 100644 --- a/uppsrc/CtrlCore/Win32Proc.cpp +++ b/uppsrc/CtrlCore/Win32Proc.cpp @@ -366,8 +366,23 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { keycode = KEYtoK((dword)wParam) | K_KEYUP; else if(message == WM_CHAR && wParam != 127 && wParam > 32 || wParam == 32 && KEYtoK(VK_SPACE) == K_SPACE) { - if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX Unicode patch + if(IsWindowUnicode(hwnd)) { // TRC 04/10/17: ActiveX Unicode patch + static WCHAR surr[2]; keycode = (dword)wParam; + if((keycode & 0XFC00) == 0xD800) { // covert UTF16 surrogate pair to UTF32 codepoint + surr[0] = (WCHAR)keycode; + return 0L; + } + if((keycode & 0xFC00) == 0xDC00) { + surr[1] = (WCHAR)keycode; + keycode = ReadSurrogatePair(surr, surr + 2); + surr[0] = 0; + if(!keycode) + return 0L; + } + else + surr[0] = 0; + } else { char b[20]; ::GetLocaleInfo(MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT), diff --git a/uppsrc/CtrlCore/Win32Wnd.cpp b/uppsrc/CtrlCore/Win32Wnd.cpp index 46b4fa1b1..894e4fd6c 100644 --- a/uppsrc/CtrlCore/Win32Wnd.cpp +++ b/uppsrc/CtrlCore/Win32Wnd.cpp @@ -5,7 +5,7 @@ namespace Upp { #define LLOG(x) // DLOG(x) -#define LOGTIMING 0 +// #define LOGTIMING 1 _DBG_ #ifdef _DEBUG #define LOGMESSAGES 0 @@ -23,8 +23,7 @@ hash_t GetHashValue(const HWND& h) bool Ctrl::GetMsg(MSG& msg) { if(!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) return false; - return IsWindowUnicode(msg.hwnd) ? PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE) - : PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + return PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE); } static bool sFinished; @@ -114,7 +113,7 @@ LRESULT CALLBACK Ctrl::OverwatchWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR } } if(ShutdownBlockReasonCreate) - ShutdownBlockReasonCreate(hwnd, ~WString(t_("waiting for user response"))); + ShutdownBlockReasonCreate(hwnd, ToSystemCharsetW(t_("waiting for user response"))); EndSession(); ELOGW("WM_QUERYENDSESSION 1"); OverwatchEndSession.Wait(); @@ -153,10 +152,7 @@ DWORD WINAPI Ctrl::Win32OverwatchThread(LPVOID) MSG Msg; while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); - if(IsWindowUnicode(Msg.hwnd)) - DispatchMessageW(&Msg); - else - DispatchMessage(&Msg); + DispatchMessageW(&Msg); } ELOGW("OverWatch 3"); return 0; @@ -239,18 +235,15 @@ void Ctrl::InitWin32(HINSTANCE hInstance) sMainThreadId = GetCurrentThreadId(); #define ILOG(x) // RLOG(x) Ctrl::hInstance = hInstance; - ILOG("RegisterClassW"); -#ifndef PLATFORM_WINCE - if(IsWinNT()) -#endif { + ILOG("RegisterClassW"); WNDCLASSW wc; Zero(wc); wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)Ctrl::WndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = IsWinVista() ? (HBRUSH)(COLOR_WINDOW+1) : (HBRUSH)NULL; + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszClassName = L"UPP-CLASS-W"; RegisterClassW(&wc); wc.style = 0x20000|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; @@ -263,35 +256,37 @@ void Ctrl::InitWin32(HINSTANCE hInstance) wc.lpszClassName = L"UPP-CLASS-SB-DS-W"; RegisterClassW(&wc); } - - ILOG("RegisterClassA"); - WNDCLASS wc; - Zero(wc); - wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; - wc.lpfnWndProc = (WNDPROC)Ctrl::WndProc; - wc.hInstance = hInstance; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = IsWinVista() ? (HBRUSH)(COLOR_WINDOW+1) : (HBRUSH)NULL; - wc.lpszClassName = L_("UPP-CLASS-A"); - RegisterClass(&wc); - if(IsWinXP()) { + { + ILOG("RegisterClassA"); + WNDCLASS wc; + Zero(wc); + wc.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC)Ctrl::WndProc; + wc.hInstance = hInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = IsWinVista() ? (HBRUSH)(COLOR_WINDOW+1) : (HBRUSH)NULL; + wc.lpszClassName = L_("UPP-CLASS-A"); + RegisterClass(&wc); wc.style = 0x20000|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; wc.lpszClassName = L_("UPP-CLASS-DS-A"); RegisterClass(&wc); - } - wc.style = CS_SAVEBITS|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; - wc.lpszClassName = L_("UPP-CLASS-SB-A"); - RegisterClass(&wc); - if(IsWinXP()) { + wc.style = CS_SAVEBITS|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW; + wc.lpszClassName = L_("UPP-CLASS-SB-A"); + RegisterClass(&wc); wc.style = 0x20000|CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS; wc.lpszClassName = L_("UPP-CLASS-SB-DS-A"); RegisterClass(&wc); } - wc.style = 0; - wc.lpszClassName = L_("UPP-TIMER"); - wc.hCursor = NULL; - wc.lpfnWndProc = &Ctrl::UtilityProc; - RegisterClass(&wc); + + WNDCLASS wca; + Zero(wca); + wca.hInstance = hInstance; + wca.hbrBackground = (HBRUSH)NULL; + wca.style = 0; + wca.lpszClassName = L_("UPP-TIMER"); + wca.hCursor = NULL; + wca.lpfnWndProc = &Ctrl::UtilityProc; + RegisterClass(&wca); ILOG("InitTimer"); InitTimer(); @@ -307,19 +302,10 @@ void Ctrl::InitWin32(HINSTANCE hInstance) OleInitialize(NULL); -/* TRC 05/11/14: moved to GuiSleep to avoid thread creation in OCX DllMain - DWORD dummy; - OverwatchThread = CreateThread(NULL, 0x100000, Win32OverwatchThread, NULL, 0, &dummy); - ExitLoopEvent().Wait(); -*/ - -// TRC 05/11/18: pSetLayeredWindowAttributes moved to GLOBAL_VAR (see below) to make OCX initialization simpler - Csizeinit(); #undef ILOG - if(IsWin7()) - GlobalBackPaint(); + GlobalBackPaint(); EnterGuiMutex(); } @@ -487,20 +473,12 @@ void Ctrl::Create(HWND parent, DWORD style, DWORD exstyle, bool savebits, int sh top = new Top; ASSERT(!parent || IsWindow(parent)); style &= ~WS_VISIBLE; - if(!IsWinXP()) - dropshadow = false; - if(IsWinNT() && (!parent || IsWindowUnicode(parent))) - top->hwnd = CreateWindowExW(exstyle, - savebits ? dropshadow ? L"UPP-CLASS-SB-DS-W" : L"UPP-CLASS-SB-W" - : dropshadow ? L"UPP-CLASS-DS-W" : L"UPP-CLASS-W", - L"", style, 0, 0, 0, 0, - parent, NULL, hInstance, this); - else - top->hwnd = CreateWindowEx(exstyle, - savebits ? dropshadow ? "UPP-CLASS-SB-DS-A" : "UPP-CLASS-SB-A" - : dropshadow ? "UPP-CLASS-DS-A" : "UPP-CLASS-A", - "", style, 0, 0, 0, 0, - parent, NULL, hInstance, this); + dropshadow = false; + top->hwnd = CreateWindowEx(exstyle, + savebits ? dropshadow ? "UPP-CLASS-SB-DS-W" : "UPP-CLASS-SB-W" + : dropshadow ? "UPP-CLASS-DS-W" : "UPP-CLASS-W", + "", style, 0, 0, 0, 0, + parent, NULL, hInstance, this); inloop = false; @@ -636,9 +614,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #if LOGMESSAGES bool logblk = false; if(message != WM_SETCURSOR && message != WM_CTLCOLORBTN && message != WM_TIMER && -#ifndef PLATFORM_WINCE message != WM_NCHITTEST && message != WM_ENTERIDLE && -#endif message != WM_CTLCOLORDLG && message != WM_CTLCOLOREDIT && message != WM_CTLCOLORLISTBOX && message != WM_CTLCOLORMSGBOX && message != WM_CTLCOLORSCROLLBAR && message != WM_CTLCOLORSTATIC && message != WM_CANCELMODE && @@ -655,7 +631,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP #endif LRESULT l = 0; if(w && (w->GetHWND() || w->isdhctrl)) { -#if defined(_DEBUG) && LOGTIMING +#if LOGTIMING int ticks = msecs(); String wname = w->Name(); #endif @@ -663,7 +639,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP l = w->WindowProc(message, wParam, lParam); if(pw) pw->SyncMoves(); -#if defined(_DEBUG) && LOGTIMING +#if LOGTIMING String msgname; for(WinMsg *m = sWinMsg; m->ID; m++) if(m->ID == message) { @@ -672,7 +648,7 @@ LRESULT CALLBACK Ctrl::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lP } if(IsNull(msgname)) msgname = NFormat("0x%04x", (int)message); - LLOG(NFormat("T+%d %s 0x%08x 0x%08x -> %s", msecs(ticks), msgname, (int)wParam, (int)lParam, wname)); + RLOG(NFormat("T+%d %s 0x%08x 0x%08x -> %s", msecs(ticks), msgname, (int)wParam, (int)lParam, wname)); #endif } else @@ -755,10 +731,7 @@ void Ctrl::sProcessMSG(MSG& msg) DDUMP(cls); #endif - if(IsWindowUnicode(msg.hwnd)) - DispatchMessageW(&msg); - else - DispatchMessage(&msg); + DispatchMessageW(&msg); } bool Ctrl::IsWaitingEvent() @@ -1271,7 +1244,7 @@ Rect Ctrl::GetScreenClient(HWND hwnd) } Rect Ctrl::GetDefaultWindowRect() { - HWND hwnd = ::CreateWindow("UPP-CLASS-A", "", WS_OVERLAPPED, + HWND hwnd = ::CreateWindow("UPP-CLASS-W", "", WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); Rect sr; diff --git a/uppsrc/CtrlLib/AKeys.cpp b/uppsrc/CtrlLib/AKeys.cpp index c141b86d1..6ca52830e 100644 --- a/uppsrc/CtrlLib/AKeys.cpp +++ b/uppsrc/CtrlLib/AKeys.cpp @@ -71,7 +71,7 @@ struct KeyCtrl : Ctrl { virtual bool Key(dword _key, int) { if(_key == K_ENTER || _key == K_ESCAPE) return false; - if((_key & K_KEYUP) || _key < 65536 || _key == K_SHIFT_KEY || _key == K_ALT_KEY || _key == K_CTRL_KEY) + if((_key & K_KEYUP) || _key < K_CHAR_LIM || _key == K_SHIFT_KEY || _key == K_ALT_KEY || _key == K_CTRL_KEY) return true; if(_key == K_SPACE || _key == K_DELETE || _key == K_BACKSPACE) key = 0; diff --git a/uppsrc/CtrlLib/ChWin32.cpp b/uppsrc/CtrlLib/ChWin32.cpp index 55e515ef1..9ec57cf96 100644 --- a/uppsrc/CtrlLib/ChWin32.cpp +++ b/uppsrc/CtrlLib/ChWin32.cpp @@ -72,7 +72,7 @@ HANDLE XpWidget(int widget) { if(xp_widget_handle[widget] == NULL && XpTheme()) xp_widget_handle[widget] = XpTheme().OpenThemeData(NULL, - (WCHAR *)(const wchar *)WString(xp_widget_name[widget])); + ToSystemCharsetW(xp_widget_name[widget])); return xp_widget_handle[widget]; } @@ -308,11 +308,11 @@ void Win32Look(Value& ch, int widget, int part, int state = 1, bool contentm = f String XpThemeInfo(LPCWSTR pszPropertyName) { - wchar theme[512], colors[512], size[512]; + WCHAR theme[512], colors[512], size[512]; XpTheme().GetCurrentThemeName(theme, 512, colors, 512, size, 512); - wchar h[1024]; + WCHAR h[1024]; XpTheme().GetThemeDocumentationProperty(theme, pszPropertyName, h, 1000); - return FromUnicode(h); + return ToUtf8(h); } struct sysColor { @@ -394,8 +394,7 @@ void ChHostSkin() ChBaseSkin(); - GUI_GlobalStyle_Write(IsWinXP() && !ScreenInPaletteMode() && IsSysFlag(0x1022 /*SPI_GETFLATMENU*/) - ? GUISTYLE_XP : GUISTYLE_CLASSIC); + GUI_GlobalStyle_Write(GUISTYLE_XP); #ifndef PLATFORM_WINCE GUI_DragFullWindow_Write(IsSysFlag(SPI_GETDRAGFULLWINDOWS)); #endif diff --git a/uppsrc/CtrlLib/CtrlUtil.h b/uppsrc/CtrlLib/CtrlUtil.h index 4a663c1c1..9f1e005f1 100644 --- a/uppsrc/CtrlLib/CtrlUtil.h +++ b/uppsrc/CtrlLib/CtrlUtil.h @@ -210,40 +210,13 @@ public: #endif #ifdef GUI_WIN -#ifndef PLATFORM_WINCE class TrayIcon : private Ctrl { - struct NotifyIconOld { - dword sz; - HWND hwnd; - dword id; - dword flags; - dword message; - HICON icon; - char tip[64]; - }; - struct NotifyIconNew { - dword sz; - HWND hwnd; - dword id; - dword flags; - dword message; - HICON icon; - char tip[128]; - - dword state; - dword statemask; - char info[256]; - dword timeout; - char title[64]; - dword infoflags; - }; - - Image icon; - bool visible; - String tip; - NotifyIconNew nid; - HWND hwnd; + Image icon; + bool visible; + String tip; + NOTIFYICONDATAW nid; + HWND hwnd; void Notify(dword msg); void DoMenu(Bar& bar); @@ -348,7 +321,6 @@ public: typedef FileSelNative FileSelector; -#endif #endif #ifdef GUI_X11 diff --git a/uppsrc/CtrlLib/DocEdit.cpp b/uppsrc/CtrlLib/DocEdit.cpp index 2d595f9b2..fa371230a 100644 --- a/uppsrc/CtrlLib/DocEdit.cpp +++ b/uppsrc/CtrlLib/DocEdit.cpp @@ -438,10 +438,10 @@ bool DocEdit::Key(dword key, int cnt) default: if(filter && key >= 32 && key < 65535) key = (*filter)(key); - if(key >= ' ' && key < 65536 || key == '\n' || key == '\t' || key == K_SHIFT_SPACE) { + if(key >= ' ' && key < K_CHAR_LIM || key == '\n' || key == '\t' || key == K_SHIFT_SPACE) { if(key == K_TAB && !processtab) return false; - if(key >= 128 && key < 65536 && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM) + if(key >= 128 && key < K_CHAR_LIM && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM) && FromUnicode((wchar)key, charset) == DEFAULTCHAR) return true; RemoveSelection(); diff --git a/uppsrc/CtrlLib/DropList.cpp b/uppsrc/CtrlLib/DropList.cpp index b9e058d76..06943ad2c 100644 --- a/uppsrc/CtrlLib/DropList.cpp +++ b/uppsrc/CtrlLib/DropList.cpp @@ -54,7 +54,7 @@ bool DropList::Key(dword k, int) { Change(-1); break; default: - if(k >= 32 && k < 65536) { + if(k >= 32 && k < K_CHAR_LIM) { bool b = list.Key(k, 1); if(list.GetCursor() >= 0 && list.GetCursor() < key.GetCount() && key[list.GetCursor()] != value) Select(); diff --git a/uppsrc/CtrlLib/EditField.cpp b/uppsrc/CtrlLib/EditField.cpp index a9f1e5392..adb9ba553 100644 --- a/uppsrc/CtrlLib/EditField.cpp +++ b/uppsrc/CtrlLib/EditField.cpp @@ -944,7 +944,7 @@ bool EditField::Key(dword key, int rep) } return false; default: - if(key >= ' ' && key < 65536 || key == K_SHIFT_SPACE) { + if(key >= ' ' && key < K_CHAR_LIM || key == K_SHIFT_SPACE) { if(!RemoveSelection()) SaveUndo(); while(rep--) Insert(key == K_SHIFT_SPACE ? ' ' : key); diff --git a/uppsrc/CtrlLib/FileList.cpp b/uppsrc/CtrlLib/FileList.cpp index 87ca05947..d96739e3b 100644 --- a/uppsrc/CtrlLib/FileList.cpp +++ b/uppsrc/CtrlLib/FileList.cpp @@ -345,7 +345,7 @@ String FileList::GetCurrentName() const int FileList::Find(const char *s) { for(int i = 0; i < GetCount(); i++) - if(strcmp(Get(i).name, s) == 0) return i; + if(Get(i).name == s) return i; return -1; } diff --git a/uppsrc/CtrlLib/FileSel.cpp b/uppsrc/CtrlLib/FileSel.cpp index 485c14918..545e87cec 100644 --- a/uppsrc/CtrlLib/FileSel.cpp +++ b/uppsrc/CtrlLib/FileSel.cpp @@ -44,11 +44,11 @@ struct FileIconMaker : ImageMaker { } virtual Image Make() const { - SHFILEINFO info; + SHFILEINFOW info; AvoidPaintingCheck__(); - SHGetFileInfo(ToSystemCharset(file), dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL, - &info, sizeof(info), - SHGFI_ICON|(large ? SHGFI_LARGEICON : SHGFI_SMALLICON)|(exe ? 0 : SHGFI_USEFILEATTRIBUTES)); + SHGetFileInfoW(ToSystemCharsetW(file), dir ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL, + &info, sizeof(info), + SHGFI_ICON|(large ? SHGFI_LARGEICON : SHGFI_SMALLICON)|(exe ? 0 : SHGFI_USEFILEATTRIBUTES)); return ProcessSHIcon(info.hIcon); } }; @@ -587,14 +587,14 @@ bool Load(FileList& list, const String& dir, const char *patterns, bool dirs, #ifdef GUI_WIN static Mutex sExeMutex; -static wchar sExePath[1025]; +static WCHAR sExePath[1025]; static bool sExeRunning; static SHFILEINFOW sExeInfo; static auxthread_t auxthread__ sExeIconThread(void *) { SHFILEINFOW info; - wchar path[1025]; + WCHAR path[1025]; CoInitialize(NULL); sExeMutex.Enter(); wcscpy(path, sExePath); @@ -649,7 +649,7 @@ void LazyExeFileIcons::Do() sExeMutex.Enter(); bool running = sExeRunning; if(!running) { - done = path == sExePath; + done = path == ToUtf32(sExePath); memcpy(&info, &sExeInfo, sizeof(info)); *sExePath = '\0'; memset(&sExeInfo, 0, sizeof(sExeInfo)); @@ -2389,7 +2389,9 @@ FileSel::FileSel() places.NoWantFocus(); #ifdef PLATFORM_WIN32 - list.IconWidth(GetFileIcon(GetHomeDirectory(), true, false, false).GetSize().cx); + int icx = GetFileIcon(GetHomeDirectory(), true, false, false).GetSize().cx; + if(icx) + list.IconWidth(icx); #endif AddStandardPlaces(); diff --git a/uppsrc/CtrlLib/Help.cpp b/uppsrc/CtrlLib/Help.cpp index a19b55eec..67d6e128e 100644 --- a/uppsrc/CtrlLib/Help.cpp +++ b/uppsrc/CtrlLib/Help.cpp @@ -24,7 +24,7 @@ bool HelpWindow::GoTo0(const String& link) topic = t.link; if(~tree != topic) tree.FindSetCursor(topic); - Title(FromUtf8(t.title)); + Title(ToUtf32(t.title)); RichText txt = ParseQTF(t.text); FinishText(txt); view.Pick(pick(txt), zoom); diff --git a/uppsrc/CtrlLib/LineEdit.cpp b/uppsrc/CtrlLib/LineEdit.cpp index f707a05ec..b17f9d6b1 100644 --- a/uppsrc/CtrlLib/LineEdit.cpp +++ b/uppsrc/CtrlLib/LineEdit.cpp @@ -11,6 +11,7 @@ LineEdit::LineEdit() { showtabs = false; tabsize = 4; font = CourierZ(12); + SyncFont(); SetFrame(ViewFrame()); sb.NoBox(); AddFrame(sb); @@ -70,10 +71,20 @@ LineEdit& LineEdit::SetFont(Font f) { return *this; } +void LineEdit::SyncFont() +{ + fsz = GetFontSize(); +} + Size LineEdit::GetFontSize() const { return Size(font.GetMonoWidth(), font.GetCy()); } +bool LineEdit::IsDoubleChar(int ch) const +{ + return ch >= 2048 && (IsDoubleWidth(ch) || font.GetWidth(ch) > fsz.cx); +} + void LineEdit::SetRectSelection(int64 anchor, int64 cursor) { dorectsel = true; @@ -396,7 +407,6 @@ void LineEdit::Paint0(Draw& w) { if(rectsel) rect = GetRectSelection(); Size sz = GetSize(); - Size fsz = GetFontSize(); Point sc = sb; int ll = min(GetLineCount(), sz.cy / fsz.cy + sc.y + 1); int y = 0; @@ -480,7 +490,7 @@ void LineEdit::Paint0(Draw& w) { x = fsz.cx * gp; } else - if(IsDoubleWidth(chr)) { + if(IsDoubleChar(chr)) { x += 2 * fsz.cx; gp += 2; } @@ -508,7 +518,7 @@ void LineEdit::Paint0(Draw& w) { h.ink = color[INK_SELECTED]; } int x = gp * fsz.cx - scx; - bool cjk = IsDoubleWidth(h.chr); + bool cjk = IsDoubleChar(h.chr); int xx = x + (gp + 1 + cjk) * fsz.cx; if(h.chr == '\t') { int ngp = (gp + tabsize) / tabsize * tabsize; @@ -649,6 +659,7 @@ void LineEdit::RefreshChars(bool (*chars)(int c)) } void LineEdit::Layout() { + SyncFont(); Size sz = sb.GetReducedViewSize(); if(nohbar || isdrag) sz.cy = GetSize().cy; @@ -671,7 +682,7 @@ int64 LineEdit::GetGPos(int ln, int cl) const { if((byte)*s < 128) gl++; else { - WString txt = FromUtf8(s, int(e - s)); + WString txt = ToUtf32(s, int(e - s)); const wchar *b = txt; const wchar *e = txt.End(); const wchar *s = b; @@ -679,7 +690,7 @@ int64 LineEdit::GetGPos(int ln, int cl) const { if(*s == '\t') gl = (gl + tabsize) / tabsize * tabsize; else - gl += 1 + IsDoubleWidth(*s); + gl += 1 + IsDoubleChar(*s); if(cl < gl) break; s++; } @@ -704,7 +715,7 @@ Point LineEdit::GetColumnLine(int64 pos) const { if(*s == '\t') p.x = (p.x + tabsize) / tabsize * tabsize; else - p.x += 1 + IsDoubleWidth(*s); + p.x += 1 + IsDoubleChar(*s); s++; } return p; @@ -1007,11 +1018,11 @@ void LineEdit::MoveTextEnd(bool sel) { bool LineEdit::InsertChar(dword key, int count, bool canow) { if(key == K_TAB && !processtab) return false; - if(filter && key >= 32 && key < 65535) + if(filter && key >= 32 && key < K_CHAR_LIM) key = (*filter)(key); - if(!IsReadOnly() && (key >= 32 && key < 65536 || key == '\t' || key == '\n' || + if(!IsReadOnly() && (key >= 32 && key < K_CHAR_LIM || key == '\t' || key == '\n' || key == K_ENTER && processenter || key == K_SHIFT_SPACE)) { - if(key >= 128 && key < 65536 && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM) + if(key >= 128 && key < K_CHAR_LIM && (charset != CHARSET_UNICODE && charset != CHARSET_UTF8_BOM) && FromUnicode((wchar)key, charset) == DEFAULTCHAR) return true; if(!RemoveSelection() && overwrite && key != '\n' && key != K_ENTER && canow) { @@ -1113,7 +1124,7 @@ void LineEdit::SetHBar() if(*s == '\t') pos = (pos + tabsize) / tabsize * tabsize; else - pos += 1 + IsDoubleWidth(*s); + pos += 1 + IsDoubleChar(*s); s++; } mpos = max(mpos, pos); diff --git a/uppsrc/CtrlLib/PopupTable.cpp b/uppsrc/CtrlLib/PopupTable.cpp index 578d63cca..4635f5124 100644 --- a/uppsrc/CtrlLib/PopupTable.cpp +++ b/uppsrc/CtrlLib/PopupTable.cpp @@ -68,6 +68,7 @@ bool PopUpTable::Key(dword key, int n) { } void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) { + TimeStop tm; if(inpopup) return; inpopup++; diff --git a/uppsrc/CtrlLib/SuggestCtrl.cpp b/uppsrc/CtrlLib/SuggestCtrl.cpp index fab48acf3..45f4301f1 100644 --- a/uppsrc/CtrlLib/SuggestCtrl.cpp +++ b/uppsrc/CtrlLib/SuggestCtrl.cpp @@ -89,7 +89,7 @@ bool SuggestCtrl::Key(dword key, int count) if(cc) key = cc; if(EditString::Key(key, count)) { - if(key >= 32 && key < 65536 || key == K_BACKSPACE || key == K_CTRL_SPACE) { + if(key >= 32 && key < K_CHAR_LIM || key == K_BACKSPACE || key == K_CTRL_SPACE) { int h; WString x = CF(ReadLast(h)); list.Clear(); diff --git a/uppsrc/CtrlLib/Text.cpp b/uppsrc/CtrlLib/Text.cpp index d77517b7e..09cc0574b 100644 --- a/uppsrc/CtrlLib/Text.cpp +++ b/uppsrc/CtrlLib/Text.cpp @@ -257,13 +257,13 @@ int TextCtrl::LoadLines(Vector& ls, int n, int64& total, Stream& in, byte ch auto put_ln = [&]() -> bool { if(view_line_count) { (*view_line_count)++; - total += charset == CHARSET_UTF8 && (b8 & 0x80) ? utf8len(~ln, ln.GetCount()) + total += charset == CHARSET_UTF8 && (b8 & 0x80) ? Utf32Len(~ln, ln.GetCount()) : ln.GetCount(); } else { Ln& l = ls.Add(); if(charset == CHARSET_UTF8) { - l.len = (b8 & 0x80) ? utf8len(~ln, ln.GetCount()) : ln.GetCount(); + l.len = (b8 & 0x80) ? Utf32Len(~ln, ln.GetCount()) : ln.GetCount(); l.text = ln; } else { @@ -501,10 +501,24 @@ void TextCtrl::Save(Stream& s, byte charset, int line_endings) const { const wchar *e = txt.End(); if(be16) for(const wchar *w = txt; w != e; w++) - s.Put16be(*w); + if(*w < 0x10000) + s.Put16be((word)*w); + else { + char16 h[2]; + ToUtf16(h, w, 1); + s.Put16be(h[0]); + s.Put16be(h[1]); + } else for(const wchar *w = txt; w != e; w++) - s.Put16le(*w); + if(*w < 0x10000) + s.Put16le((word)*w); + else { + char16 h[2]; + ToUtf16(h, w, 1); + s.Put16le(h[0]); + s.Put16le(h[1]); + } } return; } @@ -593,7 +607,7 @@ String TextCtrl::GetEncodedLine(int i, byte charset) const { charset = ResolveCharset(charset); String h = GetUtf8Line(i); - return charset == CHARSET_UTF8 ? h : FromUnicode(FromUtf8(h), charset); + return charset == CHARSET_UTF8 ? h : FromUnicode(ToUtf32(h), charset); } int TextCtrl::GetLinePos64(int64& pos) const { @@ -717,7 +731,7 @@ String TextCtrl::Get(int64 pos, int size, byte charset) const if(pos == 0 && sz == n) r.Cat(s, n); else - r.Cat(FromUtf8(s, n).Mid((int)pos, sz).ToString()); + r.Cat(ToUtf32(s, n).Mid((int)pos, sz).ToString()); size -= sz; if(size == 0) break; #ifdef PLATFORM_WIN32 @@ -998,7 +1012,7 @@ void TextCtrl::Undo() { Remove0(u.pos, u.size); } else { - WString text = FromUtf8(u.GetText()); + WString text = ToUtf32(u.GetText()); r.size = Insert0(u.pos, text); nc += r.size; } @@ -1025,7 +1039,7 @@ void TextCtrl::Redo() { if(r.size) RemoveU(r.pos, r.size); else - nc += InsertU(r.pos, FromUtf8(r.GetText())); + nc += InsertU(r.pos, ToUtf32(r.GetText())); redo.DropTail(); IncDirty(); } diff --git a/uppsrc/CtrlLib/TextEdit.h b/uppsrc/CtrlLib/TextEdit.h index 81065aa56..df5298f63 100644 --- a/uppsrc/CtrlLib/TextEdit.h +++ b/uppsrc/CtrlLib/TextEdit.h @@ -189,7 +189,7 @@ public: int GetLine(int64 pos) const { return GetLinePos64(pos); } const String& GetUtf8Line(int i) const; - WString GetWLine(int i) const { return FromUtf8(GetUtf8Line(i)); } + WString GetWLine(int i) const { return ToUtf32(GetUtf8Line(i)); } String GetEncodedLine(int i, byte charset = CHARSET_DEFAULT) const; int GetLineLength(int i) const; @@ -336,6 +336,7 @@ protected: Font font; + Size fsz; CharFilter filter; int tabsize; int bordercolumn; @@ -368,6 +369,8 @@ protected: Rect DropCaret(); void RefreshDropCaret(); void DoPasteColumn() { PasteColumn(); } + void SyncFont(); + bool IsDoubleChar(int ch) const; struct RefreshDraw; friend class TextCtrl; diff --git a/uppsrc/CtrlLib/TrayIconWin32.cpp b/uppsrc/CtrlLib/TrayIconWin32.cpp index a7b288a24..192775c73 100644 --- a/uppsrc/CtrlLib/TrayIconWin32.cpp +++ b/uppsrc/CtrlLib/TrayIconWin32.cpp @@ -31,11 +31,11 @@ TrayIcon::TrayIcon() Create(NULL, WS_POPUP, 0, false, 0, 0); Ctrl::Hide(); Zero(nid); - nid.sz = IsWin2K() ? sizeof(NotifyIconNew) : sizeof(NotifyIconOld); - nid.message = UM_TASKBAR_; - nid.hwnd = GetHWND(); + nid.cbSize = sizeof(nid); + nid.uCallbackMessage = UM_TASKBAR_; + nid.hWnd = GetHWND(); static int id; - nid.id = ++id; + nid.uID = ++id; visible = false; Show(); } @@ -43,22 +43,29 @@ TrayIcon::TrayIcon() TrayIcon::~TrayIcon() { Hide(); - if(nid.icon) - DestroyIcon(nid.icon); + if(nid.hIcon) + DestroyIcon(nid.hIcon); +} + +void Wcpy(char16 *t, const String& s, int sz) +{ + Vector w = ToSystemCharsetW(s); + if(w.GetCount() > sz) { + w.SetCount(sz - 1); + w.Add(0); + } + memcpy(t, w, w.GetCount() * sizeof(char16)); } void TrayIcon::Notify(dword msg) { if(visible) { - nid.flags = NIF_ICON|NIF_MESSAGE|NIF_TIP; - if(nid.icon) - DestroyIcon(nid.icon); - nid.icon = SystemDraw::IconWin32(icon); - String stip = ToSystemCharset(tip); - int len = min(stip.GetLength(), 125); - memcpy(nid.tip, stip, len); - nid.tip[len] = 0; - BOOL Status = Shell_NotifyIcon(msg, (NOTIFYICONDATA *)&nid); + nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; + if(nid.hIcon) + DestroyIcon(nid.hIcon); + nid.hIcon = SystemDraw::IconWin32(icon); + Wcpy(nid.szTip, tip, 128); + BOOL Status = Shell_NotifyIconW(msg, &nid); // To prevent from Shell_NotifyIcon bugs... // discussed here : http://msdn.microsoft.com/en-us/library/bb762159(v=vs.85).aspx // and here : http://issuetracker.delphi-jedi.org/bug_view_advanced_page.php?bug_id=3747 @@ -71,7 +78,7 @@ void TrayIcon::Notify(dword msg) if(ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_TIMEOUT) { for(int retry = 0; retry < 60; retry++) { Sleep(50); - if(Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA *)&nid) == (msg != NIM_DELETE)) + if(Shell_NotifyIconW(NIM_MODIFY, &nid) == (msg != NIM_DELETE)) break; } } @@ -81,23 +88,12 @@ void TrayIcon::Notify(dword msg) void TrayIcon::Message(int type, const char *title, const char *text, int timeout) { - if(!IsWin2K()) - return; - nid.flags = 0x10; - *nid.info = *nid.title = 0; - if(text) { - String h = ToSystemCharset(text); - memcpy(nid.info, h, min(h.GetLength(), 255) + 1); - nid.info[255] = 0; - } - if(title) { - String h = ToSystemCharset(title); - memcpy(nid.title, h, min(h.GetLength(), 63) + 1); - nid.title[63] = 0; - } - nid.infoflags = type; - nid.timeout = minmax(timeout, 10, 30) * 1000; - Shell_NotifyIcon(NIM_MODIFY, (NOTIFYICONDATA *)&nid); + nid.uFlags = 0x10; + Wcpy(nid.szInfo, text, 256); + Wcpy(nid.szInfoTitle, text, 64); + nid.dwInfoFlags = type; + nid.uTimeout = minmax(timeout, 10, 30) * 1000; + Shell_NotifyIconW(NIM_MODIFY, &nid); } void TrayIcon::Show(bool b) @@ -185,11 +181,11 @@ LRESULT TrayIcon::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) LeftUp(); return TRUE; case WM_LBUTTONDBLCLK: - ::SetForegroundWindow(nid.hwnd); + ::SetForegroundWindow(nid.hWnd); LeftDouble(); return TRUE; case WM_RBUTTONDOWN: - ::SetForegroundWindow(nid.hwnd); + ::SetForegroundWindow(nid.hWnd); MenuBar::Execute(NULL, THISBACK(DoMenu), GetMousePos()); return TRUE; case NIN_BALLOONSHOW_: diff --git a/uppsrc/CtrlLib/TreeCtrl.cpp b/uppsrc/CtrlLib/TreeCtrl.cpp index 9fd621201..dfd27cedc 100644 --- a/uppsrc/CtrlLib/TreeCtrl.cpp +++ b/uppsrc/CtrlLib/TreeCtrl.cpp @@ -1294,7 +1294,7 @@ bool TreeCtrl::Key(dword key, int) Open(cid); break; default: { - if(accel && key >= ' ' && key < 65536) { + if(accel && key >= ' ' && key < K_CHAR_LIM) { int ascii_line = -1; int upper_line = -1; int exact_line = -1; diff --git a/uppsrc/CtrlLib/Win32.cpp b/uppsrc/CtrlLib/Win32.cpp index f430aadf0..132afa560 100644 --- a/uppsrc/CtrlLib/Win32.cpp +++ b/uppsrc/CtrlLib/Win32.cpp @@ -26,8 +26,8 @@ FileSelNative::FileSelNative() { FileSelNative& FileSelNative::Type(const char *name, const char *ext) { FileType& t = type.Add(); - t.name = ToSystemCharset(name); - t.ext = ToSystemCharset(ext); + t.name = name; + t.ext = ext; return *this; } @@ -98,6 +98,12 @@ static UINT_PTR CALLBACK sCenterHook(HWND hdlg, UINT msg, WPARAM wParam, LPARAM #endif bool FileSelNative::Execute(bool open, const char *dlgtitle) { + Vector> s16; + auto W32 = [&](const String& s) -> char16* { + auto& h = s16.Add(); + h = ToSystemCharsetW(s); + return h; + }; String filter; for(int i = 0; i < type.GetCount(); i++) { filter.Cat(type[i].name); @@ -105,7 +111,7 @@ bool FileSelNative::Execute(bool open, const char *dlgtitle) { filter.Cat(type[i].ext); filter.Cat('\0'); } - OPENFILENAME ofn; + OPENFILENAMEW ofn; memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(OPENFILENAME); Ctrl *q = Ctrl::GetActiveWindow(); @@ -114,12 +120,12 @@ bool FileSelNative::Execute(bool open, const char *dlgtitle) { if(asking) ofn.Flags |= (open ? OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST : OFN_OVERWRITEPROMPT); if(!rdonly) ofn.Flags |= OFN_HIDEREADONLY; if(multi) ofn.Flags |= OFN_ALLOWMULTISELECT; - ofn.lpstrFilter = filter; + ofn.lpstrFilter = W32(filter); ofn.nFilterIndex = activetype; - ofn.lpstrInitialDir = activedir; + ofn.lpstrInitialDir = W32(activedir); ofn.lpfnHook = sCenterHook; int bufsize = ofn.nMaxFile = (multi ? 32000 : _MAX_PATH); - Buffer buffer(bufsize); + Buffer buffer(bufsize); *(ofn.lpstrFile = buffer) = 0; if(!filename.IsEmpty()) { @@ -127,16 +133,16 @@ bool FileSelNative::Execute(bool open, const char *dlgtitle) { for(int i = 0; i < filename.GetCount(); i++) { if(*ofn.lpstrInitialDir == 0 && FindFile().Search(AppendFileName(GetFileDirectory(filename[i]), "*"))) - ofn.lpstrInitialDir = GetFileDirectory(filename[i]); + ofn.lpstrInitialDir = W32(GetFileDirectory(filename[i])); if(!open || FileExists(filename[i])) { String fn = GetFileName(filename[i]); if(!IsNull(fn)) { if(multi && fn.Find(' ') >= 0) - out << '\"' << ToSystemCharset(fn) << '\"'; + out << W32(String() << '\"' << fn << '\"'); else - out << ToSystemCharset(fn); + out << W32(fn); out.Cat(0); } } @@ -145,44 +151,42 @@ bool FileSelNative::Execute(bool open, const char *dlgtitle) { memcpy(buffer, out, l + 1); } - String title; if(dlgtitle) - title = ToSystemCharset(dlgtitle); + ofn.lpstrTitle = W32(dlgtitle); else if(open) - title = ToSystemCharset(t_("Open..")); + ofn.lpstrTitle = W32(t_("Open..")); else - title = ToSystemCharset(t_("Save as")); - ofn.lpstrTitle = ~title; + ofn.lpstrTitle = W32(t_("Save as")); if(!defext.IsEmpty()) - ofn.lpstrDefExt = defext; - bool res = !!(open ? GetOpenFileName : GetSaveFileName)(&ofn); + ofn.lpstrDefExt = W32(defext); + bool res = !!(open ? GetOpenFileNameW : GetSaveFileNameW)(&ofn); if(!res && CommDlgExtendedError() == FNERR_INVALIDFILENAME) { *buffer = 0; - res = !!(open ? GetOpenFileName : GetSaveFileName)(&ofn); + res = !!(open ? GetOpenFileNameW : GetSaveFileNameW)(&ofn); } if(!res && CommDlgExtendedError() == FNERR_INVALIDFILENAME) { - ofn.lpstrInitialDir = ""; - res = !!(open ? GetOpenFileName : GetSaveFileName)(&ofn); + ofn.lpstrInitialDir = W32(""); + res = !!(open ? GetOpenFileNameW : GetSaveFileNameW)(&ofn); } if(!res) return false; filename.Clear(); activetype = ofn.nFilterIndex; if(multi) { - const char *s = ofn.lpstrFile; - activedir = s; - s += strlen(s); + const char16 *s = ofn.lpstrFile; + activedir = FromSystemCharsetW(s); + s += strlen16(s); if(s[1] == 0) - filename.Add() = FromSystemCharset(activedir); + filename.Add() = activedir; else do - filename.Add() = FromSystemCharset(AppendFileName(activedir, ++s)); - while((s += strlen(s))[1]); + filename.Add() = AppendFileName(activedir, FromSystemCharsetW(++s)); + while((s += strlen16(s))[1]); } else { - filename.Add(FromSystemCharset(ofn.lpstrFile)); + filename.Add(FromSystemCharsetW(ofn.lpstrFile)); activedir = GetFileDirectory(filename[0]); } readonly = ofn.Flags & OFN_READONLY ? TRUE : FALSE; diff --git a/uppsrc/Draw/Draw.h b/uppsrc/Draw/Draw.h index 2b9a56007..c9eb0e209 100644 --- a/uppsrc/Draw/Draw.h +++ b/uppsrc/Draw/Draw.h @@ -65,7 +65,7 @@ class Font : public ValueType >{ const CommonFontInfo& Fi() const; friend void sInitFonts(); - friend String GetFontDataSys(Font font); + friend String GetFontDataSys(Font font, const char *table, int offset, int size); public: enum { @@ -182,7 +182,7 @@ public: String GetTextFlags() const; void ParseTextFlags(const char *s); - String GetData() const; + String GetData(const char *table = NULL, int offset = 0, int size = INT_MAX) const; void Render(FontGlyphConsumer& sw, double x, double y, int ch) const; diff --git a/uppsrc/Draw/Draw.upp b/uppsrc/Draw/Draw.upp index 3d7bf124a..86b462e1c 100644 --- a/uppsrc/Draw/Draw.upp +++ b/uppsrc/Draw/Draw.upp @@ -8,7 +8,7 @@ acceptflags uses Core; -library(WIN32) "user32 gdi32"; +library(WIN32) "user32 gdi32 usp10"; link(OSX !X11) "-framework Foundation -framework Cocoa -framework Carbon"; @@ -20,6 +20,7 @@ file Draw.h options(BUILDER_OPTION) PCH, FontInt.h, Font.cpp, + Fonts.i, FontCR.cpp, FontWin32.cpp, FontFc.cpp, diff --git a/uppsrc/Draw/DrawText.cpp b/uppsrc/Draw/DrawText.cpp index 9c98a5382..99dca08ee 100644 --- a/uppsrc/Draw/DrawText.cpp +++ b/uppsrc/Draw/DrawText.cpp @@ -20,7 +20,7 @@ WString TextUnicode(const char *s, int n, byte cs, Font font) return WString(b); } #endif - return ToUnicode(s, n, cs); + return ToUtf32(s, n); } void Draw::DrawText(int x, int y, int angle, const wchar *text, Font font, @@ -29,7 +29,7 @@ void Draw::DrawText(int x, int y, int angle, const wchar *text, Font font, if(IsNull(ink)) return; ink = ResolveInk(ink); if(n < 0) - n = wstrlen(text); + n = strlen__(text); Std(font); double sina = 0; double cosa = 1; @@ -43,7 +43,7 @@ void Draw::DrawText(int x, int y, int angle, const wchar *text, Font font, wchar chr = text[i]; GlyphInfo gi = GetGlyphInfo(font, chr); if(gi.IsNormal()) - if(angle) + if(angle || chr >= 0x10000) DrawTextOp(int(x + cosa * posx), int(y - sina * posx), angle, &chr, font, ink, 1, NULL); else { int c = 1; @@ -212,7 +212,7 @@ Size GetTextSize(const wchar *text, Font font, int n) { FontInfo fi = font.Info(); if(n < 0) - n = wstrlen(text); + n = strlen__(text); Size sz; sz.cx = 0; const wchar *wtext = (const wchar *)text; diff --git a/uppsrc/Draw/DrawTextUtil.cpp b/uppsrc/Draw/DrawTextUtil.cpp index 14de7eedf..a61161bda 100644 --- a/uppsrc/Draw/DrawTextUtil.cpp +++ b/uppsrc/Draw/DrawTextUtil.cpp @@ -5,7 +5,7 @@ namespace Upp { void DrawTextEllipsis(Draw& w, int x, int y, int cx, const wchar *text, const char *ellipsis, Font font, Color ink, int n) { - if(n < 0) n = wstrlen(text); + if(n < 0) n = strlen__(text); FontInfo f = font.Info(); const char *s; int dtl = 0; diff --git a/uppsrc/Draw/Drawing.cpp b/uppsrc/Draw/Drawing.cpp index c0f35bb0c..be677224a 100644 --- a/uppsrc/Draw/Drawing.cpp +++ b/uppsrc/Draw/Drawing.cpp @@ -250,17 +250,23 @@ void DrawingDraw::DrawArcOp(const Rect& rc, Point start, Point end, int width, C DrawingOp(DRAWING_DRAWARC) % const_cast(rc) % start % end % color % width; } +static_assert(sizeof(wchar) == 4, "sizeof wchar"); + void DrawingDraw::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, Color ink, int n, const int *dx) { if(IsNull(ink)) return; if(n < 0) - n = wstrlen((const wchar *)text); + n = strlen__((const wchar *)text); if(n == 0) return; Stream& s = DrawingOp(DRAWING_DRAWTEXT); - byte cs = CHARSET_UNICODE; + byte cs = CHARSET_UTF32; s % x % y % angle % font % ink / n % cs; - s.PutW((wchar *)text, n); +#ifdef CPU_LE + s.Put(text, n * sizeof(wchar)); +#else + #error big endiand not supported +#endif bool dxb = dx; s % dxb; if(dx) { @@ -548,13 +554,18 @@ void Draw::DrawDrawingOp(const Rect& target, const Drawing& w) { FontInfo fi = font.Info(); font.Height(fi.GetHeight() - fi.GetInternal()); } - bool unicode = cs == CHARSET_UNICODE; WString text; - if(unicode) { + if(cs == CHARSET_UTF32) { Buffer txt(n); - ps.Stream::GetW(txt, n); + ps.Stream::Get(txt, n * sizeof(wchar)); text = WString(txt, n); } + else + if(cs == CHARSET_UNICODE) { // backward compatibility + Buffer txt(n); + ps.Stream::GetW(txt, n); + text = ToUtf32(txt, n); + } else { Buffer txt(n); ps.Stream::Get(txt, n); @@ -594,39 +605,6 @@ void Draw::DrawDrawingOp(const Rect& target, const Drawing& w) { int ht = (int)(font.GetHeight() * min(double(ps.target.cx) / ps.source.cx, double(ps.target.cy) / ps.source.cy)); font.Width((int)q * font.GetWidth()).Height(ht ? ht : 1); DrawText(ps.GetX(x), ps.GetY(y), angle, text, font, ink, dx); - /* - FontInfo fi = font.Info(); - const wchar *wp = ~text; - int odd = (angle / 900) & 1; - double ang = (double) (angle % 900) * M_2PI / 3600; - double sx = (double) ps.target.cx / ps.source.cx; - double sy = (double) ps.target.cy / ps.source.cy; - double ang2 = atan((odd ? sx / sy : sy / sx) * tan(ang)); - DDUMP(odd); - DDUMP(cx); - DDUMP(sy); - DDUMP(sin(ang)); - DDUMP(sin(ang2)); - double q = (odd ? sx : sy) * sin(ang) / sin(ang2); - double error = 0; - while(nn--) { - int cx; - if(dxb) { - ps / cx; - DDUMP(cx); - } - else - cx = fi[*wp++]; - double ncx = q * cx + error; - DDUMP(q * cx); - *wd++ = cx = (int) ncx; - error = ncx - cx; - } - int ht = (int)(fi.GetFontHeight() * (sx * sin(ang) * sin(ang2) + sy * cos(ang) * cos(ang2))); - font.Width(int(q * fi.GetAveWidth())).Height(ht ? ht : 1); - DrawText(ps.GetX(x), ps.GetY(y), int(ang2 * 3600 / M_2PI) + (angle / 900) * 900, - text, font, ink, dx); - */ } } } diff --git a/uppsrc/Draw/Font.cpp b/uppsrc/Draw/Font.cpp index 19d91f89d..8ec2d4924 100644 --- a/uppsrc/Draw/Font.cpp +++ b/uppsrc/Draw/Font.cpp @@ -386,31 +386,39 @@ String AsString(const Font& f) { struct CharEntry { int64 font; GlyphInfo info; - word chr; + wchar chr; }; -CharEntry fc_cache_global[4093]; +CharEntry fc_cache_global[16384]; inline hash_t GlyphHash(Font font, int chr) { return FoldHash(CombineHash(font.GetHashValue(), chr)); } -bool IsNormal(Font font, int chr) -{ +bool IsNormal_nc(Font font, int chr) +{ // do not change cache - to be used in Replace Mutex::Lock __(sFontLock); font.RealizeStd(); - CharEntry& e = fc_cache_global[GlyphHash(font, chr) % 4093]; + CharEntry& e = fc_cache_global[GlyphHash(font, chr) & 16383]; if(e.font == font.AsInt64() && e.chr == chr) return e.info.IsNormal(); return GetGlyphInfoSys(font, chr).IsNormal(); } -CharEntry GetGlyphEntry(Font font, int chr, hash_t hash) -{ - Mutex::Lock __(sFontLock); - CharEntry& e = fc_cache_global[hash % 4093]; - if(e.font != font.AsInt64() || e.chr != chr) { +struct GlyphInfoMaker : ValueMaker { + Font font; + int chr; + + virtual String Key() const { + StringBuffer s; + int64 h = font.AsInt64(); + RawCat(s, h); + RawCat(s, chr); + return String(s); + } + virtual int Make(Value& object) const { + CharEntry& e = CreateRawValue(object); e.font = font.AsInt64(); e.chr = chr; e.info = GetGlyphInfoSys(font, chr); @@ -419,7 +427,7 @@ CharEntry GetGlyphEntry(Font font, int chr, hash_t hash) Font rfnt; if(Compose(font, chr, cg)) { e.info.lspc = -1; - e.info.rspc = cg.basic_char; + e.info.rspc = (int16)cg.basic_char; } else if(Replace(font, chr, rfnt)) { @@ -429,8 +437,17 @@ CharEntry GetGlyphEntry(Font font, int chr, hash_t hash) else e.info.lspc = -2; } + return sizeof(e); } - return e; +}; + +CharEntry GetGlyphEntry(Font font, int chr, hash_t hash) +{ + Mutex::Lock __(sFontLock); + GlyphInfoMaker m; + m.font = font; + m.chr = chr; + return MakeValue(m).To(); } thread_local CharEntry fc_cache[512]; @@ -548,10 +565,11 @@ int Font::GetRightSpace(int c) const { return GetGlyphMetrics(*this, c).rspc; } -String Font::GetData() const +String Font::GetData(const char *table, int offset, int size) const { Mutex::Lock __(sFontLock); - return GetFontDataSys(*this); + ASSERT(!table || strlen(table) == 4); + return GetFontDataSys(*this, table, offset, size); } void Font::Render(FontGlyphConsumer& sw, double x, double y, int ch) const diff --git a/uppsrc/Draw/FontCR.cpp b/uppsrc/Draw/FontCR.cpp index 8b094c3f4..c50c5e791 100644 --- a/uppsrc/Draw/FontCR.cpp +++ b/uppsrc/Draw/FontCR.cpp @@ -1,5 +1,7 @@ #include "Draw.h" +#define LLOG(x) // LOG(x) + namespace Upp { enum { @@ -226,91 +228,223 @@ bool Compose(Font font, int chr, ComposedGlyph& cg) struct sRFace { const char *name; - dword l, h; + byte panose[10]; + dword coverage[8]; } sFontReplacements[] = { - { "Lucida Grande", 0, 0 }, - { "Apple Symbols", 0, 0 }, - { "sans-serif", 0xffee0008, 0xdc000801 }, - { "Arial", 0xfffe0000, 0x9c000801 }, - {"\346\226\260\345\256\213\344\275\223", 0xfd800000, 0x9ffff00d },//SimSun (or New Song Ti) - {"SimSun", 0xfd800000, 0x9ffff00d },//SimSun (or New Song Ti) - {"\345\256\213\344\275\223", 0xfd800000, 0x9ffff00d }, // Song Ti - {"\345\276\256\350\275\257\351\233\205\351\273\221", 0xfd800000, 0x9ffff00f }, //MS Ya Hei - {"Microsoft YaHei", 0xfd800000, 0x9ffff00f }, //MS Ya Hei -// {"\351\273\221\344\275\223", 0xfd800000, 0x09ffff00 }, // Hei Ti -// {"\346\226\207\346\263\211\351\251\277\346\255\243\351\273\221", 0xfd800000, 0x09ffff00 }, //WenQuanYi Zheng Hi -// {"\346\226\207\346\263\211\351\251\277\347\255\211\345\256\275\345\276\256\347\261\263\351\273\221", 0xfd800000, 0x09ffff00 },//WenQuanYi Wei Hei -// {"\344\273\277\345\256\213", 0xfd800000, 0x09ffff00 }, //Fang Song -// {"\346\245\267\344\275\223", 0xfd800000, 0x09ffff00 }, // Kai Ti - { "Arial Unicode MS", 0xfffc3fef, 0xfa7ff7ef }, - { "MS UI Gothic", 0xffc01008, 0xfffff001 }, - { "MS Mincho", 0xffc01008, 0xfffff001 }, - { "VL Gothic", 0xfd800000, 0x9a7ff80f }, - { "VL PGothic", 0xffe00008, 0xde7ff80f }, - { "UnDotum", 0xe5800000, 0xaa7ff7ef }, - { "UnBatang", 0xe5800000, 0xaa7ff7ef }, - { "DejaVu Sans Mono", 0xffec0004, 0xfc00080f }, - { "DejaVu Sans", 0xfffd000c, 0xfc40080f }, - { "AlArabiyaFreeSerif", 0xffdc0008, 0xd800000f }, - { "Kochi Mincho", 0xffdc0008, 0xd800000f }, - { "Kochi Gothic", 0xffdc0008, 0xd800000f }, - { "Sazanami Mincho", 0xffdc0008, 0xd800000f }, - { "Sazanami Gothic", 0xffdc0008, 0xd800000f }, - { "Gulim", 0xf7c00000, 0xba7ff7e1 }, - { "PMingLiU", 0xff800000, 0x9ffff001 }, // <--- SHOULD MOVE UP - { "FreeSans", 0xfff23d00, 0xfc00000f }, - { "FreeSerif", 0xfffd3938, 0xfc00080f }, - { "FreeMono", 0xfffc0000, 0xbc000c01 }, - { "Symbol", 0xe4000000, 0x8800000f }, - { "NanumGothic", 0xe5800000, 0xae7ff7e1 }, - { "WenQuanYi Micro Hei Mono", 0xffe00008, 0xda7ff7e1 }, - { "NanumMyeongjo", 0xe5800000, 0x8a0007e1 }, - { "WenQuanYi Micro Hei", 0xffe00008, 0xda7ff7e1 }, - { "FontAwesome", 0xc0000000, 0x88000002 }, + #include "Fonts.i" }; +bool ReadCmap(Font font, Event range, bool glyphs = false) { + String data = font.GetData("cmap"); + auto Get16 = [&](int i) { return i >= 0 && i + 2 <= data.GetCount() ? Peek16be(~data + i) : 0; }; + auto Get32 = [&](int i) { return i >= 0 && i + 4 <= data.GetCount() ? Peek32be(~data + i) : 0; }; + for(int pass = 0; pass < 2; pass++) { + int p = 0; + p += 2; + int n = Get16(p); + p += 2; + while(n-- && p < data.GetCount()) { + int pid = Get16(p); p += 2; + int psid = Get16(p); p += 2; + int offset = Get32(p); p += 4; + if(offset < 0 || offset > data.GetCount()) + return false; + int format = Get16(offset); + LLOG("cmap pid: " << pid << " psid: " << psid << " format: " << format); + if((pid == 3 && psid == 10) || (pid == 0 && psid == 4) && format == 12 && pass == 0) { + int p = offset; + int ngroups = Get32(p + 12); + p += 16; // pointer to groups table + for(int i = 0; i < ngroups; i++) { + int start = Get32(p); + int end = Get32(p + 4); + range(start, end, Get32(p + 8)); + p += 12; + } + return true; + } + else + if((pid == 3 && psid == 1) || (pid == 0 && psid == 3) && format == 4 && pass == 1) { + int p = offset; + int n = Get16(p + 6) >> 1; + int seg_end = p + 14; + int seg_start = seg_end + 2 * n + 2; + int idDelta = seg_start + 2 * n; + int idRangeOffset = idDelta + 2 * n; + for(int i = 0; i < n; i++) { + int start = Get16(seg_start + 2 * i); + int end = Get16(seg_end + 2 * i); + int delta = Get16(idDelta + 2 * i); + int ro = Get16(idRangeOffset + 2 * i); + if(glyphs) { + if (ro && delta == 0) { + LLOG("RangeOffset start: " << start << ", end: " << end << ", delta: " << (int16)delta); + int q = idRangeOffset + 2 * i + ro; + for(int c = start; c <= end; c++) { + range(c, c, (word)Get16(q)); + q += 2; + } + } + else { + LLOG("Delta start: " << start << ", end: " << end << ", delta: " << (int16)delta); + range(start, end, start + delta); + } + } + else + range(start, end, 0); + } + return true; + } + } + } + return false; +} + +bool GetPanoseNumber(Font font, byte *panose) +{ + memset(panose, 0, 10); + String data = font.GetData("OS/2", 32, 10); + if(data.GetCount() != 10) + return false; + memcpy(panose, data, data.GetCount()); + return true; +} + struct sFontMetricsReplacement { Font src; Font dst; Font mdst; }; +int PanoseDistance(byte *a, byte *b) +{ + int distance = 0; + auto pval = [&](int val, int def) { + if(val) return val; + distance += 5; + return def; + }; + if(pval(a[0], 2) != pval(b[0], 2)) return INT_MAX; + + auto Add = [&](int i, int def) { + int q = pval(a[i], def) - pval(b[i], def); + distance += q * q; + }; + Add(1, 6); + Add(2, 6); + Add(3, 4); + return distance; +} + bool Replace(Font fnt, int chr, Font& rfnt) { - static Vector rface; -// static Vector l, h; - ONCELOCK { - for(int i = 0; i < __countof(sFontReplacements) && rface.GetCount() < 20; i++) { + static VectorMap rface[2]; // face index to font info + static bool all_loaded; + if(rface[0].GetCount() == 0) { + for(int i = 0; i < __countof(sFontReplacements); i++) { int q = Font::FindFaceNameIndex(sFontReplacements[i].name); if(q > 0) { - rface.Add(q); -// l.Add(sFontReplacements[i].l); -// h.Add(sFontReplacements[i].h); + rface[0].Add(q) = &sFontReplacements[i]; } } } - Font f = fnt; - for(int i = 0; i < rface.GetCount(); i++) { - if(IsNormal(f.Face(rface[i]), chr)) { - int a = fnt.GetAscent(); - static WString apple_kbd = "⌘⌃⇧⌥"; // do not make these smaller it looks ugly... - if(f.GetAscent() > a && apple_kbd.Find(chr) < 0) { - static sFontMetricsReplacement cache[256]; - int q = CombineHash(fnt, f) & 255; - if(cache[q].src != fnt || cache[q].dst != f) { - cache[q].src = fnt; - cache[q].dst = f; - while(f.GetAscent() > a && f.GetHeight() > 1) { - f.Height(max(1, f.GetHeight() - max(1, f.GetHeight() / 20))); - } - cache[q].mdst = f; - } - else - f = cache[q].mdst; + int face = fnt.GetFace(); + byte *panose; + int q = rface[0].Find(face); // if we have this font in database, we do not need to load panose + if(q >= 0) + panose = rface[0][q]->panose; + else { + int q = rface[1].Find(face); // if we have this font in database, we do not need to load panose + if(q >= 0) + panose = rface[1][q]->panose; + else { + struct Panose : Moveable { + byte panose[10]; + }; + static ArrayMap cache; + int q = cache.Find(face); + if(q < 0) { + q = cache.GetCount(); + Font f2(face, 20); + GetPanoseNumber(f2, cache.Add(face).panose); + } + panose = cache[q].panose; + } + } + + int wi; + dword bit; + + auto ChrBit = [&](int c) { + wi = 0; + c = max(c, 0); + if(c < 2048) + bit = 0x80000000 >> (c >> 6); + else { + int bi = clamp(c - 2048, 0, 7*32*1024 - 1) >> 10; + ASSERT((bi >> 5) + 1 < 8); + wi = (bi >> 5) + 1; + bit = 0x80000000 >> (bi & 31); + } + }; + + for(int pass = 0; pass < 2; pass++) { + Font f = fnt; + Vector distance; + Vector candidate; + ChrBit(chr); + for(int i = 0; i < rface[pass].GetCount(); i++) + if(rface[pass][i]->coverage[wi] & bit) { + distance.Add(PanoseDistance(rface[pass][i]->panose, panose)); + candidate.Add(rface[pass].GetKey(i)); + } + StableIndexSort(distance, candidate); + for(int fi : candidate) { + f.Face(fi); + if(IsNormal_nc(f, chr)) { + int a = fnt.GetAscent(); + static WString apple_kbd = "⌘⌃⇧⌥"; // do not make these smaller it looks ugly... + if(f.GetAscent() > a && apple_kbd.Find(chr) < 0) { + static sFontMetricsReplacement cache[256]; + int q = CombineHash(fnt, f) & 255; + if(cache[q].src != fnt || cache[q].dst != f) { + cache[q].src = fnt; + cache[q].dst = f; + while(f.GetAscent() > a && f.GetHeight() > 1) { + f.Height(max(1, f.GetHeight() - max(1, f.GetHeight() / 20))); + } + cache[q].mdst = f; + } + else + f = cache[q].mdst; + } + rfnt = f; + return true; + } + } + if(!all_loaded) { + all_loaded = true; + for(int i = 1; i < Font::GetFaceCount(); i++) { + dword fi = Font::GetFaceInfo(i); + if(rface[1].Find(i) < 0 && !(fi & Font::SPECIAL) && (fi & Font::SCALEABLE)) { + Font fnt(i, 40); + sRFace fi; + memset(&fi, 0, sizeof(fi)); + bool hascmap = ReadCmap(fnt, [&](int start, int end, int) { + for(int c = start; c <= end; c = (c + 64) & ~63) { + ChrBit(c); + fi.coverage[wi] |= bit; + } + }); + if(hascmap && GetPanoseNumber(fnt, fi.panose)) { + static Array xface; // for those additionally loaded + sRFace& n = xface.Add(); + n = fi; + rface[1].Add(i, &n); + } + } } - rfnt = f; - return true; } } return false; diff --git a/uppsrc/Draw/FontCoco.mm b/uppsrc/Draw/FontCoco.mm index 0490a00fd..94fad406a 100644 --- a/uppsrc/Draw/FontCoco.mm +++ b/uppsrc/Draw/FontCoco.mm @@ -48,9 +48,9 @@ WString ToWString(CFStringRef s) if(!s) return Null; CFIndex l = CFStringGetLength(s); if(!l) return Null; - WStringBuffer b(l); - CFStringGetCharacters(s, CFRangeMake(0, l), (UniChar *)~b); - return b; + Buffer h(l); + CFStringGetCharacters(s, CFRangeMake(0, l), (UniChar *)~h); + return ToUtf32(~h, l); } String ToString(CFStringRef s) @@ -108,10 +108,10 @@ CTFontRef CT_Font(Font fnt, bool& synth) CGGlyph GetCharGlyph(CTFontRef ctfont, int chr) { - CGGlyph glyph_index; - UniChar h = chr; - CTFontGetGlyphsForCharacters(ctfont, &h, &glyph_index, 1); - return glyph_index; + CGGlyph glyph_index[2]; + Vector h = ToUtf16(chr); + CTFontGetGlyphsForCharacters(ctfont, (UniChar *)h.begin(), glyph_index, h.GetCount()); + return glyph_index[0]; } GlyphInfo GetGlyphInfoSys(CTFontRef ctfont, int chr, bool bold_synth, CGRect *bounds = NULL) @@ -270,9 +270,44 @@ Vector GetAllFacesSys() return r; } -String GetFontDataSys(Font font) -{ - return LoadFile(font.Fi().path); +String GetFontDataSys(Font font, const char *table, int offset, int size) +{ // read truetype or opentype table + FileIn in(font.Fi().path); + int q = in.Get32be(); + if(q == 0x74746366) { // font collection + in.Get32(); // skip major/minor version + int nfonts = in.Get32be(); + if(font.Fi().fonti >= nfonts) + return Null; + in.SeekCur(font.Fi().fonti * 4); + int offset = in.Get32be(); + if(offset < 0 || offset >= in.GetSize()) + return Null; + in.Seek(offset); + q = in.Get32be(); + } + if(q != 0x74727565 && q != 0x00010000 && q != 0x4f54544f) // 0x4f54544f means CCF font! + return Null; + int n = in.Get16be(); + in.Get32(); + in.Get16(); + while(n--) { + if(in.IsError() || in.IsEof()) return Null; + String tab = in.Get(4); + in.Get32(); + int off = in.Get32be(); + int len = in.Get32be(); + if(tab == table) { + if(off < 0 || len < 0 || off + len > in.GetSize()) + return Null; + len = min(len - offset, size); + if(len < 0) + return Null; + in.Seek(off + offset); + return in.Get(len); + } + } + return Null; } struct sCGPathTarget { diff --git a/uppsrc/Draw/FontFc.cpp b/uppsrc/Draw/FontFc.cpp index 9e8ecfe6f..b839e4f29 100644 --- a/uppsrc/Draw/FontFc.cpp +++ b/uppsrc/Draw/FontFc.cpp @@ -148,7 +148,8 @@ CommonFontInfo GetFontInfoSys(Font font) fi.avewidth = fi.maxwidth; fi.default_char = '?'; fi.fixedpitch = font.GetFaceInfo() & Font::FIXEDPITCH; - fi.ttf = path.EndsWith(".ttf") || path.EndsWith(".otf"); + fi.ttf = path.EndsWith(".ttf") || path.EndsWith(".otf") || path.EndsWith(".otc") || path.EndsWith(".ttc"); + fi.fonti = face->face_index; if(path.GetCount() < 250) strcpy(fi.path, ~path); else @@ -164,21 +165,6 @@ CommonFontInfo GetFontInfoSys(Font font) GlyphInfo (*GetGlyphInfoSysXft)(Font font, int chr); -#ifdef flagLINUXGL -#include -#include -GlyphInfo GetGlyphInfoSys(Font font, int chr) -{ - static GlyphInfo gi; - const OpenGLFont& fi = resources.GetFont(font); - gi.width = chr < fi.chars.GetCount() - ? int(fi.chars[chr].xadvance * fi.scale + 0.5f) - : 0; - gi.lspc = 0; - gi.rspc = 0; - return gi; -} -#else GlyphInfo GetGlyphInfoSys(Font font, int chr) { LTIMING("GetGlyphInfoSys"); @@ -207,7 +193,6 @@ GlyphInfo GetGlyphInfoSys(Font font, int chr) } return gi; } -#endif Vector GetAllFacesSys() { @@ -218,10 +203,11 @@ Vector GetAllFacesSys() "monospace", }; - Vector list; + VectorMap list; for(int i = 0; i < __countof(basic_fonts); i++) { - FaceInfo& fi = list.Add(); - fi.name = basic_fonts[i]; + String name = (const char *)basic_fonts[i]; + FaceInfo& fi = list.Add(name); + fi.name = name; fi.info = Font::SCALEABLE; if(i == Font::SERIF) fi.info |= Font::SERIFSTYLE; @@ -229,7 +215,7 @@ Vector GetAllFacesSys() fi.info |= Font::FIXEDPITCH; } FcPattern *p = FcPatternCreate(); - FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SPACING, FC_SCALABLE, (void *)0); + FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SPACING, FC_SCALABLE, FC_SYMBOL, FC_COLOR, (void *)0); FcFontSet *fs = FcFontList(NULL, p, os); FcPatternDestroy(p); FcObjectSetDestroy(os); @@ -237,29 +223,68 @@ Vector GetAllFacesSys() FcChar8 *family = NULL; FcPattern *pt = fs->fonts[i]; if(FcPatternGetString(pt, FC_FAMILY, 0, &family) == 0 && family) { - FaceInfo& fi = list.Add(); - fi.name = (const char *)family; - fi.info = 0; + String name = (const char *)family; + FaceInfo& fi = list.GetAdd(name); + fi.name = name; int iv; + FcBool bv; if(FcPatternGetInteger(pt, FC_SPACING, 0, &iv) == 0 && iv == FC_MONO) fi.info |= Font::FIXEDPITCH; - FcBool bv; + if(FcPatternGetBool(pt, FC_SYMBOL, 0, &bv) == 0 && bv) + fi.info |= Font::SPECIAL; + if(FcPatternGetBool(pt, FC_COLOR, 0, &bv) == 0 && bv) + fi.info |= Font::SPECIAL; if(FcPatternGetBool(pt, FC_SCALABLE, 0, &bv) == 0 && bv) fi.info |= Font::SCALEABLE; String h = ToLower(fi.name); - if(h.Find("serif") >= 0 && h.Find("sans") < 0) + if((h.Find("serif") >= 0 || h.Find("roman") >= 0) && h.Find("sans") < 0) fi.info |= Font::SERIFSTYLE; if(h.Find("script") >= 0) fi.info |= Font::SCRIPTSTYLE; } } FcFontSetDestroy(fs); - return list; + return list.PickValues(); } -String GetFontDataSys(Font font) -{ - return LoadFile(font.Fi().path); +String GetFontDataSys(Font font, const char *table, int offset, int size) +{ // read truetype or opentype table + FileIn in(font.Fi().path); + int q = in.Get32be(); + if(q == 0x74746366) { // font collection + in.Get32(); // skip major/minor version + int nfonts = in.Get32be(); + if(font.Fi().fonti >= nfonts) + return Null; + in.SeekCur(font.Fi().fonti * 4); + int offset = in.Get32be(); + if(offset < 0 || offset >= in.GetSize()) + return Null; + in.Seek(offset); + q = in.Get32be(); + } + if(q != 0x74727565 && q != 0x00010000 && q != 0x4f54544f) // 0x4f54544f means CCF font! + return Null; + int n = in.Get16be(); + in.Get32(); + in.Get16(); + while(n--) { + if(in.IsError() || in.IsEof()) return Null; + String tab = in.Get(4); + in.Get32(); + int off = in.Get32be(); + int len = in.Get32be(); + if(tab == table) { + if(off < 0 || len < 0 || off + len > in.GetSize()) + return Null; + len = min(len - offset, size); + if(len < 0) + return Null; + in.Seek(off + offset); + return in.Get(len); + } + } + return Null; } static inline double ft_dbl(int p) diff --git a/uppsrc/Draw/FontInt.h b/uppsrc/Draw/FontInt.h index e76a57bb5..1f1886e93 100644 --- a/uppsrc/Draw/FontInt.h +++ b/uppsrc/Draw/FontInt.h @@ -5,7 +5,7 @@ struct FaceInfo : Moveable { String name; - dword info; + dword info = 0; }; struct CommonFontInfo { @@ -26,7 +26,8 @@ struct CommonFontInfo { bool ttf; int aux; - char path[256]; // optional + char path[256]; // optional (linux only) + int fonti = 0; // font index in .ttc, .otc }; class Font; @@ -35,7 +36,7 @@ struct GlyphInfo { int16 width; int16 lspc; int16 rspc; - word glyphi; // optional, not available in Win32 + word glyphi = 0; // optional, not available in Win32, X11 bool IsNormal() const { return (word)width != 0x8000; } bool IsComposed() const { return !IsNormal() && (lspc == -1 || lspc == -11); } @@ -47,7 +48,7 @@ struct GlyphInfo { void Std(Font& font); GlyphInfo GetGlyphInfo(Font font, int chr); const CommonFontInfo& GetFontInfo(Font font); -bool IsNormal(Font font, int chr); +bool IsNormal_nc(Font font, int chr); void GlyphMetrics(GlyphInfo& f, Font font, int chr); void InvalidateFontList(); @@ -57,7 +58,7 @@ void InvalidateFontList(); CommonFontInfo GetFontInfoSys(Font font); GlyphInfo GetGlyphInfoSys(Font font, int chr); Vector GetAllFacesSys(); -String GetFontDataSys(Font font); +String GetFontDataSys(Font font, const char *table, int offset, int size); void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font fnt); diff --git a/uppsrc/Draw/FontWin32.cpp b/uppsrc/Draw/FontWin32.cpp index e1594cc89..650d202c4 100644 --- a/uppsrc/Draw/FontWin32.cpp +++ b/uppsrc/Draw/FontWin32.cpp @@ -6,6 +6,8 @@ namespace Upp { #ifdef PLATFORM_WIN32 +#include + #define LLOG(x) // LOG(x) #define LTIMING(x) // TIMING(x) @@ -152,7 +154,7 @@ static int CALLBACK Win32_AddFace(const LOGFONTW *logfont, const TEXTMETRICW *, static int Win32_EnumFace(HDC hdc, const char *face) { - return EnumFontFamiliesW(hdc, face ? ~ToSystemCharsetW(face) : NULL, Win32_AddFace, (LPARAM)face); + return EnumFontFamiliesW(hdc, face ? ToSystemCharsetW(face).begin() : NULL, Win32_AddFace, (LPARAM)face); } static void Win32_ForceFace(HDC hdc, const char *face, const char *aface) @@ -183,8 +185,87 @@ Vector GetAllFacesSys() #define GLYPHINFOCACHE 31 +GlyphInfo GetUnicodeGlyphInfo(Font fnt, wchar ch) +{ + struct FontRec { + Font font = Null; + SCRIPT_CACHE sc = NULL; + HDC hdc = NULL; + dword default_glyph = 0; + }; + + static FontRec cache[4]; + static int cachei; + + int ii = -1; + for(int i = 0; i < 4; i++) + if(cache[0].font == fnt) { + ii = i; + break; + } + + if(ii < 0) { + ii = cachei = (cachei + 1) & 3; + FontRec& f = cache[ii]; + f.font = fnt; + if(!f.hdc) + f.hdc = ::CreateIC("DISPLAY", NULL, NULL, NULL); + if(f.sc) { + ScriptFreeCache(&f.sc); + f.sc = 0; + } + HFONT hfont = GetWin32Font(fnt, 0); + if(hfont) + ::SelectObject(f.hdc, hfont); + + SCRIPT_FONTPROPERTIES props; + props.cBytes = sizeof(props); + ScriptGetFontProperties(f.hdc, &f.sc, &props); + f.default_glyph = props.wgDefault; + } + + GlyphInfo gi; + + memset(&gi, 0, sizeof(gi)); + gi.width = (int16)0x8000; + + FontRec& f = cache[ii]; + + char16 buf[2]; + int len = ToUtf16(buf, &ch, 1); + + SCRIPT_ITEM items[2]; + int nitems; + if(FAILED(ScriptItemize(buf, len, 2, 0, 0, items, &nitems))) + return gi; + + WORD glyphs[10]; + WORD cluster[10]; + int nglyphs; + SCRIPT_VISATTR attr[10]; + if(FAILED(ScriptShape(f.hdc, &f.sc, buf, len, 10, &items[0].a, glyphs, cluster, attr, &nglyphs))) + return gi; + + if(nglyphs == 0 || *glyphs == f.default_glyph) + return gi; + + ABC abc; + if(FAILED(ScriptGetGlyphABCWidth(f.hdc, &f.sc, glyphs[0], &abc))) + return gi; + + gi.width = abc.abcA + abc.abcB + abc.abcC; + gi.lspc = abc.abcA; + gi.rspc = abc.abcC; + gi.glyphi = *glyphs; + + return gi; +} + GlyphInfo GetGlyphInfoSys(Font font, int chr) { + if(chr >= 0x10000) + return GetUnicodeGlyphInfo(font, chr); + static Font fnt[GLYPHINFOCACHE]; static int pg[GLYPHINFOCACHE]; static GlyphInfo li[GLYPHINFOCACHE][256]; @@ -203,7 +284,8 @@ GlyphInfo GetGlyphInfoSys(Font font, int chr) HFONT hfont = GetWin32Font(font, 0); if(!hfont) { GlyphInfo n; - memset8(&n, 0, sizeof(GlyphInfo)); + memset(&n, 0, sizeof(GlyphInfo)); + n.width = (int16)0x8000; return n; } HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL); @@ -255,20 +337,22 @@ GlyphInfo GetGlyphInfoSys(Font font, int chr) return li[q][chr & 255]; } -String GetFontDataSys(Font font) +String GetFontDataSys(Font font, const char *table, int offset, int size) { String r; HFONT hfont = GetWin32Font(font, 0); if(hfont) { HDC hdc = CreateIC("DISPLAY", NULL, NULL, NULL); HFONT ohfont = (HFONT) ::SelectObject(hdc, hfont); - DWORD size = GetFontData(hdc, 0, 0, NULL, 0); - if(size == GDI_ERROR) { + int tbl = table ? ((byte)table[0] << 0) | ((byte)table[1] << 8) | ((byte)table[2] << 16) | ((byte)table[3] << 24) : 0; + DWORD sz = GetFontData(hdc, tbl, offset, NULL, 0); + if(sz == GDI_ERROR) { LLOG("PdfDraw::Finish: GDI_ERROR on font " << pdffont.GetKey(i)); } else { + size = min(size, (int)sz); StringBuffer b(size); - GetFontData(hdc, 0, 0, b, size); + GetFontData(hdc, tbl, offset, ~b, size); r = b; } ::SelectObject(hdc, ohfont); @@ -327,10 +411,20 @@ void RenderCharacterSys(FontGlyphConsumer& sw, double x, double y, int ch, Font memset8(&m_matrix, 0, sizeof(m_matrix)); m_matrix.eM11.value = 1; m_matrix.eM22.value = 1; - int gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE|GGO_UNHINTED, &gm, 0, NULL, &m_matrix); + dword flags = GGO_NATIVE|GGO_UNHINTED; + if(ch >= 0x10000) { + GlyphInfo f = GetGlyphInfo(fnt, ch); + if(f.IsNormal()) { + flags |= GGO_GLYPH_INDEX; + ch = f.glyphi; + } + else + ch = 0x25a1; + } + int gsz = GetGlyphOutlineW(hdc, ch, flags, &gm, 0, NULL, &m_matrix); if(gsz >= 0) { StringBuffer gb(gsz); - gsz = GetGlyphOutlineW(hdc, ch, GGO_NATIVE|GGO_UNHINTED, &gm, gsz, ~gb, &m_matrix); + gsz = GetGlyphOutlineW(hdc, ch, flags, &gm, gsz, ~gb, &m_matrix); if(gsz >= 0) RenderCharPath(~gb, gsz, sw, x, y + fnt.GetAscent()); } diff --git a/uppsrc/Draw/Fonts.i b/uppsrc/Draw/Fonts.i new file mode 100644 index 000000000..ccbb43751 --- /dev/null +++ b/uppsrc/Draw/Fonts.i @@ -0,0 +1,388 @@ +// Predefined replacement fonts; if codepoint is not found in these, remaining fonts cmaps from host are loaded + +#if defined(PLATFORM_POSIX) && !defined(PLATFORM_COCOA) +{ "Abyssinica SIL", { 2,0,0,0,0,0,0,0,0,0 }, { 0xfe1d0000,0x23400000,0x0080010c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Andale Mono", { 2,11,5,9,0,0,0,0,0,4 }, { 0xff17e000,0x07000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "AnjaliOldLipi", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000264,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Chandas", { 2,0,0,0,0,0,0,0,0,0 }, { 0xe0000000,0x82000000,0x00000034,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Chilanka", { 2,0,5,3,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "DejaVu Sans", { 2,11,6,3,3,8,4,2,2,4 }, { 0xfffffff1,0x77c04000,0x0100007e,0x00000000,0x00003070,0x00000000,0x00000000,0x00000000 } }, +{ "DejaVu Sans Mono", { 2,11,6,9,3,8,4,2,2,4 }, { 0xfffffef0,0x67c00000,0x0100001c,0x00000000,0x00001000,0x00000000,0x00000000,0x00000000 } }, +{ "DejaVu Serif", { 2,6,6,3,5,6,5,2,2,4 }, { 0xfffffe00,0x67c00000,0x0100001c,0x00000000,0x00001000,0x00000000,0x00000000,0x00000000 } }, +{ "Droid Sans Fallback", { 2,11,5,2,0,0,0,0,0,1 }, { 0x80000000,0x623fffff,0xfc40100d,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Dyuthi", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000264,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "FreeMono", { 2,15,4,9,2,2,5,2,4,4 }, { 0xfffffff0,0x37c00000,0x0180000e,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "FreeSans", { 2,11,5,4,2,2,2,2,2,4 }, { 0xffffff0c,0xffc00000,0x0100000f,0x80000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "FreeSerif", { 2,2,6,3,5,4,5,2,3,4 }, { 0xfffffff6,0xffc00000,0x0180000e,0x00000000,0x00003020,0x00000000,0x00000000,0x00000000 } }, +{ "Gargi", { 2,0,5,6,0,0,0,0,0,0 }, { 0xc0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Garuda", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfeba0000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gayathri", { 0,0,5,3,0,0,0,0,0,0 }, { 0xfd000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gubbi", { 0,0,4,0,0,0,0,0,0,0 }, { 0x80000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Impact", { 2,11,8,6,3,9,2,5,2,4 }, { 0xff17e000,0x07000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Jamrul", { 2,0,6,3,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstArt", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstBook", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstDecorative", { 2,0,0,0,0,0,0,0,0,0 }, { 0xc00000f0,0x00000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstDigital", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstFarsi", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstLetter", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstNaskh", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstOffice", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstOne", { 2,0,5,3,0,0,0,0,0,0 }, { 0xf00000f0,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstPen", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstPoster", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstQurn", { 0,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstScreen", { 0,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstTitle", { 2,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KacstTitleL", { 0,0,0,0,0,0,0,0,0,0 }, { 0x800000d0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kalapi", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf0080000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kalimati", { 0,0,4,0,0,0,0,0,0,0 }, { 0xc0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Karumbi", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000264,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Keraleeyam", { 2,11,8,3,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000264,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Khmer OS", { 2,0,5,0,0,0,0,2,0,4 }, { 0xfe1b0000,0x1f000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Khmer OS System", { 2,0,5,0,0,0,0,2,0,4 }, { 0xfe1b0000,0x1f000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kinnari", { 0,0,0,0,0,0,0,0,0,0 }, { 0xfeb80000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Laksaman", { 2,11,5,0,4,2,0,2,0,3 }, { 0xfe380000,0x47000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Liberation Mono", { 2,7,4,9,2,2,5,2,4,4 }, { 0xfffffb00,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Liberation Mono", { 2,7,4,9,2,2,5,2,4,4 }, { 0xfffffb00,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Liberation Sans", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfffffb00,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Liberation Sans Narrow", { 2,11,6,6,2,2,2,3,2,4 }, { 0xff97e000,0x07000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Liberation Serif", { 2,2,6,3,5,4,5,2,3,4 }, { 0xfffffb00,0x07400000,0x0100002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Likhan", { 2,0,6,3,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Assamese", { 2,11,6,0,0,0,0,0,0,0 }, { 0xf0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Bengali", { 2,11,6,0,0,0,0,0,0,0 }, { 0xf0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Devanagari", { 2,11,6,0,0,0,0,0,0,0 }, { 0xfeb90000,0x87000000,0x0080000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Gujarati", { 2,11,6,0,0,0,0,0,0,0 }, { 0xd0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Gurmukhi", { 2,11,6,0,0,0,0,0,0,0 }, { 0xd0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Kannada", { 2,11,6,0,0,0,0,0,0,0 }, { 0xf0000000,0xc3000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Malayalam", { 2,11,6,0,0,0,0,0,0,0 }, { 0x80000000,0xc3000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Odia", { 2,11,6,0,0,0,0,0,0,0 }, { 0x80000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Tamil", { 2,11,6,0,0,0,0,0,0,0 }, { 0xf0280000,0x83000000,0x00000024,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Tamil Classical", { 2,11,6,0,0,0,0,0,0,0 }, { 0xf0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lohit Telugu", { 2,11,6,0,0,0,0,0,0,0 }, { 0xfeb00000,0xc3000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Loma", { 2,11,5,4,2,2,2,2,2,4 }, { 0xfcb80000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Manjari", { 2,0,5,3,0,0,0,0,0,0 }, { 0xfd100000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Manjari", { 2,0,5,3,0,0,0,0,0,0 }, { 0xfd100000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Meera", { 2,11,6,3,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000264,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mitra Mono", { 0,11,0,9,0,0,0,0,0,0 }, { 0xf0000000,0x81000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mukti Narrow", { 0,0,0,0,0,0,0,0,0,0 }, { 0xf0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mukti Narrow", { 0,0,0,0,0,0,0,0,0,0 }, { 0xf0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Nakula", { 0,0,4,0,0,0,0,0,0,0 }, { 0xff13e000,0x87000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Navilu", { 0,0,4,0,0,0,0,0,0,0 }, { 0x80000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Norasi", { 2,7,5,6,6,0,0,2,0,4 }, { 0xfeb80000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Mono", { 2,11,6,9,3,8,4,2,2,4 }, { 0xffbbf800,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans CJK HK", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans CJK JP", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans CJK KR", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans CJK SC", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans CJK TC", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans Mono CJK HK", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans Mono CJK JP", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans Mono CJK KR", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans Mono CJK SC", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Sans Mono CJK TC", { 2,11,5,0,0,0,0,0,0,0 }, { 0xff7bc000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Serif CJK JP", { 2,2,4,0,0,0,0,0,0,0 }, { 0xff53c000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Serif CJK KR", { 2,2,4,0,0,0,0,0,0,0 }, { 0xff53c000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Serif CJK SC", { 2,2,4,0,0,0,0,0,0,0 }, { 0xff53c000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Noto Serif CJK TC", { 2,2,4,0,0,0,0,0,0,0 }, { 0xff53c000,0x27ffffff,0xfcfff00c,0x00000000,0x00000023,0xffffffff,0xffffd308,0x00000000 } }, +{ "Padauk", { 2,0,4,0,2,0,0,2,0,4 }, { 0xfe150000,0x33000000,0x0080000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Padauk Book", { 2,0,4,0,2,0,0,2,0,4 }, { 0xfe150000,0x33000000,0x0080000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Pagul", { 2,0,5,0,0,0,0,0,0,0 }, { 0xf8140000,0x02000000,0x00800004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Phetsarath OT", { 2,0,5,0,0,0,0,0,0,1 }, { 0xfe100000,0x42000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Pothana2000", { 0,0,4,0,0,0,0,0,0,0 }, { 0xd0000000,0x42000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Purisa", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfcb80000,0x43000000,0x0000003c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Rachana", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "RaghuMalayalamSans", { 2,11,4,0,0,0,0,0,0,0 }, { 0xc0000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Rasa", { 2,13,0,0,0,4,0,0,0,0 }, { 0xfffb0000,0xc7000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Rekha", { 2,0,6,0,4,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Saab", { 2,0,5,0,0,0,0,2,0,4 }, { 0xf0100000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sahadeva", { 0,0,4,0,0,0,0,0,0,0 }, { 0xff13e000,0x87000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Samanata", { 0,0,4,0,0,0,0,0,0,0 }, { 0xd0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Samyak Devanagari", { 2,0,6,3,0,0,0,0,0,0 }, { 0x80000000,0x81000000,0x00000080,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001 } }, +{ "Samyak Gujarati", { 2,0,6,3,0,0,0,0,0,0 }, { 0x80000000,0x80000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Samyak Malayalam", { 0,0,4,0,0,0,0,0,0,0 }, { 0x80000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Samyak Tamil", { 2,0,6,3,0,0,0,0,0,0 }, { 0x84000000,0x80000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sarai", { 0,0,4,0,0,0,0,0,0,0 }, { 0xd0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sawasdee", { 2,0,5,3,0,0,0,0,0,0 }, { 0xfeb80000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Suruma", { 2,0,6,3,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Symbola", { 2,2,5,3,6,8,5,2,2,4 }, { 0xfffff810,0x0fe04000,0x0180000e,0x00000000,0x00003038,0x00000000,0x00000000,0x00000001 } }, +{ "Tibetan Machine Uni", { 1,0,5,3,2,0,0,2,0,2 }, { 0xffbd0000,0x47203000,0x0000007c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000001 } }, +{ "Tlwg Mono", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfcb80000,0x43000000,0x00000014,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Tlwg Typewriter", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfcb80000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Tlwg Typist", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfcb80000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Tlwg Typo", { 2,0,6,3,0,0,0,0,0,0 }, { 0xfcb80000,0x43000000,0x00000014,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ubuntu", { 2,11,5,4,3,6,2,3,2,4 }, { 0xfffbf000,0x07000000,0x0000027c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ubuntu", { 2,11,5,4,3,6,2,3,2,4 }, { 0xfffbf000,0x07000000,0x0000027c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ubuntu", { 2,11,5,4,3,6,2,3,2,4 }, { 0xfffbf000,0x07000000,0x0000027c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ubuntu Condensed", { 2,11,5,6,3,6,2,3,2,4 }, { 0xfffbf000,0x07000000,0x0000027c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ubuntu Mono", { 2,11,5,9,3,6,2,3,2,4 }, { 0xfffbf000,0x07000000,0x0000027c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Uroob", { 0,0,8,0,0,0,0,0,0,0 }, { 0xfc100000,0x43000000,0x00000264,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Vemana2000", { 0,0,4,0,0,0,0,0,0,0 }, { 0xd0000000,0x42000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Verdana", { 2,11,6,4,3,5,4,4,2,4 }, { 0xff1fe000,0x07000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Waree", { 2,11,5,4,2,2,2,2,2,4 }, { 0xfebb0000,0x43000000,0x0000005c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Yrsa", { 2,13,0,0,0,4,0,0,0,0 }, { 0xfffb0000,0x07000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "mry_KacstQurn", { 2,6,6,3,5,6,5,2,2,4 }, { 0x800000f0,0x00000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "padmaa", { 2,0,8,0,4,0,0,0,0,0 }, { 0xf6100000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "padmaa-Bold.1.1", { 2,0,8,0,4,0,0,0,0,0 }, { 0xf6100000,0x82000000,0x00000084,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +#endif + +#ifdef PLATFORM_WIN32 +{ "Alef", { 0,0,5,0,0,0,0,0,0,0 }, { 0xfc900300,0x06000000,0x0000020c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Amiri", { 0,0,5,0,0,0,0,0,0,0 }, { 0xfdb800f4,0x87000000,0x0000000c,0x00000000,0x00000040,0x00000000,0x00000000,0x00000000 } }, +{ "Amiri Quran", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe00800f0,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arabic Transparent", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfffffff4,0x87400000,0x0180002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfffffff4,0x87400000,0x0180002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial Black", { 2,11,10,4,2,1,2,2,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Caladea", { 2,0,5,6,0,0,0,2,0,0 }, { 0xff900000,0x06000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Carlito", { 2,15,5,2,2,2,4,3,2,4 }, { 0xfffff800,0x47400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Consolas", { 2,11,6,9,2,2,4,3,2,4 }, { 0xfffffe00,0x47400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Constantia", { 2,3,6,2,5,3,6,3,3,3 }, { 0xff9fe000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Corbel", { 2,11,5,3,2,2,4,2,2,4 }, { 0xffffea80,0xd7000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Corbel Light", { 2,11,3,3,2,2,4,2,2,4 }, { 0xffffea80,0xd7000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Courier New", { 2,7,3,9,2,2,5,2,4,4 }, { 0xfffffff4,0xc7400000,0x0100002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "David CLM", { 2,0,6,3,0,0,0,0,0,0 }, { 0xe0000300,0x03000000,0x0000008c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "David Libre", { 0,0,5,0,0,0,0,0,0,0 }, { 0xffff0300,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ebrima", { 2,0,0,0,0,0,0,0,0,0 }, { 0xffff00c1,0x27400000,0x0180000d,0x00000000,0x00000080,0x00000000,0x00000000,0x00000000 } }, +{ "Frank Ruehl CLM", { 2,0,6,3,0,0,0,0,0,0 }, { 0xe0000300,0x03000000,0x0000008c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Frank Ruhl Hofshi", { 0,0,5,0,0,0,0,0,0,0 }, { 0xfe990300,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Franklin Gothic Medium", { 2,11,6,3,2,1,2,2,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gadugi", { 2,11,5,2,4,2,4,2,2,3 }, { 0xff5c0000,0x3b000000,0x00800009,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gentium Basic", { 2,0,5,3,6,0,0,2,0,4 }, { 0xffff0000,0x07400000,0x0100002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gentium Book Basic", { 2,0,5,3,6,0,0,2,0,4 }, { 0xffff0000,0x07400000,0x0100002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "HoloLens MDL2 Assets", { 5,10,1,2,1,1,1,1,1,1 }, { 0x80000000,0x00000000,0x000001e4,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ink Free", { 3,8,4,2,0,5,0,0,0,0 }, { 0xff900000,0x02000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Javanese Text", { 2,0,0,0,0,0,0,0,0,0 }, { 0xf6140000,0x03000000,0x00800004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Leelawadee UI", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe190000,0x5f000000,0x0080000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Leelawadee UI Semilight", { 2,11,4,2,4,2,4,2,2,3 }, { 0xfe190000,0x5f000000,0x0080000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lucida Console", { 2,11,6,9,4,5,4,2,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lucida Sans Unicode", { 2,11,6,2,3,5,4,2,2,4 }, { 0xfffff300,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "MS Gothic", { 2,11,6,9,7,2,5,8,2,4 }, { 0xff7ff000,0xd7bfffff,0xfc00000c,0x00000000,0x00000023,0xffffffff,0xff000000,0x00000000 } }, +{ "MS PGothic", { 2,11,6,0,7,2,5,8,2,4 }, { 0xff7ff000,0xd7bfffff,0xfc00000c,0x00000000,0x00000023,0xffffffff,0xff000000,0x00000000 } }, +{ "MS UI Gothic", { 2,11,6,0,7,2,5,8,2,4 }, { 0xff7ff000,0xd7bfffff,0xfc00000c,0x00000000,0x00000023,0xffffffff,0xff000000,0x00000000 } }, +{ "MV Boli", { 2,0,5,0,3,2,0,9,0,0 }, { 0xfe120082,0x03000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Malgun Gothic", { 2,11,5,3,2,0,0,2,0,4 }, { 0xfe13c000,0x233fffff,0xfcfff00c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Malgun Gothic Semilight", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe13c000,0x23200000,0x007ff004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft Himalaya", { 1,1,1,0,1,1,1,1,1,1 }, { 0xf6120000,0x43200000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft JhengHei", { 2,11,6,4,3,5,4,4,2,4 }, { 0xfe1f0000,0x037fffff,0xfc00000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft JhengHei Light", { 2,11,3,4,3,5,4,4,2,4 }, { 0xfe1fc000,0x037fffff,0xfc00000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft JhengHei UI", { 2,11,6,4,3,5,4,4,2,4 }, { 0xfe1f0000,0x037fffff,0xfc00000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft JhengHei UI Light", { 2,11,3,4,3,5,4,4,2,4 }, { 0xfe1fc000,0x037fffff,0xfc00000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft New Tai Lue", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe100000,0x0b200000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft PhagsPa", { 2,11,5,2,4,2,4,2,2,3 }, { 0xffd80000,0x0f202000,0x00800004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft Sans Serif", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfffffff6,0xf7400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft Tai Le", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe180000,0x2b200000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft YaHei", { 2,11,5,3,2,2,4,2,2,4 }, { 0xffd7e000,0x077fffff,0xfc00000c,0x00000000,0x00000003,0x701497c5,0xc5ffc000,0x00000000 } }, +{ "Microsoft YaHei Light", { 2,11,5,2,4,2,4,2,2,3 }, { 0xffd7e000,0x077fffff,0xfc00000c,0x00000000,0x00000003,0x701497c5,0xc5ffc000,0x00000000 } }, +{ "Microsoft YaHei UI", { 2,11,5,3,2,2,4,2,2,4 }, { 0xffd7e000,0x077fffff,0xfc00000c,0x00000000,0x00000003,0x701497c5,0xc5ffc000,0x00000000 } }, +{ "Microsoft YaHei UI Light", { 2,11,5,2,4,2,4,2,2,3 }, { 0xffd7e000,0x077fffff,0xfc00000c,0x00000000,0x00000003,0x701497c5,0xc5ffc000,0x00000000 } }, +{ "Microsoft Yi Baiti", { 3,0,5,0,0,0,0,0,0,0 }, { 0xf6100000,0x03200000,0x03000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "MingLiU-ExtB", { 2,2,5,0,0,0,0,0,0,0 }, { 0xf6100000,0x02000000,0x00000000,0x00000000,0x00000003,0xffffffff,0xfff80008,0x00000000 } }, +{ "MingLiU_HKSCS-ExtB", { 2,2,5,0,0,0,0,0,0,0 }, { 0xf6100000,0x02000000,0x00000000,0x00000000,0x00000003,0xffffffff,0xfff80008,0x00000000 } }, +{ "Miriam CLM", { 2,0,6,3,0,0,0,0,0,0 }, { 0xe0000300,0x03000000,0x0000008c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Miriam Libre", { 0,0,5,0,0,0,0,0,0,0 }, { 0xfe990300,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Miriam Mono CLM", { 2,0,5,3,0,0,0,0,0,0 }, { 0xe0000300,0x03000000,0x0000008c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mongolian Baiti", { 3,0,5,0,0,0,0,0,0,0 }, { 0xf61a0000,0x0b200000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Myanmar Text", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe140000,0x23000000,0x00800004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "NSimSun", { 2,1,6,9,3,1,1,1,1,1 }, { 0xff53c000,0x037fffff,0xfc00018c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Nachlieli CLM", { 2,0,6,3,0,0,0,0,0,0 }, { 0xe0000300,0x03000000,0x0000008c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Kufi Arabic", { 2,11,5,6,3,8,4,2,2,4 }, { 0xa00000f4,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Mono", { 2,11,6,9,3,8,4,2,2,4 }, { 0xffbbf800,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Naskh Arabic", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa00000f4,0x83400000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Naskh Arabic UI", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa00000f4,0x83400000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans", { 2,11,5,2,4,5,4,2,2,4 }, { 0xfffff800,0x0e400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Arabic", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa00400f4,0x83400000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Arabic UI", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa00400f4,0x83400000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Armenian", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa0000e00,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Cond", { 2,11,5,6,4,5,4,2,2,4 }, { 0xfffff800,0x0e400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Georgian", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa0080200,0x22400000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Hebrew", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa0000300,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Lao", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa0000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Light", { 2,11,4,2,4,5,4,2,2,4 }, { 0xfffff800,0x0e400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Lisu", { 2,11,5,2,4,5,4,2,2,4 }, { 0xa0300000,0x02200000,0x01000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif", { 2,2,5,2,6,5,5,2,2,4 }, { 0xfffff800,0x0e400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif Armenian", { 2,2,5,2,6,5,5,2,2,4 }, { 0xa0000e00,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif Cond", { 2,2,5,6,6,5,5,2,2,4 }, { 0xfffff800,0x0e400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif Georgian", { 2,2,5,2,6,5,5,2,2,4 }, { 0xa0080200,0x22400000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif Hebrew", { 2,2,5,2,6,5,5,2,2,4 }, { 0xa0000300,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif Lao", { 2,2,5,2,6,5,5,2,2,4 }, { 0xa0000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif Light", { 2,2,4,2,6,5,5,2,2,4 }, { 0xfffff800,0x0e400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "OpenSymbol", { 5,1,0,0,0,0,0,0,0,0 }, { 0xf61b0000,0x03a00000,0x0000030c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PMingLiU-ExtB", { 2,2,5,0,0,0,0,0,0,0 }, { 0xf6100000,0x02000000,0x00000000,0x00000000,0x00000003,0xffffffff,0xfff80008,0x00000000 } }, +{ "Segoe Print", { 2,0,6,0,0,0,0,0,0,0 }, { 0xffd7e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe Script", { 3,11,5,4,2,0,0,0,0,3 }, { 0xff9be000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfffffff5,0xff400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI Black", { 2,11,10,2,4,2,4,2,2,3 }, { 0xfffff800,0x47400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI Emoji", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe100000,0x03a00000,0x0000020c,0x00000000,0x00000038,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI Historic", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe1f00cc,0x13400000,0x00000007,0xe3300000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI Light", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfffffff5,0xff400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI Semibold", { 2,11,7,2,4,2,4,2,2,3 }, { 0xfffffff5,0xff400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI Semilight", { 2,11,4,2,4,2,4,2,2,3 }, { 0xfffffff5,0xff400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Segoe UI Symbol", { 2,11,5,2,4,2,4,2,2,3 }, { 0xfe1f0000,0x03e04000,0x00000225,0x00000000,0x00003038,0x00000000,0x00000000,0x00000000 } }, +{ "SimSun", { 2,1,6,0,3,1,1,1,1,1 }, { 0xff53c000,0x037fffff,0xfc00018c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "SimSun-ExtB", { 2,1,6,9,6,1,1,1,1,1 }, { 0xc0000000,0x00000000,0x00000000,0x00000000,0x00000003,0xffffffff,0xffffc000,0x00000000 } }, +{ "Sylfaen", { 1,10,5,2,5,3,6,3,3,3 }, { 0xff9fee00,0x27400000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Tahoma", { 2,11,6,4,3,5,4,4,2,4 }, { 0xfffffff6,0xd7400000,0x0180000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Times New Roman", { 2,2,6,3,5,4,5,2,3,4 }, { 0xfffffff4,0x87400000,0x0180002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Yu Gothic", { 2,11,4,0,0,0,0,0,0,0 }, { 0xffffc000,0xd7ffffff,0xfc00000c,0x00000000,0x00200023,0xffffffff,0xff981308,0x00000000 } }, +{ "Yu Gothic Light", { 2,11,3,0,0,0,0,0,0,0 }, { 0xffffc000,0xd7ffffff,0xfc00000c,0x00000000,0x00200023,0xffffffff,0xff981308,0x00000000 } }, +{ "Yu Gothic Medium", { 2,11,5,0,0,0,0,0,0,0 }, { 0xffffc000,0xd7ffffff,0xfc00000c,0x00000000,0x00200023,0xffffffff,0xff981308,0x00000000 } }, +{ "Yu Gothic UI", { 2,11,5,0,0,0,0,0,0,0 }, { 0xffffe000,0xd7ffffff,0xfc00000c,0x00000000,0x00200023,0xffffffff,0xff981308,0x00000000 } }, +{ "Yu Gothic UI Light", { 2,11,3,0,0,0,0,0,0,0 }, { 0xffffe000,0xd7ffffff,0xfc00000c,0x00000000,0x00200023,0xffffffff,0xff981308,0x00000000 } }, +{ "Yu Gothic UI Semibold", { 2,11,7,0,0,0,0,0,0,0 }, { 0xffffe000,0xd7ffffff,0xfc00000c,0x00000000,0x00200023,0xffffffff,0xff981308,0x00000000 } }, +{ "Yu Gothic UI Semilight", { 2,11,4,0,0,0,0,0,0,0 }, { 0xffffe000,0xd7ffffff,0xfc00000c,0x00000000,0x00200023,0xffffffff,0xff981308,0x00000000 } }, +#endif + +#ifdef PLATFORM_COCOA +{ "Al Bayan", { 0,0,0,0,0,0,0,0,0,0 }, { 0xf00000f0,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Al Nile", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Al Tarikh", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Andale Mono", { 2,11,5,9,0,0,0,0,0,4 }, { 0xff17e000,0x07000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Apple Chancery", { 3,2,7,2,4,5,6,6,5,4 }, { 0xff9b0000,0x03000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Apple Color Emoji", { 0,0,0,0,0,0,0,0,0,0 }, { 0xa0000000,0x03a00000,0x00000004,0x00000000,0x00000038,0x00000000,0x00000000,0x00000001 } }, +{ "Apple SD Gothic Neo", { 2,0,3,0,0,0,0,0,0,0 }, { 0xfdbfd000,0x27e07fff,0xfc7ff00c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Apple Symbols", { 2,0,0,0,0,0,0,0,0,0 }, { 0xf23f0000,0x17e04000,0x01000007,0x00000000,0x00003030,0x00000000,0x00000000,0x00000000 } }, +{ "Arial", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfffffbf4,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial Black", { 2,11,10,4,2,1,2,2,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial Hebrew", { 0,0,0,0,0,0,0,0,0,0 }, { 0xe0040300,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial Hebrew Scholar", { 0,0,0,0,0,0,0,0,0,0 }, { 0xe0040300,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial Narrow", { 2,11,6,6,2,2,2,3,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial Rounded MT Bold", { 2,15,7,4,3,5,4,3,2,4 }, { 0xfe110000,0x03000000,0x00000024,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Arial Unicode MS", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfffffff0,0xe7207fff,0xfc7ff0bc,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Avenir", { 2,0,5,3,2,0,0,2,0,3 }, { 0xfe930000,0x03000000,0x0000020c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Avenir Next", { 2,11,8,3,2,2,2,2,2,4 }, { 0xffbff000,0x07000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Avenir Next Condensed", { 2,11,8,6,2,2,2,2,2,4 }, { 0xfe970000,0x03000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Ayuthaya", { 0,0,4,0,0,0,0,0,0,0 }, { 0xffdff000,0x47000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Baghdad", { 1,0,5,0,0,0,0,2,0,4 }, { 0xf00000f0,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Bangla MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Bangla Sangam MN", { 2,0,0,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Baskerville", { 2,2,5,2,7,4,1,2,3,3 }, { 0xfffff000,0x07400000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Beirut", { 0,0,6,0,0,0,0,0,0,0 }, { 0xf00000f0,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Big Caslon", { 2,0,6,3,9,0,0,2,0,3 }, { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Bodoni 72", { 0,0,4,0,0,0,0,0,0,0 }, { 0xffff1000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Bodoni 72 Oldstyle", { 0,0,4,0,0,0,0,0,0,0 }, { 0xfe130000,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Bodoni 72 Smallcaps", { 0,0,4,0,0,0,0,0,0,0 }, { 0xfe130000,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Bodoni Ornaments", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf0030000,0x02000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Bradley Hand", { 0,0,7,0,0,0,0,0,0,0 }, { 0xfffff800,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Brush Script MT", { 3,6,8,2,4,4,6,7,3,4 }, { 0xfffff000,0x07000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Chalkboard", { 3,5,6,2,4,2,2,2,2,5 }, { 0xff9f1000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Chalkboard SE", { 3,5,6,2,4,2,2,2,2,5 }, { 0xfffff000,0x27200000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Chalkduster", { 3,5,6,2,4,2,2,2,2,5 }, { 0xffbf1000,0x27200000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Charter", { 2,4,5,3,5,5,6,2,2,3 }, { 0xfffff800,0x07400000,0x0100003c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Comic Sans MS", { 3,15,7,2,3,3,2,2,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Copperplate", { 2,0,5,4,0,0,0,2,0,4 }, { 0xffbff800,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Corsiva Hebrew", { 0,0,0,0,0,0,0,0,0,0 }, { 0xe0040300,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Courier New", { 2,7,3,9,2,2,5,2,4,4 }, { 0xfffffbf4,0x07400000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Damascus", { 0,0,4,0,0,0,0,0,0,0 }, { 0xa00000f4,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "DecoType Naskh", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Devanagari MT", { 2,0,5,0,2,0,0,0,0,0 }, { 0xd0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Devanagari Sangam MN", { 2,0,0,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Didot", { 2,0,5,3,0,0,0,2,0,3 }, { 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Diwan Kufi", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Diwan Thuluth", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000c0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Farah", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Farisi", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000c0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Futura", { 2,11,6,2,2,2,4,2,3,3 }, { 0xfebb0000,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Galvji", { 2,11,5,4,2,2,2,2,2,4 }, { 0xfe1f0000,0x27000000,0x0080000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Geeza Pro", { 2,0,4,0,0,0,0,0,0,0 }, { 0xa00000f4,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Georgia", { 2,4,5,2,5,4,5,2,3,3 }, { 0xfffff000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gill Sans", { 2,11,5,2,2,1,4,2,2,3 }, { 0xfe18f000,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Grantha Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xfe9f0000,0x87000000,0x00000008,0x24000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gujarati MT", { 0,0,5,0,7,0,0,0,0,0 }, { 0xf0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gujarati Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gurmukhi MN", { 2,2,6,0,5,4,5,2,3,4 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gurmukhi MT", { 0,0,0,0,0,0,0,0,0,0 }, { 0xd0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Gurmukhi Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Helvetica", { 0,0,0,0,0,0,0,0,0,0 }, { 0xfffff800,0x67400000,0x0100001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Hiragino Maru Gothic ProN", { 2,15,4,0,0,0,0,0,0,0 }, { 0xff7fc000,0x07ffffff,0xfc00000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Hiragino Mincho ProN", { 2,2,3,0,0,0,0,0,0,0 }, { 0xffffc000,0x47ffffff,0xfd80000c,0x00000000,0x00000023,0xffffffff,0xff981308,0x00000000 } }, +{ "Hiragino Sans", { 2,11,3,0,0,0,0,0,0,0 }, { 0xffffc000,0x47ffffff,0xfd80000c,0x00000000,0x00000023,0xffffffff,0xff981308,0x00000000 } }, +{ "Hiragino Sans GB", { 2,11,3,0,0,0,0,0,0,0 }, { 0xfd53c000,0x077fffff,0xfc00018c,0x00000000,0x00000003,0x90820000,0x00000000,0x00000000 } }, +{ "Hoefler Text", { 2,3,6,2,5,5,6,2,2,3 }, { 0xffdbf000,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "ITF Devanagari", { 2,0,0,0,0,0,0,0,0,0 }, { 0xf0200000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "ITF Devanagari Marathi", { 2,0,0,0,0,0,0,0,0,0 }, { 0xf0200000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Impact", { 2,11,8,6,3,9,2,5,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "InaiMathi", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0340000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kailasa", { 2,0,5,0,0,0,0,2,0,4 }, { 0xa0000000,0x40000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kannada MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kannada Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kefa", { 2,0,5,6,0,0,0,2,0,4 }, { 0xfe130000,0x23400000,0x0080000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Khmer MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x1b000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Khmer Sangam MN", { 2,0,4,0,0,0,0,0,0,0 }, { 0xe0000000,0x1b000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kohinoor Bangla", { 2,0,0,0,0,0,0,0,0,0 }, { 0xfeb10000,0x87000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kohinoor Devanagari", { 2,0,0,0,0,0,0,0,0,0 }, { 0xfeb10000,0x87000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kohinoor Gujarati", { 0,0,8,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kohinoor Telugu", { 2,0,0,0,0,0,0,0,0,0 }, { 0xfe910000,0xc7000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Kokonor", { 1,0,5,0,0,0,0,2,0,3 }, { 0x80000000,0x43000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Krungthep", { 2,0,4,0,0,0,0,0,0,0 }, { 0xffdf1000,0x47000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "KufiStandardGK", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lao MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lao Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Lucida Grande", { 2,11,6,0,4,5,2,2,2,4 }, { 0xfffffb00,0x07800000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Luminari", { 2,0,5,5,0,0,0,2,0,4 }, { 0xffbff000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Malayalam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Malayalam Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Marker Felt", { 2,0,4,0,0,0,0,0,0,0 }, { 0xfffbf000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Menlo", { 2,11,6,9,3,8,4,2,2,4 }, { 0xfffff800,0x27c00000,0x0100001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Microsoft Sans Serif", { 2,11,6,4,2,2,2,2,2,4 }, { 0xfffffbf4,0x47400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mishafi", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000c0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mishafi Gold", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x00000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mshtakan", { 2,0,4,0,0,0,0,0,0,0 }, { 0xf2000e00,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Mukta Mahee", { 2,11,0,0,0,0,0,0,0,0 }, { 0xff910000,0x87000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Muna", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Myanmar MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x23000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Myanmar Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x23000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Nadeem", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "New Peninim MT", { 0,0,0,0,0,0,0,0,0,0 }, { 0xe0040300,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noteworthy", { 2,0,4,0,0,0,0,0,0,0 }, { 0xfffff000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Nastaliq Urdu", { 2,11,5,2,4,5,4,2,2,4 }, { 0xf00000f4,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Kannada", { 2,11,10,2,4,5,4,2,2,4 }, { 0xf0000000,0xc7000000,0x00800004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Myanmar", { 2,11,10,2,4,5,4,2,2,4 }, { 0xa0000000,0x23000000,0x00800004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Sans Oriya", { 2,11,5,2,4,5,4,2,2,4 }, { 0xf0000000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Noto Serif Myanmar", { 2,2,10,2,6,5,5,2,2,4 }, { 0xa0000000,0x23000000,0x00800004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Optima", { 2,0,5,3,6,0,0,2,0,4 }, { 0xfe180000,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Oriya MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Oriya Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PT Mono", { 2,6,7,9,2,2,5,2,2,4 }, { 0xffbbf800,0x07400000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PT Sans", { 2,11,5,3,2,2,3,2,2,4 }, { 0xffbbf800,0x07400000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PT Sans Caption", { 2,11,5,3,2,2,3,2,2,4 }, { 0xffbbf800,0x07400000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PT Sans Narrow", { 2,11,5,3,2,2,3,2,2,4 }, { 0xffbbf800,0x07400000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PT Serif", { 2,10,6,3,4,5,5,2,2,4 }, { 0xffbbf800,0x07400000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PT Serif Caption", { 2,6,6,3,5,5,5,2,2,4 }, { 0xffbbf800,0x07400000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Palatino", { 0,0,0,0,0,0,0,0,0,0 }, { 0xfffff000,0x27200000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Papyrus", { 2,11,6,2,4,2,0,2,3,3 }, { 0xffff1000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Party LET", { 0,0,0,0,0,0,0,0,0,0 }, { 0xffbe1000,0x06000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Phosphate", { 2,0,5,6,5,0,0,2,0,4 }, { 0xfffff000,0x07000000,0x0000002c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "PingFang HK", { 2,11,4,0,0,0,0,0,0,0 }, { 0xffffc000,0x07ffffff,0xfc00000c,0x00000000,0x00000023,0xffffffff,0xff400008,0x00000000 } }, +{ "PingFang SC", { 2,11,4,0,0,0,0,0,0,0 }, { 0xffffc000,0x07ffffff,0xfc00000c,0x00000000,0x00000023,0xffffffff,0xff400008,0x00000000 } }, +{ "PingFang TC", { 2,11,4,0,0,0,0,0,0,0 }, { 0xffffc000,0x07ffffff,0xfc00000c,0x00000000,0x00000023,0xffffffff,0xff400008,0x00000000 } }, +{ "Plantagenet Cherokee", { 2,2,0,0,0,0,0,0,0,0 }, { 0xf61c0000,0x22000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Raanana", { 0,0,0,0,0,0,0,0,0,0 }, { 0xe0040300,0x02000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Rockwell", { 2,6,5,3,2,2,5,2,4,3 }, { 0xffffea80,0xd6000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "STSong", { 2,1,8,0,4,1,1,1,1,1 }, { 0xfd53c000,0x07207fff,0xfc000184,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sana", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000f0,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sathu", { 0,0,4,0,0,0,0,0,0,0 }, { 0xfffff000,0x47000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Savoye LET", { 0,0,0,0,0,0,0,0,0,0 }, { 0xfffff800,0x06800000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Shree Devanagari 714", { 2,0,6,0,0,0,0,0,0,0 }, { 0xf6100000,0x83000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "SignPainter", { 2,0,0,6,7,0,0,2,0,4 }, { 0xff9bf800,0x07000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Silom", { 0,0,4,0,0,0,0,0,0,0 }, { 0xffdf1000,0x47000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sinhala MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sinhala Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Skia", { 2,13,5,2,2,2,4,2,2,4 }, { 0xff9b0000,0x03000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Snell Roundhand", { 2,0,6,3,8,0,0,9,0,4 }, { 0xfffff800,0x26e00000,0x0100001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Songti SC", { 2,1,8,0,4,1,1,1,1,1 }, { 0xfd53c000,0x07207fff,0xfc000184,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Songti TC", { 2,1,8,0,4,1,1,1,1,1 }, { 0xfd53c000,0x07207fff,0xfc000184,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Sukhumvit Set", { 2,0,5,6,0,0,0,2,0,4 }, { 0xfe130000,0x43000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Symbol", { 0,0,0,0,0,0,0,0,0,0 }, { 0xf22b0000,0x03200000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Tahoma", { 2,11,6,4,3,5,4,4,2,4 }, { 0xfffffbf4,0x47400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Tamil MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x83000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Tamil Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xfe9f0000,0x87000000,0x00000008,0x24000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Telugu MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Telugu Sangam MN", { 0,0,5,0,0,0,0,0,0,0 }, { 0xe0000000,0x43000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Thonburi", { 0,0,4,0,0,0,0,0,0,0 }, { 0xfffff000,0x47000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Times", { 0,0,5,0,0,0,0,2,0,0 }, { 0xfffff000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Times New Roman", { 2,2,6,3,5,4,5,2,3,4 }, { 0xfffffbf4,0x07400000,0x0100000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Trattatello", { 2,15,4,3,2,2,0,2,3,3 }, { 0xffbff000,0x07000000,0x0000001c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Trebuchet MS", { 2,11,6,3,2,2,2,2,2,4 }, { 0xff97e000,0x07000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Verdana", { 2,11,6,4,3,5,4,4,2,4 }, { 0xffdff600,0x47000000,0x0000000c,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +{ "Waseem", { 0,0,4,0,0,0,0,0,0,0 }, { 0xf00000c0,0x00000000,0x00000004,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 } }, +#endif diff --git a/uppsrc/Draw/Image.cpp b/uppsrc/Draw/Image.cpp index 9730a1a1d..1698c9e8d 100644 --- a/uppsrc/Draw/Image.cpp +++ b/uppsrc/Draw/Image.cpp @@ -281,7 +281,7 @@ bool Image::operator==(const Image& img) const Get2ndSpot() == img.Get2ndSpot() && GetDots() == img.GetDots() && GetResolution() == img.GetResolution() && - memeq32(~*this, ~img, GetLength()); + memeq_t(~*this, ~img, GetLength()); } bool Image::operator!=(const Image& img) const diff --git a/uppsrc/Draw/src.tpp/Font_en-us.tpp b/uppsrc/Draw/src.tpp/Font_en-us.tpp index 0d720fabe..544a9d1b7 100644 --- a/uppsrc/Draw/src.tpp/Font_en-us.tpp +++ b/uppsrc/Draw/src.tpp/Font_en-us.tpp @@ -347,7 +347,7 @@ there is a space inside the cell not used for glyph.&] [s5;:Font`:`:GetRightSpace`(int`)const: [@(0.0.255) int]_[* GetRightSpace]([@(0.0.255) int]_ [@3 c])_[@(0.0.255) const]&] [s2;%% Similar to GetLeftSpace for the right edge of character cell.&] -[s3; &] +[s3;%% &] [s4; &] [s5;:Font`:`:IsFixedPitch`(`)const: [@(0.0.255) bool]_[* IsFixedPitch]()_[@(0.0.255) const]&] [s2;%% True if font is mono`-spaced.&] @@ -393,6 +393,16 @@ onst]_[@(0.0.255) char]_`*[*@3 s])&] [s5;:Font`:`:GetData`(`)const: [_^String^ String]_[* GetData]()_[@(0.0.255) const]&] [s2;%% Returns the raw content of font file.&] [s3; &] +[s3; &] +[s4; &] +[s5;:Upp`:`:Font`:`:GetData`(const char`*`,int`,int`)const: [_^Upp`:`:String^ String]_[* G +etData]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 table]_`=_NULL, +[@(0.0.255) int]_[*@3 offset]_`=_`-[@3 1], [@(0.0.255) int]_[*@3 size]_`=_`-[@3 1])_[@(0.0.255) c +onst]&] +[s2;%% Returns the raw content of font file. [%-*@3 table] [%-*@3 offset] +[%-*@3 size] can specify which part of TTF or OTF font data to +retrieve.&] +[s0;%% &] [s4; &] [s5;:Font`:`:Render`(FontGlyphConsumer`&`,double`,double`,int`)const: [@(0.0.255) void]_ [* Render]([_^FontGlyphConsumer^ FontGlyphConsumer][@(0.0.255) `&]_[*@3 sw], diff --git a/uppsrc/Esc/Esc.cpp b/uppsrc/Esc/Esc.cpp index 829d5c7aa..a47cad40e 100644 --- a/uppsrc/Esc/Esc.cpp +++ b/uppsrc/Esc/Esc.cpp @@ -320,11 +320,11 @@ void Esc::Term(SRVal& r) return; } if(IsString()) { - r = EscValue(FromUtf8(ReadString())); + r = EscValue(ToUtf32(ReadString())); return; } if(IsChar('\'')) { - WString s = FromUtf8(ReadString('\'')); + WString s = ToUtf32(ReadString('\'')); if(s.GetLength() != 1) ThrowError("invalid character literal"); r = (int64)s[0]; diff --git a/uppsrc/GLCtrl/GLCtrl.cpp b/uppsrc/GLCtrl/GLCtrl.cpp index 955a63de2..44961cde5 100644 --- a/uppsrc/GLCtrl/GLCtrl.cpp +++ b/uppsrc/GLCtrl/GLCtrl.cpp @@ -12,6 +12,8 @@ extern void (*restore_gl_viewport__)(); void GLCtrl::DoGLPaint() { + MemoryIgnoreLeaksBlock __; + glClearDepth(1); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); @@ -47,6 +49,8 @@ void GLCtrl::SetCurrentViewport() void GLCtrl::StdView() { + MemoryIgnoreLeaksBlock __; + glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClearDepth(1.0f); diff --git a/uppsrc/HexView/HexView.cpp b/uppsrc/HexView/HexView.cpp index f29cf3283..de84abeb7 100644 --- a/uppsrc/HexView/HexView.cpp +++ b/uppsrc/HexView/HexView.cpp @@ -85,7 +85,7 @@ void HexViewInfo::Paint(Draw& w) break; sh[i] = data[i]; } - WString ws = FromUtf8(sh, i); + WString ws = ToUtf32(sh, i); w.DrawText(x, 0, ws, font, Cyan, i); if(mode < 2) return; diff --git a/uppsrc/ODBC/ODBC.cpp b/uppsrc/ODBC/ODBC.cpp index 42ea1bfd4..0e20c1dcd 100644 --- a/uppsrc/ODBC/ODBC.cpp +++ b/uppsrc/ODBC/ODBC.cpp @@ -620,11 +620,10 @@ bool ODBCConnection::Fetch0() break; if(li != SQL_NULL_DATA && li >= 0) { if(ct == SQL_C_WCHAR) { - WStringBuffer sb; - sb.SetLength(li / 2); + Buffer sb(li / 2); if(!IsOk(SQLGetData(session->hstmt, i + 1, ct, ~sb, li + 2, &li))) break; - v = WString(sb); + v = ToUtf32(sb, li / 2); } else { StringBuffer sb; diff --git a/uppsrc/Painter/DrawOp.cpp b/uppsrc/Painter/DrawOp.cpp index 76d504bbc..1095999e5 100644 --- a/uppsrc/Painter/DrawOp.cpp +++ b/uppsrc/Painter/DrawOp.cpp @@ -215,7 +215,7 @@ void Painter::DrawTextOp(int x, int y, int angle, const wchar *text, Font font, if(angle) Rotate(-angle * M_2PI / 3600); if(n < 0) - n = wstrlen(text); + n = strlen__(text); double *ddx = NULL; Buffer h; if(dx) { diff --git a/uppsrc/Painter/Painter.cpp b/uppsrc/Painter/Painter.cpp index 47fbb465b..fa0a09bb2 100644 --- a/uppsrc/Painter/Painter.cpp +++ b/uppsrc/Painter/Painter.cpp @@ -242,7 +242,7 @@ void Painter::TextOp(const Pointf& p, const wchar *text, Font fnt, int n, const Painter& Painter::Text(double x, double y, const wchar *text, Font fnt, int n, const double *dx) { - return Text(Pointf(x, y), text, fnt, n < 0 ? wstrlen(text) : n, dx); + return Text(Pointf(x, y), text, fnt, n < 0 ? strlen__(text) : n, dx); } Painter& Painter::Text(const Pointf& p, const WString& s, Font fnt, const double *dx) @@ -267,7 +267,7 @@ Painter& Painter::Text(double x, double y, const String& s, Font fnt, const doub Painter& Painter::Text(const Pointf& p, const char *text, Font fnt, int n, const double *dx) { - WString s = ToUnicode(text, CHARSET_DEFAULT); + WString s = ToUtf32(text, n); return Text(p, s, fnt, n < 0 ? s.GetCount() : n, dx); } diff --git a/uppsrc/RichEdit/Kbd.cpp b/uppsrc/RichEdit/Kbd.cpp index 5022551fc..84d7436c4 100644 --- a/uppsrc/RichEdit/Kbd.cpp +++ b/uppsrc/RichEdit/Kbd.cpp @@ -184,7 +184,7 @@ bool RichEdit::Key(dword key, int count) } if(key == K_SHIFT_SPACE) key = ' '; - if(key == 9 || key >= 32 && key < 65536) { + if(key == 9 || key >= 32 && key < K_CHAR_LIM) { RichPara::Format f; if(IsSelection()) { f = text.GetRichPos(min(cursor, anchor)).format; diff --git a/uppsrc/RichText/ParaData.cpp b/uppsrc/RichText/ParaData.cpp index 220473e7c..cd82235c5 100644 --- a/uppsrc/RichText/ParaData.cpp +++ b/uppsrc/RichText/ParaData.cpp @@ -562,7 +562,7 @@ void RichPara::UnpackParts(Stream& in, const RichPara::CharFormat& chrstyle, b.Reserve(512); while(in.Term() >= 32 || in.Term() == 9) b.Cat(in.Get()); - part.Top().text.Cat(FromUtf8(~b)); + part.Top().text.Cat(ToUtf32(~b)); } if(part.Top().text.GetLength() == 0 && part.Top().IsText()) part.Drop(); @@ -736,7 +736,7 @@ void RichPara::Mid(int pos) } void ApplyCharStyle(RichPara::CharFormat& format, const RichPara::CharFormat& f0, - const RichPara::CharFormat& newstyle) { + const RichPara::CharFormat& newstyle) { if(format.IsBold() == f0.IsBold()) format.Bold(newstyle.IsBold()); if(format.IsUnderline() == f0.IsUnderline()) diff --git a/uppsrc/RichText/ParseQtf.cpp b/uppsrc/RichText/ParseQtf.cpp index 866144131..d2d45d46d 100644 --- a/uppsrc/RichText/ParseQtf.cpp +++ b/uppsrc/RichText/ParseQtf.cpp @@ -628,7 +628,7 @@ void RichQtfParser::Parse(const char *qtf, int _accesskey) case '`': format.sscript = format.sscript == 1 ? 0 : 1; break; case ',': format.sscript = format.sscript == 2 ? 0 : 2; break; case '^': format.link = GetText('^'); break; - case 'I': format.indexentry = FromUtf8(GetText(';')); break; + case 'I': format.indexentry = ToUtf32(GetText(';')); break; case '+': format.Height(GetNumber()); break; case '@': format.ink = GetColor(); break; case '$': format.paper = GetColor(); break; @@ -1011,25 +1011,10 @@ void RichQtfParser::Parse(const char *qtf, int _accesskey) if(istable) EndPart(); if(format.charset == CHARSET_UTF8) { - word code = (byte)*term++; - if(code <= 0x7F) - Cat(code); - else - if(code <= 0xDF) { - if(*term == '\0') break; - int c0 = (byte)*term++; - if(c0 < 0x80) - Error("Invalid UTF-8 sequence"); - Cat(((code - 0xC0) << 6) + c0 - 0x80); - } - else - if(code <= 0xEF) { - int c0 = (byte)*term++; - int c1 = (byte)*term++; - if(c0 < 0x80 || c1 < 0x80) - Error("Invalid UTF-8 sequence"); - Cat(((code - 0xE0) << 12) + ((c0 - 0x80) << 6) + c1 - 0x80); - } + bool ok = true; + wchar c = FetchUtf8(term, ok); + if(ok) + Cat(c); else Error("Invalid UTF-8 sequence"); } diff --git a/uppsrc/ide/About.cpp b/uppsrc/ide/About.cpp index a7fea4a1f..80d54d5a0 100644 --- a/uppsrc/ide/About.cpp +++ b/uppsrc/ide/About.cpp @@ -21,6 +21,8 @@ String SplashCtrl::GenerateVersionInfo(char separator) h << "(64 bit)"; else h << "(32 bit)"; + if(sizeof(wchar) == 4) + h << " (wchar32)"; #ifdef _MSC_VER h << " (MSC)"; #endif @@ -114,7 +116,9 @@ void HideSplash() void ShowSplash() { Single().PopUp(nullptr, false, false); - SetTimeCallback(750, [] { HideSplash(); }); + SetTimeCallback(750, [] { + HideSplash(); + }); } bool IsSplashOpen() diff --git a/uppsrc/ide/Browser/Base.cpp b/uppsrc/ide/Browser/Base.cpp index 47386d6fe..5d8812d67 100644 --- a/uppsrc/ide/Browser/Base.cpp +++ b/uppsrc/ide/Browser/Base.cpp @@ -38,6 +38,15 @@ void LockCodeBase() sGLock.Enter(); } +bool TryLockCodeBase() +{ + if(sGLockLevel == 0 && sGLock.TryEnter()) { + sGLockLevel++; + return true; + } + return false; +} + void UnlockCodeBase() { if(sGLockLevel > 0 && --sGLockLevel == 0) @@ -454,6 +463,16 @@ void CodeBaseScanFile(Stream& in, const String& fn) FinishCodeBase(); } +bool TryCodeBaseScanFile(Stream& in, const String& fn) +{ + if(DeadLockCheck() || !CppBaseMutex.TryEnter()) + return false; + CodeBaseScanFile0(in, fn); + FinishCodeBase(); + CppBaseMutex.Leave(); + return true; +} + void CodeBaseScanFile(const String& fn, bool auto_check) { LLOG("CodeBaseScanFile " << fn); diff --git a/uppsrc/ide/Browser/Browser.h b/uppsrc/ide/Browser/Browser.h index 4e12f3434..d520892a8 100644 --- a/uppsrc/ide/Browser/Browser.h +++ b/uppsrc/ide/Browser/Browser.h @@ -21,6 +21,7 @@ class Browser; void ReduceCacheFolder(const char *path, int max_total); void LockCodeBase(); +bool TryLockCodeBase(); void UnlockCodeBase(); void UnlockCodeBaseAll(); @@ -47,6 +48,7 @@ void NewCodeBase(); void ParseSrc(Stream& in, int file, Event error); void CodeBaseScanFile(Stream& in, const String& fn); void CodeBaseScanFile(const String& fn, bool auto_check); +bool TryCodeBaseScanFile(Stream& in, const String& fn); void ClearCodeBase(); // void CheckCodeBase(); void RescanCodeBase(); diff --git a/uppsrc/ide/Builders/Build.cpp b/uppsrc/ide/Builders/Build.cpp index 78323e935..c53786d07 100644 --- a/uppsrc/ide/Builders/Build.cpp +++ b/uppsrc/ide/Builders/Build.cpp @@ -521,10 +521,16 @@ bool MakeBuild::Build(const Workspace& wspc, String mainparam, String outfile, b return ok; } +void MakeBuild::BuildWorkspace(Workspace& wspc, Host& host, Builder& builder) +{ + Index p = PackageConfig(GetIdeWorkspace(), 0, GetMethodVars(method), mainconfigparam, + host, builder); + wspc.Scan(GetMain(), p.GetKeys()); +} + bool MakeBuild::Build() { - VectorMap bm = GetMethodVars(method); - if(bm.GetCount() == 0) { + if(GetMethodVars(method).GetCount() == 0) { PutConsole(GetInvalidBuildMethodError(method)); ConsoleShow(); return false; @@ -534,10 +540,8 @@ bool MakeBuild::Build() One builder = CreateBuilder(&host); if(!builder) return false; - Index p = PackageConfig(GetIdeWorkspace(), 0, bm, mainconfigparam, - host, *builder); Workspace wspc; - wspc.Scan(GetMain(), p.GetKeys()); + BuildWorkspace(wspc, host, *builder); return Build(wspc, mainconfigparam, Null); } @@ -568,7 +572,8 @@ void MakeBuild::Clean() return; builder->target = target; - const Workspace& wspc = GetIdeWorkspace(); + Workspace wspc; + BuildWorkspace(wspc, host, *builder); for(int i = 0; i < wspc.GetCount(); i++) CleanPackage(wspc, i); diff --git a/uppsrc/ide/Builders/Build.h b/uppsrc/ide/Builders/Build.h index 8b5be2663..4d257dbd2 100644 --- a/uppsrc/ide/Builders/Build.h +++ b/uppsrc/ide/Builders/Build.h @@ -85,6 +85,7 @@ public: Vector GetAllLibraries(const Workspace& wspc, int index, const VectorMap& bm, String mainparam, Host& host, Builder& builder); + void BuildWorkspace(Workspace& wspc, Host& host, Builder& builder); bool Build(const Workspace& wspc, String mainparam, String outfile, bool clear_console = true); bool Build(); void CleanPackage(const Workspace& wspc, int package); diff --git a/uppsrc/ide/Calc.cpp b/uppsrc/ide/Calc.cpp index 2029dd0cb..38e6c54d1 100644 --- a/uppsrc/ide/Calc.cpp +++ b/uppsrc/ide/Calc.cpp @@ -50,7 +50,7 @@ void IdeCalc::Execute() Paste("$"); SetCursor(GetLength64()); Paste("\n"); - Paste(FromUtf8(txt)); + Paste(ToUtf32(txt)); Paste("\n"); } diff --git a/uppsrc/ide/Core/Util.cpp b/uppsrc/ide/Core/Util.cpp index e6ea0d3ff..748760f22 100644 --- a/uppsrc/ide/Core/Util.cpp +++ b/uppsrc/ide/Core/Util.cpp @@ -7,7 +7,8 @@ int GetRepo(String& path) if(DirectoryExists(AppendFileName(path, ".svn")) || DirectoryExists(AppendFileName(path, "_svn"))) return SVN_DIR; for(;;) { - if(DirectoryExists(AppendFileName(path, ".git"))) + String git = AppendFileName(path, ".git"); + if(DirectoryExists(git) || FileExists(git)) return GIT_DIR; if(DirectoryExists(AppendFileName(path, ".svn"))) return SVN_DIR; diff --git a/uppsrc/ide/Debug.cpp b/uppsrc/ide/Debug.cpp index fd25c8e3d..43d1e8cb0 100644 --- a/uppsrc/ide/Debug.cpp +++ b/uppsrc/ide/Debug.cpp @@ -144,7 +144,7 @@ void Ide::ExecuteBinary() Minimize(); if(!runexternal) cmdline << '\"' << target << "\" "; - cmdline << ToSystemCharset(runarg); + cmdline << runarg; int exitcode; switch(runmode) { diff --git a/uppsrc/ide/Debuggers/Sym.cpp b/uppsrc/ide/Debuggers/Sym.cpp index 80cc1e96d..dc3db9e53 100644 --- a/uppsrc/ide/Debuggers/Sym.cpp +++ b/uppsrc/ide/Debuggers/Sym.cpp @@ -321,7 +321,7 @@ String Pdb::GetSymName(adr_t modbase, dword typeindex) { WCHAR *pwszTypeName; if(SymGetTypeInfo(hProcess, modbase, typeindex, TI_GET_SYMNAME, &pwszTypeName)) { - WString w((const wchar *)pwszTypeName); + WString w = pwszTypeName; LocalFree(pwszTypeName); return w.ToString(); } @@ -416,6 +416,13 @@ const Pdb::Type& Pdb::GetType(int ti) return t; } +static int CALLBACK sSymEnum(PSYMBOL_INFO pSym, ULONG SymbolSize, PVOID UserContext) +{ + auto type_index = (VectorMap *)UserContext; + type_index->GetAdd(pSym->Name) = pSym->TypeIndex; + return TRUE; +} + int Pdb::FindType(adr_t modbase, const String& name) { static VectorMap primitive = { @@ -443,11 +450,7 @@ int Pdb::FindType(adr_t modbase, const String& name) return q; if(type_bases.Find(modbase) < 0) { type_bases.Add(modbase); - SymEnumTypes(hProcess, current_modbase, [](PSYMBOL_INFO pSym, ULONG SymbolSize, PVOID UserContext)->int { - auto type_index = (VectorMap *)UserContext; - type_index->GetAdd(pSym->Name) = pSym->TypeIndex; - return TRUE; - }, &type_index); + SymEnumTypes(hProcess, current_modbase, sSymEnum, &type_index); // DDUMPM(type_index); } int ndx = type_index.Get(name, Null); diff --git a/uppsrc/ide/Errors.cpp b/uppsrc/ide/Errors.cpp index ce5dc364e..a687dfb54 100644 --- a/uppsrc/ide/Errors.cpp +++ b/uppsrc/ide/Errors.cpp @@ -715,8 +715,8 @@ void Ide::FoundDisplay::Paint(Draw& w, const Rect& r, const Value& q, Color ink, int fcy = GetStdFontCy(); int y = r.top + (r.GetHeight() - fcy) / 2; w.DrawRect(r, paper); - int sl = utf8len(~h[3], atoi(h[1])); - int sh = utf8len(~h[3] + sl, atoi(h[2])) + sl; + int sl = Utf32Len(~h[3], atoi(h[1])); + int sh = Utf32Len(~h[3] + sl, atoi(h[2])) + sl; for(int text = 0; text < 2; text++) { int x = r.left; for(int i = 0; i < hln.GetCount(); i++) { diff --git a/uppsrc/ide/FindInFiles.cpp b/uppsrc/ide/FindInFiles.cpp index 2946dbb1b..5b53511bb 100644 --- a/uppsrc/ide/FindInFiles.cpp +++ b/uppsrc/ide/FindInFiles.cpp @@ -322,7 +322,7 @@ void Ide::FindFileAll(const Vector>& f) editor.CachePos(pos.a); int linei = editor.GetLinePos64(pos.a); WString ln = editor.GetWLine(linei); - AddFoundFile(editfile, linei + 1, ln.ToString(), lenAsUtf8(~ln, (int)pos.a), lenAsUtf8(~ln + pos.a, pos.b)); + AddFoundFile(editfile, linei + 1, ln.ToString(), Utf8Len(~ln, (int)pos.a), Utf8Len(~ln + pos.a, pos.b)); } FFound().HeaderTab(2).SetText(Format("Source line (%d)", FFound().GetCount())); FFound().Add(Null, Null, AsString(f.GetCount()) + " occurrence(s) have been found."); diff --git a/uppsrc/ide/Help.cpp b/uppsrc/ide/Help.cpp index 840ba6b33..9805eacaf 100644 --- a/uppsrc/ide/Help.cpp +++ b/uppsrc/ide/Help.cpp @@ -147,7 +147,7 @@ void TopicCtrl::SyncDocTree() Vector sdx; for(int i = 0; i < ss.GetCount(); i++) - sdx.Add(ToUtf8(ToLower(FromUtf8(ss[i])))); + sdx.Add(ToUtf8(ToLower(ToUtf32(ss[i])))); ClearTree(); diff --git a/uppsrc/ide/LayDes/laydes.cpp b/uppsrc/ide/LayDes/laydes.cpp index 9f3338d25..775dfd51c 100644 --- a/uppsrc/ide/LayDes/laydes.cpp +++ b/uppsrc/ide/LayDes/laydes.cpp @@ -286,6 +286,7 @@ void LayDes::Paint(Draw& w) if(HasCapture() && draghandle == 14) DrawFrame(w, dragrect.Normalized(), LtRed); w.End(); + w.End(); } void LayDes::SaveState() diff --git a/uppsrc/ide/LayDes/textprop.cpp b/uppsrc/ide/LayDes/textprop.cpp index 2161d19c8..1b2ca64c3 100644 --- a/uppsrc/ide/LayDes/textprop.cpp +++ b/uppsrc/ide/LayDes/textprop.cpp @@ -123,7 +123,7 @@ void LTProperty::Read(CParser& p) String LTProperty::Save() const { String px = ~lid; - String txt = FromUnicode((WString)Get(), charset); + String txt = FromUnicode(Get(), charset); if(id) return "t_(" + AsCString(px + "\a" + txt) + ')'; else diff --git a/uppsrc/ide/Navigator.cpp b/uppsrc/ide/Navigator.cpp index 74dc3cd2f..fe335aa10 100644 --- a/uppsrc/ide/Navigator.cpp +++ b/uppsrc/ide/Navigator.cpp @@ -730,8 +730,10 @@ void Navigator::Scope() litem.Add(m); } } + int lsc = list.GetScroll(); list.Clear(); list.SetVirtualCount(litem.GetCount()); + list.ScrollTo(lsc); } void Navigator::ListLineEnabled(int i, bool& b) diff --git a/uppsrc/ide/ide.cpp b/uppsrc/ide/ide.cpp index b6e7d3344..57e94d22d 100644 --- a/uppsrc/ide/ide.cpp +++ b/uppsrc/ide/ide.cpp @@ -646,8 +646,8 @@ void Ide::Periodic() if(debugger && debugger->IsFinished() && !IdeIsDebugLock()) IdeEndDebug(); if(file_scanned) { - EditFileAssistSync2(); - file_scanned = false; + if(EditFileAssistSync2()) + file_scanned = false; } } diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index c4b0815ec..5183d4b47 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -765,10 +765,10 @@ public: void PosSync(); String IncludesMD5(); - void EditFileAssistSync2(); + bool EditFileAssistSync2(); void EditFileAssistSync(); - TimeCallback text_updated; + TimeCallback text_updated, trigger_assist; std::atomic file_scan; bool file_scanned = false; diff --git a/uppsrc/ide/idefile.cpp b/uppsrc/ide/idefile.cpp index 9cad3b98f..13a5d51bc 100644 --- a/uppsrc/ide/idefile.cpp +++ b/uppsrc/ide/idefile.cpp @@ -661,10 +661,15 @@ void Ide::ScanFile(bool check_includes) } } -void Ide::EditFileAssistSync2() +bool Ide::EditFileAssistSync2() { - editor.Annotate(editfile); - editor.SyncNavigator(); + if(TryLockCodeBase()) { + editor.Annotate(editfile); + editor.SyncNavigator(); + UnlockCodeBase(); + return true; + } + return false; } void Ide::EditFileAssistSync() @@ -683,11 +688,14 @@ void Ide::TriggerAssistSync() file_scan++; if(!CoWork::TrySchedule([=] { StringStream ss(s); - CodeBaseScanFile(ss, editfile); + file_scanned = TryCodeBaseScanFile(ss, editfile); file_scan--; - file_scanned = true; - })) + if(!file_scanned) + trigger_assist.KillSet(100, [=] { TriggerAssistSync(); }); + })) { file_scan--; + trigger_assist.KillSet(100, [=] { TriggerAssistSync(); }); + } } }); } diff --git a/upptst/CJK/CJK.upp b/upptst/CJK/CJK.upp new file mode 100644 index 000000000..78e4a082c --- /dev/null +++ b/upptst/CJK/CJK.upp @@ -0,0 +1,12 @@ +uses + CtrlLib, + CtrlLib; + +file + main.cpp; + +mainconfig + "" = "GUI DEBUGCODE", + "" = "GUI", + "" = "GUI X11"; + diff --git a/upptst/CJK/main.cpp b/upptst/CJK/main.cpp new file mode 100644 index 000000000..a555b7499 --- /dev/null +++ b/upptst/CJK/main.cpp @@ -0,0 +1,37 @@ +#include + +using namespace Upp; + +struct MyApp : TopWindow { + void Paint(Draw& w) { + String text; + text << WString(0x1F603, 1).ToString(); + text << " Quick brown fox, 訓民正音 (훈민정음) "; + + w.DrawRect(GetSize(), White()); + int y = 10; + int x = 10; + for(int i = 0; i < Font::GetFaceCount(); i++) + { + Font fnt(i, 30); + if(fnt.IsSpecial()) continue; + fnt.Italic(); + String n = AsString(i) + ": " + fnt.GetFaceName() + ": "; + if(fnt.IsSpecial()) + n << " (special)"; + w.DrawText(x, y, n, StdFont()); + w.DrawText(x + GetTextSize(n, StdFont()).cx, y, text, fnt); + y += fnt.GetLineHeight() + 10; + if(y > GetSize().cy) { + x += GetSize().cx / 3; + if(x > GetSize().cx) + return; + y = 10; + } + } + } +}; + +GUI_APP_MAIN { + MyApp().Sizeable().Zoomable().Run(); +} \ No newline at end of file diff --git a/upptst/FileSel/main.cpp b/upptst/FileSel/main.cpp index 19dc71464..83ab8859a 100644 --- a/upptst/FileSel/main.cpp +++ b/upptst/FileSel/main.cpp @@ -10,30 +10,14 @@ GUI_APP_MAIN sel.Type("All", "*.*"); sel.Type("All 2", "*"); sel.ActiveType(1); - for(int i = 0; i < sel.GetCount(); i++) - DDUMP(sel[i]); - sel.Multi(); - if(!sel.ExecuteSaveAs("Test!")) - return; - for(int i = 0; i < sel.GetCount(); i++) - DDUMP(sel[i]); - sel = "/home/cxl/Temp/Gui2/main.cpp"; + while(sel.ExecuteSaveAs("Test!")) { + for(int i = 0; i < sel.GetCount(); i++) + DDUMP(sel[i]); + sel.Multi(); + sel.NoAsking(); + } + sel = GetDataFile("main.cpp"); if(!sel.ExecuteSaveAs("as")) return; DDUMP(~sel); - sel.NoAsking(); - if(!sel.ExecuteSaveAs("as")) - return; - return; -/* - DocEdit a; - TopWindow w1, w2; - w1.Add(a.SizePos()); - w1.OpenMain(); - Button b; - b <<= callback(Sel); - w2.Add(b.SizePos()); - w2.Open(&w1); - w2.Run(); -*/ }