diff --git a/build/linux/platform_specific_code/juce_linux_Fonts.cpp b/build/linux/platform_specific_code/juce_linux_Fonts.cpp index 72ce9acb1d..50fe0424ac 100644 --- a/build/linux/platform_specific_code/juce_linux_Fonts.cpp +++ b/build/linux/platform_specific_code/juce_linux_Fonts.cpp @@ -553,9 +553,9 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, ->createTypeface (fontName, bold, italic, *this, addAllGlyphsToFont); } -void Typeface::findAndAddSystemGlyph (juce_wchar character) throw() +bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() { - FreeTypeInterface::getInstance() + return FreeTypeInterface::getInstance() ->addGlyphToFont (character, getName(), isBold(), isItalic(), *this); } diff --git a/build/macosx/platform_specific_code/juce_mac_Fonts.cpp b/build/macosx/platform_specific_code/juce_mac_Fonts.cpp index 92cfb9a542..298b6763cd 100644 --- a/build/macosx/platform_specific_code/juce_mac_Fonts.cpp +++ b/build/macosx/platform_specific_code/juce_mac_Fonts.cpp @@ -414,13 +414,14 @@ void Typeface::initialiseTypefaceCharacteristics (const String& fontName, ATSFontHelperCache::getInstance()->releaseFont (helper); } -void Typeface::findAndAddSystemGlyph (juce_wchar character) throw() +bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() { ATSFontHelper* const helper = ATSFontHelperCache::getInstance() ->getFont (getName(), isBold(), isItalic()); Path path; float width; + bool foundOne = false; if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0)) { @@ -450,9 +451,12 @@ void Typeface::findAndAddSystemGlyph (juce_wchar character) throw() addKerningPair (g->getCharacter(), character, kerning); } } + + foundOne = true; } ATSFontHelperCache::getInstance()->releaseFont (helper); + return foundOne; } const StringArray Font::findAllTypefaceNames() throw() diff --git a/build/macosx/platform_specific_code/juce_mac_Windowing.cpp b/build/macosx/platform_specific_code/juce_mac_Windowing.cpp index 2e0fcfd9fd..b0a683f258 100644 --- a/build/macosx/platform_specific_code/juce_mac_Windowing.cpp +++ b/build/macosx/platform_specific_code/juce_mac_Windowing.cpp @@ -1070,8 +1070,6 @@ public: } } -DBG (String ((int) rawKey) + " " + String ((int) keyCode) + " " + String::charToString (textCharacter) + " " + String ((int) currentModifiers)); - if ((currentModifiers & (ModifierKeys::commandModifier | ModifierKeys::ctrlModifier)) != 0) textCharacter = 0; @@ -2824,7 +2822,7 @@ private: if (keyPresses.size() > 0) { - const KeyPress& kp = keyPresses.getUnchecked(0); + const KeyPress& kp = keyPresses.getReference(0); int mods = 0; if (kp.getModifiers().isShiftDown()) diff --git a/build/win32/platform_specific_code/juce_win32_Files.cpp b/build/win32/platform_specific_code/juce_win32_Files.cpp index de166b3e84..1260fcc578 100644 --- a/build/win32/platform_specific_code/juce_win32_Files.cpp +++ b/build/win32/platform_specific_code/juce_win32_Files.cpp @@ -44,6 +44,15 @@ #endif #include +#ifndef CSIDL_MYMUSIC + #define CSIDL_MYMUSIC 0x000d +#endif + +#ifndef CSIDL_MYVIDEO + #define CSIDL_MYVIDEO 0x000e +#endif + + BEGIN_JUCE_NAMESPACE #include "../../../src/juce_core/io/files/juce_File.h" @@ -81,6 +90,9 @@ UNICODE_FUNCTION (FindNextFileW, BOOL, (HANDLE, LPWIN32_FIND_DATAW)) void juce_initialiseUnicodeFileFunctions() throw() { + static_jassert (CSIDL_MYMUSIC == 0x000d); + static_jassert (CSIDL_MYVIDEO == 0x000e); + if ((SystemStats::getOperatingSystemType() & SystemStats::WindowsNT) != 0) { HMODULE h = GetModuleHandleA ("kernel32.dll"); diff --git a/build/win32/platform_specific_code/juce_win32_Fonts.cpp b/build/win32/platform_specific_code/juce_win32_Fonts.cpp index ca92574e7f..49e1637fd6 100644 --- a/build/win32/platform_specific_code/juce_win32_Fonts.cpp +++ b/build/win32/platform_specific_code/juce_win32_Fonts.cpp @@ -48,6 +48,7 @@ BEGIN_JUCE_NAMESPACE UNICODE_FUNCTION (GetKerningPairsW, DWORD, (HDC, DWORD, LPKERNINGPAIR)) UNICODE_FUNCTION (EnumFontFamiliesExW, int, (HDC, LPLOGFONTW, FONTENUMPROCW, LPARAM, DWORD)) UNICODE_FUNCTION (CreateFontIndirectW, HFONT, (CONST LOGFONTW *)); + UNICODE_FUNCTION (GetGlyphIndicesW, DWORD, (HDC, LPCWSTR, int, LPWORD, DWORD)); static void juce_initialiseUnicodeFileFontFunctions() { @@ -65,6 +66,7 @@ BEGIN_JUCE_NAMESPACE UNICODE_FUNCTION_LOAD (GetKerningPairsW) UNICODE_FUNCTION_LOAD (EnumFontFamiliesExW) UNICODE_FUNCTION_LOAD (CreateFontIndirectW) + UNICODE_FUNCTION_LOAD (GetGlyphIndicesW) } } } @@ -466,7 +468,7 @@ juce_ImplementSingleton_SingleThreaded (FontDCHolder); //============================================================================== -static void addGlyphToTypeface (HDC dc, +static bool addGlyphToTypeface (HDC dc, juce_wchar character, Typeface& dest, bool addKerning) @@ -478,6 +480,18 @@ static void addGlyphToTypeface (HDC dc, BOOL ok = false; #if JUCE_ENABLE_WIN98_COMPATIBILITY + if (wGetGlyphIndicesW != 0) + { + const WCHAR charToTest[] = { (WCHAR)character, 0 }; + WORD index = 0; + + if (wGetGlyphIndicesW (dc, charToTest, 1, &index, GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR + && index < 0) + { + return false; + } + } + if (wGetTextMetricsW != 0) { TEXTMETRICW tm; @@ -493,6 +507,17 @@ static void addGlyphToTypeface (HDC dc, height = (float) tm.tmHeight; } #else + { + const WCHAR charToTest[] = { (WCHAR)character, 0 }; + WORD index = 0; + + if (GetGlyphIndicesW (dc, charToTest, 1, &index, GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR + && index < 0) + { + return false; + } + } + TEXTMETRICW tm; ok = GetTextMetricsW (dc, &tm); @@ -502,7 +527,7 @@ static void addGlyphToTypeface (HDC dc, if (! ok) { dest.addGlyph (character, destShape, 0); - return; + return true; } const float scaleX = 1.0f / height; @@ -620,13 +645,15 @@ static void addGlyphToTypeface (HDC dc, } } } + + return true; } //============================================================================== -void Typeface::findAndAddSystemGlyph (juce_wchar character) throw() +bool Typeface::findAndAddSystemGlyph (juce_wchar character) throw() { HDC dc = FontDCHolder::getInstance()->loadFont (getName(), isBold(), isItalic(), 0); - addGlyphToTypeface (dc, character, *this, true); + return addGlyphToTypeface (dc, character, *this, true); } /*Image* Typeface::renderGlyphToImage (juce_wchar character, float& topLeftX, float& topLeftY) diff --git a/build/win32/platform_specific_code/juce_win32_Windowing.cpp b/build/win32/platform_specific_code/juce_win32_Windowing.cpp index 7fc2c459e1..fb18683782 100644 --- a/build/win32/platform_specific_code/juce_win32_Windowing.cpp +++ b/build/win32/platform_specific_code/juce_win32_Windowing.cpp @@ -138,6 +138,7 @@ bool Desktop::canUseSemiTransparentWindows() throw() UNICODE_FUNCTION (SetWindowTextW, BOOL, (HWND, LPCWSTR)) UNICODE_FUNCTION (DragQueryFileW, UINT, (HDROP, UINT, LPWSTR, UINT)) UNICODE_FUNCTION (MapVirtualKeyW, UINT, (UINT, UINT)) + UNICODE_FUNCTION (ToUnicode, int, (UINT, UINT, const PBYTE, LPWSTR, int, UINT)) UNICODE_FUNCTION (RegisterClassExW, ATOM, (CONST WNDCLASSEXW*)) UNICODE_FUNCTION (CreateWindowExW, HWND, (DWORD, LPCWSTR, LPCWSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID)) UNICODE_FUNCTION (DefWindowProcW, LRESULT, (HWND, UINT, WPARAM, LPARAM)) @@ -155,6 +156,7 @@ bool Desktop::canUseSemiTransparentWindows() throw() HMODULE h = LoadLibraryA ("user32.dll"); UNICODE_FUNCTION_LOAD (SetWindowTextW) UNICODE_FUNCTION_LOAD (MapVirtualKeyW) + UNICODE_FUNCTION_LOAD (ToUnicode) UNICODE_FUNCTION_LOAD (RegisterClassExW) UNICODE_FUNCTION_LOAD (CreateWindowExW) UNICODE_FUNCTION_LOAD (DefWindowProcW) @@ -1693,7 +1695,7 @@ private: { updateKeyModifiers(); - const juce_wchar textChar = (juce_wchar) key; + juce_wchar textChar = (juce_wchar) key; const int virtualScanCode = (flags >> 16) & 0xff; if (key >= '0' && key <= '9') @@ -1723,10 +1725,35 @@ private: // convert the scan code to an unmodified character code.. #if JUCE_ENABLE_WIN98_COMPATIBILITY - UINT keyChar = wMapVirtualKeyW != 0 ? wMapVirtualKeyW (wMapVirtualKeyW (virtualScanCode, 1), 2) - : MapVirtualKey (MapVirtualKey (virtualScanCode, 1), 2); + const UINT virtualKey = wMapVirtualKeyW != 0 ? wMapVirtualKeyW (virtualScanCode, 1) + : MapVirtualKey (virtualScanCode, 1); + + UINT keyChar = wMapVirtualKeyW != 0 ? wMapVirtualKeyW (virtualKey, 2) + : MapVirtualKey (virtualKey, 2); + + if (wToUnicode != 0) + { + BYTE keyState[256]; + GetKeyboardState (keyState); + WCHAR unicodeChar[32]; + const DWORD converted = wToUnicode (virtualKey, virtualScanCode, keyState, + unicodeChar, 32, 0); + if (converted > 0) + textChar = unicodeChar[0]; + } #else - UINT keyChar = MapVirtualKeyW (MapVirtualKeyW (virtualScanCode, 1), 2); + const UINT virtualKey = MapVirtualKeyW (virtualScanCode, 1); + UINT keyChar = MapVirtualKeyW (virtualKey, 2); + + { + BYTE keyState[256]; + GetKeyboardState (keyState); + WCHAR unicodeChar[32]; + const DWORD converted = ToUnicode (virtualKey, virtualScanCode, keyState, + unicodeChar, 32, 0); + if (converted > 0) + textChar = unicodeChar[0]; + } #endif keyChar = LOWORD (keyChar); diff --git a/src/juce_appframework/gui/components/keyboard/juce_KeyPress.cpp b/src/juce_appframework/gui/components/keyboard/juce_KeyPress.cpp index e81266c081..39f2a8e46f 100644 --- a/src/juce_appframework/gui/components/keyboard/juce_KeyPress.cpp +++ b/src/juce_appframework/gui/components/keyboard/juce_KeyPress.cpp @@ -96,30 +96,9 @@ bool KeyPress::operator!= (const KeyPress& other) const throw() bool KeyPress::isCurrentlyDown() const throw() { - int modsMask = ModifierKeys::commandModifier - | ModifierKeys::ctrlModifier - | ModifierKeys::altModifier; - - if (keyCode == KeyPress::downKey - || keyCode == KeyPress::upKey - || keyCode == KeyPress::leftKey - || keyCode == KeyPress::rightKey - || keyCode == KeyPress::deleteKey - || keyCode == KeyPress::backspaceKey - || keyCode == KeyPress::returnKey - || keyCode == KeyPress::escapeKey - || keyCode == KeyPress::homeKey - || keyCode == KeyPress::endKey - || keyCode == KeyPress::pageUpKey - || keyCode == KeyPress::pageDownKey - || (keyCode >= KeyPress::F1Key && keyCode <= KeyPress::F16Key)) - { - modsMask |= ModifierKeys::shiftModifier; - } - return isKeyCurrentlyDown (keyCode) - && (ModifierKeys::getCurrentModifiers().getRawFlags() & modsMask) - == (mods.getRawFlags() & modsMask); + && (ModifierKeys::getCurrentModifiers().getRawFlags() & ModifierKeys::allKeyboardModifiers) + == (mods.getRawFlags() & ModifierKeys::allKeyboardModifiers); } //============================================================================== diff --git a/src/juce_appframework/gui/graphics/fonts/juce_Typeface.cpp b/src/juce_appframework/gui/graphics/fonts/juce_Typeface.cpp index 4ae7ed47e0..da3f5dc0fe 100644 --- a/src/juce_appframework/gui/graphics/fonts/juce_Typeface.cpp +++ b/src/juce_appframework/gui/graphics/fonts/juce_Typeface.cpp @@ -288,10 +288,9 @@ const TypefaceGlyphInfo* Typeface::getGlyph (const juce_wchar character) throw() return g; } - if (! isFullyPopulated) + if ((! isFullyPopulated) + && findAndAddSystemGlyph (character)) { - findAndAddSystemGlyph (character); - for (int i = 0; i < glyphs.size(); ++i) { const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i); diff --git a/src/juce_appframework/gui/graphics/fonts/juce_Typeface.h b/src/juce_appframework/gui/graphics/fonts/juce_Typeface.h index 15328617d3..8044399b0c 100644 --- a/src/juce_appframework/gui/graphics/fonts/juce_Typeface.h +++ b/src/juce_appframework/gui/graphics/fonts/juce_Typeface.h @@ -295,7 +295,7 @@ private: bool addAllGlyphsToFont) throw(); // platform-specific routine to look up and add a glyph to this typeface - void findAndAddSystemGlyph (juce_wchar character) throw(); + bool findAndAddSystemGlyph (juce_wchar character) throw(); void updateHashCode() throw(); };