Browse Source

small change for loading opentype fonts in win32; fix for an audio plugins crash when closing the plugin in some recent hosts; fixes for linux VST event handling; change to the format reported by RTAS plugins with zero inputs or outputs; NPAPI plugin positioning for for mac firefox; fix for TreeViewItem button safety; added method LookAndFeel::getFontForTextButton; added an interpolation quality selector to MagnifierComponent; AlertWindows are now always-on-top in plugins; fix to RectanglePlacement::getScaleToFit(); added some utility methods to the URL class.

tags/2021-05-28
jules 16 years ago
parent
commit
1e53260e0a
17 changed files with 1290 additions and 1031 deletions
  1. +2
    -3
      build/win32/platform_specific_code/juce_win32_Fonts.cpp
  2. +17
    -6
      extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm
  3. +1002
    -1002
      extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp
  4. +18
    -2
      extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp
  5. +1
    -1
      extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp
  6. +93
    -10
      juce_amalgamated.cpp
  7. +33
    -0
      juce_amalgamated.h
  8. +10
    -1
      src/juce_appframework/gui/components/controls/juce_TreeView.cpp
  9. +6
    -1
      src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp
  10. +2
    -0
      src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h
  11. +3
    -2
      src/juce_appframework/gui/components/special/juce_MagnifierComponent.cpp
  12. +4
    -0
      src/juce_appframework/gui/components/special/juce_MagnifierComponent.h
  13. +4
    -0
      src/juce_appframework/gui/components/windows/juce_AlertWindow.cpp
  14. +1
    -0
      src/juce_appframework/gui/graphics/contexts/juce_EdgeTable.cpp
  15. +1
    -3
      src/juce_appframework/gui/graphics/contexts/juce_RectanglePlacement.cpp
  16. +67
    -0
      src/juce_core/io/network/juce_URL.cpp
  17. +26
    -0
      src/juce_core/io/network/juce_URL.h

+ 2
- 3
build/win32/platform_specific_code/juce_win32_Fonts.cpp View File

@@ -40,7 +40,7 @@ static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
int type,
LPARAM lParam)
{
if (lpelfe != 0 && type == TRUETYPE_FONTTYPE)
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
const String fontName (lpelfe->elfLogFont.lfFaceName);
@@ -55,8 +55,7 @@ static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
int type,
LPARAM lParam)
{
if (lpelfe != 0
&& ((type & (DEVICE_FONTTYPE | RASTER_FONTTYPE)) == 0))
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
LOGFONTW lf;
zerostruct (lf);


+ 17
- 6
extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm View File

@@ -55,7 +55,7 @@
//==============================================================================
#define juceFilterObjectPropertyID 0x1a45ffe9
static VoidArray activePlugins;
static VoidArray activePlugins, activeUIs;
static const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations };
static const int numChannelConfigs = numElementsInArray (channelConfigs);
@@ -108,7 +108,7 @@ public:
channels (0),
prepared (false)
{
if (activePlugins.size() == 0)
if (activePlugins.size() + activeUIs.size() == 0)
{
#if BUILD_AU_CARBON_UI
NSApplicationLoad();
@@ -143,7 +143,7 @@ public:
jassert (activePlugins.contains (this));
activePlugins.removeValue (this);
if (activePlugins.size() == 0)
if (activePlugins.size() + activeUIs.size() == 0)
shutdownJuce_GUI();
}
@@ -993,6 +993,8 @@ public:
[self setHidden: NO];
[self setPostsFrameChangedNotifications: YES];
activeUIs.add (self);
editorComp->addToDesktop (0, (void*) self);
editorComp->setVisible (true);
@@ -1005,10 +1007,19 @@ public:
// is trying to delete our plugin..
jassert (Component::getCurrentlyModalComponent() == 0);
if (editorComp != 0 && editorComp->getChildComponent(0) != 0)
filter->editorBeingDeleted ((AudioProcessorEditor*) editorComp->getChildComponent(0));
if (editorComp != 0 && editorComp->isValidComponent())
{
if (editorComp->getChildComponent(0) != 0)
if (activePlugins.contains ((void*) filter)) // plugin may have been deleted before the UI
filter->editorBeingDeleted ((AudioProcessorEditor*) editorComp->getChildComponent(0));
deleteAndZero (editorComp);
}
deleteAndZero (editorComp);
jassert (activeUIs.contains (self));
activeUIs.removeValue (self);
if (activePlugins.size() + activeUIs.size() == 0)
shutdownJuce_GUI();
[super dealloc];
}


+ 1002
- 1002
extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp
File diff suppressed because it is too large
View File


+ 18
- 2
extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp View File

@@ -221,9 +221,13 @@ class SharedMessageThread : public Thread
{
public:
SharedMessageThread()
: Thread (T("VstMessageThread"))
: Thread (T("VstMessageThread")),
initialised (false)
{
startThread (7);
while (! initialised)
sleep (1);
}
~SharedMessageThread()
@@ -241,6 +245,9 @@ public:
const Thread::ThreadID originalThreadId = messageManager->getCurrentMessageThread();
messageManager->setCurrentMessageThread (Thread::getCurrentThreadId());
initialiseJuce_GUI();
initialised = true;
while ((! threadShouldExit()) && messageManager->runDispatchLoopUntil (250))
{
}
@@ -249,8 +256,12 @@ public:
}
juce_DeclareSingleton (SharedMessageThread, false)
private:
bool initialised;
};
juce_ImplementSingleton (SharedMessageThread)
#endif
@@ -446,6 +457,7 @@ public:
{
if (editorComp == 0)
{
const MessageManagerLock mmLock;
AudioProcessorEditor* const ed = filter->createEditorIfNeeded();
if (ed != 0)
@@ -462,6 +474,7 @@ public:
void close()
{
const MessageManagerLock mmLock;
jassert (! recursionCheck);
stopTimer();
@@ -1179,6 +1192,7 @@ public:
if (canDeleteLaterIfModal)
{
shouldDeleteEditor = true;
recursionCheck = false;
return;
}
}
@@ -1219,6 +1233,7 @@ public:
}
else if (opCode == effEditOpen)
{
const MessageManagerLock mmLock;
jassert (! recursionCheck);
deleteEditor (true);
@@ -1253,11 +1268,13 @@ public:
}
else if (opCode == effEditClose)
{
const MessageManagerLock mmLock;
deleteEditor (true);
return 0;
}
else if (opCode == effEditGetRect)
{
const MessageManagerLock mmLock;
createEditorComp();
if (editorComp != 0)
@@ -1490,7 +1507,6 @@ extern "C" __attribute__ ((visibility("default"))) AEffect* main_macho (audioMas
extern "C" AEffect* VSTPluginMain (audioMasterCallback audioMaster)
{
initialiseJuce_GUI();
SharedMessageThread::getInstance();
return pluginEntryPoint (audioMaster);


+ 1
- 1
extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp View File

@@ -447,7 +447,7 @@ public:
{
return [[v className] isEqualToString: @"WebNetscapePluginDocumentView"]
|| [[v className] isEqualToString: @"WebPluginDocumentView"]
|| [[v className] isEqualToString: @"ChildView"];
|| ([[v className] isEqualToString: @"ChildView"] && ([v frame].origin.x != 0 && [v frame].origin.y != 0));
}
void setWindow (NPWindow* window)


+ 93
- 10
juce_amalgamated.cpp View File

@@ -7965,6 +7965,73 @@ bool URL::isWellFormed() const
return url.isNotEmpty();
}

static int findStartOfDomain (const String& url)
{
int i = 0;

while (CharacterFunctions::isLetterOrDigit (url[i])
|| CharacterFunctions::indexOfChar (T("+-."), url[i], false) >= 0)
++i;

return url[i] == T(':') ? i + 1 : 0;
}

const String URL::getDomain() const
{
int start = findStartOfDomain (url);
while (url[start] == T('/'))
++start;

const int end1 = url.indexOfChar (start, T('/'));
const int end2 = url.indexOfChar (start, T(':'));

const int end = (end1 < 0 || end2 < 0) ? jmax (end1, end2)
: jmin (end1, end2);

return url.substring (start, end);
}

const String URL::getSubPath() const
{
int start = findStartOfDomain (url);
while (url[start] == T('/'))
++start;

const int startOfPath = url.indexOfChar (start, T('/')) + 1;

return startOfPath <= 0 ? String::empty
: url.substring (startOfPath);
}

const String URL::getScheme() const
{
return url.substring (0, findStartOfDomain (url) - 1);
}

const URL URL::withNewSubPath (const String& newPath) const
{
int start = findStartOfDomain (url);
while (url[start] == T('/'))
++start;

const int startOfPath = url.indexOfChar (start, T('/')) + 1;

URL u (*this);

if (startOfPath > 0)
u.url = url.substring (0, startOfPath);

if (! u.url.endsWithChar (T('/')))
u.url << '/';

if (newPath.startsWithChar (T('/')))
u.url << newPath.substring (1);
else
u.url << newPath;

return u;
}

bool URL::isProbablyAWebsiteURL (const String& possibleURL)
{
if (possibleURL.startsWithIgnoreCase (T("http:"))
@@ -52504,7 +52571,7 @@ public:

if (buttonUnderMouse != newItem)
{
if (buttonUnderMouse != 0)
if (buttonUnderMouse != 0 && containsItem (buttonUnderMouse))
{
const Rectangle r (buttonUnderMouse->getItemPosition (false));
repaint (0, r.getY(), r.getX(), buttonUnderMouse->getItemHeight());
@@ -52588,6 +52655,15 @@ private:
item->setSelected ((! cmd) || (! item->isSelected()), ! cmd);
}
}

bool containsItem (TreeViewItem* const item) const
{
for (int i = rowComponentItems.size(); --i >= 0;)
if ((TreeViewItem*) rowComponentItems.getUnchecked (i) == item)
return true;

return false;
}
};

class TreeViewport : public Viewport
@@ -61074,10 +61150,15 @@ void LookAndFeel::drawButtonBackground (Graphics& g,
button.isConnectedOnBottom());
}

const Font LookAndFeel::getFontForTextButton (TextButton& button)
{
return button.getFont();
}

void LookAndFeel::drawButtonText (Graphics& g, TextButton& button,
bool /*isMouseOverButton*/, bool /*isButtonDown*/)
{
g.setFont (button.getFont());
g.setFont (getFontForTextButton (button));
g.setColour (button.findColour (TextButton::textColourId)
.withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));

@@ -70772,7 +70853,8 @@ MagnifierComponent::MagnifierComponent (Component* const content_,
: content (content_),
scaleFactor (0.0),
peer (0),
deleteContent (deleteContentCompWhenNoLongerNeeded)
deleteContent (deleteContentCompWhenNoLongerNeeded),
quality (Graphics::lowResamplingQuality)
{
holderComp = new PeerHolderComp (this);
setScaleFactor (1.0);
@@ -70844,7 +70926,7 @@ void MagnifierComponent::paint (Graphics& g)
g2.reduceClipRegion (srcX, srcY, srcW, srcH);
holderComp->paintEntireComponent (g2);

g.setImageResamplingQuality (Graphics::lowResamplingQuality);
g.setImageResamplingQuality (quality);
g.drawImage (&temp,
0, 0, (int) (w * scaleFactor), (int) (h * scaleFactor),
0, 0, w, h,
@@ -72256,6 +72338,9 @@ AlertWindow::AlertWindow (const String& title,
}
}

if (JUCEApplication::getInstance() == 0)
setAlwaysOnTop (true); // for a plugin, make it always-on-top because the host windows are often top-level

lookAndFeelChanged();

constrainer.setMinimumOnscreenAmounts (0x10000, 0x10000, 0x10000, 0x10000);
@@ -76602,6 +76687,7 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw
if (n >= maxEdgesPerLine)
{
remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine);
jassert (n < maxEdgesPerLine);
lineStart = table + lineStrideElements * y;
}

@@ -80551,11 +80637,9 @@ const AffineTransform RectanglePlacement::getTransformToFit (float x, float y,
const float scaleY = dh / h;

if ((flags & stretchToFit) != 0)
{
return AffineTransform::translation (-x, -y)
.scaled (scaleX, scaleY)
.translated (dx - x, dy - y);
}
.translated (dx, dy);

float scale = (flags & fillDestination) != 0 ? jmax (scaleX, scaleY)
: jmin (scaleX, scaleY);
@@ -246621,7 +246705,7 @@ static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
int type,
LPARAM lParam)
{
if (lpelfe != 0 && type == TRUETYPE_FONTTYPE)
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
const String fontName (lpelfe->elfLogFont.lfFaceName);

@@ -246636,8 +246720,7 @@ static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
int type,
LPARAM lParam)
{
if (lpelfe != 0
&& ((type & (DEVICE_FONTTYPE | RASTER_FONTTYPE)) == 0))
if (lpelfe != 0 && (type & RASTER_FONTTYPE) == 0)
{
LOGFONTW lf;
zerostruct (lf);


+ 33
- 0
juce_amalgamated.h View File

@@ -12593,6 +12593,32 @@ public:
/** True if it seems to be valid. */
bool isWellFormed() const;

/** Returns just the domain part of the URL.

E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com".
*/
const String getDomain() const;

/** Returns the path part of the URL.

E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar".
*/
const String getSubPath() const;

/** Returns the scheme of the URL.

E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't
include the colon).
*/
const String getScheme() const;

/** Returns a new version of this URL that uses a different sub-path.

E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
"bar", it'll return "http://www.xyz.com/bar?x=1".
*/
const URL withNewSubPath (const String& newPath) const;

/** Returns a copy of this URL, with a GET parameter added to the end.

Any control characters in the value will be encoded.
@@ -52446,6 +52472,10 @@ public:
/** Returns the current zoom factor. */
double getScaleFactor() const throw() { return scaleFactor; }

/** Changes the quality setting used to rescale the graphics.
*/
void setResamplingQuality (Graphics::ResamplingQuality newQuality);

juce_UseDebuggingNewOperator

/** @internal */
@@ -52457,6 +52487,7 @@ private:
double scaleFactor;
ComponentPeer* peer;
bool deleteContent;
Graphics::ResamplingQuality quality;

void paint (Graphics& g);
void mouseDown (const MouseEvent& e);
@@ -53803,6 +53834,8 @@ public:
bool isMouseOverButton,
bool isButtonDown);

virtual const Font getFontForTextButton (TextButton& button);

/** Draws the text for a TextButton. */
virtual void drawButtonText (Graphics& g,
TextButton& button,


+ 10
- 1
src/juce_appframework/gui/components/controls/juce_TreeView.cpp View File

@@ -278,7 +278,7 @@ public:
if (buttonUnderMouse != newItem)
{
if (buttonUnderMouse != 0)
if (buttonUnderMouse != 0 && containsItem (buttonUnderMouse))
{
const Rectangle r (buttonUnderMouse->getItemPosition (false));
repaint (0, r.getY(), r.getX(), buttonUnderMouse->getItemHeight());
@@ -363,6 +363,15 @@ private:
item->setSelected ((! cmd) || (! item->isSelected()), ! cmd);
}
}
bool containsItem (TreeViewItem* const item) const
{
for (int i = rowComponentItems.size(); --i >= 0;)
if ((TreeViewItem*) rowComponentItems.getUnchecked (i) == item)
return true;
return false;
}
};
//==============================================================================


+ 6
- 1
src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp View File

@@ -365,10 +365,15 @@ void LookAndFeel::drawButtonBackground (Graphics& g,
button.isConnectedOnBottom());
}
const Font LookAndFeel::getFontForTextButton (TextButton& button)
{
return button.getFont();
}
void LookAndFeel::drawButtonText (Graphics& g, TextButton& button,
bool /*isMouseOverButton*/, bool /*isButtonDown*/)
{
g.setFont (button.getFont());
g.setFont (getFontForTextButton (button));
g.setColour (button.findColour (TextButton::textColourId)
.withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));


+ 2
- 0
src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.h View File

@@ -153,6 +153,8 @@ public:
bool isMouseOverButton,
bool isButtonDown);
virtual const Font getFontForTextButton (TextButton& button);
/** Draws the text for a TextButton. */
virtual void drawButtonText (Graphics& g,
TextButton& button,


+ 3
- 2
src/juce_appframework/gui/components/special/juce_MagnifierComponent.cpp View File

@@ -200,7 +200,8 @@ MagnifierComponent::MagnifierComponent (Component* const content_,
: content (content_),
scaleFactor (0.0),
peer (0),
deleteContent (deleteContentCompWhenNoLongerNeeded)
deleteContent (deleteContentCompWhenNoLongerNeeded),
quality (Graphics::lowResamplingQuality)
{
holderComp = new PeerHolderComp (this);
setScaleFactor (1.0);
@@ -272,7 +273,7 @@ void MagnifierComponent::paint (Graphics& g)
g2.reduceClipRegion (srcX, srcY, srcW, srcH);
holderComp->paintEntireComponent (g2);
g.setImageResamplingQuality (Graphics::lowResamplingQuality);
g.setImageResamplingQuality (quality);
g.drawImage (&temp,
0, 0, (int) (w * scaleFactor), (int) (h * scaleFactor),
0, 0, w, h,


+ 4
- 0
src/juce_appframework/gui/components/special/juce_MagnifierComponent.h View File

@@ -89,6 +89,9 @@ public:
/** Returns the current zoom factor. */
double getScaleFactor() const throw() { return scaleFactor; }
/** Changes the quality setting used to rescale the graphics.
*/
void setResamplingQuality (Graphics::ResamplingQuality newQuality);
//==============================================================================
juce_UseDebuggingNewOperator
@@ -102,6 +105,7 @@ private:
double scaleFactor;
ComponentPeer* peer;
bool deleteContent;
Graphics::ResamplingQuality quality;
//==============================================================================
void paint (Graphics& g);


+ 4
- 0
src/juce_appframework/gui/components/windows/juce_AlertWindow.cpp View File

@@ -41,6 +41,7 @@ BEGIN_JUCE_NAMESPACE
#include "../juce_Desktop.h"
#include "../../../../juce_core/text/juce_LocalisedStrings.h"
#include "../../../events/juce_MessageManager.h"
#include "../../../application/juce_Application.h"
static const int titleH = 24;
static const int iconWidth = 80;
@@ -112,6 +113,9 @@ AlertWindow::AlertWindow (const String& title,
}
}
if (JUCEApplication::getInstance() == 0)
setAlwaysOnTop (true); // for a plugin, make it always-on-top because the host windows are often top-level
lookAndFeelChanged();
constrainer.setMinimumOnscreenAmounts (0x10000, 0x10000, 0x10000, 0x10000);


+ 1
- 0
src/juce_appframework/gui/graphics/contexts/juce_EdgeTable.cpp View File

@@ -135,6 +135,7 @@ void EdgeTable::addEdgePoint (const int x, const int y, const int winding) throw
if (n >= maxEdgesPerLine)
{
remapTableForNumEdges (maxEdgesPerLine + juce_edgeTableDefaultEdgesPerLine);
jassert (n < maxEdgesPerLine);
lineStart = table + lineStrideElements * y;
}


+ 1
- 3
src/juce_appframework/gui/graphics/contexts/juce_RectanglePlacement.cpp View File

@@ -105,11 +105,9 @@ const AffineTransform RectanglePlacement::getTransformToFit (float x, float y,
const float scaleY = dh / h;
if ((flags & stretchToFit) != 0)
{
return AffineTransform::translation (-x, -y)
.scaled (scaleX, scaleY)
.translated (dx - x, dy - y);
}
.translated (dx, dy);
float scale = (flags & fillDestination) != 0 ? jmax (scaleX, scaleY)
: jmin (scaleX, scaleY);


+ 67
- 0
src/juce_core/io/network/juce_URL.cpp View File

@@ -133,6 +133,73 @@ bool URL::isWellFormed() const
return url.isNotEmpty();
}
static int findStartOfDomain (const String& url)
{
int i = 0;
while (CharacterFunctions::isLetterOrDigit (url[i])
|| CharacterFunctions::indexOfChar (T("+-."), url[i], false) >= 0)
++i;
return url[i] == T(':') ? i + 1 : 0;
}
const String URL::getDomain() const
{
int start = findStartOfDomain (url);
while (url[start] == T('/'))
++start;
const int end1 = url.indexOfChar (start, T('/'));
const int end2 = url.indexOfChar (start, T(':'));
const int end = (end1 < 0 || end2 < 0) ? jmax (end1, end2)
: jmin (end1, end2);
return url.substring (start, end);
}
const String URL::getSubPath() const
{
int start = findStartOfDomain (url);
while (url[start] == T('/'))
++start;
const int startOfPath = url.indexOfChar (start, T('/')) + 1;
return startOfPath <= 0 ? String::empty
: url.substring (startOfPath);
}
const String URL::getScheme() const
{
return url.substring (0, findStartOfDomain (url) - 1);
}
const URL URL::withNewSubPath (const String& newPath) const
{
int start = findStartOfDomain (url);
while (url[start] == T('/'))
++start;
const int startOfPath = url.indexOfChar (start, T('/')) + 1;
URL u (*this);
if (startOfPath > 0)
u.url = url.substring (0, startOfPath);
if (! u.url.endsWithChar (T('/')))
u.url << '/';
if (newPath.startsWithChar (T('/')))
u.url << newPath.substring (1);
else
u.url << newPath;
return u;
}
//==============================================================================
bool URL::isProbablyAWebsiteURL (const String& possibleURL)
{


+ 26
- 0
src/juce_core/io/network/juce_URL.h View File

@@ -75,6 +75,32 @@ public:
/** True if it seems to be valid. */
bool isWellFormed() const;
/** Returns just the domain part of the URL.
E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com".
*/
const String getDomain() const;
/** Returns the path part of the URL.
E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar".
*/
const String getSubPath() const;
/** Returns the scheme of the URL.
E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't
include the colon).
*/
const String getScheme() const;
/** Returns a new version of this URL that uses a different sub-path.
E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
"bar", it'll return "http://www.xyz.com/bar?x=1".
*/
const URL withNewSubPath (const String& newPath) const;
//==============================================================================
/** Returns a copy of this URL, with a GET parameter added to the end.


Loading…
Cancel
Save