diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 66aee53a0e..deee0aab0f 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -30953,34 +30953,29 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (const StringArray& files, { for (int i = 0; i < files.size(); ++i) { - bool loaded = false; - for (int j = 0; j < AudioPluginFormatManager::getInstance()->getNumFormats(); ++j) { AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (j); if (scanAndAddFile (files[i], true, typesFound, *format)) - loaded = true; + return; } - if (! loaded) + const File f (files[i]); + + if (f.isDirectory()) { - const File f (files[i]); + StringArray s; - if (f.isDirectory()) { - StringArray s; - - { - Array subFiles; - f.findChildFiles (subFiles, File::findFilesAndDirectories, false); + Array subFiles; + f.findChildFiles (subFiles, File::findFilesAndDirectories, false); - for (int j = 0; j < subFiles.size(); ++j) - s.add (subFiles.getReference(j).getFullPathName()); - } - - scanAndAddDragAndDroppedFiles (s, typesFound); + for (int j = 0; j < subFiles.size(); ++j) + s.add (subFiles.getReference(j).getFullPathName()); } + + scanAndAddDragAndDroppedFiles (s, typesFound); } } } @@ -42334,7 +42329,8 @@ const Colour Component::findColour (const int colourId, const bool inheritFromPa if (v != nullptr) return Colour ((int) *v); - if (inheritFromParent && parentComponent != nullptr) + if (inheritFromParent && parentComponent != nullptr + && (lookAndFeel == nullptr || ! lookAndFeel->isColourSpecified (colourId))) return parentComponent->findColour (colourId, true); return getLookAndFeel().findColour (colourId); @@ -64008,7 +64004,7 @@ void ResizableCornerComponent::mouseDrag (const MouseEvent& e) void ResizableCornerComponent::mouseUp (const MouseEvent&) { if (constrainer != nullptr) - constrainer->resizeStart(); + constrainer->resizeEnd(); } bool ResizableCornerComponent::hitTest (int x, int y) @@ -130661,7 +130657,7 @@ FlacAudioFormat::~FlacAudioFormat() const Array FlacAudioFormat::getPossibleSampleRates() { - const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 0 }; + const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 0 }; return Array (rates); } @@ -130707,6 +130703,12 @@ AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out, return nullptr; } +const StringArray FlacAudioFormat::getQualityOptions() +{ + const char* options[] = { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)", 0 }; + return StringArray (options); +} + END_JUCE_NAMESPACE #endif @@ -262869,23 +262871,12 @@ private: bool hasSerif, monospaced; }; -class FreeTypeInterface : public DeletedAtShutdown +class LinuxFontFileIterator { public: - - FreeTypeInterface() - : ftLib (0), - lastFace (0), - lastBold (false), - lastItalic (false) + LinuxFontFileIterator() + : index (0) { - if (FT_Init_FreeType (&ftLib) != 0) - { - ftLib = 0; - DBG ("Failed to initialize FreeType"); - } - - StringArray fontDirs; fontDirs.addTokens (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH")), ";,", String::empty); fontDirs.removeEmptyStrings (true); @@ -262905,96 +262896,124 @@ public: if (fontDirs.size() == 0) fontDirs.add ("/usr/X11R6/lib/X11/fonts"); - for (int i = 0; i < fontDirs.size(); ++i) - enumerateFaces (fontDirs[i]); + fontDirs.removeEmptyStrings (true); } - ~FreeTypeInterface() + bool next() { - if (lastFace != 0) - FT_Done_Face (lastFace); + if (iter != nullptr) + { + while (iter->next()) + if (getFile().hasFileExtension ("ttf;pfb;pcf")) + return true; + } - if (ftLib != 0) - FT_Done_FreeType (ftLib); + if (index >= fontDirs.size()) + return false; - clearSingletonInstance(); + iter = new DirectoryIterator (fontDirs [index++], true); + return next(); } - FreeTypeFontFace* findOrCreate (const String& familyName, const bool create = false) - { - for (int i = 0; i < faces.size(); i++) - if (faces[i]->getFamilyName() == familyName) - return faces[i]; - - if (! create) - return nullptr; + File getFile() const { jassert (iter != nullptr); return iter->getFile(); } - FreeTypeFontFace* newFace = new FreeTypeFontFace (familyName); - faces.add (newFace); +private: + StringArray fontDirs; + int index; + ScopedPointer iter; +}; - return newFace; - } +class FreeTypeInterface : public DeletedAtShutdown +{ +public: - // Enumerate all font faces available in a given directory - void enumerateFaces (const String& path) + FreeTypeInterface() + : ftLib (0), + lastFace (0), + lastBold (false), + lastItalic (false) { - File dirPath (path); - if (path.isEmpty() || ! dirPath.isDirectory()) - return; + if (FT_Init_FreeType (&ftLib) != 0) + { + ftLib = 0; + DBG ("Failed to initialize FreeType"); + } - DirectoryIterator di (dirPath, true); + LinuxFontFileIterator fontFileIterator; - while (di.next()) + while (fontFileIterator.next()) { - File possible (di.getFile()); + FT_Face face; + int faceIndex = 0; + int numFaces = 0; - if (possible.hasFileExtension ("ttf") - || possible.hasFileExtension ("pfb") - || possible.hasFileExtension ("pcf")) + do { - FT_Face face; - int faceIndex = 0; - int numFaces = 0; - - do + if (FT_New_Face (ftLib, fontFileIterator.getFile().getFullPathName().toUTF8(), + faceIndex, &face) == 0) { - if (FT_New_Face (ftLib, possible.getFullPathName().toUTF8(), - faceIndex, &face) == 0) + if (faceIndex == 0) + numFaces = face->num_faces; + + if ((face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) { - if (faceIndex == 0) - numFaces = face->num_faces; + FreeTypeFontFace* const newFace = findOrCreate (face->family_name, true); + int style = (int) FreeTypeFontFace::Plain; - if ((face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) - { - FreeTypeFontFace* const newFace = findOrCreate (face->family_name, true); - int style = (int) FreeTypeFontFace::Plain; + if ((face->style_flags & FT_STYLE_FLAG_BOLD) != 0) + style |= (int) FreeTypeFontFace::Bold; - if ((face->style_flags & FT_STYLE_FLAG_BOLD) != 0) - style |= (int) FreeTypeFontFace::Bold; + if ((face->style_flags & FT_STYLE_FLAG_ITALIC) != 0) + style |= (int) FreeTypeFontFace::Italic; - if ((face->style_flags & FT_STYLE_FLAG_ITALIC) != 0) - style |= (int) FreeTypeFontFace::Italic; + newFace->setFileName (fontFileIterator.getFile().getFullPathName(), + faceIndex, (FreeTypeFontFace::FontStyle) style); + newFace->setMonospaced ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0); - newFace->setFileName (possible.getFullPathName(), faceIndex, (FreeTypeFontFace::FontStyle) style); - newFace->setMonospaced ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0); + // Surely there must be a better way to do this? + const String name (face->family_name); + newFace->setSerif (! (name.containsIgnoreCase ("Sans") + || name.containsIgnoreCase ("Verdana") + || name.containsIgnoreCase ("Arial"))); - // Surely there must be a better way to do this? - const String name (face->family_name); - newFace->setSerif (! (name.containsIgnoreCase ("Sans") - || name.containsIgnoreCase ("Verdana") - || name.containsIgnoreCase ("Arial"))); - } - - FT_Done_Face (face); + //DBG (fontFileIterator.getFile().getFullPathName() << " - " << name); } - ++faceIndex; + FT_Done_Face (face); } - while (faceIndex < numFaces); + + ++faceIndex; } + while (faceIndex < numFaces); } } + ~FreeTypeInterface() + { + if (lastFace != 0) + FT_Done_Face (lastFace); + + if (ftLib != 0) + FT_Done_FreeType (ftLib); + + clearSingletonInstance(); + } + + FreeTypeFontFace* findOrCreate (const String& familyName, const bool create = false) + { + for (int i = 0; i < faces.size(); i++) + if (faces[i]->getFamilyName() == familyName) + return faces[i]; + + if (! create) + return nullptr; + + FreeTypeFontFace* newFace = new FreeTypeFontFace (familyName); + faces.add (newFace); + + return newFace; + } + // Create a FreeType face object for a given font FT_Face createFT_Face (const String& fontName, const bool bold, const bool italic) { @@ -263252,11 +263271,11 @@ public: if (face == 0) { -#if JUCE_DEBUG + #if JUCE_DEBUG String msg ("Failed to create typeface: "); msg << font.getTypefaceName() << " " << (font.isBold() ? 'B' : ' ') << (font.isItalic() ? 'I' : ' '); DBG (msg); -#endif + #endif } else { @@ -263287,15 +263306,12 @@ const StringArray Font::findAllTypefaceNames() return s; } -namespace +namespace LinuxFontHelpers { const String pickBestFont (const StringArray& names, - const char* const choicesString) + const char* const* choicesString) { - StringArray choices; - choices.addTokens (String (choicesString), ",", String::empty); - choices.trim(); - choices.removeEmptyStrings(); + const StringArray choices (choicesString); int i, j; for (j = 0; j < choices.size(); ++j) @@ -263315,36 +263331,39 @@ namespace return names[0]; } - const String linux_getDefaultSansSerifFontName() + const String getDefaultSansSerifFontName() { StringArray allFonts; FreeTypeInterface::getInstance()->getSansSerifNames (allFonts); - return pickBestFont (allFonts, "Verdana, Bitstream Vera Sans, Luxi Sans, Sans"); + const char* targets[] = { "Verdana", "Bitstream Vera Sans", "Luxi Sans", "Sans", 0 }; + return pickBestFont (allFonts, targets); } - const String linux_getDefaultSerifFontName() + const String getDefaultSerifFontName() { StringArray allFonts; FreeTypeInterface::getInstance()->getSerifNames (allFonts); - return pickBestFont (allFonts, "Bitstream Vera Serif, Times, Nimbus Roman, Serif"); + const char* targets[] = { "Bitstream Vera Serif", "Times", "Nimbus Roman", "Serif", 0 }; + return pickBestFont (allFonts, targets); } - const String linux_getDefaultMonospacedFontName() + const String getDefaultMonospacedFontName() { StringArray allFonts; FreeTypeInterface::getInstance()->getMonospacedNames (allFonts); - return pickBestFont (allFonts, "Bitstream Vera Sans Mono, Courier, Sans Mono, Mono"); + const char* targets[] = { "Bitstream Vera Sans Mono", "Courier", "Sans Mono", "Mono", 0 }; + return pickBestFont (allFonts, targets); } } void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& /*defaultFallback*/) { - defaultSans = linux_getDefaultSansSerifFontName(); - defaultSerif = linux_getDefaultSerifFontName(); - defaultFixed = linux_getDefaultMonospacedFontName(); + defaultSans = LinuxFontHelpers::getDefaultSansSerifFontName(); + defaultSerif = LinuxFontHelpers::getDefaultSerifFontName(); + defaultFixed = LinuxFontHelpers::getDefaultMonospacedFontName(); } #endif @@ -279769,11 +279788,10 @@ bool NSViewComponentPeer::contains (const Point& position, bool trueIfInACh && isPositiveAndBelow (position.getY(), component->getHeight()))) return false; - NSPoint p; - p.x = (float) position.getX(); - p.y = (float) position.getY(); + NSRect frameRect = [view frame]; - NSView* v = [view hitTest: p]; + NSView* v = [view hitTest: NSMakePoint (frameRect.origin.x + position.getX(), + frameRect.origin.y + frameRect.size.height - position.getY())]; if (trueIfInAChildWindow) return v != nil; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 0f5ab51cf0..96f79e9ba4 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 90 +#define JUCE_BUILDNUMBER 91 /** Current Juce version number. @@ -37649,6 +37649,7 @@ public: bool canDoStereo(); bool canDoMono(); bool isCompressed(); + const StringArray getQualityOptions(); AudioFormatReader* createReaderFor (InputStream* sourceStream, bool deleteStreamIfOpeningFails); @@ -37659,7 +37660,6 @@ public: int bitsPerSample, const StringPairArray& metadataValues, int qualityOptionIndex); - private: JUCE_LEAK_DETECTOR (FlacAudioFormat); }; @@ -58916,229 +58916,6 @@ private: #ifndef __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ #define __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ - -/*** Start of inlined file: juce_Keypress.h ***/ -#ifndef __JUCE_KEYPRESS_JUCEHEADER__ -#define __JUCE_KEYPRESS_JUCEHEADER__ - -/** - Represents a key press, including any modifier keys that are needed. - - E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc. - - @see Component, KeyListener, Button::addShortcut, KeyPressMappingManager -*/ -class JUCE_API KeyPress -{ -public: - - /** Creates an (invalid) KeyPress. - - @see isValid - */ - KeyPress() noexcept; - - /** Creates a KeyPress for a key and some modifiers. - - e.g. - CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier) - SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier) - - @param keyCode a code that represents the key - this value must be - one of special constants listed in this class, or an - 8-bit character code such as a letter (case is ignored), - digit or a simple key like "," or ".". Note that this - isn't the same as the textCharacter parameter, so for example - a keyCode of 'a' and a shift-key modifier should have a - textCharacter value of 'A'. - @param modifiers the modifiers to associate with the keystroke - @param textCharacter the character that would be printed if someone typed - this keypress into a text editor. This value may be - null if the keypress is a non-printing character - @see getKeyCode, isKeyCode, getModifiers - */ - KeyPress (int keyCode, - const ModifierKeys& modifiers, - juce_wchar textCharacter) noexcept; - - /** Creates a keypress with a keyCode but no modifiers or text character. - */ - KeyPress (int keyCode) noexcept; - - /** Creates a copy of another KeyPress. */ - KeyPress (const KeyPress& other) noexcept; - - /** Copies this KeyPress from another one. */ - KeyPress& operator= (const KeyPress& other) noexcept; - - /** Compares two KeyPress objects. */ - bool operator== (const KeyPress& other) const noexcept; - - /** Compares two KeyPress objects. */ - bool operator!= (const KeyPress& other) const noexcept; - - /** Returns true if this is a valid KeyPress. - - A null keypress can be created by the default constructor, in case it's - needed. - */ - bool isValid() const noexcept { return keyCode != 0; } - - /** Returns the key code itself. - - This will either be one of the special constants defined in this class, - or an 8-bit character code. - */ - int getKeyCode() const noexcept { return keyCode; } - - /** Returns the key modifiers. - - @see ModifierKeys - */ - const ModifierKeys getModifiers() const noexcept { return mods; } - - /** Returns the character that is associated with this keypress. - - This is the character that you'd expect to see printed if you press this - keypress in a text editor or similar component. - */ - juce_wchar getTextCharacter() const noexcept { return textCharacter; } - - /** Checks whether the KeyPress's key is the same as the one provided, without checking - the modifiers. - - The values for key codes can either be one of the special constants defined in - this class, or an 8-bit character code. - - @see getKeyCode - */ - bool isKeyCode (int keyCodeToCompare) const noexcept { return keyCode == keyCodeToCompare; } - - /** Converts a textual key description to a KeyPress. - - This attempts to decode a textual version of a keypress, e.g. "CTRL + C" or "SPACE". - - This isn't designed to cope with any kind of input, but should be given the - strings that are created by the getTextDescription() method. - - If the string can't be parsed, the object returned will be invalid. - - @see getTextDescription - */ - static const KeyPress createFromDescription (const String& textVersion); - - /** Creates a textual description of the key combination. - - e.g. "CTRL + C" or "DELETE". - - To store a keypress in a file, use this method, along with createFromDescription() - to retrieve it later. - */ - const String getTextDescription() const; - - /** Creates a textual description of the key combination, using unicode icon symbols if possible. - - On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual - modifier key descriptions that are returned by getTextDescription() - */ - const String getTextDescriptionWithIcons() const; - - /** Checks whether the user is currently holding down the keys that make up this - KeyPress. - - Note that this will return false if any extra modifier keys are - down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x - then it will be false. - */ - bool isCurrentlyDown() const; - - /** Checks whether a particular key is held down, irrespective of modifiers. - - The values for key codes can either be one of the special constants defined in - this class, or an 8-bit character code. - */ - static bool isKeyCurrentlyDown (int keyCode); - - // Key codes - // - // Note that the actual values of these are platform-specific and may change - // without warning, so don't store them anywhere as constants. For persisting/retrieving - // KeyPress objects, use getTextDescription() and createFromDescription() instead. - // - - static const int spaceKey; /**< key-code for the space bar */ - static const int escapeKey; /**< key-code for the escape key */ - static const int returnKey; /**< key-code for the return key*/ - static const int tabKey; /**< key-code for the tab key*/ - - static const int deleteKey; /**< key-code for the delete key (not backspace) */ - static const int backspaceKey; /**< key-code for the backspace key */ - static const int insertKey; /**< key-code for the insert key */ - - static const int upKey; /**< key-code for the cursor-up key */ - static const int downKey; /**< key-code for the cursor-down key */ - static const int leftKey; /**< key-code for the cursor-left key */ - static const int rightKey; /**< key-code for the cursor-right key */ - static const int pageUpKey; /**< key-code for the page-up key */ - static const int pageDownKey; /**< key-code for the page-down key */ - static const int homeKey; /**< key-code for the home key */ - static const int endKey; /**< key-code for the end key */ - - static const int F1Key; /**< key-code for the F1 key */ - static const int F2Key; /**< key-code for the F2 key */ - static const int F3Key; /**< key-code for the F3 key */ - static const int F4Key; /**< key-code for the F4 key */ - static const int F5Key; /**< key-code for the F5 key */ - static const int F6Key; /**< key-code for the F6 key */ - static const int F7Key; /**< key-code for the F7 key */ - static const int F8Key; /**< key-code for the F8 key */ - static const int F9Key; /**< key-code for the F9 key */ - static const int F10Key; /**< key-code for the F10 key */ - static const int F11Key; /**< key-code for the F11 key */ - static const int F12Key; /**< key-code for the F12 key */ - static const int F13Key; /**< key-code for the F13 key */ - static const int F14Key; /**< key-code for the F14 key */ - static const int F15Key; /**< key-code for the F15 key */ - static const int F16Key; /**< key-code for the F16 key */ - - static const int numberPad0; /**< key-code for the 0 on the numeric keypad. */ - static const int numberPad1; /**< key-code for the 1 on the numeric keypad. */ - static const int numberPad2; /**< key-code for the 2 on the numeric keypad. */ - static const int numberPad3; /**< key-code for the 3 on the numeric keypad. */ - static const int numberPad4; /**< key-code for the 4 on the numeric keypad. */ - static const int numberPad5; /**< key-code for the 5 on the numeric keypad. */ - static const int numberPad6; /**< key-code for the 6 on the numeric keypad. */ - static const int numberPad7; /**< key-code for the 7 on the numeric keypad. */ - static const int numberPad8; /**< key-code for the 8 on the numeric keypad. */ - static const int numberPad9; /**< key-code for the 9 on the numeric keypad. */ - - static const int numberPadAdd; /**< key-code for the add sign on the numeric keypad. */ - static const int numberPadSubtract; /**< key-code for the subtract sign on the numeric keypad. */ - static const int numberPadMultiply; /**< key-code for the multiply sign on the numeric keypad. */ - static const int numberPadDivide; /**< key-code for the divide sign on the numeric keypad. */ - static const int numberPadSeparator; /**< key-code for the comma on the numeric keypad. */ - static const int numberPadDecimalPoint; /**< key-code for the decimal point sign on the numeric keypad. */ - static const int numberPadEquals; /**< key-code for the equals key on the numeric keypad. */ - static const int numberPadDelete; /**< key-code for the delete key on the numeric keypad. */ - - static const int playKey; /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */ - static const int stopKey; /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */ - static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */ - static const int rewindKey; /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */ - -private: - - int keyCode; - ModifierKeys mods; - juce_wchar textCharacter; - - JUCE_LEAK_DETECTOR (KeyPress); -}; - -#endif // __JUCE_KEYPRESS_JUCEHEADER__ - -/*** End of inlined file: juce_Keypress.h ***/ - /** This class is used to invoke a range of text-editor navigation methods on an object, based upon a keypress event. diff --git a/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp b/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp index 9c41e09423..be59d9e6e3 100644 --- a/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_FlacAudioFormat.cpp @@ -488,7 +488,7 @@ FlacAudioFormat::~FlacAudioFormat() const Array FlacAudioFormat::getPossibleSampleRates() { - const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 0 }; + const int rates[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 0 }; return Array (rates); } @@ -534,6 +534,12 @@ AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out, return nullptr; } +const StringArray FlacAudioFormat::getQualityOptions() +{ + const char* options[] = { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)", 0 }; + return StringArray (options); +} + END_JUCE_NAMESPACE #endif diff --git a/src/audio/audio_file_formats/juce_FlacAudioFormat.h b/src/audio/audio_file_formats/juce_FlacAudioFormat.h index bf30857441..3c67c67128 100644 --- a/src/audio/audio_file_formats/juce_FlacAudioFormat.h +++ b/src/audio/audio_file_formats/juce_FlacAudioFormat.h @@ -54,6 +54,7 @@ public: bool canDoStereo(); bool canDoMono(); bool isCompressed(); + const StringArray getQualityOptions(); //============================================================================== AudioFormatReader* createReaderFor (InputStream* sourceStream, @@ -65,7 +66,6 @@ public: int bitsPerSample, const StringPairArray& metadataValues, int qualityOptionIndex); - private: JUCE_LEAK_DETECTOR (FlacAudioFormat); }; diff --git a/src/audio/plugin_host/juce_KnownPluginList.cpp b/src/audio/plugin_host/juce_KnownPluginList.cpp index 3bb169d748..ff592c1299 100644 --- a/src/audio/plugin_host/juce_KnownPluginList.cpp +++ b/src/audio/plugin_host/juce_KnownPluginList.cpp @@ -179,34 +179,29 @@ void KnownPluginList::scanAndAddDragAndDroppedFiles (const StringArray& files, { for (int i = 0; i < files.size(); ++i) { - bool loaded = false; - for (int j = 0; j < AudioPluginFormatManager::getInstance()->getNumFormats(); ++j) { AudioPluginFormat* const format = AudioPluginFormatManager::getInstance()->getFormat (j); if (scanAndAddFile (files[i], true, typesFound, *format)) - loaded = true; + return; } - if (! loaded) + const File f (files[i]); + + if (f.isDirectory()) { - const File f (files[i]); + StringArray s; - if (f.isDirectory()) { - StringArray s; - - { - Array subFiles; - f.findChildFiles (subFiles, File::findFilesAndDirectories, false); + Array subFiles; + f.findChildFiles (subFiles, File::findFilesAndDirectories, false); - for (int j = 0; j < subFiles.size(); ++j) - s.add (subFiles.getReference(j).getFullPathName()); - } - - scanAndAddDragAndDroppedFiles (s, typesFound); + for (int j = 0; j < subFiles.size(); ++j) + s.add (subFiles.getReference(j).getFullPathName()); } + + scanAndAddDragAndDroppedFiles (s, typesFound); } } } diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 4c26505ba4..172ff38b26 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 90 +#define JUCE_BUILDNUMBER 91 /** Current Juce version number. diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp index 89b4548343..5f92921e94 100644 --- a/src/gui/components/juce_Component.cpp +++ b/src/gui/components/juce_Component.cpp @@ -2043,7 +2043,8 @@ const Colour Component::findColour (const int colourId, const bool inheritFromPa if (v != nullptr) return Colour ((int) *v); - if (inheritFromParent && parentComponent != nullptr) + if (inheritFromParent && parentComponent != nullptr + && (lookAndFeel == nullptr || ! lookAndFeel->isColourSpecified (colourId))) return parentComponent->findColour (colourId, true); return getLookAndFeel().findColour (colourId); diff --git a/src/gui/components/keyboard/juce_TextEditorKeyMapper.h b/src/gui/components/keyboard/juce_TextEditorKeyMapper.h index 7ed41bd548..e8bacae01a 100644 --- a/src/gui/components/keyboard/juce_TextEditorKeyMapper.h +++ b/src/gui/components/keyboard/juce_TextEditorKeyMapper.h @@ -26,7 +26,8 @@ #ifndef __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ #define __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ -#include "juce_Keypress.h" +#include "juce_KeyPress.h" + //============================================================================== /** This class is used to invoke a range of text-editor navigation methods on diff --git a/src/gui/components/layout/juce_ResizableCornerComponent.cpp b/src/gui/components/layout/juce_ResizableCornerComponent.cpp index d8af351ec5..4555090cba 100644 --- a/src/gui/components/layout/juce_ResizableCornerComponent.cpp +++ b/src/gui/components/layout/juce_ResizableCornerComponent.cpp @@ -99,7 +99,7 @@ void ResizableCornerComponent::mouseDrag (const MouseEvent& e) void ResizableCornerComponent::mouseUp (const MouseEvent&) { if (constrainer != nullptr) - constrainer->resizeStart(); + constrainer->resizeEnd(); } bool ResizableCornerComponent::hitTest (int x, int y) diff --git a/src/native/linux/juce_linux_Fonts.cpp b/src/native/linux/juce_linux_Fonts.cpp index cfbab691ac..9b59de675c 100644 --- a/src/native/linux/juce_linux_Fonts.cpp +++ b/src/native/linux/juce_linux_Fonts.cpp @@ -85,6 +85,60 @@ private: bool hasSerif, monospaced; }; +//============================================================================== +class LinuxFontFileIterator +{ +public: + LinuxFontFileIterator() + : index (0) + { + fontDirs.addTokens (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH")), ";,", String::empty); + fontDirs.removeEmptyStrings (true); + + if (fontDirs.size() == 0) + { + const ScopedPointer fontsInfo (XmlDocument::parse (File ("/etc/fonts/fonts.conf"))); + + if (fontsInfo != nullptr) + { + forEachXmlChildElementWithTagName (*fontsInfo, e, "dir") + { + fontDirs.add (e->getAllSubText().trim()); + } + } + } + + if (fontDirs.size() == 0) + fontDirs.add ("/usr/X11R6/lib/X11/fonts"); + + fontDirs.removeEmptyStrings (true); + } + + bool next() + { + if (iter != nullptr) + { + while (iter->next()) + if (getFile().hasFileExtension ("ttf;pfb;pcf")) + return true; + } + + if (index >= fontDirs.size()) + return false; + + iter = new DirectoryIterator (fontDirs [index++], true); + return next(); + } + + File getFile() const { jassert (iter != nullptr); return iter->getFile(); } + +private: + StringArray fontDirs; + int index; + ScopedPointer iter; +}; + + //============================================================================== class FreeTypeInterface : public DeletedAtShutdown { @@ -102,28 +156,53 @@ public: DBG ("Failed to initialize FreeType"); } - StringArray fontDirs; - fontDirs.addTokens (CharPointer_UTF8 (getenv ("JUCE_FONT_PATH")), ";,", String::empty); - fontDirs.removeEmptyStrings (true); + LinuxFontFileIterator fontFileIterator; - if (fontDirs.size() == 0) + while (fontFileIterator.next()) { - const ScopedPointer fontsInfo (XmlDocument::parse (File ("/etc/fonts/fonts.conf"))); + FT_Face face; + int faceIndex = 0; + int numFaces = 0; - if (fontsInfo != nullptr) + do { - forEachXmlChildElementWithTagName (*fontsInfo, e, "dir") + if (FT_New_Face (ftLib, fontFileIterator.getFile().getFullPathName().toUTF8(), + faceIndex, &face) == 0) { - fontDirs.add (e->getAllSubText().trim()); + if (faceIndex == 0) + numFaces = face->num_faces; + + if ((face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) + { + FreeTypeFontFace* const newFace = findOrCreate (face->family_name, true); + int style = (int) FreeTypeFontFace::Plain; + + if ((face->style_flags & FT_STYLE_FLAG_BOLD) != 0) + style |= (int) FreeTypeFontFace::Bold; + + if ((face->style_flags & FT_STYLE_FLAG_ITALIC) != 0) + style |= (int) FreeTypeFontFace::Italic; + + newFace->setFileName (fontFileIterator.getFile().getFullPathName(), + faceIndex, (FreeTypeFontFace::FontStyle) style); + newFace->setMonospaced ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0); + + // Surely there must be a better way to do this? + const String name (face->family_name); + newFace->setSerif (! (name.containsIgnoreCase ("Sans") + || name.containsIgnoreCase ("Verdana") + || name.containsIgnoreCase ("Arial"))); + + //DBG (fontFileIterator.getFile().getFullPathName() << " - " << name); + } + + FT_Done_Face (face); } + + ++faceIndex; } + while (faceIndex < numFaces); } - - if (fontDirs.size() == 0) - fontDirs.add ("/usr/X11R6/lib/X11/fonts"); - - for (int i = 0; i < fontDirs.size(); ++i) - enumerateFaces (fontDirs[i]); } ~FreeTypeInterface() @@ -153,66 +232,6 @@ public: return newFace; } - // Enumerate all font faces available in a given directory - void enumerateFaces (const String& path) - { - File dirPath (path); - if (path.isEmpty() || ! dirPath.isDirectory()) - return; - - DirectoryIterator di (dirPath, true); - - while (di.next()) - { - File possible (di.getFile()); - - if (possible.hasFileExtension ("ttf") - || possible.hasFileExtension ("pfb") - || possible.hasFileExtension ("pcf")) - { - FT_Face face; - int faceIndex = 0; - int numFaces = 0; - - do - { - if (FT_New_Face (ftLib, possible.getFullPathName().toUTF8(), - faceIndex, &face) == 0) - { - if (faceIndex == 0) - numFaces = face->num_faces; - - if ((face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) - { - FreeTypeFontFace* const newFace = findOrCreate (face->family_name, true); - int style = (int) FreeTypeFontFace::Plain; - - if ((face->style_flags & FT_STYLE_FLAG_BOLD) != 0) - style |= (int) FreeTypeFontFace::Bold; - - if ((face->style_flags & FT_STYLE_FLAG_ITALIC) != 0) - style |= (int) FreeTypeFontFace::Italic; - - newFace->setFileName (possible.getFullPathName(), faceIndex, (FreeTypeFontFace::FontStyle) style); - newFace->setMonospaced ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0); - - // Surely there must be a better way to do this? - const String name (face->family_name); - newFace->setSerif (! (name.containsIgnoreCase ("Sans") - || name.containsIgnoreCase ("Verdana") - || name.containsIgnoreCase ("Arial"))); - } - - FT_Done_Face (face); - } - - ++faceIndex; - } - while (faceIndex < numFaces); - } - } - } - // Create a FreeType face object for a given font FT_Face createFT_Face (const String& fontName, const bool bold, const bool italic) { @@ -473,11 +492,11 @@ public: if (face == 0) { -#if JUCE_DEBUG + #if JUCE_DEBUG String msg ("Failed to create typeface: "); msg << font.getTypefaceName() << " " << (font.isBold() ? 'B' : ' ') << (font.isItalic() ? 'I' : ' '); DBG (msg); -#endif + #endif } else { @@ -509,15 +528,12 @@ const StringArray Font::findAllTypefaceNames() return s; } -namespace +namespace LinuxFontHelpers { const String pickBestFont (const StringArray& names, - const char* const choicesString) + const char* const* choicesString) { - StringArray choices; - choices.addTokens (String (choicesString), ",", String::empty); - choices.trim(); - choices.removeEmptyStrings(); + const StringArray choices (choicesString); int i, j; for (j = 0; j < choices.size(); ++j) @@ -537,36 +553,39 @@ namespace return names[0]; } - const String linux_getDefaultSansSerifFontName() + const String getDefaultSansSerifFontName() { StringArray allFonts; FreeTypeInterface::getInstance()->getSansSerifNames (allFonts); - return pickBestFont (allFonts, "Verdana, Bitstream Vera Sans, Luxi Sans, Sans"); + const char* targets[] = { "Verdana", "Bitstream Vera Sans", "Luxi Sans", "Sans", 0 }; + return pickBestFont (allFonts, targets); } - const String linux_getDefaultSerifFontName() + const String getDefaultSerifFontName() { StringArray allFonts; FreeTypeInterface::getInstance()->getSerifNames (allFonts); - return pickBestFont (allFonts, "Bitstream Vera Serif, Times, Nimbus Roman, Serif"); + const char* targets[] = { "Bitstream Vera Serif", "Times", "Nimbus Roman", "Serif", 0 }; + return pickBestFont (allFonts, targets); } - const String linux_getDefaultMonospacedFontName() + const String getDefaultMonospacedFontName() { StringArray allFonts; FreeTypeInterface::getInstance()->getMonospacedNames (allFonts); - return pickBestFont (allFonts, "Bitstream Vera Sans Mono, Courier, Sans Mono, Mono"); + const char* targets[] = { "Bitstream Vera Sans Mono", "Courier", "Sans Mono", "Mono", 0 }; + return pickBestFont (allFonts, targets); } } void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& /*defaultFallback*/) { - defaultSans = linux_getDefaultSansSerifFontName(); - defaultSerif = linux_getDefaultSerifFontName(); - defaultFixed = linux_getDefaultMonospacedFontName(); + defaultSans = LinuxFontHelpers::getDefaultSansSerifFontName(); + defaultSerif = LinuxFontHelpers::getDefaultSerifFontName(); + defaultFixed = LinuxFontHelpers::getDefaultMonospacedFontName(); } #endif diff --git a/src/native/mac/juce_mac_NSViewComponentPeer.mm b/src/native/mac/juce_mac_NSViewComponentPeer.mm index 120d1abeba..2e2caa49ff 100644 --- a/src/native/mac/juce_mac_NSViewComponentPeer.mm +++ b/src/native/mac/juce_mac_NSViewComponentPeer.mm @@ -1115,11 +1115,10 @@ bool NSViewComponentPeer::contains (const Point& position, bool trueIfInACh && isPositiveAndBelow (position.getY(), component->getHeight()))) return false; - NSPoint p; - p.x = (float) position.getX(); - p.y = (float) position.getY(); + NSRect frameRect = [view frame]; - NSView* v = [view hitTest: p]; + NSView* v = [view hitTest: NSMakePoint (frameRect.origin.x + position.getX(), + frameRect.origin.y + frameRect.size.height - position.getY())]; if (trueIfInAChildWindow) return v != nil;