mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-08 04:20:09 +00:00
OSX10.4 menu fix. Graphics::drawSingleLineText justification.
This commit is contained in:
parent
b23e5c4515
commit
27d7185f34
13 changed files with 110 additions and 39 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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<int>& delta) = 0;
|
||||
virtual void translate (const Point<int>& delta) = 0;
|
||||
|
||||
virtual bool clipRegionIntersects (const Rectangle<int>& r) const = 0;
|
||||
virtual Rectangle<int> getClipBounds() const = 0;
|
||||
|
|
@ -1294,10 +1294,9 @@ public:
|
|||
return edgeTable.isEmpty() ? nullptr : this;
|
||||
}
|
||||
|
||||
Ptr translated (const Point<int>& delta)
|
||||
void translate (const Point<int>& delta)
|
||||
{
|
||||
edgeTable.translate ((float) delta.getX(), delta.getY());
|
||||
return edgeTable.isEmpty() ? nullptr : this;
|
||||
}
|
||||
|
||||
bool clipRegionIntersects (const Rectangle<int>& r) const
|
||||
|
|
@ -1451,10 +1450,9 @@ public:
|
|||
return toEdgeTable()->clipToImageAlpha (image, transform, betterQuality);
|
||||
}
|
||||
|
||||
Ptr translated (const Point<int>& delta)
|
||||
void translate (const Point<int>& delta)
|
||||
{
|
||||
clip.offsetAll (delta.getX(), delta.getY());
|
||||
return clip.isEmpty() ? nullptr : this;
|
||||
}
|
||||
|
||||
bool clipRegionIntersects (const Rectangle<int>& r) const
|
||||
|
|
@ -1821,12 +1819,6 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
Rectangle<int> getUntransformedClipBounds() const
|
||||
{
|
||||
return clip != nullptr ? clip->getClipBounds()
|
||||
: Rectangle<int>();
|
||||
}
|
||||
|
||||
Rectangle<int> getClipBounds() const
|
||||
{
|
||||
return clip != nullptr ? transform.deviceSpaceToUserSpace (clip->getClipBounds())
|
||||
|
|
@ -1835,26 +1827,34 @@ public:
|
|||
|
||||
SavedState* beginTransparencyLayer (float opacity)
|
||||
{
|
||||
const Rectangle<int> 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<int> 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<int> layerBounds (getUntransformedClipBounds());
|
||||
if (clip != nullptr)
|
||||
{
|
||||
const Rectangle<int> layerBounds (clip->getClipBounds());
|
||||
|
||||
const ScopedPointer<LowLevelGraphicsContext> g (image.createLowLevelContext());
|
||||
g->setOpacity (finishedLayerState.transparencyLayerAlpha);
|
||||
g->drawImage (finishedLayerState.image, AffineTransform::translation ((float) layerBounds.getX(),
|
||||
(float) layerBounds.getY()));
|
||||
const ScopedPointer<LowLevelGraphicsContext> g (image.createLowLevelContext());
|
||||
g->setOpacity (finishedLayerState.transparencyLayerAlpha);
|
||||
g->drawImage (finishedLayerState.image, AffineTransform::translation ((float) layerBounds.getX(),
|
||||
(float) layerBounds.getY()));
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -57,13 +57,13 @@ public:
|
|||
const AffineTransform& transform);
|
||||
|
||||
/** Creates an edge table containing a rectangle. */
|
||||
EdgeTable (const Rectangle<int>& rectangleToAdd);
|
||||
explicit EdgeTable (const Rectangle<int>& 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<float>& rectangleToAdd);
|
||||
explicit EdgeTable (const Rectangle<float>& rectangleToAdd);
|
||||
|
||||
/** Creates a copy of another edge table. */
|
||||
EdgeTable (const EdgeTable& other);
|
||||
|
|
|
|||
|
|
@ -1162,7 +1162,7 @@ void Component::setBoundsToFit (int x, int y, int width, int height,
|
|||
}
|
||||
|
||||
if (newW > 0 && newH > 0)
|
||||
setBounds (justification.appliedToRectangle (Rectangle<int> (0, 0, newW, newH),
|
||||
setBounds (justification.appliedToRectangle (Rectangle<int> (newW, newH),
|
||||
Rectangle<int> (x, y, width, height)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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..
|
||||
|
|
|
|||
|
|
@ -610,7 +610,7 @@ public:
|
|||
|
||||
Graphics::ScopedSaveState state (g);
|
||||
g.reduceClipRegion (Rectangle<int> (startX, baselineY, endX - startX, 1));
|
||||
g.fillCheckerBoard (Rectangle<int> (0, 0, endX, baselineY + 1), 3, 1, colour, Colours::transparentBlack);
|
||||
g.fillCheckerBoard (Rectangle<int> (endX, baselineY + 1), 3, 1, colour, Colours::transparentBlack);
|
||||
}
|
||||
|
||||
void drawSelectedText (Graphics& g,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public:
|
|||
Rectangle<int> getViewBounds() const
|
||||
{
|
||||
CGRect r = [view frame];
|
||||
return Rectangle<int> (0, 0, (int) r.size.width, (int) r.size.height);
|
||||
return Rectangle<int> ((int) r.size.width, (int) r.size.height);
|
||||
}
|
||||
|
||||
UIView* const view;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public:
|
|||
Rectangle<int> getViewBounds() const
|
||||
{
|
||||
NSRect r = [view frame];
|
||||
return Rectangle<int> (0, 0, (int) r.size.width, (int) r.size.height);
|
||||
return Rectangle<int> ((int) r.size.width, (int) r.size.height);
|
||||
}
|
||||
|
||||
NSView* const view;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue