Browse Source

New method Array::resize(). Tweaked AudioThumbnail to avoid clearing the input source when loaded. New class SingleThreadedReferenceCountedObject (and used this for Font, Typeface, Expression, Value and ValueTree classes, since none of these were safe to use with threads anyway). Minor additions to GlyphArrangement.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
1dac02369e
16 changed files with 325 additions and 113 deletions
  1. +49
    -27
      juce_amalgamated.cpp
  2. +112
    -29
      juce_amalgamated.h
  3. +5
    -1
      src/audio/audio_file_formats/juce_AudioThumbnail.cpp
  4. +1
    -0
      src/audio/audio_file_formats/juce_AudioThumbnail.h
  5. +18
    -0
      src/containers/juce_Array.h
  6. +1
    -1
      src/containers/juce_Value.h
  7. +5
    -8
      src/containers/juce_ValueTree.h
  8. +1
    -1
      src/gui/components/menus/juce_PopupMenu.h
  9. +1
    -1
      src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
  10. +1
    -1
      src/gui/graphics/fonts/juce_Font.h
  11. +42
    -24
      src/gui/graphics/fonts/juce_GlyphArrangement.cpp
  12. +21
    -11
      src/gui/graphics/fonts/juce_GlyphArrangement.h
  13. +1
    -1
      src/gui/graphics/fonts/juce_Typeface.h
  14. +1
    -1
      src/maths/juce_Expression.cpp
  15. +64
    -5
      src/memory/juce_ReferenceCountedObject.h
  16. +2
    -2
      src/memory/juce_WeakReference.h

+ 49
- 27
juce_amalgamated.cpp View File

@@ -4908,7 +4908,7 @@ END_JUCE_NAMESPACE
/*** Start of inlined file: juce_Expression.cpp ***/
BEGIN_JUCE_NAMESPACE

class Expression::Term : public ReferenceCountedObject
class Expression::Term : public SingleThreadedReferenceCountedObject
{
public:
Term() {}
@@ -22501,7 +22501,11 @@ AudioThumbnail::~AudioThumbnail()
void AudioThumbnail::clear()
{
source = nullptr;
clearChannelData();
}

void AudioThumbnail::clearChannelData()
{
const ScopedLock sl (lock);
window->invalidate();
channels.clear();
@@ -22531,7 +22535,7 @@ void AudioThumbnail::createChannels (const int length)

void AudioThumbnail::loadFrom (InputStream& rawInput)
{
clear();
clearChannelData();

BufferedInputStream input (rawInput, 4096);

@@ -86247,7 +86251,7 @@ private:
JUCE_DECLARE_NON_COPYABLE (TransformedImageFillEdgeTableRenderer);
};

class ClipRegionBase : public ReferenceCountedObject
class ClipRegionBase : public SingleThreadedReferenceCountedObject
{
public:
ClipRegionBase() {}
@@ -91982,33 +91986,40 @@ END_JUCE_NAMESPACE
/*** Start of inlined file: juce_GlyphArrangement.cpp ***/
BEGIN_JUCE_NAMESPACE

PositionedGlyph::PositionedGlyph (const float x_, const float y_, const float w_, const Font& font_,
const juce_wchar character_, const int glyph_)
: x (x_),
y (y_),
w (w_),
font (font_),
character (character_),
glyph (glyph_)
PositionedGlyph::PositionedGlyph (const Font& font_, const juce_wchar character_, const int glyph_,
const float x_, const float y_, const float w_, const bool whitespace_)
: font (font_), character (character_), glyph (glyph_),
x (x_), y (y_), w (w_), whitespace (whitespace_)
{
}

PositionedGlyph::PositionedGlyph (const PositionedGlyph& other)
: x (other.x),
y (other.y),
w (other.w),
font (other.font),
character (other.character),
glyph (other.glyph)
: font (other.font), character (other.character), glyph (other.glyph),
x (other.x), y (other.y), w (other.w), whitespace (other.whitespace)
{
}

PositionedGlyph::~PositionedGlyph() {}

PositionedGlyph& PositionedGlyph::operator= (const PositionedGlyph& other)
{
font = other.font;
character = other.character;
glyph = other.glyph;
x = other.x;
y = other.y;
w = other.w;
whitespace = other.whitespace;
return *this;
}

void PositionedGlyph::draw (const Graphics& g) const
{
if (! isWhitespace())
{
g.getInternalContext()->setFont (font);
g.getInternalContext()->drawGlyph (glyph, AffineTransform::translation (x, y));
LowLevelGraphicsContext* const context = g.getInternalContext();
context->setFont (font);
context->drawGlyph (glyph, AffineTransform::translation (x, y));
}
}

@@ -92017,9 +92028,10 @@ void PositionedGlyph::draw (const Graphics& g,
{
if (! isWhitespace())
{
g.getInternalContext()->setFont (font);
g.getInternalContext()->drawGlyph (glyph, AffineTransform::translation (x, y)
.followedBy (transform));
LowLevelGraphicsContext* const context = g.getInternalContext();
context->setFont (font);
context->drawGlyph (glyph, AffineTransform::translation (x, y)
.followedBy (transform));
}
}

@@ -92112,6 +92124,11 @@ void GlyphArrangement::addGlyphArrangement (const GlyphArrangement& other)
glyphs.addCopiesOf (other.glyphs);
}

void GlyphArrangement::addGlyph (const PositionedGlyph& glyph)
{
glyphs.add (new PositionedGlyph (glyph));
}

void GlyphArrangement::removeRangeOfGlyphs (int startIndex, const int num)
{
glyphs.removeRange (startIndex, num < 0 ? glyphs.size() : num);
@@ -92129,7 +92146,7 @@ void GlyphArrangement::addLineOfText (const Font& font,

void GlyphArrangement::addCurtailedLineOfText (const Font& font,
const String& text,
float xOffset,
const float xOffset,
const float yOffset,
const float maxWidthPixels,
const bool useEllipsis)
@@ -92140,6 +92157,7 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font,
Array <float> xOffsets;
font.getGlyphPositions (text, newGlyphs, xOffsets);
const int textLen = newGlyphs.size();
glyphs.ensureStorageAllocated (glyphs.size() + textLen);

String::CharPointerType t (text.getCharPointer());

@@ -92158,8 +92176,12 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font,
}
else
{
glyphs.add (new PositionedGlyph (xOffset + thisX, yOffset, nextX - thisX,
font, t.getAndAdvance(), newGlyphs.getUnchecked(i)));
const bool isWhitespace = t.isWhitespace();

glyphs.add (new PositionedGlyph (font, t.getAndAdvance(),
newGlyphs.getUnchecked(i),
xOffset + thisX, yOffset,
nextX - thisX, isWhitespace));
}
}
}
@@ -92194,8 +92216,8 @@ int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos,

for (int i = 3; --i >= 0;)
{
glyphs.insert (endIndex++, new PositionedGlyph (xOffset, yOffset, dx,
font, '.', dotGlyphs.getFirst()));
glyphs.insert (endIndex++, new PositionedGlyph (font, '.', dotGlyphs.getFirst(),
xOffset, yOffset, dx, false));
--numDeleted;
xOffset += dx;



+ 112
- 29
juce_amalgamated.h View File

@@ -7412,6 +7412,24 @@ public:
}
}

/** This will enlarge or shrink the array to the given number of elements, by adding
or removing items from its end.

If the array is smaller than the given target size, empty elements will be appended
until its size is as specified. If its size is larger than the target, items will be
removed from its end to shorten it.
*/
void resize (const int targetNumItems)
{
jassert (targetNumItems >= 0);

const int numToAdd = targetNumItems - numUsed;
if (numToAdd > 0)
insertMultiple (numUsed, ElementType(), numToAdd);
else if (numToAdd < 0)
removeRange (targetNumItems, -numToAdd);
}

/** Inserts a new element into the array, assuming that the array is sorted.

This will use a comparator to find the position at which the new element
@@ -9059,7 +9077,11 @@ private:
Once a new ReferenceCountedObject has been assigned to a pointer, be
careful not to delete the object manually.

@see ReferenceCountedObjectPtr, ReferenceCountedArray
This class uses an Atomic<int> value to hold the reference count, so that it
the pointers can be passed between threads safely. For a faster but non-thread-safe
version, use SingleThreadedReferenceCountedObject instead.

@see ReferenceCountedObjectPtr, ReferenceCountedArray, SingleThreadedReferenceCountedObject
*/
class JUCE_API ReferenceCountedObject
{
@@ -9088,10 +9110,7 @@ public:
}

/** Returns the object's current reference count. */
inline int getReferenceCount() const noexcept
{
return refCount.get();
}
inline int getReferenceCount() const noexcept { return refCount.get(); }

protected:

@@ -9112,6 +9131,62 @@ private:
Atomic <int> refCount;
};

/**
Adds reference-counting to an object.

This is efectively a version of the ReferenceCountedObject class, but which
uses a non-atomic counter, and so is not thread-safe (but which will be more
efficient).
For more details on how to use it, see the ReferenceCountedObject class notes.

@see ReferenceCountedObject, ReferenceCountedObjectPtr, ReferenceCountedArray
*/
class JUCE_API SingleThreadedReferenceCountedObject
{
public:

/** Increments the object's reference count.

This is done automatically by the smart pointer, but is public just
in case it's needed for nefarious purposes.
*/
inline void incReferenceCount() noexcept
{
++refCount;
}

/** Decreases the object's reference count.

If the count gets to zero, the object will be deleted.
*/
inline void decReferenceCount() noexcept
{
jassert (getReferenceCount() > 0);

if (--refCount == 0)
delete this;
}

/** Returns the object's current reference count. */
inline int getReferenceCount() const noexcept { return refCount; }

protected:

/** Creates the reference-counted object (with an initial ref count of zero). */
SingleThreadedReferenceCountedObject() : refCount (0) {}

/** Destructor. */
virtual ~SingleThreadedReferenceCountedObject()
{
// it's dangerous to delete an object that's still referenced by something else!
jassert (getReferenceCount() == 0);
}

private:

int refCount;
};

/**
A smart-pointer class which points to a reference-counted object.

@@ -16262,7 +16337,7 @@ public:
of a ValueSource object. If you're feeling adventurous, you can create your own custom
ValueSource classes to allow Value objects to represent your own custom data items.
*/
class JUCE_API ValueSource : public ReferenceCountedObject,
class JUCE_API ValueSource : public SingleThreadedReferenceCountedObject,
public AsyncUpdater
{
public:
@@ -17147,14 +17222,11 @@ public:

private:

class SetPropertyAction;
friend class SetPropertyAction;
class AddOrRemoveChildAction;
friend class AddOrRemoveChildAction;
class MoveChildAction;
friend class MoveChildAction;
class SetPropertyAction; friend class SetPropertyAction;
class AddOrRemoveChildAction; friend class AddOrRemoveChildAction;
class MoveChildAction; friend class MoveChildAction;

class JUCE_API SharedObject : public ReferenceCountedObject
class JUCE_API SharedObject : public SingleThreadedReferenceCountedObject
{
public:
explicit SharedObject (const Identifier& type);
@@ -21560,7 +21632,7 @@ private:

@see WeakReference::Master
*/
template <class ObjectType>
template <class ObjectType, class ReferenceCountingType = ReferenceCountedObject>
class WeakReference
{
public:
@@ -21607,7 +21679,7 @@ public:
in your code!
@see WeakReference
*/
class SharedPointer : public ReferenceCountedObject
class SharedPointer : public ReferenceCountingType
{
public:
explicit SharedPointer (ObjectType* const owner_) noexcept : owner (owner_) {}
@@ -24999,7 +25071,7 @@ class AffineTransform;

@see CustomTypeface, Font
*/
class JUCE_API Typeface : public ReferenceCountedObject
class JUCE_API Typeface : public SingleThreadedReferenceCountedObject
{
public:

@@ -25403,7 +25475,7 @@ private:
friend class FontGlyphAlphaMap;
friend class TypefaceCache;

class SharedFontInternal : public ReferenceCountedObject
class SharedFontInternal : public SingleThreadedReferenceCountedObject
{
public:
SharedFontInternal (float height, int styleFlags) noexcept;
@@ -37453,6 +37525,7 @@ private:
double sampleRate;
CriticalSection lock;

void clearChannelData();
bool setDataSource (LevelDataSource* newSource);
void setLevels (const MinMaxValue* const* values, int thumbIndex, int numChans, int numValues);
void createChannels (int length);
@@ -44045,7 +44118,7 @@ public:
@see PopupMenu::addCustomItem
*/
class JUCE_API CustomComponent : public Component,
public ReferenceCountedObject
public SingleThreadedReferenceCountedObject
{
public:
/** Creates a custom item.
@@ -57363,25 +57436,33 @@ private:
A glyph from a particular font, with a particular size, style,
typeface and position.

You should rarely need to use this class directly - for most purposes, the
GlyphArrangement class will do what you need for text layout.

@see GlyphArrangement, Font
*/
class JUCE_API PositionedGlyph
{
public:

PositionedGlyph (const Font& font, juce_wchar character, int glyphNumber,
float anchorX, float baselineY, float width, bool isWhitespace);

PositionedGlyph (const PositionedGlyph& other);
PositionedGlyph& operator= (const PositionedGlyph& other);
~PositionedGlyph();

/** Returns the character the glyph represents. */
juce_wchar getCharacter() const { return character; }
juce_wchar getCharacter() const noexcept { return character; }
/** Checks whether the glyph is actually empty. */
bool isWhitespace() const { return CharacterFunctions::isWhitespace (character); }
bool isWhitespace() const noexcept { return whitespace; }

/** Returns the position of the glyph's left-hand edge. */
float getLeft() const { return x; }
float getLeft() const noexcept { return x; }
/** Returns the position of the glyph's right-hand edge. */
float getRight() const { return x + w; }
float getRight() const noexcept { return x + w; }
/** Returns the y position of the glyph's baseline. */
float getBaselineY() const { return y; }
float getBaselineY() const noexcept { return y; }
/** Returns the y position of the top of the glyph. */
float getTop() const { return y - font.getAscent(); }
/** Returns the y position of the bottom of the glyph. */
@@ -57410,12 +57491,12 @@ public:
private:

friend class GlyphArrangement;
float x, y, w;
Font font;
juce_wchar character;
int glyph;
float x, y, w;
bool whitespace;

PositionedGlyph (float x, float y, float w, const Font& font, juce_wchar character, int glyph);
JUCE_LEAK_DETECTOR (PositionedGlyph);
};

@@ -57439,7 +57520,6 @@ public:
GlyphArrangement (const GlyphArrangement& other);

/** Copies another arrangement onto this one.

To add another arrangement without clearing this one, use addGlyphArrangement().
*/
GlyphArrangement& operator= (const GlyphArrangement& other);
@@ -57530,6 +57610,9 @@ public:
/** Appends another glyph arrangement to this one. */
void addGlyphArrangement (const GlyphArrangement& other);

/** Appends a custom glyph to the arrangement. */
void addGlyph (const PositionedGlyph& glyph);

/** Draws this glyph arrangement to a graphics context.

This uses cached bitmaps so is much faster than the draw (Graphics&, const AffineTransform&)
@@ -57611,9 +57694,9 @@ private:

OwnedArray <PositionedGlyph> glyphs;

int insertEllipsis (const Font& font, float maxXPos, int startIndex, int endIndex);
int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font,
const Justification& justification, float minimumHorizontalScale);
int insertEllipsis (const Font&, float maxXPos, int startIndex, int endIndex);
int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font&,
const Justification&, float minimumHorizontalScale);
void spreadOutLine (int start, int numGlyphs, float targetWidth);

JUCE_LEAK_DETECTOR (GlyphArrangement);


+ 5
- 1
src/audio/audio_file_formats/juce_AudioThumbnail.cpp View File

@@ -541,7 +541,11 @@ AudioThumbnail::~AudioThumbnail()
void AudioThumbnail::clear()
{
source = nullptr;
clearChannelData();
}
void AudioThumbnail::clearChannelData()
{
const ScopedLock sl (lock);
window->invalidate();
channels.clear();
@@ -572,7 +576,7 @@ void AudioThumbnail::createChannels (const int length)
//==============================================================================
void AudioThumbnail::loadFrom (InputStream& rawInput)
{
clear();
clearChannelData();
BufferedInputStream input (rawInput, 4096);


+ 1
- 0
src/audio/audio_file_formats/juce_AudioThumbnail.h View File

@@ -227,6 +227,7 @@ private:
double sampleRate;
CriticalSection lock;
void clearChannelData();
bool setDataSource (LevelDataSource* newSource);
void setLevels (const MinMaxValue* const* values, int thumbIndex, int numChans, int numValues);
void createChannels (int length);


+ 18
- 0
src/containers/juce_Array.h View File

@@ -594,6 +594,24 @@ public:
}
}
/** This will enlarge or shrink the array to the given number of elements, by adding
or removing items from its end.
If the array is smaller than the given target size, empty elements will be appended
until its size is as specified. If its size is larger than the target, items will be
removed from its end to shorten it.
*/
void resize (const int targetNumItems)
{
jassert (targetNumItems >= 0);
const int numToAdd = targetNumItems - numUsed;
if (numToAdd > 0)
insertMultiple (numUsed, ElementType(), numToAdd);
else if (numToAdd < 0)
removeRange (targetNumItems, -numToAdd);
}
/** Inserts a new element into the array, assuming that the array is sorted.
This will use a comparator to find the position at which the new element


+ 1
- 1
src/containers/juce_Value.h View File

@@ -170,7 +170,7 @@ public:
of a ValueSource object. If you're feeling adventurous, you can create your own custom
ValueSource classes to allow Value objects to represent your own custom data items.
*/
class JUCE_API ValueSource : public ReferenceCountedObject,
class JUCE_API ValueSource : public SingleThreadedReferenceCountedObject,
public AsyncUpdater
{
public:


+ 5
- 8
src/containers/juce_ValueTree.h View File

@@ -466,14 +466,11 @@ public:
private:
//==============================================================================
class SetPropertyAction;
friend class SetPropertyAction;
class AddOrRemoveChildAction;
friend class AddOrRemoveChildAction;
class MoveChildAction;
friend class MoveChildAction;
class JUCE_API SharedObject : public ReferenceCountedObject
class SetPropertyAction; friend class SetPropertyAction;
class AddOrRemoveChildAction; friend class AddOrRemoveChildAction;
class MoveChildAction; friend class MoveChildAction;
class JUCE_API SharedObject : public SingleThreadedReferenceCountedObject
{
public:
explicit SharedObject (const Identifier& type);


+ 1
- 1
src/gui/components/menus/juce_PopupMenu.h View File

@@ -415,7 +415,7 @@ public:
@see PopupMenu::addCustomItem
*/
class JUCE_API CustomComponent : public Component,
public ReferenceCountedObject
public SingleThreadedReferenceCountedObject
{
public:
/** Creates a custom item.


+ 1
- 1
src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp View File

@@ -1018,7 +1018,7 @@ private:
};
//==============================================================================
class ClipRegionBase : public ReferenceCountedObject
class ClipRegionBase : public SingleThreadedReferenceCountedObject
{
public:
ClipRegionBase() {}


+ 1
- 1
src/gui/graphics/fonts/juce_Font.h View File

@@ -364,7 +364,7 @@ private:
friend class FontGlyphAlphaMap;
friend class TypefaceCache;
class SharedFontInternal : public ReferenceCountedObject
class SharedFontInternal : public SingleThreadedReferenceCountedObject
{
public:
SharedFontInternal (float height, int styleFlags) noexcept;


+ 42
- 24
src/gui/graphics/fonts/juce_GlyphArrangement.cpp View File

@@ -34,33 +34,40 @@ BEGIN_JUCE_NAMESPACE
//==============================================================================
PositionedGlyph::PositionedGlyph (const float x_, const float y_, const float w_, const Font& font_,
const juce_wchar character_, const int glyph_)
: x (x_),
y (y_),
w (w_),
font (font_),
character (character_),
glyph (glyph_)
PositionedGlyph::PositionedGlyph (const Font& font_, const juce_wchar character_, const int glyph_,
const float x_, const float y_, const float w_, const bool whitespace_)
: font (font_), character (character_), glyph (glyph_),
x (x_), y (y_), w (w_), whitespace (whitespace_)
{
}
PositionedGlyph::PositionedGlyph (const PositionedGlyph& other)
: x (other.x),
y (other.y),
w (other.w),
font (other.font),
character (other.character),
glyph (other.glyph)
: font (other.font), character (other.character), glyph (other.glyph),
x (other.x), y (other.y), w (other.w), whitespace (other.whitespace)
{
}
PositionedGlyph::~PositionedGlyph() {}
PositionedGlyph& PositionedGlyph::operator= (const PositionedGlyph& other)
{
font = other.font;
character = other.character;
glyph = other.glyph;
x = other.x;
y = other.y;
w = other.w;
whitespace = other.whitespace;
return *this;
}
void PositionedGlyph::draw (const Graphics& g) const
{
if (! isWhitespace())
{
g.getInternalContext()->setFont (font);
g.getInternalContext()->drawGlyph (glyph, AffineTransform::translation (x, y));
LowLevelGraphicsContext* const context = g.getInternalContext();
context->setFont (font);
context->drawGlyph (glyph, AffineTransform::translation (x, y));
}
}
@@ -69,9 +76,10 @@ void PositionedGlyph::draw (const Graphics& g,
{
if (! isWhitespace())
{
g.getInternalContext()->setFont (font);
g.getInternalContext()->drawGlyph (glyph, AffineTransform::translation (x, y)
.followedBy (transform));
LowLevelGraphicsContext* const context = g.getInternalContext();
context->setFont (font);
context->drawGlyph (glyph, AffineTransform::translation (x, y)
.followedBy (transform));
}
}
@@ -168,6 +176,11 @@ void GlyphArrangement::addGlyphArrangement (const GlyphArrangement& other)
glyphs.addCopiesOf (other.glyphs);
}
void GlyphArrangement::addGlyph (const PositionedGlyph& glyph)
{
glyphs.add (new PositionedGlyph (glyph));
}
void GlyphArrangement::removeRangeOfGlyphs (int startIndex, const int num)
{
glyphs.removeRange (startIndex, num < 0 ? glyphs.size() : num);
@@ -186,7 +199,7 @@ void GlyphArrangement::addLineOfText (const Font& font,
void GlyphArrangement::addCurtailedLineOfText (const Font& font,
const String& text,
float xOffset,
const float xOffset,
const float yOffset,
const float maxWidthPixels,
const bool useEllipsis)
@@ -197,6 +210,7 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font,
Array <float> xOffsets;
font.getGlyphPositions (text, newGlyphs, xOffsets);
const int textLen = newGlyphs.size();
glyphs.ensureStorageAllocated (glyphs.size() + textLen);
String::CharPointerType t (text.getCharPointer());
@@ -215,8 +229,12 @@ void GlyphArrangement::addCurtailedLineOfText (const Font& font,
}
else
{
glyphs.add (new PositionedGlyph (xOffset + thisX, yOffset, nextX - thisX,
font, t.getAndAdvance(), newGlyphs.getUnchecked(i)));
const bool isWhitespace = t.isWhitespace();
glyphs.add (new PositionedGlyph (font, t.getAndAdvance(),
newGlyphs.getUnchecked(i),
xOffset + thisX, yOffset,
nextX - thisX, isWhitespace));
}
}
}
@@ -251,8 +269,8 @@ int GlyphArrangement::insertEllipsis (const Font& font, const float maxXPos,
for (int i = 3; --i >= 0;)
{
glyphs.insert (endIndex++, new PositionedGlyph (xOffset, yOffset, dx,
font, '.', dotGlyphs.getFirst()));
glyphs.insert (endIndex++, new PositionedGlyph (font, '.', dotGlyphs.getFirst(),
xOffset, yOffset, dx, false));
--numDeleted;
xOffset += dx;


+ 21
- 11
src/gui/graphics/fonts/juce_GlyphArrangement.h View File

@@ -35,25 +35,33 @@
A glyph from a particular font, with a particular size, style,
typeface and position.
You should rarely need to use this class directly - for most purposes, the
GlyphArrangement class will do what you need for text layout.
@see GlyphArrangement, Font
*/
class JUCE_API PositionedGlyph
{
public:
//==============================================================================
PositionedGlyph (const Font& font, juce_wchar character, int glyphNumber,
float anchorX, float baselineY, float width, bool isWhitespace);
PositionedGlyph (const PositionedGlyph& other);
PositionedGlyph& operator= (const PositionedGlyph& other);
~PositionedGlyph();
/** Returns the character the glyph represents. */
juce_wchar getCharacter() const { return character; }
juce_wchar getCharacter() const noexcept { return character; }
/** Checks whether the glyph is actually empty. */
bool isWhitespace() const { return CharacterFunctions::isWhitespace (character); }
bool isWhitespace() const noexcept { return whitespace; }
/** Returns the position of the glyph's left-hand edge. */
float getLeft() const { return x; }
float getLeft() const noexcept { return x; }
/** Returns the position of the glyph's right-hand edge. */
float getRight() const { return x + w; }
float getRight() const noexcept { return x + w; }
/** Returns the y position of the glyph's baseline. */
float getBaselineY() const { return y; }
float getBaselineY() const noexcept { return y; }
/** Returns the y position of the top of the glyph. */
float getTop() const { return y - font.getAscent(); }
/** Returns the y position of the bottom of the glyph. */
@@ -84,12 +92,12 @@ public:
private:
//==============================================================================
friend class GlyphArrangement;
float x, y, w;
Font font;
juce_wchar character;
int glyph;
float x, y, w;
bool whitespace;
PositionedGlyph (float x, float y, float w, const Font& font, juce_wchar character, int glyph);
JUCE_LEAK_DETECTOR (PositionedGlyph);
};
@@ -115,7 +123,6 @@ public:
GlyphArrangement (const GlyphArrangement& other);
/** Copies another arrangement onto this one.
To add another arrangement without clearing this one, use addGlyphArrangement().
*/
GlyphArrangement& operator= (const GlyphArrangement& other);
@@ -208,6 +215,9 @@ public:
/** Appends another glyph arrangement to this one. */
void addGlyphArrangement (const GlyphArrangement& other);
/** Appends a custom glyph to the arrangement. */
void addGlyph (const PositionedGlyph& glyph);
//==============================================================================
/** Draws this glyph arrangement to a graphics context.
@@ -293,9 +303,9 @@ private:
//==============================================================================
OwnedArray <PositionedGlyph> glyphs;
int insertEllipsis (const Font& font, float maxXPos, int startIndex, int endIndex);
int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font,
const Justification& justification, float minimumHorizontalScale);
int insertEllipsis (const Font&, float maxXPos, int startIndex, int endIndex);
int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font&,
const Justification&, float minimumHorizontalScale);
void spreadOutLine (int start, int numGlyphs, float targetWidth);
JUCE_LEAK_DETECTOR (GlyphArrangement);


+ 1
- 1
src/gui/graphics/fonts/juce_Typeface.h View File

@@ -49,7 +49,7 @@ class AffineTransform;
@see CustomTypeface, Font
*/
class JUCE_API Typeface : public ReferenceCountedObject
class JUCE_API Typeface : public SingleThreadedReferenceCountedObject
{
public:
//==============================================================================


+ 1
- 1
src/maths/juce_Expression.cpp View File

@@ -32,7 +32,7 @@ BEGIN_JUCE_NAMESPACE
//==============================================================================
class Expression::Term : public ReferenceCountedObject
class Expression::Term : public SingleThreadedReferenceCountedObject
{
public:
Term() {}


+ 64
- 5
src/memory/juce_ReferenceCountedObject.h View File

@@ -55,7 +55,11 @@
Once a new ReferenceCountedObject has been assigned to a pointer, be
careful not to delete the object manually.
@see ReferenceCountedObjectPtr, ReferenceCountedArray
This class uses an Atomic<int> value to hold the reference count, so that it
the pointers can be passed between threads safely. For a faster but non-thread-safe
version, use SingleThreadedReferenceCountedObject instead.
@see ReferenceCountedObjectPtr, ReferenceCountedArray, SingleThreadedReferenceCountedObject
*/
class JUCE_API ReferenceCountedObject
{
@@ -84,10 +88,7 @@ public:
}
/** Returns the object's current reference count. */
inline int getReferenceCount() const noexcept
{
return refCount.get();
}
inline int getReferenceCount() const noexcept { return refCount.get(); }
protected:
@@ -110,6 +111,64 @@ private:
};
//==============================================================================
/**
Adds reference-counting to an object.
This is efectively a version of the ReferenceCountedObject class, but which
uses a non-atomic counter, and so is not thread-safe (but which will be more
efficient).
For more details on how to use it, see the ReferenceCountedObject class notes.
@see ReferenceCountedObject, ReferenceCountedObjectPtr, ReferenceCountedArray
*/
class JUCE_API SingleThreadedReferenceCountedObject
{
public:
//==============================================================================
/** Increments the object's reference count.
This is done automatically by the smart pointer, but is public just
in case it's needed for nefarious purposes.
*/
inline void incReferenceCount() noexcept
{
++refCount;
}
/** Decreases the object's reference count.
If the count gets to zero, the object will be deleted.
*/
inline void decReferenceCount() noexcept
{
jassert (getReferenceCount() > 0);
if (--refCount == 0)
delete this;
}
/** Returns the object's current reference count. */
inline int getReferenceCount() const noexcept { return refCount; }
protected:
//==============================================================================
/** Creates the reference-counted object (with an initial ref count of zero). */
SingleThreadedReferenceCountedObject() : refCount (0) {}
/** Destructor. */
virtual ~SingleThreadedReferenceCountedObject()
{
// it's dangerous to delete an object that's still referenced by something else!
jassert (getReferenceCount() == 0);
}
private:
//==============================================================================
int refCount;
};
//==============================================================================
/**


+ 2
- 2
src/memory/juce_WeakReference.h View File

@@ -81,7 +81,7 @@
@see WeakReference::Master
*/
template <class ObjectType>
template <class ObjectType, class ReferenceCountingType = ReferenceCountedObject>
class WeakReference
{
public:
@@ -129,7 +129,7 @@ public:
in your code!
@see WeakReference
*/
class SharedPointer : public ReferenceCountedObject
class SharedPointer : public ReferenceCountingType
{
public:
explicit SharedPointer (ObjectType* const owner_) noexcept : owner (owner_) {}


Loading…
Cancel
Save