diff --git a/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp b/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp index ff3889ce64..8b6cfe58f8 100644 --- a/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioThumbnailCache.cpp @@ -40,7 +40,7 @@ public: { hash = in.readInt64(); const int64 len = in.readInt64(); - in.readIntoMemoryBlock (data, len); + in.readIntoMemoryBlock (data, (ssize_t) len); } void write (OutputStream& out) diff --git a/modules/juce_core/maths/juce_MathsFunctions.h b/modules/juce_core/maths/juce_MathsFunctions.h index 816c4b3fc3..6c6f587cd1 100644 --- a/modules/juce_core/maths/juce_MathsFunctions.h +++ b/modules/juce_core/maths/juce_MathsFunctions.h @@ -91,6 +91,10 @@ typedef unsigned int uint32; typedef unsigned int pointer_sized_uint; #endif +#if JUCE_MSVC + typedef pointer_sized_int ssize_t; +#endif + //============================================================================== // Some indispensible min/max functions @@ -351,6 +355,10 @@ inline bool juce_isfinite (FloatingPointType value) } //============================================================================== +#if JUCE_MSVC + #pragma optimize ("t", off) +#endif + /** Fast floating-point-to-integer conversion. This is faster than using the normal c++ cast to convert a float to an int, and @@ -374,6 +382,10 @@ inline int roundToInt (const FloatType value) noexcept #endif } +#if JUCE_MSVC + #pragma optimize ("", on) // resets optimisations to the project defaults +#endif + /** Fast floating-point-to-integer conversion. This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works @@ -424,6 +436,19 @@ bool isPowerOfTwo (IntegerType value) return (value & (value - 1)) == 0; } +/** Returns the next power-of-two which is equal to or greater than the given integer. +*/ +inline int nextPowerOfTwo (int n) +{ + --n; + n |= (n >> 1); + n |= (n >> 2); + n |= (n >> 4); + n |= (n >> 8); + n |= (n >> 16); + return n + 1; +} + /** Performs a modulo operation, but can cope with the dividend being negative. The divisor must be greater than zero. */ diff --git a/modules/juce_core/streams/juce_InputStream.cpp b/modules/juce_core/streams/juce_InputStream.cpp index 1fd2994d11..d40ebbf843 100644 --- a/modules/juce_core/streams/juce_InputStream.cpp +++ b/modules/juce_core/streams/juce_InputStream.cpp @@ -199,7 +199,7 @@ String InputStream::readNextLine() return String::fromUTF8 (data, (int) i); } -int InputStream::readIntoMemoryBlock (MemoryBlock& block, int numBytes) +int InputStream::readIntoMemoryBlock (MemoryBlock& block, ssize_t numBytes) { MemoryOutputStream mo (block, true); return mo.writeFromInputStream (*this, numBytes); diff --git a/modules/juce_core/streams/juce_InputStream.h b/modules/juce_core/streams/juce_InputStream.h index a9bd62ec76..2d0ec04dce 100644 --- a/modules/juce_core/streams/juce_InputStream.h +++ b/modules/juce_core/streams/juce_InputStream.h @@ -245,7 +245,7 @@ public: @returns the number of bytes that were added to the memory block */ virtual int readIntoMemoryBlock (MemoryBlock& destBlock, - int maxNumBytesToRead = -1); + ssize_t maxNumBytesToRead = -1); //============================================================================== /** Returns the offset of the next byte that will be read from the stream. diff --git a/modules/juce_graphics/contexts/juce_GraphicsContext.cpp b/modules/juce_graphics/contexts/juce_GraphicsContext.cpp index cd5d224352..3521465994 100644 --- a/modules/juce_graphics/contexts/juce_GraphicsContext.cpp +++ b/modules/juce_graphics/contexts/juce_GraphicsContext.cpp @@ -231,14 +231,33 @@ Font Graphics::getCurrentFont() const } //============================================================================== -void Graphics::drawSingleLineText (const String& text, const int startX, const int baselineY) const +void Graphics::drawSingleLineText (const String& text, const int startX, const int baselineY, + const Justification& justification) const { if (text.isNotEmpty() && startX < context->getClipBounds().getRight()) { GlyphArrangement arr; arr.addLineOfText (context->getFont(), text, (float) startX, (float) baselineY); - arr.draw (*this); + + // Don't pass any vertical placement flags to this method - they'll be ignored. + jassert (justification.getOnlyVerticalFlags() == 0); + + const int flags = justification.getOnlyHorizontalFlags(); + + if (flags != Justification::left) + { + float w = arr.getBoundingBox (0, -1, true).getWidth(); + + if ((flags & (Justification::horizontallyCentred | Justification::horizontallyJustified)) != 0) + w /= 2.0f; + + arr.draw (*this, AffineTransform::translation (-w, 0)); + } + else + { + arr.draw (*this); + } } } diff --git a/modules/juce_graphics/contexts/juce_GraphicsContext.h b/modules/juce_graphics/contexts/juce_GraphicsContext.h index e7f9e3a95e..b75db811bd 100644 --- a/modules/juce_graphics/contexts/juce_GraphicsContext.h +++ b/modules/juce_graphics/contexts/juce_GraphicsContext.h @@ -138,13 +138,16 @@ public: This will use the current colour (or brush) to fill the text. The font is the last one specified by setFont(). - @param text the string to draw - @param startX the position to draw the left-hand edge of the text - @param baselineY the position of the text's baseline + @param text the string to draw + @param startX the position to draw the left-hand edge of the text + @param baselineY the position of the text's baseline + @param justification the horizontal flags indicate which end of the text string is + anchored at the specified point. @see drawMultiLineText, drawText, drawFittedText, GlyphArrangement::addLineOfText */ void drawSingleLineText (const String& text, - int startX, int baselineY) const; + int startX, int baselineY, + const Justification& justification = Justification::left) const; /** Draws text across multiple lines. diff --git a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index 1fd6726e55..27056a8cca 100644 --- a/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/modules/juce_graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -1012,7 +1012,7 @@ public: virtual Ptr clipToPath (const Path& p, const AffineTransform& transform) = 0; virtual Ptr clipToEdgeTable (const EdgeTable& et) = 0; virtual Ptr clipToImageAlpha (const Image& image, const AffineTransform& t, const bool betterQuality) = 0; - virtual Ptr translated (const Point& delta) = 0; + virtual void translate (const Point& delta) = 0; virtual bool clipRegionIntersects (const Rectangle& r) const = 0; virtual Rectangle getClipBounds() const = 0; @@ -1294,10 +1294,9 @@ public: return edgeTable.isEmpty() ? nullptr : this; } - Ptr translated (const Point& delta) + void translate (const Point& delta) { edgeTable.translate ((float) delta.getX(), delta.getY()); - return edgeTable.isEmpty() ? nullptr : this; } bool clipRegionIntersects (const Rectangle& r) const @@ -1451,10 +1450,9 @@ public: return toEdgeTable()->clipToImageAlpha (image, transform, betterQuality); } - Ptr translated (const Point& delta) + void translate (const Point& delta) { clip.offsetAll (delta.getX(), delta.getY()); - return clip.isEmpty() ? nullptr : this; } bool clipRegionIntersects (const Rectangle& r) const @@ -1821,12 +1819,6 @@ public: return false; } - Rectangle getUntransformedClipBounds() const - { - return clip != nullptr ? clip->getClipBounds() - : Rectangle(); - } - Rectangle getClipBounds() const { return clip != nullptr ? transform.deviceSpaceToUserSpace (clip->getClipBounds()) @@ -1835,26 +1827,34 @@ public: SavedState* beginTransparencyLayer (float opacity) { - const Rectangle layerBounds (getUntransformedClipBounds()); - SavedState* s = new SavedState (*this); - s->image = Image (Image::ARGB, layerBounds.getWidth(), layerBounds.getHeight(), true); - s->transparencyLayerAlpha = opacity; - s->transform.moveOriginInDeviceSpace (-layerBounds.getX(), -layerBounds.getY()); - s->cloneClipIfMultiplyReferenced(); - s->clip = s->clip->translated (-layerBounds.getPosition()); + if (clip != nullptr) + { + const Rectangle layerBounds (clip->getClipBounds()); + + s->image = Image (Image::ARGB, layerBounds.getWidth(), layerBounds.getHeight(), true); + s->transparencyLayerAlpha = opacity; + s->transform.moveOriginInDeviceSpace (-layerBounds.getX(), -layerBounds.getY()); + + s->cloneClipIfMultiplyReferenced(); + s->clip->translate (-layerBounds.getPosition()); + } + return s; } void endTransparencyLayer (SavedState& finishedLayerState) { - const Rectangle layerBounds (getUntransformedClipBounds()); + if (clip != nullptr) + { + const Rectangle layerBounds (clip->getClipBounds()); - const ScopedPointer g (image.createLowLevelContext()); - g->setOpacity (finishedLayerState.transparencyLayerAlpha); - g->drawImage (finishedLayerState.image, AffineTransform::translation ((float) layerBounds.getX(), - (float) layerBounds.getY())); + const ScopedPointer g (image.createLowLevelContext()); + g->setOpacity (finishedLayerState.transparencyLayerAlpha); + g->drawImage (finishedLayerState.image, AffineTransform::translation ((float) layerBounds.getX(), + (float) layerBounds.getY())); + } } //============================================================================== diff --git a/modules/juce_graphics/geometry/juce_EdgeTable.h b/modules/juce_graphics/geometry/juce_EdgeTable.h index 2cff9ac8fa..fd1e625f62 100644 --- a/modules/juce_graphics/geometry/juce_EdgeTable.h +++ b/modules/juce_graphics/geometry/juce_EdgeTable.h @@ -57,13 +57,13 @@ public: const AffineTransform& transform); /** Creates an edge table containing a rectangle. */ - EdgeTable (const Rectangle& rectangleToAdd); + explicit EdgeTable (const Rectangle& rectangleToAdd); /** Creates an edge table containing a rectangle list. */ - EdgeTable (const RectangleList& rectanglesToAdd); + explicit EdgeTable (const RectangleList& rectanglesToAdd); /** Creates an edge table containing a rectangle. */ - EdgeTable (const Rectangle& rectangleToAdd); + explicit EdgeTable (const Rectangle& rectangleToAdd); /** Creates a copy of another edge table. */ EdgeTable (const EdgeTable& other); diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index a198901416..f12728cbdf 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -1162,7 +1162,7 @@ void Component::setBoundsToFit (int x, int y, int width, int height, } if (newW > 0 && newH > 0) - setBounds (justification.appliedToRectangle (Rectangle (0, 0, newW, newH), + setBounds (justification.appliedToRectangle (Rectangle (newW, newH), Rectangle (x, y, width, height))); } } diff --git a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm index 58c7eb9abe..8efe91dedd 100644 --- a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm +++ b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm @@ -104,6 +104,30 @@ public: void updateSubMenu (NSMenuItem* parentItem, const PopupMenu& menuToCopy, const String& name, const int menuId, const int tag) { + #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + static bool is10_4 = (SystemStats::getOSXMinorVersionNumber() <= 4); + + if (is10_4) + { + [parentItem setTag: tag]; + NSMenu* menu = [parentItem submenu]; + + [menu setTitle: juceStringToNS (name)]; + + while ([menu numberOfItems] > 0) + [menu removeItemAtIndex: 0]; + + PopupMenu::MenuItemIterator iter (menuToCopy); + + while (iter.next()) + addMenuItem (iter, menu, menuId, tag); + + [menu setAutoenablesItems: false]; + [menu update]; + return; + } + #endif + // Note: This method used to update the contents of the existing menu in-place, but that caused // weird side-effects which messed-up keyboard focus when switching between windows. By creating // a new menu and replacing the old one with it, that problem seems to be avoided.. diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp index b146689255..01a218af11 100644 --- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp +++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp @@ -610,7 +610,7 @@ public: Graphics::ScopedSaveState state (g); g.reduceClipRegion (Rectangle (startX, baselineY, endX - startX, 1)); - g.fillCheckerBoard (Rectangle (0, 0, endX, baselineY + 1), 3, 1, colour, Colours::transparentBlack); + g.fillCheckerBoard (Rectangle (endX, baselineY + 1), 3, 1, colour, Colours::transparentBlack); } void drawSelectedText (Graphics& g, diff --git a/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm b/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm index e19229c0fd..5b5d08541b 100644 --- a/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm +++ b/modules/juce_gui_extra/native/juce_ios_UIViewComponent.mm @@ -87,7 +87,7 @@ public: Rectangle getViewBounds() const { CGRect r = [view frame]; - return Rectangle (0, 0, (int) r.size.width, (int) r.size.height); + return Rectangle ((int) r.size.width, (int) r.size.height); } UIView* const view; diff --git a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm index b196b1919c..9e7baf122e 100644 --- a/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm +++ b/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm @@ -99,7 +99,7 @@ public: Rectangle getViewBounds() const { NSRect r = [view frame]; - return Rectangle (0, 0, (int) r.size.width, (int) r.size.height); + return Rectangle ((int) r.size.width, (int) r.size.height); } NSView* const view;