upgrade to JUCE 5.4.3. Remove (probably) unused JUCE modules. Remove VST2 target (it's been end-of-life'd by Steinberg and by JUCE)

This commit is contained in:
Alex Birch
2019-06-22 20:41:38 +01:00
parent d22c2cd4fa
commit 9ee566b251
1140 changed files with 67534 additions and 105952 deletions

View File

@ -140,22 +140,6 @@ namespace ColourHelpers
}
//==============================================================================
Colour::Colour() noexcept
: argb (0, 0, 0, 0)
{
}
Colour::Colour (const Colour& other) noexcept
: argb (other.argb)
{
}
Colour& Colour::operator= (const Colour& other) noexcept
{
argb = other.argb;
return *this;
}
bool Colour::operator== (const Colour& other) const noexcept { return argb.getNativeARGB() == other.argb.getNativeARGB(); }
bool Colour::operator!= (const Colour& other) const noexcept { return argb.getNativeARGB() != other.argb.getNativeARGB(); }
@ -227,11 +211,6 @@ Colour::Colour (PixelAlpha alpha) noexcept
{
}
Colour::~Colour() noexcept
{
}
//==============================================================================
const PixelARGB Colour::getPixelARGB() const noexcept
{

View File

@ -40,10 +40,10 @@ class JUCE_API Colour final
public:
//==============================================================================
/** Creates a transparent black colour. */
Colour() noexcept;
Colour() = default;
/** Creates a copy of another Colour object. */
Colour (const Colour& other) noexcept;
Colour (const Colour&) = default;
/** Creates a colour from a 32-bit ARGB value.
@ -143,10 +143,10 @@ public:
float alpha) noexcept;
/** Destructor. */
~Colour() noexcept;
~Colour() = default;
/** Copies another Colour object. */
Colour& operator= (const Colour& other) noexcept;
Colour& operator= (const Colour&) = default;
/** Compares two colours. */
bool operator== (const Colour& other) const noexcept;
@ -191,7 +191,7 @@ public:
/** Returns a 32-bit integer that represents this colour.
The format of this number is:
((alpha << 24) | (red << 16) | (green << 16) | blue).
((alpha << 24) | (red << 16) | (green << 8) | blue).
*/
uint32 getARGB() const noexcept;
@ -363,7 +363,7 @@ public:
private:
//==============================================================================
PixelARGB argb;
PixelARGB argb { 0, 0, 0, 0 };
};
} // namespace juce

View File

@ -43,7 +43,7 @@ ColourGradient::ColourGradient (const ColourGradient& other)
ColourGradient::ColourGradient (ColourGradient&& other) noexcept
: point1 (other.point1), point2 (other.point2), isRadial (other.isRadial),
colours (static_cast<Array<ColourPoint>&&> (other.colours))
colours (std::move (other.colours))
{}
ColourGradient& ColourGradient::operator= (const ColourGradient& other)
@ -60,7 +60,7 @@ ColourGradient& ColourGradient::operator= (ColourGradient&& other) noexcept
point1 = other.point1;
point2 = other.point2;
isRadial = other.isRadial;
colours = static_cast<Array<ColourPoint>&&> (other.colours);
colours = std::move (other.colours);
return *this;
}

View File

@ -43,7 +43,7 @@ FillType::FillType (const ColourGradient& g)
}
FillType::FillType (ColourGradient&& g)
: colour (0xff000000), gradient (new ColourGradient (static_cast<ColourGradient&&> (g)))
: colour (0xff000000), gradient (new ColourGradient (std::move (g)))
{
}
@ -75,8 +75,8 @@ FillType& FillType::operator= (const FillType& other)
FillType::FillType (FillType&& other) noexcept
: colour (other.colour),
gradient (static_cast<std::unique_ptr<ColourGradient>&&> (other.gradient)),
image (static_cast<Image&&> (other.image)),
gradient (std::move (other.gradient)),
image (std::move (other.image)),
transform (other.transform)
{
}
@ -86,8 +86,8 @@ FillType& FillType::operator= (FillType&& other) noexcept
jassert (this != &other); // hopefully the compiler should make this situation impossible!
colour = other.colour;
gradient = static_cast<std::unique_ptr<ColourGradient>&&> (other.gradient);
image = static_cast<Image&&> (other.image);
gradient = std::move (other.gradient);
image = std::move (other.image);
transform = other.transform;
return *this;
}

View File

@ -60,8 +60,8 @@ class JUCE_API PixelARGB
{
public:
/** Creates a pixel without defining its colour. */
PixelARGB() noexcept {}
~PixelARGB() noexcept {}
PixelARGB() = default;
~PixelARGB() = default;
PixelARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) noexcept
{
@ -315,8 +315,7 @@ public:
private:
//==============================================================================
PixelARGB (const uint32 internalValue) noexcept
: internal (internalValue)
PixelARGB (uint32 internalValue) noexcept : internal (internalValue)
{
}
@ -367,8 +366,8 @@ class JUCE_API PixelRGB
{
public:
/** Creates a pixel without defining its colour. */
PixelRGB() noexcept {}
~PixelRGB() noexcept {}
PixelRGB() = default;
~PixelRGB() = default;
//==============================================================================
/** Returns a uint32 which represents the pixel in a platform dependent format which is compatible
@ -378,9 +377,9 @@ public:
forcedinline uint32 getNativeARGB() const noexcept
{
#if JUCE_ANDROID
return (uint32) ((0xff << 24) | r | (g << 8) | (b << 16));
return (uint32) ((0xffu << 24) | r | ((uint32) g << 8) | ((uint32) b << 16));
#else
return (uint32) ((0xff << 24) | b | (g << 8) | (r << 16));
return (uint32) ((0xffu << 24) | b | ((uint32) g << 8) | ((uint32) r << 16));
#endif
}
@ -389,7 +388,7 @@ public:
forcedinline uint32 getInARGBMaskOrder() const noexcept
{
#if JUCE_ANDROID
return (uint32) ((0xff << 24) | (r << 16) | (g << 8) | (b << 0));
return (uint32) ((0xffu << 24) | b | ((uint32) g << 8) | ((uint32) r << 16));
#else
return getNativeARGB();
#endif
@ -618,8 +617,8 @@ class JUCE_API PixelAlpha
{
public:
/** Creates a pixel without defining its colour. */
PixelAlpha() noexcept {}
~PixelAlpha() noexcept {}
PixelAlpha() = default;
~PixelAlpha() = default;
//==============================================================================
/** Returns a uint32 which represents the pixel in a platform dependent format which is compatible

View File

@ -203,7 +203,7 @@ void Graphics::setGradientFill (const ColourGradient& gradient)
void Graphics::setGradientFill (ColourGradient&& gradient)
{
setFillType (static_cast<ColourGradient&&> (gradient));
setFillType (std::move (gradient));
}
void Graphics::setTiledImageFill (const Image& imageToUse, const int anchorX, const int anchorY, const float opacity)
@ -273,7 +273,8 @@ void Graphics::drawSingleLineText (const String& text, const int startX, const i
}
void Graphics::drawMultiLineText (const String& text, const int startX,
const int baselineY, const int maximumLineWidth) const
const int baselineY, const int maximumLineWidth,
Justification justification) const
{
if (text.isNotEmpty()
&& startX < context.getClipBounds().getRight())
@ -281,7 +282,7 @@ void Graphics::drawMultiLineText (const String& text, const int startX,
GlyphArrangement arr;
arr.addJustifiedText (context.getFont(), text,
(float) startX, (float) baselineY, (float) maximumLineWidth,
Justification::left);
justification);
arr.draw (*this);
}
}

View File

@ -145,7 +145,8 @@ public:
*/
void drawMultiLineText (const String& text,
int startX, int baselineY,
int maximumLineWidth) const;
int maximumLineWidth,
Justification justification = Justification::left) const;
/** Draws a line of text within a specified rectangle.

View File

@ -351,8 +351,8 @@ void LowLevelGraphicsPostScriptRenderer::fillRect (const Rectangle<float>& r)
writeClip();
writeColour (stateStack.getLast()->fillType.colour);
Rectangle<float> r2 (r.translated ((float) stateStack.getLast()->xOffset,
(float) stateStack.getLast()->yOffset));
auto r2 = r.translated ((float) stateStack.getLast()->xOffset,
(float) stateStack.getLast()->yOffset);
out << r2.getX() << ' ' << -r2.getBottom() << ' ' << r2.getWidth() << ' ' << r2.getHeight() << " rectfill\n";
}
@ -401,7 +401,7 @@ void LowLevelGraphicsPostScriptRenderer::fillPath (const Path& path, const Affin
out << "clip\n";
}
const Rectangle<int> bounds (stateStack.getLast()->clip.getBounds());
auto bounds = stateStack.getLast()->clip.getBounds();
// ideally this would draw lots of lines or ellipses to approximate the gradient, but for the
// time-being, this just fills it with the average colour..

View File

@ -43,7 +43,7 @@ public:
int totalWidth,
int totalHeight);
~LowLevelGraphicsPostScriptRenderer();
~LowLevelGraphicsPostScriptRenderer() override;
//==============================================================================
bool isVectorDevice() const override;

View File

@ -49,7 +49,7 @@ public:
const RectangleList<int>& initialClip);
/** Destructor. */
~LowLevelGraphicsSoftwareRenderer();
~LowLevelGraphicsSoftwareRenderer() override;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LowLevelGraphicsSoftwareRenderer)

View File

@ -68,11 +68,6 @@ static void blurSingleChannelImage (Image& image, int radius)
}
//==============================================================================
DropShadow::DropShadow() noexcept
: colour (0x90000000), radius (4)
{
}
DropShadow::DropShadow (Colour shadowColour, const int r, Point<int> o) noexcept
: colour (shadowColour), radius (r), offset (o)
{
@ -99,9 +94,9 @@ void DropShadow::drawForPath (Graphics& g, const Path& path) const
{
jassert (radius > 0);
const Rectangle<int> area ((path.getBounds().getSmallestIntegerContainer() + offset)
.expanded (radius + 1)
.getIntersection (g.getClipBounds().expanded (radius + 1)));
auto area = (path.getBounds().getSmallestIntegerContainer() + offset)
.expanded (radius + 1)
.getIntersection (g.getClipBounds().expanded (radius + 1));
if (area.getWidth() > 2 && area.getHeight() > 2)
{
@ -139,14 +134,14 @@ void DropShadow::drawForRectangle (Graphics& g, const Rectangle<int>& targetArea
for (float i = 0.05f; i < 1.0f; i += 0.1f)
cg.addColour (1.0 - i, colour.withMultipliedAlpha (i * i));
const float radiusInset = (radius + 1) / 2.0f;
const float radiusInset = radius / 2.0f;
const float expandedRadius = radius + radiusInset;
const Rectangle<float> area (targetArea.toFloat().reduced (radiusInset) + offset.toFloat());
auto area = targetArea.toFloat().reduced (radiusInset) + offset.toFloat();
Rectangle<float> r (area.expanded (expandedRadius));
Rectangle<float> top (r.removeFromTop (expandedRadius));
Rectangle<float> bottom (r.removeFromBottom (expandedRadius));
auto r = area.expanded (expandedRadius);
auto top = r.removeFromTop (expandedRadius);
auto bottom = r.removeFromBottom (expandedRadius);
drawShadowSection (g, cg, top.removeFromLeft (expandedRadius), true, 1.0f, 1.0f, 0, 1.0f);
drawShadowSection (g, cg, top.removeFromRight (expandedRadius), true, 0, 1.0f, 1.0f, 1.0f);

View File

@ -36,7 +36,7 @@ namespace juce
struct JUCE_API DropShadow
{
/** Creates a default drop-shadow effect. */
DropShadow() noexcept;
DropShadow() = default;
/** Creates a drop-shadow object with the given parameters. */
DropShadow (Colour shadowColour, int radius, Point<int> offset) noexcept;
@ -56,10 +56,10 @@ struct JUCE_API DropShadow
In most cases you'll probably want to leave this as black with an alpha
value of around 0.5
*/
Colour colour;
Colour colour { 0x90000000 };
/** The approximate spread of the shadow. */
int radius;
int radius { 4 };
/** The offset of the shadow. */
Point<int> offset;
@ -93,7 +93,7 @@ public:
DropShadowEffect();
/** Destructor. */
~DropShadowEffect();
~DropShadowEffect() override;
//==============================================================================
/** Sets up parameters affecting the shadow's appearance. */

View File

@ -47,7 +47,7 @@ public:
GlowEffect();
/** Destructor. */
~GlowEffect();
~GlowEffect() override;
//==============================================================================
/** Sets the glow's radius and colour.

View File

@ -65,7 +65,7 @@ public:
float alpha) = 0;
/** Destructor. */
virtual ~ImageEffectFilter() {}
virtual ~ImageEffectFilter() = default;
};

View File

@ -38,14 +38,14 @@ namespace
{
for (int i = atts.size(); --i >= 0;)
{
const AttributedString::Attribute& att = atts.getReference (i);
const int offset = position - att.range.getStart();
const auto& att = atts.getUnchecked (i);
auto offset = position - att.range.getStart();
if (offset >= 0)
{
if (offset > 0 && position < att.range.getEnd())
{
atts.insert (i + 1, att);
atts.insert (i + 1, AttributedString::Attribute (att));
atts.getReference (i).range.setEnd (position);
atts.getReference (i + 1).range.setStart (position);
}
@ -57,7 +57,7 @@ namespace
Range<int> splitAttributeRanges (Array<AttributedString::Attribute>& atts, Range<int> newRange)
{
newRange = newRange.getIntersectionWith (Range<int> (0, getLength (atts)));
newRange = newRange.getIntersectionWith ({ 0, getLength (atts) });
if (! newRange.isEmpty())
{
@ -72,8 +72,8 @@ namespace
{
for (int i = atts.size() - 1; --i >= 0;)
{
AttributedString::Attribute& a1 = atts.getReference (i);
AttributedString::Attribute& a2 = atts.getReference (i + 1);
auto& a1 = atts.getReference (i);
auto& a2 = atts.getReference (i + 1);
if (a1.colour == a2.colour && a1.font == a2.font)
{
@ -91,16 +91,15 @@ namespace
{
if (atts.size() == 0)
{
atts.add (AttributedString::Attribute (Range<int> (0, length),
f != nullptr ? *f : Font(),
c != nullptr ? *c : Colour (0xff000000)));
atts.add ({ Range<int> (0, length), f != nullptr ? *f : Font(), c != nullptr ? *c : Colour (0xff000000) });
}
else
{
const int start = getLength (atts);
atts.add (AttributedString::Attribute (Range<int> (start, start + length),
f != nullptr ? *f : atts.getReference (atts.size() - 1).font,
c != nullptr ? *c : atts.getReference (atts.size() - 1).colour));
auto start = getLength (atts);
atts.add ({ Range<int> (start, start + length),
f != nullptr ? *f : atts.getReference (atts.size() - 1).font,
c != nullptr ? *c : atts.getReference (atts.size() - 1).colour });
mergeAdjacentRanges (atts);
}
}
@ -110,10 +109,8 @@ namespace
{
range = splitAttributeRanges (atts, range);
for (int i = 0; i < atts.size(); ++i)
for (auto& att : atts)
{
AttributedString::Attribute& att = atts.getReference (i);
if (range.getStart() < att.range.getEnd())
{
if (range.getEnd() <= att.range.getStart())
@ -138,12 +135,9 @@ namespace
}
//==============================================================================
AttributedString::Attribute::Attribute() noexcept : colour (0xff000000) {}
AttributedString::Attribute::~Attribute() noexcept {}
AttributedString::Attribute::Attribute (Attribute&& other) noexcept
: range (other.range),
font (static_cast<Font&&> (other.font)),
font (std::move (other.font)),
colour (other.colour)
{
}
@ -151,22 +145,7 @@ AttributedString::Attribute::Attribute (Attribute&& other) noexcept
AttributedString::Attribute& AttributedString::Attribute::operator= (Attribute&& other) noexcept
{
range = other.range;
font = static_cast<Font&&> (other.font);
colour = other.colour;
return *this;
}
AttributedString::Attribute::Attribute (const Attribute& other) noexcept
: range (other.range),
font (other.font),
colour (other.colour)
{
}
AttributedString::Attribute& AttributedString::Attribute::operator= (const Attribute& other) noexcept
{
range = other.range;
font = other.font;
font = std::move (other.font);
colour = other.colour;
return *this;
}
@ -177,75 +156,32 @@ AttributedString::Attribute::Attribute (Range<int> r, const Font& f, Colour c) n
}
//==============================================================================
AttributedString::AttributedString()
: lineSpacing (0.0f),
justification (Justification::left),
wordWrap (AttributedString::byWord),
readingDirection (AttributedString::natural)
{
}
AttributedString::AttributedString (const String& newString)
: lineSpacing (0.0f),
justification (Justification::left),
wordWrap (AttributedString::byWord),
readingDirection (AttributedString::natural)
{
setText (newString);
}
AttributedString::AttributedString (const AttributedString& other)
: text (other.text),
lineSpacing (other.lineSpacing),
justification (other.justification),
wordWrap (other.wordWrap),
readingDirection (other.readingDirection),
attributes (other.attributes)
{
}
AttributedString& AttributedString::operator= (const AttributedString& other)
{
if (this != &other)
{
text = other.text;
lineSpacing = other.lineSpacing;
justification = other.justification;
wordWrap = other.wordWrap;
readingDirection = other.readingDirection;
attributes = other.attributes;
}
return *this;
}
AttributedString::AttributedString (AttributedString&& other) noexcept
: text (static_cast<String&&> (other.text)),
: text (std::move (other.text)),
lineSpacing (other.lineSpacing),
justification (other.justification),
wordWrap (other.wordWrap),
readingDirection (other.readingDirection),
attributes (static_cast<Array<Attribute>&&> (other.attributes))
attributes (std::move (other.attributes))
{
}
AttributedString& AttributedString::operator= (AttributedString&& other) noexcept
{
text = static_cast<String&&> (other.text);
text = std::move (other.text);
lineSpacing = other.lineSpacing;
justification = other.justification;
wordWrap = other.wordWrap;
readingDirection = other.readingDirection;
attributes = static_cast<Array<Attribute>&&> (other.attributes);
attributes = std::move (other.attributes);
return *this;
}
AttributedString::~AttributedString() noexcept {}
void AttributedString::setText (const String& newText)
{
const int newLength = newText.length();
const int oldLength = getLength (attributes);
auto newLength = newText.length();
auto oldLength = getLength (attributes);
if (newLength > oldLength)
appendRange (attributes, newLength - oldLength, nullptr, nullptr);
@ -281,12 +217,12 @@ void AttributedString::append (const String& textToAppend, const Font& font, Col
void AttributedString::append (const AttributedString& other)
{
const int originalLength = getLength (attributes);
const int originalNumAtts = attributes.size();
auto originalLength = getLength (attributes);
auto originalNumAtts = attributes.size();
text += other.text;
attributes.addArray (other.attributes);
for (int i = originalNumAtts; i < attributes.size(); ++i)
for (auto i = originalNumAtts; i < attributes.size(); ++i)
attributes.getReference (i).range += originalLength;
mergeAdjacentRanges (attributes);
@ -330,12 +266,12 @@ void AttributedString::setFont (Range<int> range, const Font& font)
void AttributedString::setColour (Colour colour)
{
setColour (Range<int> (0, getLength (attributes)), colour);
setColour ({ 0, getLength (attributes) }, colour);
}
void AttributedString::setFont (const Font& font)
{
setFont (Range<int> (0, getLength (attributes)), font);
setFont ({ 0, getLength (attributes) }, font);
}
void AttributedString::draw (Graphics& g, const Rectangle<float>& area) const

View File

@ -43,22 +43,21 @@ class JUCE_API AttributedString
{
public:
/** Creates an empty attributed string. */
AttributedString();
AttributedString() = default;
/** Creates an attributed string with the given text. */
explicit AttributedString (const String& text);
explicit AttributedString (const String& newString) { setText (newString); }
AttributedString (const AttributedString&);
AttributedString& operator= (const AttributedString&);
AttributedString (const AttributedString&) = default;
AttributedString& operator= (const AttributedString&) = default;
// VS2013 can't default move constructors and assignments
AttributedString (AttributedString&&) noexcept;
AttributedString& operator= (AttributedString&&) noexcept;
/** Destructor. */
~AttributedString() noexcept;
//==============================================================================
/** Returns the complete text of this attributed string. */
const String& getText() const noexcept { return text; }
const String& getText() const noexcept { return text; }
/** Replaces all the text.
This will change the text, but won't affect any of the colour or font attributes
@ -151,10 +150,12 @@ public:
class JUCE_API Attribute
{
public:
Attribute() noexcept;
~Attribute() noexcept;
Attribute (const Attribute&) noexcept;
Attribute& operator= (const Attribute&) noexcept;
Attribute() = default;
Attribute (const Attribute&) = default;
Attribute& operator= (const Attribute&) = default;
// VS2013 can't default move constructors and assignments
Attribute (Attribute&&) noexcept;
Attribute& operator= (Attribute&&) noexcept;
@ -168,7 +169,7 @@ public:
Font font;
/** The colour for this range of characters. */
Colour colour;
Colour colour { 0xff000000 };
private:
JUCE_LEAK_DETECTOR (Attribute)
@ -197,10 +198,10 @@ public:
private:
String text;
float lineSpacing;
Justification justification;
WordWrap wordWrap;
ReadingDirection readingDirection;
float lineSpacing = 0.0f;
Justification justification = Justification::left;
WordWrap wordWrap = AttributedString::byWord;
ReadingDirection readingDirection = AttributedString::natural;
Array<Attribute> attributes;
JUCE_LEAK_DETECTOR (AttributedString)

View File

@ -313,7 +313,7 @@ float CustomTypeface::getStringWidth (const String& text)
else
{
if (auto fallbackTypeface = Typeface::getFallbackTypeface())
if (fallbackTypeface != this)
if (fallbackTypeface.get() != this)
x += fallbackTypeface->getStringWidth (String::charToString (c));
}
}
@ -342,7 +342,7 @@ void CustomTypeface::getGlyphPositions (const String& text, Array<int>& resultGl
{
auto fallbackTypeface = getFallbackTypeface();
if (fallbackTypeface != nullptr && fallbackTypeface != this)
if (fallbackTypeface != nullptr && fallbackTypeface.get() != this)
{
Array<int> subGlyphs;
Array<float> subOffsets;
@ -371,7 +371,7 @@ bool CustomTypeface::getOutlineForGlyph (int glyphNumber, Path& path)
}
if (auto fallbackTypeface = getFallbackTypeface())
if (fallbackTypeface != this)
if (fallbackTypeface.get() != this)
return fallbackTypeface->getOutlineForGlyph (glyphNumber, path);
return false;
@ -389,7 +389,7 @@ EdgeTable* CustomTypeface::getEdgeTableForGlyph (int glyphNumber, const AffineTr
else
{
if (auto fallbackTypeface = getFallbackTypeface())
if (fallbackTypeface != this)
if (fallbackTypeface.get() != this)
return fallbackTypeface->getEdgeTableForGlyph (glyphNumber, transform, fontHeight);
}

View File

@ -65,7 +65,7 @@ public:
explicit CustomTypeface (InputStream& serialisedTypefaceStream);
/** Destructor. */
~CustomTypeface();
~CustomTypeface() override;
//==============================================================================
/** Resets this typeface, deleting all its glyphs and settings. */
@ -155,9 +155,8 @@ protected:
private:
//==============================================================================
class GlyphInfo;
friend struct ContainerDeletePolicy<GlyphInfo>;
OwnedArray<GlyphInfo> glyphs;
short lookupTable [128];
short lookupTable[128];
GlyphInfo* findGlyph (const juce_wchar character, bool loadIfNeeded) noexcept;

View File

@ -40,7 +40,7 @@ namespace FontValues
String fallbackFontStyle;
}
typedef Typeface::Ptr (*GetTypefaceForFont) (const Font&);
using GetTypefaceForFont = Typeface::Ptr (*)(const Font&);
GetTypefaceForFont juce_getTypefaceForFont = nullptr;
float Font::getDefaultMinimumHorizontalScaleFactor() noexcept { return FontValues::minimumHorizontalScale; }
@ -280,13 +280,13 @@ Font& Font::operator= (const Font& other) noexcept
}
Font::Font (Font&& other) noexcept
: font (static_cast<ReferenceCountedObjectPtr<SharedFontInternal>&&> (other.font))
: font (std::move (other.font))
{
}
Font& Font::operator= (Font&& other) noexcept
{
font = static_cast<ReferenceCountedObjectPtr<SharedFontInternal>&&> (other.font);
font = std::move (other.font);
return *this;
}
@ -308,7 +308,7 @@ bool Font::operator!= (const Font& other) const noexcept
void Font::dupeInternalIfShared()
{
if (font->getReferenceCount() > 1)
font = new SharedFontInternal (*font);
font = *new SharedFontInternal (*font);
}
void Font::checkTypefaceSuitability()
@ -392,7 +392,7 @@ Typeface* Font::getTypeface() const
jassert (font->typeface != nullptr);
}
return font->typeface;
return font->typeface.get();
}
//==============================================================================

View File

@ -40,7 +40,7 @@ PositionedGlyph::PositionedGlyph (const Font& font_, juce_wchar character_, int
}
PositionedGlyph::PositionedGlyph (PositionedGlyph&& other) noexcept
: font (static_cast<Font&&> (other.font)),
: font (std::move (other.font)),
character (other.character), glyph (other.glyph),
x (other.x), y (other.y), w (other.w), whitespace (other.whitespace)
{
@ -48,7 +48,7 @@ PositionedGlyph::PositionedGlyph (PositionedGlyph&& other) noexcept
PositionedGlyph& PositionedGlyph::operator= (PositionedGlyph&& other) noexcept
{
font = static_cast<Font&&> (other.font);
font = std::move (other.font);
character = other.character;
glyph = other.glyph;
x = other.x;
@ -129,13 +129,13 @@ GlyphArrangement::GlyphArrangement()
}
GlyphArrangement::GlyphArrangement (GlyphArrangement&& other)
: glyphs (static_cast<Array<PositionedGlyph>&&> (other.glyphs))
: glyphs (std::move (other.glyphs))
{
}
GlyphArrangement& GlyphArrangement::operator= (GlyphArrangement&& other)
{
glyphs = static_cast<Array<PositionedGlyph>&&> (other.glyphs);
glyphs = std::move (other.glyphs);
return *this;
}

View File

@ -51,7 +51,7 @@ public:
PositionedGlyph (const PositionedGlyph&) = default;
PositionedGlyph& operator= (const PositionedGlyph&) = default;
// VS2013 can't default move constructors and assignmants
// VS2013 can't default move constructors and assignments
PositionedGlyph (PositionedGlyph&&) noexcept;
PositionedGlyph& operator= (PositionedGlyph&&) noexcept;

View File

@ -168,7 +168,7 @@ TextLayout::TextLayout (const TextLayout& other)
}
TextLayout::TextLayout (TextLayout&& other) noexcept
: lines (static_cast<OwnedArray<Line>&&> (other.lines)),
: lines (std::move (other.lines)),
width (other.width), height (other.height),
justification (other.justification)
{
@ -176,7 +176,7 @@ TextLayout::TextLayout (TextLayout&& other) noexcept
TextLayout& TextLayout::operator= (TextLayout&& other) noexcept
{
lines = static_cast<OwnedArray<Line>&&> (other.lines);
lines = std::move (other.lines);
width = other.width;
height = other.height;
justification = other.justification;

View File

@ -118,7 +118,7 @@ Typeface::~Typeface()
Typeface::Ptr Typeface::getFallbackTypeface()
{
const Font fallbackFont (Font::getFallbackFontName(), Font::getFallbackFontStyle(), 10.0f);
return fallbackFont.getTypeface();
return Typeface::Ptr (fallbackFont.getTypeface());
}
EdgeTable* Typeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransform& transform, float fontHeight)
@ -140,9 +140,8 @@ EdgeTable* Typeface::getEdgeTableForGlyph (int glyphNumber, const AffineTransfor
struct Typeface::HintingParams
{
HintingParams (Typeface& t)
: cachedSize (0), top (0), middle (0), bottom (0)
{
Font font (&t);
Font font (t);
font = font.withHeight ((float) standardHeight);
top = getAverageY (font, "BDEFPRTZOQ", true);
@ -209,7 +208,7 @@ private:
float middle, upperScale, upperOffset, lowerScale, lowerOffset;
};
float cachedSize;
float cachedSize = 0;
Scaling cachedScale;
static float getAverageY (const Font& font, const char* chars, bool getTop)
@ -248,7 +247,7 @@ private:
}
enum { standardHeight = 100 };
float top, middle, bottom;
float top = 0, middle = 0, bottom = 0;
};
void Typeface::applyVerticalHintingTransform (float fontSize, Path& path)

View File

@ -75,7 +75,7 @@ public:
//==============================================================================
/** Destructor. */
virtual ~Typeface();
~Typeface() override;
/** Returns true if this typeface can be used to render the specified font.
When called, the font will already have been checked to make sure that its name and
@ -153,7 +153,6 @@ protected:
private:
struct HintingParams;
friend struct ContainerDeletePolicy<HintingParams>;
std::unique_ptr<HintingParams> hintingParams;
CriticalSection hintingLock;

View File

@ -27,18 +27,6 @@
namespace juce
{
AffineTransform::AffineTransform() noexcept
: mat00 (1.0f), mat01 (0), mat02 (0),
mat10 (0), mat11 (1.0f), mat12 (0)
{
}
AffineTransform::AffineTransform (const AffineTransform& other) noexcept
: mat00 (other.mat00), mat01 (other.mat01), mat02 (other.mat02),
mat10 (other.mat10), mat11 (other.mat11), mat12 (other.mat12)
{
}
AffineTransform::AffineTransform (float m00, float m01, float m02,
float m10, float m11, float m12) noexcept
: mat00 (m00), mat01 (m01), mat02 (m02),
@ -46,18 +34,6 @@ AffineTransform::AffineTransform (float m00, float m01, float m02,
{
}
AffineTransform& AffineTransform::operator= (const AffineTransform& other) noexcept
{
mat00 = other.mat00;
mat01 = other.mat01;
mat02 = other.mat02;
mat10 = other.mat10;
mat11 = other.mat11;
mat12 = other.mat12;
return *this;
}
bool AffineTransform::operator== (const AffineTransform& other) const noexcept
{
return mat00 == other.mat00
@ -84,7 +60,7 @@ bool AffineTransform::isIdentity() const noexcept
&& mat11 == 1.0f;
}
JUCE_DECLARE_DEPRECATED_STATIC (const AffineTransform AffineTransform::identity;)
JUCE_DECLARE_DEPRECATED_STATIC (const AffineTransform AffineTransform::identity (1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);)
//==============================================================================
AffineTransform AffineTransform::followedBy (const AffineTransform& other) const noexcept

View File

@ -45,10 +45,10 @@ class JUCE_API AffineTransform final
public:
//==============================================================================
/** Creates an identity transform. */
AffineTransform() noexcept;
AffineTransform() = default;
/** Creates a copy of another transform. */
AffineTransform (const AffineTransform& other) noexcept;
AffineTransform (const AffineTransform&) = default;
/** Creates a transform from a set of raw matrix values.
@ -62,7 +62,7 @@ public:
float mat10, float mat11, float mat12) noexcept;
/** Copies from another AffineTransform object */
AffineTransform& operator= (const AffineTransform& other) noexcept;
AffineTransform& operator= (const AffineTransform&) = default;
/** Compares two transforms. */
bool operator== (const AffineTransform& other) const noexcept;
@ -282,8 +282,8 @@ public:
(mat10 mat11 mat12)
( 0 0 1 )
*/
float mat00, mat01, mat02;
float mat10, mat11, mat12;
float mat00 { 1.0f }, mat01 { 0.0f }, mat02 { 0.0f };
float mat10 { 0.0f }, mat11 { 1.0f }, mat12 { 0.0f };
};
} // namespace juce

View File

@ -46,16 +46,10 @@ public:
/** Creates a null border.
All sizes are left as 0.
*/
BorderSize() noexcept
: top(), left(), bottom(), right()
{
}
BorderSize() = default;
/** Creates a copy of another border. */
BorderSize (const BorderSize& other) noexcept
: top (other.top), left (other.left), bottom (other.bottom), right (other.right)
{
}
BorderSize (const BorderSize&) = default;
/** Creates a border with the given gaps. */
BorderSize (ValueType topGap, ValueType leftGap, ValueType bottomGap, ValueType rightGap) noexcept
@ -73,13 +67,13 @@ public:
/** Returns the gap that should be left at the top of the region. */
ValueType getTop() const noexcept { return top; }
/** Returns the gap that should be left at the top of the region. */
/** Returns the gap that should be left at the left of the region. */
ValueType getLeft() const noexcept { return left; }
/** Returns the gap that should be left at the top of the region. */
/** Returns the gap that should be left at the bottom of the region. */
ValueType getBottom() const noexcept { return bottom; }
/** Returns the gap that should be left at the top of the region. */
/** Returns the gap that should be left at the right of the region. */
ValueType getRight() const noexcept { return right; }
/** Returns the sum of the top and bottom gaps. */
@ -149,7 +143,7 @@ public:
private:
//==============================================================================
ValueType top, left, bottom, right;
ValueType top{}, left{}, bottom{}, right{};
};
} // namespace juce

View File

@ -49,13 +49,10 @@ class Line
public:
//==============================================================================
/** Creates a line, using (0, 0) as its start and end points. */
Line() noexcept {}
Line() = default;
/** Creates a copy of another line. */
Line (const Line& other) noexcept
: start (other.start), end (other.end)
{
}
Line (const Line&) = default;
/** Creates a line based on the coordinates of its start and end points. */
Line (ValueType startX, ValueType startY, ValueType endX, ValueType endY) noexcept
@ -70,15 +67,10 @@ public:
}
/** Copies a line from another one. */
Line& operator= (const Line& other) noexcept
{
start = other.start;
end = other.end;
return *this;
}
Line& operator= (const Line&) = default;
/** Destructor. */
~Line() noexcept {}
~Line() = default;
//==============================================================================
/** Returns the x coordinate of the line's start point. */
@ -186,7 +178,7 @@ public:
the intersection (if the lines intersect). If the lines
are parallel, this will just be set to the position
of one of the line's endpoints.
@returns true if the line segments intersect; false if they dont. Even if they
@returns true if the line segments intersect; false if they don't. Even if they
don't intersect, the intersection coordinates returned will still
be valid
*/

View File

@ -41,15 +41,10 @@ public:
//==============================================================================
/** Creates a parallelogram with zero size at the origin.
*/
Parallelogram() noexcept
{
}
Parallelogram() = default;
/** Creates a copy of another parallelogram. */
Parallelogram (const Parallelogram& other) noexcept
: topLeft (other.topLeft), topRight (other.topRight), bottomLeft (other.bottomLeft)
{
}
Parallelogram (const Parallelogram&) = default;
/** Creates a parallelogram based on 3 points. */
Parallelogram (Point<ValueType> topLeftPosition,
@ -67,16 +62,10 @@ public:
{
}
Parallelogram& operator= (const Parallelogram& other) noexcept
{
topLeft = other.topLeft;
topRight = other.topRight;
bottomLeft = other.bottomLeft;
return *this;
}
Parallelogram& operator= (const Parallelogram&) = default;
/** Destructor. */
~Parallelogram() noexcept {}
~Parallelogram() = default;
//==============================================================================
/** Returns true if the parallelogram has a width or height of more than zero. */

View File

@ -132,7 +132,7 @@ Path& Path::operator= (const Path& other)
}
Path::Path (Path&& other) noexcept
: data (static_cast<Array<float>&&> (other.data)),
: data (std::move (other.data)),
bounds (other.bounds),
useNonZeroWinding (other.useNonZeroWinding)
{
@ -140,7 +140,7 @@ Path::Path (Path&& other) noexcept
Path& Path::operator= (Path&& other) noexcept
{
data = static_cast<Array<float>&&> (other.data);
data = std::move (other.data);
bounds = other.bounds;
useNonZeroWinding = other.useNonZeroWinding;
return *this;
@ -674,8 +674,8 @@ void Path::addBubble (Rectangle<float> bodyArea,
startNewSubPath (bodyArea.getX() + cornerSizeW, bodyArea.getY());
const Rectangle<float> targetLimit (bodyArea.reduced (jmin (halfW - 1.0f, cornerSizeW + arrowBaseWidth),
jmin (halfH - 1.0f, cornerSizeH + arrowBaseWidth)));
auto targetLimit = bodyArea.reduced (jmin (halfW - 1.0f, cornerSizeW + arrowBaseWidth),
jmin (halfH - 1.0f, cornerSizeH + arrowBaseWidth));
if (Rectangle<float> (targetLimit.getX(), maximumArea.getY(),
targetLimit.getWidth(), bodyArea.getY() - maximumArea.getY()).contains (arrowTip))

View File

@ -654,10 +654,10 @@ namespace PathStrokeHelpers
}
void PathStrokeType::createStrokedPath (Path& destPath, const Path& sourcePath,
const AffineTransform& transform, const float extraAccuracy) const
const AffineTransform& transform, float extraAccuracy) const
{
PathStrokeHelpers::createStroke (thickness, jointStyle, endStyle, destPath, sourcePath,
transform, extraAccuracy, 0);
transform, extraAccuracy, nullptr);
}
void PathStrokeType::createDashedStroke (Path& destPath,
@ -665,7 +665,7 @@ void PathStrokeType::createDashedStroke (Path& destPath,
const float* dashLengths,
int numDashLengths,
const AffineTransform& transform,
const float extraAccuracy) const
float extraAccuracy) const
{
jassert (extraAccuracy > 0);

View File

@ -43,17 +43,17 @@ class Point
{
public:
/** Creates a point at the origin */
JUCE_CONSTEXPR Point() noexcept : x(), y() {}
JUCE_CONSTEXPR Point() = default;
/** Creates a copy of another point. */
JUCE_CONSTEXPR Point (const Point& other) noexcept : x (other.x), y (other.y) {}
JUCE_CONSTEXPR Point (const Point&) = default;
/** Creates a point from an (x, y) position. */
JUCE_CONSTEXPR Point (ValueType initialX, ValueType initialY) noexcept : x (initialX), y (initialY) {}
//==============================================================================
/** Copies this point from another one. */
Point& operator= (const Point& other) noexcept { x = other.x; y = other.y; return *this; }
Point& operator= (const Point&) = default;
JUCE_CONSTEXPR inline bool operator== (Point other) const noexcept { return x == other.x && y == other.y; }
JUCE_CONSTEXPR inline bool operator!= (Point other) const noexcept { return x != other.x || y != other.y; }
@ -141,7 +141,7 @@ public:
//==============================================================================
/** This type will be double if the Point's type is double, otherwise it will be float. */
typedef typename TypeHelpers::SmallestFloatType<ValueType>::type FloatType;
using FloatType = typename TypeHelpers::SmallestFloatType<ValueType>::type;
//==============================================================================
/** Returns the straight-line distance between this point and the origin. */
@ -234,8 +234,8 @@ public:
String toString() const { return String (x) + ", " + String (y); }
//==============================================================================
ValueType x; /**< The point's X coordinate. */
ValueType y; /**< The point's Y coordinate. */
ValueType x{}; /**< The point's X coordinate. */
ValueType y{}; /**< The point's Y coordinate. */
};
/** Multiplies the point's coordinates by a scalar value. */

View File

@ -43,16 +43,10 @@ public:
/** Creates a rectangle of zero size.
The default coordinates will be (0, 0, 0, 0).
*/
Rectangle() noexcept
: w(), h()
{
}
Rectangle() = default;
/** Creates a copy of another rectangle. */
Rectangle (const Rectangle& other) noexcept
: pos (other.pos), w (other.w), h (other.h)
{
}
Rectangle (const Rectangle&) = default;
/** Creates a rectangle with a given position and size. */
Rectangle (ValueType initialX, ValueType initialY,
@ -89,15 +83,11 @@ public:
return { left, top, right - left, bottom - top };
}
Rectangle& operator= (const Rectangle& other) noexcept
{
pos = other.pos;
w = other.w; h = other.h;
return *this;
}
/** Creates a copy of another rectangle. */
Rectangle& operator= (const Rectangle&) = default;
/** Destructor. */
~Rectangle() noexcept {}
~Rectangle() = default;
//==============================================================================
/** Returns true if the rectangle's width or height are zero or less */
@ -974,7 +964,7 @@ private:
template <typename OtherType> friend class Rectangle;
Point<ValueType> pos;
ValueType w, h;
ValueType w{}, h{};
static ValueType parseIntAfterSpace (StringRef s) noexcept
{ return static_cast<ValueType> (s.text.findEndOfWhitespace().getIntValue32()); }

View File

@ -43,11 +43,11 @@ template <typename ValueType>
class RectangleList final
{
public:
typedef Rectangle<ValueType> RectangleType;
using RectangleType = Rectangle<ValueType>;
//==============================================================================
/** Creates an empty RectangleList */
RectangleList() noexcept {}
RectangleList() = default;
/** Creates a copy of another list */
RectangleList (const RectangleList& other) : rects (other.rects)
@ -69,14 +69,14 @@ public:
/** Move constructor */
RectangleList (RectangleList&& other) noexcept
: rects (static_cast<Array<RectangleType>&&> (other.rects))
: rects (std::move (other.rects))
{
}
/** Move assignment operator */
RectangleList& operator= (RectangleList&& other) noexcept
{
rects = static_cast<Array<RectangleType>&&> (other.rects);
rects = std::move (other.rects);
return *this;
}
@ -194,7 +194,7 @@ public:
void add (const RectangleList& other)
{
for (auto& r : other)
add (*r);
add (r);
}
/** Removes a rectangular region from the list.

View File

@ -35,18 +35,26 @@ namespace juce
namespace jpeglibNamespace
{
#if JUCE_INCLUDE_JPEGLIB_CODE || ! defined (JUCE_INCLUDE_JPEGLIB_CODE)
#if JUCE_MINGW
typedef unsigned char boolean;
#endif
#if JUCE_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wdeprecated-register"
#if __has_warning("-Wcomma")
#pragma clang diagnostic ignored "-Wcomma"
#if JUCE_MINGW
typedef unsigned char boolean;
#endif
#if JUCE_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wdeprecated-register"
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#if __has_warning("-Wcomma")
#pragma clang diagnostic ignored "-Wcomma"
#endif
#endif
#if JUCE_GCC && __GNUC__ > 5
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshift-negative-value"
#endif
#endif
#define JPEG_INTERNALS
#undef FAR
@ -121,9 +129,13 @@ namespace jpeglibNamespace
#include "jpglib/jutils.c"
#include "jpglib/transupp.c"
#if JUCE_CLANG
#pragma clang diagnostic pop
#endif
#if JUCE_CLANG
#pragma clang diagnostic pop
#endif
#if JUCE_GCC && __GNUC__ > 5
#pragma GCC diagnostic pop
#endif
#else
#define JPEG_INTERNALS
#undef FAR

View File

@ -66,6 +66,9 @@ namespace pnglibNamespace
#if JUCE_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#if __has_warning("-Wcomma")
#pragma clang diagnostic ignored "-Wcomma"
#endif
@ -520,23 +523,23 @@ Image PNGImageFormat::decodeImage (InputStream& in)
bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
{
using namespace pnglibNamespace;
const int width = image.getWidth();
const int height = image.getHeight();
auto width = image.getWidth();
auto height = image.getHeight();
png_structp pngWriteStruct = png_create_write_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0);
auto pngWriteStruct = png_create_write_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (pngWriteStruct == nullptr)
return false;
png_infop pngInfoStruct = png_create_info_struct (pngWriteStruct);
auto pngInfoStruct = png_create_info_struct (pngWriteStruct);
if (pngInfoStruct == nullptr)
{
png_destroy_write_struct (&pngWriteStruct, (png_infopp) nullptr);
png_destroy_write_struct (&pngWriteStruct, nullptr);
return false;
}
png_set_write_fn (pngWriteStruct, &out, PNGHelpers::writeDataCallback, 0);
png_set_write_fn (pngWriteStruct, &out, PNGHelpers::writeDataCallback, nullptr);
png_set_IHDR (pngWriteStruct, pngInfoStruct, (png_uint_32) width, (png_uint_32) height, 8,
image.hasAlphaChannel() ? PNG_COLOR_TYPE_RGB_ALPHA

View File

@ -28,7 +28,7 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
{
png_debug(1, "in png_set_sig_bytes");
if (png_ptr == NULL)
if (png_ptr == NULL)
return;
if (num_bytes > 8)

View File

@ -27,7 +27,7 @@
namespace juce
{
ImagePixelData::ImagePixelData (const Image::PixelFormat format, const int w, const int h)
ImagePixelData::ImagePixelData (Image::PixelFormat format, int w, int h)
: pixelFormat (format), width (w), height (h)
{
jassert (format == Image::RGB || format == Image::ARGB || format == Image::SingleChannel);
@ -82,9 +82,9 @@ Image ImageType::convert (const Image& source) const
class SoftwarePixelData : public ImagePixelData
{
public:
SoftwarePixelData (const Image::PixelFormat format_, const int w, const int h, const bool clearImage)
: ImagePixelData (format_, w, h),
pixelStride (format_ == Image::RGB ? 3 : ((format_ == Image::ARGB) ? 4 : 1)),
SoftwarePixelData (Image::PixelFormat formatToUse, int w, int h, bool clearImage)
: ImagePixelData (formatToUse, w, h),
pixelStride (formatToUse == Image::RGB ? 3 : ((formatToUse == Image::ARGB) ? 4 : 1)),
lineStride ((pixelStride * jmax (1, w) + 3) & ~3)
{
imageData.allocate ((size_t) lineStride * (size_t) jmax (1, h), clearImage);
@ -93,7 +93,7 @@ public:
LowLevelGraphicsContext* createLowLevelContext() override
{
sendDataChangeMessage();
return new LowLevelGraphicsSoftwareRenderer (Image (this));
return new LowLevelGraphicsSoftwareRenderer (Image (*this));
}
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override
@ -109,9 +109,9 @@ public:
ImagePixelData::Ptr clone() override
{
SoftwarePixelData* s = new SoftwarePixelData (pixelFormat, width, height, false);
auto s = new SoftwarePixelData (pixelFormat, width, height, false);
memcpy (s->imageData, imageData, (size_t) lineStride * (size_t) height);
return s;
return *s;
}
ImageType* createType() const override { return new SoftwareImageType(); }
@ -128,7 +128,7 @@ SoftwareImageType::~SoftwareImageType() {}
ImagePixelData::Ptr SoftwareImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const
{
return new SoftwarePixelData (format, width, height, clearImage);
return *new SoftwarePixelData (format, width, height, clearImage);
}
int SoftwareImageType::getTypeID() const
@ -156,9 +156,9 @@ ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int widt
class SubsectionPixelData : public ImagePixelData
{
public:
SubsectionPixelData (ImagePixelData* const im, const Rectangle<int>& r)
: ImagePixelData (im->pixelFormat, r.getWidth(), r.getHeight()),
sourceImage (im), area (r)
SubsectionPixelData (ImagePixelData::Ptr source, Rectangle<int> r)
: ImagePixelData (source->pixelFormat, r.getWidth(), r.getHeight()),
sourceImage (std::move (source)), area (r)
{
}
@ -187,10 +187,10 @@ public:
{
Graphics g (newImage);
g.drawImageAt (Image (this), 0, 0);
g.drawImageAt (Image (*this), 0, 0);
}
return newImage.getPixelData();
return *newImage.getPixelData();
}
ImageType* createType() const override { return sourceImage->createType(); }
@ -211,8 +211,12 @@ Image Image::getClippedImage (const Rectangle<int>& area) const
if (area.contains (getBounds()))
return *this;
const Rectangle<int> validArea (area.getIntersection (getBounds()));
return Image (validArea.isEmpty() ? nullptr : new SubsectionPixelData (image, validArea));
auto validArea = area.getIntersection (getBounds());
if (validArea.isEmpty())
return {};
return Image (*new SubsectionPixelData (image, validArea));
}
@ -221,17 +225,17 @@ Image::Image() noexcept
{
}
Image::Image (ImagePixelData* const instance) noexcept
: image (instance)
Image::Image (ReferenceCountedObjectPtr<ImagePixelData> instance) noexcept
: image (std::move (instance))
{
}
Image::Image (const PixelFormat format, int width, int height, bool clearImage)
Image::Image (PixelFormat format, int width, int height, bool clearImage)
: image (NativeImageType().create (format, width, height, clearImage))
{
}
Image::Image (const PixelFormat format, int width, int height, bool clearImage, const ImageType& type)
Image::Image (PixelFormat format, int width, int height, bool clearImage, const ImageType& type)
: image (type.create (format, width, height, clearImage))
{
}
@ -248,13 +252,13 @@ Image& Image::operator= (const Image& other)
}
Image::Image (Image&& other) noexcept
: image (static_cast<ImagePixelData::Ptr&&> (other.image))
: image (std::move (other.image))
{
}
Image& Image::operator= (Image&& other) noexcept
{
image = static_cast<ImagePixelData::Ptr&&> (other.image);
image = std::move (other.image);
return *this;
}
@ -290,10 +294,10 @@ Image Image::createCopy() const
if (image != nullptr)
return Image (image->clone());
return Image();
return {};
}
Image Image::rescaled (const int newWidth, const int newHeight, const Graphics::ResamplingQuality quality) const
Image Image::rescaled (int newWidth, int newHeight, Graphics::ResamplingQuality quality) const
{
if (image == nullptr || (image->width == newWidth && image->height == newHeight))
return *this;
@ -313,7 +317,7 @@ Image Image::convertedToFormat (PixelFormat newFormat) const
if (image == nullptr || newFormat == image->pixelFormat)
return *this;
const int w = image->width, h = image->height;
auto w = image->width, h = image->height;
const std::unique_ptr<ImageType> type (image->createType());
Image newImage (type->create (newFormat, w, h, false));
@ -331,8 +335,8 @@ Image Image::convertedToFormat (PixelFormat newFormat) const
for (int y = 0; y < h; ++y)
{
const PixelARGB* const src = (const PixelARGB*) srcData.getLinePointer (y);
uint8* const dst = destData.getLinePointer (y);
auto src = reinterpret_cast<const PixelARGB*> (srcData.getLinePointer (y));
auto dst = destData.getLinePointer (y);
for (int x = 0; x < w; ++x)
dst[x] = src[x].getAlpha();
@ -346,8 +350,8 @@ Image Image::convertedToFormat (PixelFormat newFormat) const
for (int y = 0; y < h; ++y)
{
const PixelAlpha* const src = (const PixelAlpha*) srcData.getLinePointer (y);
PixelARGB* const dst = (PixelARGB*) destData.getLinePointer (y);
auto src = reinterpret_cast<const PixelAlpha*> (srcData.getLinePointer (y));
auto dst = reinterpret_cast<PixelARGB*> (destData.getLinePointer (y));
for (int x = 0; x < w; ++x)
dst[x].set (src[x]);
@ -371,7 +375,7 @@ NamedValueSet* Image::getProperties() const
}
//==============================================================================
Image::BitmapData::BitmapData (Image& im, const int x, const int y, const int w, const int h, BitmapData::ReadWriteMode mode)
Image::BitmapData::BitmapData (Image& im, int x, int y, int w, int h, BitmapData::ReadWriteMode mode)
: width (w), height (h)
{
// The BitmapData class must be given a valid image, and a valid rectangle within it!
@ -382,7 +386,7 @@ Image::BitmapData::BitmapData (Image& im, const int x, const int y, const int w,
jassert (data != nullptr && pixelStride > 0 && lineStride != 0);
}
Image::BitmapData::BitmapData (const Image& im, const int x, const int y, const int w, const int h)
Image::BitmapData::BitmapData (const Image& im, int x, int y, int w, int h)
: width (w), height (h)
{
// The BitmapData class must be given a valid image, and a valid rectangle within it!
@ -408,11 +412,11 @@ Image::BitmapData::~BitmapData()
{
}
Colour Image::BitmapData::getPixelColour (const int x, const int y) const noexcept
Colour Image::BitmapData::getPixelColour (int x, int y) const noexcept
{
jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height));
const uint8* const pixel = getPixelPointer (x, y);
auto pixel = getPixelPointer (x, y);
switch (pixelFormat)
{
@ -422,15 +426,15 @@ Colour Image::BitmapData::getPixelColour (const int x, const int y) const noexce
default: jassertfalse; break;
}
return Colour();
return {};
}
void Image::BitmapData::setPixelColour (const int x, const int y, Colour colour) const noexcept
void Image::BitmapData::setPixelColour (int x, int y, Colour colour) const noexcept
{
jassert (isPositiveAndBelow (x, width) && isPositiveAndBelow (y, height));
uint8* const pixel = getPixelPointer (x, y);
const PixelARGB col (colour.getPixelARGB());
auto pixel = getPixelPointer (x, y);
auto col = colour.getPixelARGB();
switch (pixelFormat)
{
@ -453,7 +457,7 @@ void Image::clear (const Rectangle<int>& area, Colour colourToClearTo)
}
//==============================================================================
Colour Image::getPixelAt (const int x, const int y) const
Colour Image::getPixelAt (int x, int y) const
{
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()))
{
@ -461,10 +465,10 @@ Colour Image::getPixelAt (const int x, const int y) const
return srcData.getPixelColour (0, 0);
}
return Colour();
return {};
}
void Image::setPixelAt (const int x, const int y, Colour colour)
void Image::setPixelAt (int x, int y, Colour colour)
{
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()))
{
@ -473,7 +477,7 @@ void Image::setPixelAt (const int x, const int y, Colour colour)
}
}
void Image::multiplyAlphaAt (const int x, const int y, const float multiplier)
void Image::multiplyAlphaAt (int x, int y, float multiplier)
{
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight())
&& hasAlphaChannel())
@ -481,7 +485,7 @@ void Image::multiplyAlphaAt (const int x, const int y, const float multiplier)
const BitmapData destData (*this, x, y, 1, 1, BitmapData::readWrite);
if (isARGB())
((PixelARGB*) destData.data)->multiplyAlpha (multiplier);
reinterpret_cast<PixelARGB*> (destData.data)->multiplyAlpha (multiplier);
else
*(destData.data) = (uint8) (*(destData.data) * multiplier);
}
@ -495,11 +499,11 @@ struct PixelIterator
{
for (int y = 0; y < data.height; ++y)
{
uint8* p = data.getLinePointer (y);
auto p = data.getLinePointer (y);
for (int x = 0; x < data.width; ++x)
{
pixelOp (*(PixelType*) p);
pixelOp (*reinterpret_cast<PixelType*> (p));
p += data.pixelStride;
}
}
@ -529,7 +533,7 @@ struct AlphaMultiplyOp
}
};
void Image::multiplyAllAlphas (const float amountToMultiplyBy)
void Image::multiplyAllAlphas (float amountToMultiplyBy)
{
jassert (hasAlphaChannel());
@ -555,11 +559,11 @@ void Image::desaturate()
}
}
void Image::createSolidAreaMask (RectangleList<int>& result, const float alphaThreshold) const
void Image::createSolidAreaMask (RectangleList<int>& result, float alphaThreshold) const
{
if (hasAlphaChannel())
{
const uint8 threshold = (uint8) jlimit (0, 255, roundToInt (alphaThreshold * 255.0f));
auto threshold = (uint8) jlimit (0, 255, roundToInt (alphaThreshold * 255.0f));
SparseSet<int> pixelsOnRow;
const BitmapData srcData (*this, 0, 0, getWidth(), getHeight());
@ -567,13 +571,13 @@ void Image::createSolidAreaMask (RectangleList<int>& result, const float alphaTh
for (int y = 0; y < srcData.height; ++y)
{
pixelsOnRow.clear();
const uint8* lineData = srcData.getLinePointer (y);
auto lineData = srcData.getLinePointer (y);
if (isARGB())
{
for (int x = 0; x < srcData.width; ++x)
{
if (((const PixelARGB*) lineData)->getAlpha() >= threshold)
if (reinterpret_cast<const PixelARGB*> (lineData)->getAlpha() >= threshold)
pixelsOnRow.addRange (Range<int> (x, x + 1));
lineData += srcData.pixelStride;
@ -592,7 +596,7 @@ void Image::createSolidAreaMask (RectangleList<int>& result, const float alphaTh
for (int i = 0; i < pixelsOnRow.getNumRanges(); ++i)
{
const Range<int> range (pixelsOnRow.getRange (i));
auto range = pixelsOnRow.getRange (i);
result.add (Rectangle<int> (range.getStart(), y, range.getLength(), 1));
}
@ -645,15 +649,15 @@ void Image::moveImageSection (int dx, int dy,
if (w > 0 && h > 0)
{
const int maxX = jmax (dx, sx) + w;
const int maxY = jmax (dy, sy) + h;
auto maxX = jmax (dx, sx) + w;
auto maxY = jmax (dy, sy) + h;
const BitmapData destData (*this, minX, minY, maxX - minX, maxY - minY, BitmapData::readWrite);
uint8* dst = destData.getPixelPointer (dx - minX, dy - minY);
const uint8* src = destData.getPixelPointer (sx - minX, sy - minY);
auto dst = destData.getPixelPointer (dx - minX, dy - minY);
auto src = destData.getPixelPointer (sx - minX, sy - minY);
const size_t lineSize = (size_t) (destData.pixelStride * w);
auto lineSize = (size_t) (destData.pixelStride * w);
if (dy > sy)
{

View File

@ -360,9 +360,9 @@ public:
class BitmapDataReleaser
{
protected:
BitmapDataReleaser() {}
BitmapDataReleaser() = default;
public:
virtual ~BitmapDataReleaser() {}
virtual ~BitmapDataReleaser() = default;
};
std::unique_ptr<BitmapDataReleaser> dataReleaser;
@ -409,10 +409,10 @@ public:
//==============================================================================
/** @internal */
ImagePixelData* getPixelData() const noexcept { return image; }
ImagePixelData* getPixelData() const noexcept { return image.get(); }
/** @internal */
explicit Image (ImagePixelData*) noexcept;
explicit Image (ReferenceCountedObjectPtr<ImagePixelData>) noexcept;
/* A null Image object that can be used when you need to return an invalid image.
@deprecated If you need a default-constructed var, just use Image() or {}.
@ -444,7 +444,7 @@ class JUCE_API ImagePixelData : public ReferenceCountedObject
{
public:
ImagePixelData (Image::PixelFormat, int width, int height);
~ImagePixelData();
~ImagePixelData() override;
using Ptr = ReferenceCountedObjectPtr<ImagePixelData>;
@ -475,7 +475,7 @@ public:
/** Used to receive callbacks for image data changes */
struct Listener
{
virtual ~Listener() {}
virtual ~Listener() = default;
virtual void imageDataChanged (ImagePixelData*) = 0;
virtual void imageDataBeingDeleted (ImagePixelData*) = 0;
@ -528,7 +528,7 @@ class JUCE_API SoftwareImageType : public ImageType
{
public:
SoftwareImageType();
~SoftwareImageType();
~SoftwareImageType() override;
ImagePixelData::Ptr create (Image::PixelFormat, int width, int height, bool clearImage) const override;
int getTypeID() const override;
@ -546,7 +546,7 @@ class JUCE_API NativeImageType : public ImageType
{
public:
NativeImageType();
~NativeImageType();
~NativeImageType() override;
ImagePixelData::Ptr create (Image::PixelFormat, int width, int height, bool clearImage) const override;
int getTypeID() const override;

View File

@ -31,7 +31,7 @@ struct ImageCache::Pimpl : private Timer,
private DeletedAtShutdown
{
Pimpl() {}
~Pimpl() { clearSingletonInstance(); }
~Pimpl() override { clearSingletonInstance(); }
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (ImageCache::Pimpl)

View File

@ -44,11 +44,11 @@ class JUCE_API ImageFileFormat
protected:
//==============================================================================
/** Creates an ImageFormat. */
ImageFileFormat() {}
ImageFileFormat() = default;
public:
/** Destructor. */
virtual ~ImageFileFormat() {}
virtual ~ImageFileFormat() = default;
//==============================================================================
/** Returns a description of this file format.
@ -153,7 +153,7 @@ class JUCE_API PNGImageFormat : public ImageFileFormat
public:
//==============================================================================
PNGImageFormat();
~PNGImageFormat();
~PNGImageFormat() override;
//==============================================================================
String getFormatName() override;
@ -177,7 +177,7 @@ class JUCE_API JPEGImageFormat : public ImageFileFormat
public:
//==============================================================================
JPEGImageFormat();
~JPEGImageFormat();
~JPEGImageFormat() override;
//==============================================================================
/** Specifies the quality to be used when writing a JPEG file.
@ -211,7 +211,7 @@ class JUCE_API GIFImageFormat : public ImageFileFormat
public:
//==============================================================================
GIFImageFormat();
~GIFImageFormat();
~GIFImageFormat() override;
//==============================================================================
String getFormatName() override;

View File

@ -71,6 +71,8 @@
#include <cstdio>
#endif
#include <unordered_map>
#ifdef JUCE_MSVC
#pragma warning (pop)
#endif

View File

@ -35,7 +35,7 @@
ID: juce_graphics
vendor: juce
version: 5.3.2
version: 5.4.3
name: JUCE graphics classes
description: Classes for 2D vector graphics, image loading/saving, font handling, etc.
website: http://www.juce.com/juce
@ -77,6 +77,15 @@
#define JUCE_USE_DIRECTWRITE 1
#endif
/** Config: JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
Setting this flag will turn off CoreGraphics font smoothing, which some people
find makes the text too 'fat' for their taste.
*/
#ifndef JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
#define JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING 0
#endif
#ifndef JUCE_INCLUDE_PNGLIB_CODE
#define JUCE_INCLUDE_PNGLIB_CODE 1
#endif

View File

@ -43,14 +43,10 @@ namespace RenderingHelpers
class TranslationOrTransform
{
public:
TranslationOrTransform() noexcept {}
TranslationOrTransform() = default;
TranslationOrTransform (Point<int> origin) noexcept : offset (origin) {}
TranslationOrTransform (const TranslationOrTransform& other) noexcept
: complexTransform (other.complexTransform), offset (other.offset),
isOnlyTranslated (other.isOnlyTranslated), isRotated (other.isRotated)
{
}
TranslationOrTransform (const TranslationOrTransform& other) = default;
AffineTransform getTransform() const noexcept
{
@ -156,7 +152,7 @@ public:
reset();
}
~GlyphCache()
~GlyphCache() override
{
getSingletonPointer() = nullptr;
}
@ -194,35 +190,34 @@ public:
{
const ScopedLock sl (lock);
if (auto* g = findExistingGlyph (font, glyphNumber))
if (auto g = findExistingGlyph (font, glyphNumber))
{
++hits;
return g;
}
++misses;
auto* g = getGlyphForReuse();
auto g = getGlyphForReuse();
jassert (g != nullptr);
g->generate (font, glyphNumber);
return g;
}
private:
friend struct ContainerDeletePolicy<CachedGlyphType>;
ReferenceCountedArray<CachedGlyphType> glyphs;
Atomic<int> accessCounter, hits, misses;
CriticalSection lock;
CachedGlyphType* findExistingGlyph (const Font& font, int glyphNumber) const noexcept
ReferenceCountedObjectPtr<CachedGlyphType> findExistingGlyph (const Font& font, int glyphNumber) const noexcept
{
for (auto* g : glyphs)
for (auto g : glyphs)
if (g->glyph == glyphNumber && g->font == font)
return g;
return *g;
return nullptr;
return {};
}
CachedGlyphType* getGlyphForReuse()
ReferenceCountedObjectPtr<CachedGlyphType> getGlyphForReuse()
{
if (hits.get() + misses.get() > glyphs.size() * 16)
{
@ -233,8 +228,8 @@ private:
misses = 0;
}
if (auto* g = findLeastRecentlyUsedGlyph())
return g;
if (auto g = findLeastRecentlyUsedGlyph())
return *g;
addNewGlyphSlots (32);
return glyphs.getLast();
@ -284,7 +279,7 @@ template <class RendererType>
class CachedGlyphEdgeTable : public ReferenceCountedObject
{
public:
CachedGlyphEdgeTable() {}
CachedGlyphEdgeTable() = default;
void draw (RendererType& state, Point<float> pos) const
{
@ -581,7 +576,7 @@ namespace EdgeTableFillers
SolidColour (const Image::BitmapData& image, PixelARGB colour)
: destData (image), sourceColour (colour)
{
if (sizeof (PixelType) == 3 && destData.pixelStride == sizeof (PixelType))
if (sizeof (PixelType) == 3 && (size_t) destData.pixelStride == sizeof (PixelType))
{
areRGBComponentsEqual = sourceColour.getRed() == sourceColour.getGreen()
&& sourceColour.getGreen() == sourceColour.getBlue();
@ -690,11 +685,11 @@ namespace EdgeTableFillers
forcedinline void replaceLine (PixelRGB* dest, PixelARGB colour, int width) const noexcept
{
if (destData.pixelStride == sizeof (*dest))
if ((size_t) destData.pixelStride == sizeof (*dest))
{
if (areRGBComponentsEqual) // if all the component values are the same, we can cheat..
{
memset (dest, colour.getRed(), (size_t) width * 3);
memset ((void*) dest, colour.getRed(), (size_t) width * 3);
}
else
{
@ -735,8 +730,8 @@ namespace EdgeTableFillers
forcedinline void replaceLine (PixelAlpha* dest, const PixelARGB colour, int width) const noexcept
{
if (destData.pixelStride == sizeof (*dest))
memset (dest, colour.getAlpha(), (size_t) width);
if ((size_t) destData.pixelStride == sizeof (*dest))
memset ((void*) dest, colour.getAlpha(), (size_t) width);
else
JUCE_PERFORM_PIXEL_OP_LOOP (setAlpha (colour.getAlpha()))
}
@ -966,7 +961,7 @@ namespace EdgeTableFillers
&& srcData.pixelFormat == Image::RGB
&& destData.pixelFormat == Image::RGB)
{
memcpy (dest, src, (size_t) (width * srcStride));
memcpy ((void*) dest, src, (size_t) (width * srcStride));
}
else
{
@ -1398,7 +1393,7 @@ namespace EdgeTableFillers
private:
struct BresenhamInterpolator
{
BresenhamInterpolator() noexcept {}
BresenhamInterpolator() = default;
void set (int n1, int n2, int steps, int offsetInt) noexcept
{
@ -1629,8 +1624,8 @@ struct ClipRegions
{
struct Base : public SingleThreadedReferenceCountedObject
{
Base() {}
virtual ~Base() {}
Base() = default;
~Base() override = default;
using Ptr = ReferenceCountedObjectPtr<Base>;
@ -1671,13 +1666,13 @@ struct ClipRegions
using Ptr = typename Base::Ptr;
Ptr clone() const override { return new EdgeTableRegion (*this); }
Ptr clone() const override { return *new EdgeTableRegion (*this); }
Ptr applyClipTo (const Ptr& target) const override { return target->clipToEdgeTable (edgeTable); }
Ptr clipToRectangle (Rectangle<int> r) override
{
edgeTable.clipToRectangle (r);
return edgeTable.isEmpty() ? nullptr : this;
return edgeTable.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr clipToRectangleList (const RectangleList<int>& r) override
@ -1688,26 +1683,26 @@ struct ClipRegions
for (auto& i : inverse)
edgeTable.excludeRectangle (i);
return edgeTable.isEmpty() ? nullptr : this;
return edgeTable.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr excludeClipRectangle (Rectangle<int> r) override
{
edgeTable.excludeRectangle (r);
return edgeTable.isEmpty() ? nullptr : this;
return edgeTable.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr clipToPath (const Path& p, const AffineTransform& transform) override
{
EdgeTable et (edgeTable.getMaximumBounds(), p, transform);
edgeTable.clipToEdgeTable (et);
return edgeTable.isEmpty() ? nullptr : this;
return edgeTable.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr clipToEdgeTable (const EdgeTable& et) override
{
edgeTable.clipToEdgeTable (et);
return edgeTable.isEmpty() ? nullptr : this;
return edgeTable.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr clipToImageAlpha (const Image& image, const AffineTransform& transform, Graphics::ResamplingQuality quality) override
@ -1726,11 +1721,11 @@ struct ClipRegions
auto imageY = ((ty + 128) >> 8);
if (image.getFormat() == Image::ARGB)
straightClipImage (srcData, imageX, imageY, (PixelARGB*) 0);
straightClipImage (srcData, imageX, imageY, (PixelARGB*) nullptr);
else
straightClipImage (srcData, imageX, imageY, (PixelAlpha*) 0);
straightClipImage (srcData, imageX, imageY, (PixelAlpha*) nullptr);
return edgeTable.isEmpty() ? nullptr : this;
return edgeTable.isEmpty() ? Ptr() : Ptr (*this);
}
}
@ -1747,12 +1742,12 @@ struct ClipRegions
if (! edgeTable.isEmpty())
{
if (image.getFormat() == Image::ARGB)
transformedClipImage (srcData, transform, quality, (PixelARGB*) 0);
transformedClipImage (srcData, transform, quality, (PixelARGB*) nullptr);
else
transformedClipImage (srcData, transform, quality, (PixelAlpha*) 0);
transformedClipImage (srcData, transform, quality, (PixelAlpha*) nullptr);
}
return edgeTable.isEmpty() ? nullptr : this;
return edgeTable.isEmpty() ? Ptr() : Ptr (*this);
}
void translate (Point<int> delta) override
@ -1852,25 +1847,25 @@ struct ClipRegions
using Ptr = typename Base::Ptr;
Ptr clone() const override { return new RectangleListRegion (*this); }
Ptr clone() const override { return *new RectangleListRegion (*this); }
Ptr applyClipTo (const Ptr& target) const override { return target->clipToRectangleList (clip); }
Ptr clipToRectangle (Rectangle<int> r) override
{
clip.clipTo (r);
return clip.isEmpty() ? nullptr : this;
return clip.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr clipToRectangleList (const RectangleList<int>& r) override
{
clip.clipTo (r);
return clip.isEmpty() ? nullptr : this;
return clip.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr excludeClipRectangle (Rectangle<int> r) override
{
clip.subtract (r);
return clip.isEmpty() ? nullptr : this;
return clip.isEmpty() ? Ptr() : Ptr (*this);
}
Ptr clipToPath (const Path& p, const AffineTransform& transform) override { return toEdgeTable()->clipToPath (p, transform); }
@ -2069,9 +2064,9 @@ struct ClipRegions
JUCE_DECLARE_NON_COPYABLE (SubRectangleIteratorFloat)
};
Ptr toEdgeTable() const { return new EdgeTableRegion (clip); }
Ptr toEdgeTable() const { return *new EdgeTableRegion (clip); }
RectangleListRegion& operator= (const RectangleListRegion&);
RectangleListRegion& operator= (const RectangleListRegion&) = delete;
};
};
@ -2268,7 +2263,7 @@ public:
auto clipped = clip->getClipBounds().getIntersection (r);
if (! clipped.isEmpty())
fillShape (new RectangleListRegionType (clipped), false);
fillShape (*new RectangleListRegionType (clipped), false);
}
}
@ -2283,7 +2278,7 @@ public:
auto clipped = clip->getClipBounds().toFloat().getIntersection (r);
if (! clipped.isEmpty())
fillShape (new EdgeTableRegionType (clipped), false);
fillShape (*new EdgeTableRegionType (clipped), false);
}
}
@ -2337,7 +2332,7 @@ public:
if (transform.isIdentity())
{
fillShape (new EdgeTableRegionType (list), false);
fillShape (*new EdgeTableRegionType (list), false);
}
else if (! transform.isRotated)
{
@ -2348,7 +2343,7 @@ public:
else
transformed.transformAll (transform.getTransform());
fillShape (new EdgeTableRegionType (transformed), false);
fillShape (*new EdgeTableRegionType (transformed), false);
}
else
{
@ -2365,7 +2360,7 @@ public:
auto clipRect = clip->getClipBounds();
if (path.getBoundsTransformed (trans).getSmallestIntegerContainer().intersects (clipRect))
fillShape (new EdgeTableRegionType (clipRect, path, trans), false);
fillShape (*new EdgeTableRegionType (clipRect, path, trans), false);
}
}
@ -2384,7 +2379,7 @@ public:
edgeTableClip->edgeTable.multiplyLevels (1.0f + 1.6f * brightness);
}
fillShape (edgeTableClip, false);
fillShape (*edgeTableClip, false);
}
}
@ -2398,15 +2393,15 @@ public:
void drawImage (const Image& sourceImage, const AffineTransform& trans)
{
if (clip != nullptr && ! fillType.colour.isTransparent())
renderImage (sourceImage, trans, nullptr);
renderImage (sourceImage, trans, {});
}
static bool isOnlyTranslationAllowingError (const AffineTransform& t, float tolerence) noexcept
static bool isOnlyTranslationAllowingError (const AffineTransform& t, float tolerance) noexcept
{
return std::abs (t.mat01) < tolerence
&& std::abs (t.mat10) < tolerence
&& std::abs (t.mat00 - 1.0f) < tolerence
&& std::abs (t.mat11 - 1.0f) < tolerence;
return std::abs (t.mat01) < tolerance
&& std::abs (t.mat10) < tolerance
&& std::abs (t.mat00 - 1.0f) < tolerance
&& std::abs (t.mat11 - 1.0f) < tolerance;
}
void renderImage (const Image& sourceImage, const AffineTransform& trans, const BaseRegionType* tiledFillClipRegion)
@ -2435,7 +2430,7 @@ public:
area = area.getIntersection (getThis().getMaximumBounds());
if (! area.isEmpty())
if (auto c = clip->applyClipTo (new EdgeTableRegionType (area)))
if (auto c = clip->applyClipTo (*new EdgeTableRegionType (area)))
c->renderImageUntransformed (getThis(), sourceImage, alpha, tx, ty, false);
}
@ -2491,7 +2486,7 @@ public:
}
else if (fillType.isTiledImage())
{
renderImage (fillType.image, fillType.transform, shapeToFill);
renderImage (fillType.image, fillType.transform, shapeToFill.get());
}
else
{
@ -2529,10 +2524,7 @@ public:
{
}
SoftwareRendererSavedState (const SoftwareRendererSavedState& other)
: BaseClass (other), image (other.image), font (other.font)
{
}
SoftwareRendererSavedState (const SoftwareRendererSavedState& other) = default;
SoftwareRendererSavedState* beginTransparencyLayer (float opacity)
{
@ -2610,7 +2602,7 @@ public:
std::unique_ptr<EdgeTable> et (font.getTypeface()->getEdgeTableForGlyph (glyphNumber, t, fontHeight));
if (et != nullptr)
fillShape (new EdgeTableRegionType (*et), false);
fillShape (*new EdgeTableRegionType (*et), false);
}
}
}
@ -2641,9 +2633,9 @@ public:
switch (destData.pixelFormat)
{
case Image::ARGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelARGB*) 0); break;
case Image::RGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelRGB*) 0); break;
default: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelAlpha*) 0); break;
case Image::ARGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelARGB*) nullptr); break;
case Image::RGB: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelRGB*) nullptr); break;
default: EdgeTableFillers::renderSolidFill (iter, destData, colour, replaceContents, (PixelAlpha*) nullptr); break;
}
}
@ -2658,9 +2650,9 @@ public:
switch (destData.pixelFormat)
{
case Image::ARGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelARGB*) 0); break;
case Image::RGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelRGB*) 0); break;
default: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelAlpha*) 0); break;
case Image::ARGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelARGB*) nullptr); break;
case Image::RGB: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelRGB*) nullptr); break;
default: EdgeTableFillers::renderGradient (iter, destData, gradient, trans, lookupTable, numLookupEntries, isIdentity, (PixelAlpha*) nullptr); break;
}
}
@ -2669,7 +2661,7 @@ public:
Font font;
private:
SoftwareRendererSavedState& operator= (const SoftwareRendererSavedState&);
SoftwareRendererSavedState& operator= (const SoftwareRendererSavedState&) = delete;
};
//==============================================================================
@ -2681,7 +2673,7 @@ public:
: currentState (initialState)
{}
SavedStateStack() noexcept {}
SavedStateStack() = default;
void initialise (StateObjectType* state)
{
@ -2765,7 +2757,7 @@ public:
protected:
StackBasedLowLevelGraphicsContext (SavedStateType* initialState) : stack (initialState) {}
StackBasedLowLevelGraphicsContext() {}
StackBasedLowLevelGraphicsContext() = default;
RenderingHelpers::SavedStateStack<SavedStateType> stack;
};

View File

@ -94,11 +94,37 @@ bool TextLayout::createNativeLayout (const AttributedString&)
#else
//==============================================================================
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
STATICMETHOD (create, "create", "(Ljava/lang/String;I)Landroid/graphics/Typeface;") \
STATICMETHOD (createFromFile, "createFromFile", "(Ljava/lang/String;)Landroid/graphics/Typeface;") \
STATICMETHOD (createFromAsset, "createFromAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;)Landroid/graphics/Typeface;")
DECLARE_JNI_CLASS (TypefaceClass, "android/graphics/Typeface");
DECLARE_JNI_CLASS (TypefaceClass, "android/graphics/Typeface")
#undef JNI_CLASS_MEMBERS
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
METHOD (constructor, "<init>", "()V") \
METHOD (computeBounds, "computeBounds", "(Landroid/graphics/RectF;Z)V")
DECLARE_JNI_CLASS (AndroidPath, "android/graphics/Path")
#undef JNI_CLASS_MEMBERS
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
METHOD (constructor, "<init>", "()V") \
FIELD (left, "left", "F") \
FIELD (right, "right", "F") \
FIELD (top, "top", "F") \
FIELD (bottom, "bottom", "F") \
METHOD (roundOut, "roundOut", "(Landroid/graphics/Rect;)V")
DECLARE_JNI_CLASS (AndroidRectF, "android/graphics/RectF")
#undef JNI_CLASS_MEMBERS
#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
STATICMETHOD (getInstance, "getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;") \
METHOD (update, "update", "([B)V") \
METHOD (digest, "digest", "()[B")
DECLARE_JNI_CLASS (JavaMessageDigest, "java/security/MessageDigest")
#undef JNI_CLASS_MEMBERS
//==============================================================================
@ -136,8 +162,7 @@ public:
JNIEnv* const env = getEnv();
// First check whether there's an embedded asset with this font name:
typeface = GlobalRef (android.activity.callObjectMethod (JuceAppActivity.getTypeFaceFromAsset,
javaString ("fonts/" + name).get()));
typeface = GlobalRef (getTypefaceFromAsset (name));
if (typeface.get() == nullptr)
{
@ -150,12 +175,12 @@ public:
fontFile = findFontFile (name, isBold, isItalic);
if (fontFile.exists())
typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.createFromFile,
javaString (fontFile.getFullPathName()).get()));
typeface = GlobalRef (LocalRef<jobject>(env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.createFromFile,
javaString (fontFile.getFullPathName()).get())));
else
typeface = GlobalRef (env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.create,
javaString (getName()).get(),
(isBold ? 1 : 0) + (isItalic ? 2 : 0)));
typeface = GlobalRef (LocalRef<jobject>(env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.create,
javaString (getName()).get(),
(isBold ? 1 : 0) + (isItalic ? 2 : 0))));
}
initialise (env);
@ -164,23 +189,24 @@ public:
AndroidTypeface (const void* data, size_t size)
: Typeface (String (static_cast<uint64> (reinterpret_cast<uintptr_t> (data))), String())
{
JNIEnv* const env = getEnv();
auto* env = getEnv();
auto cacheFile = getCacheFileForData (data, size);
LocalRef<jbyteArray> bytes (env->NewByteArray ((jsize) size));
env->SetByteArrayRegion (bytes, 0, (jsize) size, (const jbyte*) data);
typeface = GlobalRef (android.activity.callObjectMethod (JuceAppActivity.getTypeFaceFromByteArray, bytes.get()));
typeface = GlobalRef (LocalRef<jobject>(env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.createFromFile,
javaString (cacheFile.getFullPathName()).get())));
initialise (env);
}
void initialise (JNIEnv* const env)
{
rect = GlobalRef (env->NewObject (AndroidRect, AndroidRect.constructor, 0, 0, 0, 0));
rect = GlobalRef (LocalRef<jobject>(env->NewObject (AndroidRect, AndroidRect.constructor, 0, 0, 0, 0)));
paint = GlobalRef (GraphicsHelpers::createPaint (Graphics::highResamplingQuality));
const LocalRef<jobject> ignored (paint.callObjectMethod (AndroidPaint.setTypeface, typeface.get()));
charArray = GlobalRef (LocalRef<jobject>((jobject) env->NewCharArray (2)));
paint.callVoidMethod (AndroidPaint.setTextSize, referenceFontSize);
const float fullAscent = std::abs (paint.callFloatMethod (AndroidPaint.ascent));
@ -199,8 +225,8 @@ public:
float getStringWidth (const String& text) override
{
JNIEnv* env = getEnv();
const int numChars = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer());
jfloatArray widths = env->NewFloatArray (numChars);
auto numChars = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer());
jfloatArray widths = env->NewFloatArray ((int) numChars);
const int numDone = paint.callIntMethod (AndroidPaint.getTextWidths, javaString (text).get(), widths);
@ -209,6 +235,7 @@ public:
env->DeleteLocalRef (widths);
float x = 0;
for (int i = 0; i < numDone; ++i)
x += localWidths[i];
@ -218,8 +245,8 @@ public:
void getGlyphPositions (const String& text, Array<int>& glyphs, Array<float>& xOffsets) override
{
JNIEnv* env = getEnv();
const int numChars = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer());
jfloatArray widths = env->NewFloatArray (numChars);
auto numChars = CharPointer_UTF16::getBytesRequiredFor (text.getCharPointer());
jfloatArray widths = env->NewFloatArray ((int) numChars);
const int numDone = paint.callIntMethod (AndroidPaint.getTextWidths, javaString (text).get(), widths);
@ -230,8 +257,8 @@ public:
auto s = text.getCharPointer();
xOffsets.add (0);
float x = 0;
for (int i = 0; i < numDone; ++i)
{
const float local = localWidths[i];
@ -290,20 +317,56 @@ public:
#else
jchar ch1 = glyphNumber, ch2 = 0;
#endif
Rectangle<int> bounds;
auto* env = getEnv();
JNIEnv* env = getEnv();
{
LocalRef<jobject> matrix (GraphicsHelpers::createMatrix (env, AffineTransform::scale (referenceFontToUnits).followedBy (t)));
jobject matrix = GraphicsHelpers::createMatrix (env, AffineTransform::scale (referenceFontToUnits).followedBy (t));
jintArray maskData = (jintArray) android.activity.callObjectMethod (JuceAppActivity.renderGlyph, ch1, ch2, paint.get(), matrix, rect.get());
jboolean isCopy;
auto* buffer = env->GetCharArrayElements ((jcharArray) charArray.get(), &isCopy);
env->DeleteLocalRef (matrix);
buffer[0] = ch1; buffer[1] = ch2;
env->ReleaseCharArrayElements ((jcharArray) charArray.get(), buffer, 0);
const int left = env->GetIntField (rect.get(), AndroidRect.left);
const int top = env->GetIntField (rect.get(), AndroidRect.top);
const int right = env->GetIntField (rect.get(), AndroidRect.right);
const int bottom = env->GetIntField (rect.get(), AndroidRect.bottom);
LocalRef<jobject> path (env->NewObject (AndroidPath, AndroidPath.constructor));
LocalRef<jobject> boundsF (env->NewObject (AndroidRectF, AndroidRectF.constructor));
const Rectangle<int> bounds (left, top, right - left, bottom - top);
env->CallVoidMethod (paint.get(), AndroidPaint.getCharsPath, charArray.get(), 0, (ch2 != 0 ? 2 : 1), 0.0f, 0.0f, path.get());
env->CallVoidMethod (path.get(), AndroidPath.computeBounds, boundsF.get(), 1);
env->CallBooleanMethod (matrix.get(), AndroidMatrix.mapRect, boundsF.get());
env->CallVoidMethod (boundsF.get(), AndroidRectF.roundOut, rect.get());
bounds = Rectangle<int>::leftTopRightBottom (env->GetIntField (rect.get(), AndroidRect.left) - 1,
env->GetIntField (rect.get(), AndroidRect.top),
env->GetIntField (rect.get(), AndroidRect.right) + 1,
env->GetIntField (rect.get(), AndroidRect.bottom));
auto w = bounds.getWidth();
auto h = jmax (1, bounds.getHeight());
LocalRef<jobject> bitmapConfig (env->CallStaticObjectMethod (AndroidBitmapConfig, AndroidBitmapConfig.valueOf, javaString ("ARGB_8888").get()));
LocalRef<jobject> bitmap (env->CallStaticObjectMethod (AndroidBitmap, AndroidBitmap.createBitmap, w, h, bitmapConfig.get()));
LocalRef<jobject> canvas (env->NewObject (AndroidCanvas, AndroidCanvas.create, bitmap.get()));
env->CallBooleanMethod (matrix.get(), AndroidMatrix.postTranslate, bounds.getX() * -1.0f, bounds.getY() * -1.0f);
env->CallVoidMethod (canvas.get(), AndroidCanvas.setMatrix, matrix.get());
env->CallVoidMethod (canvas.get(), AndroidCanvas.drawPath, path.get(), paint.get());
int requiredRenderArraySize = w * h;
if (requiredRenderArraySize > lastCachedRenderArraySize)
{
cachedRenderArray = GlobalRef (LocalRef<jobject> ((jobject) env->NewIntArray (requiredRenderArraySize)));
lastCachedRenderArraySize = requiredRenderArraySize;
}
env->CallVoidMethod (bitmap.get(), AndroidBitmap.getPixels, cachedRenderArray.get(), 0, w, 0, 0, w, h);
env->CallVoidMethod (bitmap.get(), AndroidBitmap.recycle);
}
EdgeTable* et = nullptr;
@ -311,10 +374,10 @@ public:
{
et = new EdgeTable (bounds);
jint* const maskDataElements = env->GetIntArrayElements (maskData, 0);
jint* const maskDataElements = env->GetIntArrayElements ((jintArray) cachedRenderArray.get(), 0);
const jint* mask = maskDataElements;
for (int y = top; y < bottom; ++y)
for (int y = bounds.getY(); y < bounds.getBottom(); ++y)
{
#if JUCE_LITTLE_ENDIAN
const uint8* const lineBytes = ((const uint8*) mask) + 3;
@ -322,19 +385,19 @@ public:
const uint8* const lineBytes = (const uint8*) mask;
#endif
et->clipLineToMask (left, y, lineBytes, 4, bounds.getWidth());
et->clipLineToMask (bounds.getX(), y, lineBytes, 4, bounds.getWidth());
mask += bounds.getWidth();
}
env->ReleaseIntArrayElements (maskData, maskDataElements, 0);
env->ReleaseIntArrayElements ((jintArray) cachedRenderArray.get(), maskDataElements, 0);
}
env->DeleteLocalRef (maskData);
return et;
}
GlobalRef typeface, paint, rect;
GlobalRef typeface, paint, rect, charArray, cachedRenderArray;
float ascent, descent, heightToPointsFactor;
int lastCachedRenderArraySize = -1;
private:
static File findFontFile (const String& family,
@ -372,6 +435,92 @@ private:
return File (path + ".ttf");
}
static LocalRef<jobject> getTypefaceFromAsset (const String& typefaceName)
{
auto* env = getEnv();
LocalRef<jobject> assetManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getAssets));
if (assetManager == nullptr)
return LocalRef<jobject>();
auto assetTypeface = env->CallStaticObjectMethod (TypefaceClass, TypefaceClass.createFromAsset, assetManager.get(),
javaString ("fonts/" + typefaceName).get());
// this may throw
if (env->ExceptionCheck() != 0)
{
env->ExceptionClear();
return LocalRef<jobject>();
}
return LocalRef<jobject> (assetTypeface);
}
static File getCacheDirectory()
{
static File result = [] ()
{
auto appContext = getAppContext();
if (appContext != nullptr)
{
auto* env = getEnv();
LocalRef<jobject> cacheFile (env->CallObjectMethod (appContext.get(), AndroidContext.getCacheDir));
LocalRef<jstring> jPath ((jstring) env->CallObjectMethod (cacheFile.get(), JavaFile.getAbsolutePath));
return File (juceString (env, jPath.get()));
}
jassertfalse;
return File();
} ();
return result;
}
static HashMap<String, File>& getInMemoryFontCache()
{
static HashMap<String, File> cache;
return cache;
}
static File getCacheFileForData (const void* data, size_t size)
{
static CriticalSection cs;
JNIEnv* const env = getEnv();
String key;
{
LocalRef<jobject> digest (env->CallStaticObjectMethod (JavaMessageDigest, JavaMessageDigest.getInstance, javaString("MD5").get()));
LocalRef<jbyteArray> bytes(env->NewByteArray(size));
jboolean ignore;
auto* jbytes = env->GetByteArrayElements(bytes.get(), &ignore);
memcpy(jbytes, data, size);
env->ReleaseByteArrayElements(bytes.get(), jbytes, 0);
env->CallVoidMethod(digest.get(), JavaMessageDigest.update, bytes.get());
LocalRef<jbyteArray> result((jbyteArray) env->CallObjectMethod(digest.get(), JavaMessageDigest.digest));
auto* md5Bytes = env->GetByteArrayElements(result.get(), &ignore);
key = String::toHexString(md5Bytes, env->GetArrayLength(result.get()), 0);
env->ReleaseByteArrayElements(result.get(), md5Bytes, 0);
}
ScopedLock lock (cs);
auto& mapEntry = getInMemoryFontCache().getReference (key);
if (mapEntry == File())
{
mapEntry = getCacheDirectory().getChildFile ("bindata_" + key);
mapEntry.replaceWithData (data, size);
}
return mapEntry;
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidTypeface)
};

View File

@ -29,7 +29,7 @@ namespace juce
namespace GraphicsHelpers
{
jobject createPaint (Graphics::ResamplingQuality quality)
LocalRef<jobject> createPaint (Graphics::ResamplingQuality quality)
{
jint constructorFlags = 1 /*ANTI_ALIAS_FLAG*/
| 4 /*DITHER_FLAG*/
@ -38,12 +38,12 @@ namespace GraphicsHelpers
if (quality > Graphics::lowResamplingQuality)
constructorFlags |= 2; /*FILTER_BITMAP_FLAG*/
return getEnv()->NewObject (AndroidPaint, AndroidPaint.constructor, constructorFlags);
return LocalRef<jobject>(getEnv()->NewObject (AndroidPaint, AndroidPaint.constructor, constructorFlags));
}
const jobject createMatrix (JNIEnv* env, const AffineTransform& t)
const LocalRef<jobject> createMatrix (JNIEnv* env, const AffineTransform& t)
{
jobject m = env->NewObject (AndroidMatrix, AndroidMatrix.constructor);
auto m = LocalRef<jobject>(env->NewObject (AndroidMatrix, AndroidMatrix.constructor));
jfloat values[9] = { t.mat00, t.mat01, t.mat02,
t.mat10, t.mat11, t.mat12,

View File

@ -27,13 +27,13 @@
namespace juce
{
struct FTLibWrapper : public ReferenceCountedObject
struct FTLibWrapper : public ReferenceCountedObject
{
FTLibWrapper() : library (0)
FTLibWrapper()
{
if (FT_Init_FreeType (&library) != 0)
{
library = 0;
library = {};
DBG ("Failed to initialize FreeType");
}
}
@ -44,7 +44,7 @@ struct FTLibWrapper : public ReferenceCountedObject
FT_Done_FreeType (library);
}
FT_Library library;
FT_Library library = {};
using Ptr = ReferenceCountedObjectPtr<FTLibWrapper>;
@ -55,18 +55,18 @@ struct FTLibWrapper : public ReferenceCountedObject
struct FTFaceWrapper : public ReferenceCountedObject
{
FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const File& file, int faceIndex)
: face (0), library (ftLib)
: library (ftLib)
{
if (FT_New_Face (ftLib->library, file.getFullPathName().toUTF8(), faceIndex, &face) != 0)
face = 0;
face = {};
}
FTFaceWrapper (const FTLibWrapper::Ptr& ftLib, const void* data, size_t dataSize, int faceIndex)
: face (0), library (ftLib), savedFaceData (data, dataSize)
: library (ftLib), savedFaceData (data, dataSize)
{
if (FT_New_Memory_Face (ftLib->library, (const FT_Byte*) savedFaceData.getData(),
(FT_Long) savedFaceData.getSize(), faceIndex, &face) != 0)
face = 0;
face = {};
}
~FTFaceWrapper()
@ -75,7 +75,7 @@ struct FTFaceWrapper : public ReferenceCountedObject
FT_Done_Face (face);
}
FT_Face face;
FT_Face face = {};
FTLibWrapper::Ptr library;
MemoryBlock savedFaceData;
@ -101,7 +101,7 @@ public:
//==============================================================================
struct KnownTypeface
{
KnownTypeface (const File& f, const int index, const FTFaceWrapper& face)
KnownTypeface (const File& f, int index, const FTFaceWrapper& face)
: file (f),
family (face.face->family_name),
style (face.face->style_name),
@ -141,10 +141,10 @@ public:
FTFaceWrapper::Ptr createFace (const String& fontName, const String& fontStyle)
{
const KnownTypeface* ftFace = matchTypeface (fontName, fontStyle);
auto ftFace = matchTypeface (fontName, fontStyle);
if (ftFace == nullptr) ftFace = matchTypeface (fontName, "Regular");
if (ftFace == nullptr) ftFace = matchTypeface (fontName, String());
if (ftFace == nullptr) ftFace = matchTypeface (fontName, {});
if (ftFace != nullptr)
return createFace (ftFace->file, ftFace->faceIndex);
@ -157,8 +157,8 @@ public:
{
StringArray s;
for (int i = 0; i < faces.size(); ++i)
s.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
for (auto* face : faces)
s.addIfNotAlreadyThere (face->family);
return s;
}
@ -167,28 +167,27 @@ public:
{
int i = styles.indexOf ("Regular", true);
if (i < 0)
for (i = 0; i < styles.size(); ++i)
if (! (styles[i].containsIgnoreCase ("Bold") || styles[i].containsIgnoreCase ("Italic")))
break;
if (i >= 0)
return i;
return i;
for (i = 0; i < styles.size(); ++i)
if (! (styles[i].containsIgnoreCase ("Bold") || styles[i].containsIgnoreCase ("Italic")))
return i;
return -1;
}
StringArray findAllTypefaceStyles (const String& family) const
{
StringArray s;
for (int i = 0; i < faces.size(); ++i)
{
const KnownTypeface* const face = faces.getUnchecked(i);
for (auto* face : faces)
if (face->family == family)
s.addIfNotAlreadyThere (face->style);
}
// try to get a regular style to be first in the list
const int regular = indexOfRegularStyle (s);
auto regular = indexOfRegularStyle (s);
if (regular > 0)
s.strings.swap (0, regular);
@ -197,10 +196,9 @@ public:
void scanFontPaths (const StringArray& paths)
{
for (int i = 0; i < paths.size(); ++i)
for (auto& path : paths)
{
DirectoryIterator iter (File::getCurrentWorkingDirectory()
.getChildFile (paths[i]), true);
DirectoryIterator iter (File::getCurrentWorkingDirectory().getChildFile (path), true);
while (iter.next())
if (iter.getFile().hasFileExtension ("ttf;pfb;pcf;otf"))
@ -210,23 +208,23 @@ public:
void getMonospacedNames (StringArray& monoSpaced) const
{
for (int i = 0; i < faces.size(); ++i)
if (faces.getUnchecked(i)->isMonospaced)
monoSpaced.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
for (auto* face : faces)
if (face->isMonospaced)
monoSpaced.addIfNotAlreadyThere (face->family);
}
void getSerifNames (StringArray& serif) const
{
for (int i = 0; i < faces.size(); ++i)
if (! faces.getUnchecked(i)->isSansSerif)
serif.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
for (auto* face : faces)
if (! (face->isSansSerif || face->isMonospaced))
serif.addIfNotAlreadyThere (face->family);
}
void getSansSerifNames (StringArray& sansSerif) const
{
for (int i = 0; i < faces.size(); ++i)
if (faces.getUnchecked(i)->isSansSerif)
sansSerif.addIfNotAlreadyThere (faces.getUnchecked(i)->family);
for (auto* face : faces)
if (face->isSansSerif)
sansSerif.addIfNotAlreadyThere (face->family);
}
JUCE_DECLARE_SINGLETON_SINGLETHREADED_MINIMAL (FTTypefaceList)
@ -262,14 +260,10 @@ private:
const KnownTypeface* matchTypeface (const String& familyName, const String& style) const noexcept
{
for (int i = 0; i < faces.size(); ++i)
{
const KnownTypeface* const face = faces.getUnchecked(i);
for (auto* face : faces)
if (face->family == familyName
&& (face->style.equalsIgnoreCase (style) || style.isEmpty()))
return face;
}
return nullptr;
}
@ -278,8 +272,8 @@ private:
{
static const char* sansNames[] = { "Sans", "Verdana", "Arial", "Ubuntu" };
for (int i = 0; i < numElementsInArray (sansNames); ++i)
if (family.containsIgnoreCase (sansNames[i]))
for (auto* name : sansNames)
if (family.containsIgnoreCase (name))
return true;
return false;
@ -323,13 +317,13 @@ public:
{
if (faceWrapper != nullptr)
{
FT_Face face = faceWrapper->face;
const unsigned int glyphIndex = FT_Get_Char_Index (face, (FT_ULong) character);
auto face = faceWrapper->face;
auto glyphIndex = FT_Get_Char_Index (face, (FT_ULong) character);
if (FT_Load_Glyph (face, glyphIndex, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM | FT_LOAD_NO_HINTING) == 0
&& face->glyph->format == ft_glyph_format_outline)
{
const float scale = 1.0f / (float) (face->ascender - face->descender);
auto scale = 1.0f / (float) (face->ascender - face->descender);
Path destShape;
if (getGlyphShape (destShape, face->glyph->outline, scale))
@ -350,12 +344,12 @@ public:
private:
FTFaceWrapper::Ptr faceWrapper;
bool getGlyphShape (Path& destShape, const FT_Outline& outline, const float scaleX)
bool getGlyphShape (Path& destShape, const FT_Outline& outline, float scaleX)
{
const float scaleY = -scaleX;
const short* const contours = outline.contours;
const char* const tags = outline.tags;
const FT_Vector* const points = outline.points;
auto scaleY = -scaleX;
auto* contours = outline.contours;
auto* tags = outline.tags;
auto* points = outline.points;
for (int c = 0; c < outline.n_contours; ++c)
{
@ -364,15 +358,15 @@ private:
for (int p = startPoint; p <= endPoint; ++p)
{
const float x = scaleX * points[p].x;
const float y = scaleY * points[p].y;
auto x = scaleX * points[p].x;
auto y = scaleY * points[p].y;
if (p == startPoint)
{
if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
{
float x2 = scaleX * points [endPoint].x;
float y2 = scaleY * points [endPoint].y;
auto x2 = scaleX * points [endPoint].x;
auto y2 = scaleY * points [endPoint].y;
if (FT_CURVE_TAG (tags[endPoint]) != FT_Curve_Tag_On)
{
@ -396,8 +390,8 @@ private:
else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
{
const int nextIndex = (p == endPoint) ? startPoint : p + 1;
float x2 = scaleX * points [nextIndex].x;
float y2 = scaleY * points [nextIndex].y;
auto x2 = scaleX * points [nextIndex].x;
auto y2 = scaleY * points [nextIndex].y;
if (FT_CURVE_TAG (tags [nextIndex]) == FT_Curve_Tag_Conic)
{
@ -421,10 +415,10 @@ private:
|| FT_CURVE_TAG (tags[next2]) != FT_Curve_Tag_On)
return false;
const float x2 = scaleX * points [next1].x;
const float y2 = scaleY * points [next1].y;
const float x3 = scaleX * points [next2].x;
const float y3 = scaleY * points [next2].y;
auto x2 = scaleX * points [next1].x;
auto y2 = scaleY * points [next1].y;
auto x3 = scaleX * points [next2].x;
auto y3 = scaleY * points [next2].y;
destShape.cubicTo (x, y, x2, y2, x3, y3);
p += 2;
@ -439,10 +433,10 @@ private:
void addKerning (FT_Face face, const uint32 character, const uint32 glyphIndex)
{
const float height = (float) (face->ascender - face->descender);
auto height = (float) (face->ascender - face->descender);
uint32 rightGlyphIndex;
FT_ULong rightCharCode = FT_Get_First_Char (face, &rightGlyphIndex);
auto rightCharCode = FT_Get_First_Char (face, &rightGlyphIndex);
while (rightGlyphIndex != 0)
{

View File

@ -27,16 +27,16 @@
namespace juce
{
static XmlElement* findFontsConfFile()
static std::unique_ptr<XmlElement> findFontsConfFile()
{
static const char* pathsToSearch[] = { "/etc/fonts/fonts.conf",
"/usr/share/fonts/fonts.conf" };
for (auto* path : pathsToSearch)
if (auto* xml = XmlDocument::parse (File (path)))
if (auto xml = parseXML (File (path)))
return xml;
return nullptr;
return {};
}
StringArray FTTypefaceList::getDefaultFontDirectories()
@ -48,9 +48,7 @@ StringArray FTTypefaceList::getDefaultFontDirectories()
if (fontDirs.isEmpty())
{
std::unique_ptr<XmlElement> fontsInfo (findFontsConfFile());
if (fontsInfo != nullptr)
if (auto fontsInfo = findFontsConfFile())
{
forEachXmlChildElementWithTagName (*fontsInfo, e, "dir")
{

View File

@ -32,7 +32,7 @@ class CoreGraphicsContext : public LowLevelGraphicsContext
{
public:
CoreGraphicsContext (CGContextRef context, float flipHeight, float targetScale);
~CoreGraphicsContext();
~CoreGraphicsContext() override;
//==============================================================================
bool isVectorDevice() const override { return false; }
@ -80,7 +80,7 @@ private:
float targetScale;
CGColorSpaceRef rgbColourSpace, greyColourSpace;
mutable Rectangle<int> lastClipRect;
mutable bool lastClipRectIsValid;
mutable bool lastClipRectIsValid = false;
struct SavedState
{
@ -92,9 +92,9 @@ private:
FillType fillType;
Font font;
CGFontRef fontRef;
CGFontRef fontRef = {};
CGAffineTransform fontTransform;
CGGradientRef gradient;
CGGradientRef gradient = {};
};
std::unique_ptr<SavedState> state;

View File

@ -27,27 +27,37 @@
namespace juce
{
//==============================================================================
class CoreGraphicsImage : public ImagePixelData
{
public:
CoreGraphicsImage (const Image::PixelFormat format, const int w, const int h, const bool clearImage)
: ImagePixelData (format, w, h), cachedImageRef (0)
CoreGraphicsImage (const Image::PixelFormat format, int w, int h, bool clearImage)
: ImagePixelData (format, w, h)
{
pixelStride = format == Image::RGB ? 3 : ((format == Image::ARGB) ? 4 : 1);
lineStride = (pixelStride * jmax (1, width) + 3) & ~3;
imageData.allocate ((size_t) lineStride * (size_t) jmax (1, height), clearImage);
auto numComponents = (size_t) lineStride * (size_t) jmax (1, height);
# if JUCE_MAC && defined (__MAC_10_14)
// This version of the SDK intermittently requires a bit of extra space
// at the end of the image data. This feels like something has gone
// wrong in Apple's code.
numComponents += (size_t) lineStride;
#endif
imageDataHolder->data.allocate (numComponents, clearImage);
CGColorSpaceRef colourSpace = (format == Image::SingleChannel) ? CGColorSpaceCreateDeviceGray()
: CGColorSpaceCreateDeviceRGB();
context = CGBitmapContextCreate (imageData, (size_t) width, (size_t) height, 8, (size_t) lineStride,
context = CGBitmapContextCreate (imageDataHolder->data, (size_t) width, (size_t) height, 8, (size_t) lineStride,
colourSpace, getCGImageFlags (format));
CGColorSpaceRelease (colourSpace);
}
~CoreGraphicsImage()
~CoreGraphicsImage() override
{
freeCachedImageRef();
CGContextRelease (context);
@ -62,7 +72,7 @@ public:
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode) override
{
bitmap.data = imageData + x * pixelStride + y * lineStride;
bitmap.data = imageDataHolder->data + x * pixelStride + y * lineStride;
bitmap.pixelFormat = pixelFormat;
bitmap.lineStride = lineStride;
bitmap.pixelStride = pixelStride;
@ -76,9 +86,9 @@ public:
ImagePixelData::Ptr clone() override
{
CoreGraphicsImage* im = new CoreGraphicsImage (pixelFormat, width, height, false);
memcpy (im->imageData, imageData, (size_t) (lineStride * height));
return im;
auto im = new CoreGraphicsImage (pixelFormat, width, height, false);
memcpy (im->imageDataHolder->data, imageDataHolder->data, (size_t) (lineStride * height));
return *im;
}
ImageType* createType() const override { return new NativeImageType(); }
@ -86,9 +96,9 @@ public:
//==============================================================================
static CGImageRef getCachedImageRef (const Image& juceImage, CGColorSpaceRef colourSpace)
{
CoreGraphicsImage* const cgim = dynamic_cast<CoreGraphicsImage*> (juceImage.getPixelData());
auto cgim = dynamic_cast<CoreGraphicsImage*> (juceImage.getPixelData());
if (cgim != nullptr && cgim->cachedImageRef != 0)
if (cgim != nullptr && cgim->cachedImageRef != nullptr)
{
CGImageRetain (cgim->cachedImageRef);
return cgim->cachedImageRef;
@ -97,36 +107,45 @@ public:
CGImageRef ref = createImage (juceImage, colourSpace, false);
if (cgim != nullptr)
{
CGImageRetain (ref);
cgim->cachedImageRef = ref;
}
cgim->cachedImageRef = CGImageRetain (ref);
return ref;
}
static CGImageRef createImage (const Image& juceImage, CGColorSpaceRef colourSpace, const bool mustOutliveSource)
static CGImageRef createImage (const Image& juceImage, CGColorSpaceRef colourSpace, bool mustOutliveSource)
{
const Image::BitmapData srcData (juceImage, Image::BitmapData::readOnly);
CGDataProviderRef provider;
if (mustOutliveSource)
{
CFDataRef data = CFDataCreate (0, (const UInt8*) srcData.data, (CFIndex) ((size_t) srcData.lineStride * (size_t) srcData.height));
CFDataRef data = CFDataCreate (nullptr, (const UInt8*) srcData.data, (CFIndex) ((size_t) srcData.lineStride * (size_t) srcData.height));
provider = CGDataProviderCreateWithCFData (data);
CFRelease (data);
}
else
{
provider = CGDataProviderCreateWithData (0, srcData.data, (size_t) srcData.lineStride * (size_t) srcData.height, 0);
auto* imageDataContainer = [](const Image& img) -> HeapBlockContainer::Ptr*
{
if (auto* cgim = dynamic_cast<CoreGraphicsImage*> (img.getPixelData()))
return new HeapBlockContainer::Ptr (cgim->imageDataHolder);
return nullptr;
} (juceImage);
provider = CGDataProviderCreateWithData (imageDataContainer,
srcData.data,
(size_t) srcData.lineStride * (size_t) srcData.height,
[] (void * __nullable info, const void*, size_t) { delete (HeapBlockContainer::Ptr*) info; });
}
CGImageRef imageRef = CGImageCreate ((size_t) srcData.width,
(size_t) srcData.height,
8, (size_t) srcData.pixelStride * 8,
8,
(size_t) srcData.pixelStride * 8,
(size_t) srcData.lineStride,
colourSpace, getCGImageFlags (juceImage.getFormat()), provider,
0, true, kCGRenderingIntentDefault);
nullptr, true, kCGRenderingIntentDefault);
CGDataProviderRelease (provider);
return imageRef;
@ -134,17 +153,24 @@ public:
//==============================================================================
CGContextRef context;
CGImageRef cachedImageRef;
HeapBlock<uint8> imageData;
CGImageRef cachedImageRef = {};
struct HeapBlockContainer : public ReferenceCountedObject
{
using Ptr = ReferenceCountedObjectPtr<HeapBlockContainer>;
HeapBlock<uint8> data;
};
HeapBlockContainer::Ptr imageDataHolder = new HeapBlockContainer();
int pixelStride, lineStride;
private:
void freeCachedImageRef()
{
if (cachedImageRef != 0)
if (cachedImageRef != CGImageRef())
{
CGImageRelease (cachedImageRef);
cachedImageRef = 0;
cachedImageRef = {};
}
}
@ -162,21 +188,28 @@ private:
ImagePixelData::Ptr NativeImageType::create (Image::PixelFormat format, int width, int height, bool clearImage) const
{
return new CoreGraphicsImage (format == Image::RGB ? Image::ARGB : format, width, height, clearImage);
return *new CoreGraphicsImage (format == Image::RGB ? Image::ARGB : format, width, height, clearImage);
}
//==============================================================================
CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, const float h, const float scale)
CoreGraphicsContext::CoreGraphicsContext (CGContextRef c, float h, float scale)
: context (c),
flipHeight (h),
targetScale (scale),
lastClipRectIsValid (false),
state (new SavedState())
{
CGContextRetain (context);
CGContextSaveGState (context);
CGContextSetShouldSmoothFonts (context, true);
CGContextSetAllowsFontSmoothing (context, true);
bool enableFontSmoothing
#if JUCE_DISABLE_COREGRAPHICS_FONT_SMOOTHING
= false;
#else
= true;
#endif
CGContextSetShouldSmoothFonts (context, enableFontSmoothing);
CGContextSetAllowsFontSmoothing (context, enableFontSmoothing);
CGContextSetShouldAntialias (context, true);
CGContextSetBlendMode (context, kCGBlendModeNormal);
rgbColourSpace = CGColorSpaceCreateDeviceRGB();
@ -215,14 +248,15 @@ void CoreGraphicsContext::addTransform (const AffineTransform& transform)
float CoreGraphicsContext::getPhysicalPixelScaleFactor()
{
const CGAffineTransform t = CGContextGetCTM (context);
auto t = CGContextGetCTM (context);
return targetScale * (float) (juce_hypot (t.a, t.c) + juce_hypot (t.b, t.d)) / 2.0f;
}
bool CoreGraphicsContext::clipToRectangle (const Rectangle<int>& r)
{
CGContextClipToRect (context, CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()));
CGContextClipToRect (context, CGRectMake (r.getX(), flipHeight - r.getBottom(),
r.getWidth(), r.getHeight()));
if (lastClipRectIsValid)
{
@ -295,10 +329,10 @@ void CoreGraphicsContext::clipToImageAlpha (const Image& sourceImage, const Affi
CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, greyColourSpace, true);
flip();
AffineTransform t (AffineTransform::verticalFlip (sourceImage.getHeight()).followedBy (transform));
auto t = AffineTransform::verticalFlip (sourceImage.getHeight()).followedBy (transform);
applyTransform (t);
CGRect r = convertToCGRect (sourceImage.getBounds());
auto r = convertToCGRect (sourceImage.getBounds());
CGContextClipToMask (context, r, image);
applyTransform (t.inverted());
@ -318,7 +352,7 @@ Rectangle<int> CoreGraphicsContext::getClipBounds() const
{
if (! lastClipRectIsValid)
{
CGRect bounds = CGRectIntegral (CGContextGetClipBoundingBox (context));
auto bounds = CGRectIntegral (CGContextGetClipBoundingBox (context));
lastClipRectIsValid = true;
lastClipRect.setBounds (roundToInt (bounds.origin.x),
@ -362,7 +396,7 @@ void CoreGraphicsContext::beginTransparencyLayer (float opacity)
{
saveState();
CGContextSetAlpha (context, opacity);
CGContextBeginTransparencyLayer (context, 0);
CGContextBeginTransparencyLayer (context, nullptr);
}
void CoreGraphicsContext::endTransparencyLayer()
@ -402,7 +436,7 @@ void CoreGraphicsContext::setInterpolationQuality (Graphics::ResamplingQuality q
}
//==============================================================================
void CoreGraphicsContext::fillRect (const Rectangle<int>& r, const bool replaceExistingContents)
void CoreGraphicsContext::fillRect (const Rectangle<int>& r, bool replaceExistingContents)
{
fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), replaceExistingContents);
}
@ -412,7 +446,7 @@ void CoreGraphicsContext::fillRect (const Rectangle<float>& r)
fillCGRect (CGRectMake (r.getX(), flipHeight - r.getBottom(), r.getWidth(), r.getHeight()), false);
}
void CoreGraphicsContext::fillCGRect (const CGRect& cgRect, const bool replaceExistingContents)
void CoreGraphicsContext::fillCGRect (const CGRect& cgRect, bool replaceExistingContents)
{
if (replaceExistingContents)
{
@ -481,19 +515,21 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
drawImage (sourceImage, transform, false);
}
void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTransform& transform, const bool fillEntireClipAsTiles)
void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles)
{
const int iw = sourceImage.getWidth();
const int ih = sourceImage.getHeight();
CGImageRef image = CoreGraphicsImage::getCachedImageRef (sourceImage, sourceImage.getFormat() == Image::PixelFormat::SingleChannel ? greyColourSpace
: rgbColourSpace);
auto iw = sourceImage.getWidth();
auto ih = sourceImage.getHeight();
auto colourSpace = sourceImage.getFormat() == Image::PixelFormat::SingleChannel ? greyColourSpace
: rgbColourSpace;
CGImageRef image = CoreGraphicsImage::getCachedImageRef (sourceImage, colourSpace);
CGContextSaveGState (context);
CGContextSetAlpha (context, state->fillType.getOpacity());
flip();
applyTransform (AffineTransform::verticalFlip (ih).followedBy (transform));
CGRect imageRect = CGRectMake (0, 0, iw, ih);
auto imageRect = CGRectMake (0, 0, iw, ih);
if (fillEntireClipAsTiles)
{
@ -502,21 +538,21 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
#else
// There's a bug in CGContextDrawTiledImage that makes it incredibly slow
// if it's doing a transformation - it's quicker to just draw lots of images manually
if (&CGContextDrawTiledImage != 0 && transform.isOnlyTranslation())
if (&CGContextDrawTiledImage != nullptr && transform.isOnlyTranslation())
{
CGContextDrawTiledImage (context, imageRect, image);
}
else
{
// Fallback to manually doing a tiled fill
CGRect clip = CGRectIntegral (CGContextGetClipBoundingBox (context));
auto clip = CGRectIntegral (CGContextGetClipBoundingBox (context));
int x = 0, y = 0;
while (x > clip.origin.x) x -= iw;
while (y > clip.origin.y) y -= ih;
const int right = (int) (clip.origin.x + clip.size.width);
const int bottom = (int) (clip.origin.y + clip.size.height);
auto right = (int) (clip.origin.x + clip.size.width);
auto bottom = (int) (clip.origin.y + clip.size.height);
while (y < bottom)
{
@ -540,25 +576,9 @@ void CoreGraphicsContext::drawImage (const Image& sourceImage, const AffineTrans
//==============================================================================
void CoreGraphicsContext::drawLine (const Line<float>& line)
{
if (state->fillType.isColour())
{
CGContextSetLineCap (context, kCGLineCapSquare);
CGContextSetLineWidth (context, 1.0f);
CGContextSetRGBStrokeColor (context,
state->fillType.colour.getFloatRed(), state->fillType.colour.getFloatGreen(),
state->fillType.colour.getFloatBlue(), state->fillType.colour.getFloatAlpha());
CGPoint cgLine[] = { { (CGFloat) line.getStartX(), flipHeight - (CGFloat) line.getStartY() },
{ (CGFloat) line.getEndX(), flipHeight - (CGFloat) line.getEndY() } };
CGContextStrokeLineSegments (context, cgLine, 1);
}
else
{
Path p;
p.addLineSegment (line, 1.0f);
fillPath (p, AffineTransform());
}
Path p;
p.addLineSegment (line, 1.0f);
fillPath (p, {});
}
void CoreGraphicsContext::fillRectList (const RectangleList<float>& list)
@ -594,10 +614,10 @@ void CoreGraphicsContext::setFont (const Font& newFont)
{
if (state->font != newFont)
{
state->fontRef = 0;
state->fontRef = nullptr;
state->font = newFont;
if (OSXTypeface* osxTypeface = dynamic_cast<OSXTypeface*> (state->font.getTypeface()))
if (auto osxTypeface = dynamic_cast<OSXTypeface*> (state->font.getTypeface()))
{
state->fontRef = osxTypeface->fontRef;
CGContextSetFont (context, state->fontRef);
@ -617,7 +637,7 @@ const Font& CoreGraphicsContext::getFont()
void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& transform)
{
if (state->fontRef != 0 && state->fillType.isColour())
if (state->fontRef != nullptr && state->fillType.isColour())
{
#if JUCE_CLANG
#pragma clang diagnostic push
@ -628,7 +648,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
{
CGContextSetTextMatrix (context, state->fontTransform); // have to set this each time, as it's not saved as part of the state
CGGlyph g = (CGGlyph) glyphNumber;
auto g = (CGGlyph) glyphNumber;
CGContextShowGlyphsAtPoint (context, transform.getTranslationX(),
flipHeight - roundToInt (transform.getTranslationY()), &g, 1);
}
@ -638,11 +658,11 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
flip();
applyTransform (transform);
CGAffineTransform t = state->fontTransform;
auto t = state->fontTransform;
t.d = -t.d;
CGContextSetTextMatrix (context, t);
CGGlyph g = (CGGlyph) glyphNumber;
auto g = (CGGlyph) glyphNumber;
CGContextShowGlyphsAtPoint (context, 0, 0, &g, 1);
CGContextRestoreGState (context);
@ -655,7 +675,7 @@ void CoreGraphicsContext::drawGlyph (int glyphNumber, const AffineTransform& tra
else
{
Path p;
Font& f = state->font;
auto& f = state->font;
f.getTypeface()->getOutlineForGlyph (glyphNumber, p);
fillPath (p, AffineTransform::scale (f.getHeight() * f.getHorizontalScale(), f.getHeight())
@ -670,7 +690,7 @@ bool CoreGraphicsContext::drawTextLayout (const AttributedString& text, const Re
}
CoreGraphicsContext::SavedState::SavedState()
: font (1.0f), fontRef (0), fontTransform (CGAffineTransformIdentity), gradient (0)
: font (1.0f), fontTransform (CGAffineTransformIdentity)
{
}
@ -678,13 +698,13 @@ CoreGraphicsContext::SavedState::SavedState (const SavedState& other)
: fillType (other.fillType), font (other.font), fontRef (other.fontRef),
fontTransform (other.fontTransform), gradient (other.gradient)
{
if (gradient != 0)
if (gradient != nullptr)
CGGradientRetain (gradient);
}
CoreGraphicsContext::SavedState::~SavedState()
{
if (gradient != 0)
if (gradient != nullptr)
CGGradientRelease (gradient);
}
@ -692,24 +712,24 @@ void CoreGraphicsContext::SavedState::setFill (const FillType& newFill)
{
fillType = newFill;
if (gradient != 0)
if (gradient != nullptr)
{
CGGradientRelease (gradient);
gradient = 0;
gradient = nullptr;
}
}
static CGGradientRef createGradient (const ColourGradient& g, CGColorSpaceRef colourSpace)
{
const int numColours = g.getNumColours();
CGFloat* const data = (CGFloat*) alloca ((size_t) numColours * 5 * sizeof (CGFloat));
CGFloat* const locations = data;
CGFloat* const components = data + numColours;
CGFloat* comps = components;
auto numColours = g.getNumColours();
auto data = (CGFloat*) alloca ((size_t) numColours * 5 * sizeof (CGFloat));
auto locations = data;
auto components = data + numColours;
auto comps = components;
for (int i = 0; i < numColours; ++i)
{
const Colour colour (g.getColour (i));
auto colour = g.getColour (i);
*comps++ = (CGFloat) colour.getFloatRed();
*comps++ = (CGFloat) colour.getFloatGreen();
*comps++ = (CGFloat) colour.getFloatBlue();
@ -730,14 +750,14 @@ void CoreGraphicsContext::drawGradient()
applyTransform (state->fillType.transform);
CGContextSetAlpha (context, state->fillType.getOpacity());
const ColourGradient& g = *state->fillType.gradient;
auto& g = *state->fillType.gradient;
CGPoint p1 (convertToCGPoint (g.point1));
CGPoint p2 (convertToCGPoint (g.point2));
auto p1 = convertToCGPoint (g.point1);
auto p2 = convertToCGPoint (g.point2);
state->fillType.transform.transformPoints (p1.x, p1.y, p2.x, p2.y);
if (state->gradient == 0)
if (state->gradient == nullptr)
state->gradient = createGradient (g, rgbColourSpace);
if (g.isRadial)
@ -820,34 +840,43 @@ void CoreGraphicsContext::applyTransform (const AffineTransform& transform) cons
#if USE_COREGRAPHICS_RENDERING && JUCE_USE_COREIMAGE_LOADER
Image juce_loadWithCoreImage (InputStream& input)
{
MemoryBlock data;
input.readIntoMemoryBlock (data, -1);
struct MemoryBlockHolder : public ReferenceCountedObject
{
using Ptr = ReferenceCountedObjectPtr<MemoryBlockHolder>;
MemoryBlock block;
};
MemoryBlockHolder::Ptr memBlockHolder = new MemoryBlockHolder();
input.readIntoMemoryBlock (memBlockHolder->block, -1);
#if JUCE_IOS
JUCE_AUTORELEASEPOOL
#endif
{
#if JUCE_IOS
if (UIImage* uiImage = [UIImage imageWithData: [NSData dataWithBytesNoCopy: data.getData()
length: data.getSize()
if (UIImage* uiImage = [UIImage imageWithData: [NSData dataWithBytesNoCopy: memBlockHolder->block.getData()
length: memBlockHolder->block.getSize()
freeWhenDone: NO]])
{
CGImageRef loadedImage = uiImage.CGImage;
#else
CGDataProviderRef provider = CGDataProviderCreateWithData (0, data.getData(), data.getSize(), 0);
CGImageSourceRef imageSource = CGImageSourceCreateWithDataProvider (provider, 0);
auto provider = CGDataProviderCreateWithData (new MemoryBlockHolder::Ptr (memBlockHolder),
memBlockHolder->block.getData(),
memBlockHolder->block.getSize(),
[] (void * __nullable info, const void*, size_t) { delete (MemoryBlockHolder::Ptr*) info; });
auto imageSource = CGImageSourceCreateWithDataProvider (provider, nullptr);
CGDataProviderRelease (provider);
if (imageSource != 0)
if (imageSource != nullptr)
{
CGImageRef loadedImage = CGImageSourceCreateImageAtIndex (imageSource, 0, 0);
auto loadedImage = CGImageSourceCreateImageAtIndex (imageSource, 0, nullptr);
CFRelease (imageSource);
#endif
if (loadedImage != 0)
if (loadedImage != nullptr)
{
CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo (loadedImage);
auto alphaInfo = CGImageGetAlphaInfo (loadedImage);
const bool hasAlphaChan = (alphaInfo != kCGImageAlphaNone
&& alphaInfo != kCGImageAlphaNoneSkipLast
&& alphaInfo != kCGImageAlphaNoneSkipFirst);
@ -857,7 +886,7 @@ Image juce_loadWithCoreImage (InputStream& input)
(int) CGImageGetHeight (loadedImage),
hasAlphaChan));
CoreGraphicsImage* const cgImage = dynamic_cast<CoreGraphicsImage*> (image.getPixelData());
auto cgImage = dynamic_cast<CoreGraphicsImage*> (image.getPixelData());
jassert (cgImage != nullptr); // if USE_COREGRAPHICS_RENDERING is set, the CoreGraphicsImage class should have been used.
CGContextDrawImage (cgImage->context, convertToCGRect (image.getBounds()), loadedImage);
@ -875,20 +904,20 @@ Image juce_loadWithCoreImage (InputStream& input)
}
}
return Image();
return {};
}
#endif
Image juce_createImageFromCIImage (CIImage*, int, int);
Image juce_createImageFromCIImage (CIImage* im, int w, int h)
{
CoreGraphicsImage* cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false);
auto cgImage = new CoreGraphicsImage (Image::ARGB, w, h, false);
CIContext* cic = [CIContext contextWithCGContext: cgImage->context options: nil];
[cic drawImage: im inRect: CGRectMake (0, 0, w, h) fromRect: CGRectMake (0, 0, w, h)];
CGContextFlush (cgImage->context);
return Image (cgImage);
return Image (*cgImage);
}
CGImageRef juce_createCoreGraphicsImage (const Image& juceImage, CGColorSpaceRef colourSpace,
@ -899,11 +928,11 @@ CGImageRef juce_createCoreGraphicsImage (const Image& juceImage, CGColorSpaceRef
CGContextRef juce_getImageContext (const Image& image)
{
if (CoreGraphicsImage* const cgi = dynamic_cast<CoreGraphicsImage*> (image.getPixelData()))
if (auto cgi = dynamic_cast<CoreGraphicsImage*> (image.getPixelData()))
return cgi->context;
jassertfalse;
return 0;
return {};
}
#if JUCE_IOS
@ -929,8 +958,8 @@ CGContextRef juce_getImageContext (const Image& image)
auto requiredSize = NSMakeSize (image.getWidth() / scaleFactor, image.getHeight() / scaleFactor);
[im setSize: requiredSize];
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef imageRef = juce_createCoreGraphicsImage (image, colourSpace, true);
auto colourSpace = CGColorSpaceCreateDeviceRGB();
auto imageRef = juce_createCoreGraphicsImage (image, colourSpace, true);
CGColorSpaceRelease (colourSpace);
NSBitmapImageRep* imageRep = [[NSBitmapImageRep alloc] initWithCGImage: imageRef];

View File

@ -239,7 +239,7 @@ namespace CoreTextTypeLayout
{
extraKerning *= attr.font.getHeight();
auto numberRef = CFNumberCreate (0, kCFNumberFloatType, &extraKerning);
auto numberRef = CFNumberCreate (nullptr, kCFNumberFloatType, &extraKerning);
CFAttributedStringSetAttribute (attribString, range, kCTKernAttributeName, numberRef);
CFRelease (numberRef);
}
@ -503,7 +503,8 @@ public:
if (fontRef != nullptr)
{
#if JUCE_MAC && defined (MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8
canBeUsedForLayout = CTFontManagerRegisterGraphicsFont (fontRef, nullptr);
if (SystemStats::getOperatingSystemType() >= SystemStats::OperatingSystemType::MacOSX_10_11)
canBeUsedForLayout = CTFontManagerRegisterGraphicsFont (fontRef, nullptr);
#endif
ctFontRef = CTFontCreateWithGraphicsFont (fontRef, referenceFontSize, nullptr, nullptr);
@ -540,7 +541,7 @@ public:
fontHeightToPointsFactor = referenceFontSize / ctTotalHeight;
const short zero = 0;
auto numberRef = CFNumberCreate (0, kCFNumberShortType, &zero);
auto numberRef = CFNumberCreate (nullptr, kCFNumberShortType, &zero);
CFStringRef keys[] = { kCTFontAttributeName, kCTLigatureAttributeName };
CFTypeRef values[] = { ctFontRef, numberRef };
@ -550,7 +551,7 @@ public:
CFRelease (numberRef);
}
~OSXTypeface()
~OSXTypeface() override
{
if (attributedStringAtts != nullptr)
CFRelease (attributedStringAtts);
@ -788,8 +789,8 @@ StringArray Font::findAllTypefaceStyles (const String& family)
//==============================================================================
Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) { return new OSXTypeface (font); }
Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t size) { return new OSXTypeface (data, size); }
Typeface::Ptr Typeface::createSystemTypefaceFor (const Font& font) { return *new OSXTypeface (font); }
Typeface::Ptr Typeface::createSystemTypefaceFor (const void* data, size_t size) { return *new OSXTypeface (data, size); }
void Typeface::scanFolderForFonts (const File&)
{

View File

@ -761,7 +761,7 @@ void Direct2DLowLevelGraphicsContext::drawImage (const Image& image, const Affin
pimpl->renderingTarget->SetTransform (D2D1::IdentityMatrix());
}
void Direct2DLowLevelGraphicsContext::drawLine (const Line <float>& line)
void Direct2DLowLevelGraphicsContext::drawLine (const Line<float>& line)
{
// xxx doesn't seem to be correctly aligned, may need nudging by 0.5 to match the software renderer's behaviour
pimpl->renderingTarget->SetTransform (transformToMatrix (currentState->transform));

View File

@ -96,8 +96,6 @@ private:
Rectangle<int> bounds;
struct Pimpl;
friend struct Pimpl;
friend struct ContainerDeletePolicy<Pimpl>;
std::unique_ptr<Pimpl> pimpl;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Direct2DLowLevelGraphicsContext)

View File

@ -36,9 +36,7 @@ namespace DirectWriteTypeLayout
CustomDirectWriteTextRenderer (IDWriteFontCollection& fonts, const AttributedString& as)
: ComBaseClassHelper<IDWriteTextRenderer> (0),
attributedString (as),
fontCollection (fonts),
currentLine (-1),
lastOriginY (-10000.0f)
fontCollection (fonts)
{
}
@ -89,7 +87,7 @@ namespace DirectWriteTypeLayout
DWRITE_GLYPH_RUN const* glyphRun, DWRITE_GLYPH_RUN_DESCRIPTION const* runDescription,
IUnknown* clientDrawingEffect) override
{
TextLayout* const layout = static_cast<TextLayout*> (clientDrawingContext);
auto layout = static_cast<TextLayout*> (clientDrawingContext);
if (! (baselineOriginY >= -1.0e10f && baselineOriginY <= 1.0e10f))
baselineOriginY = 0; // DirectWrite sometimes sends NaNs in this parameter
@ -102,14 +100,14 @@ namespace DirectWriteTypeLayout
if (currentLine >= layout->getNumLines())
{
jassert (currentLine == layout->getNumLines());
TextLayout::Line* const line = new TextLayout::Line();
auto line = new TextLayout::Line();
layout->addLine (line);
line->lineOrigin = Point<float> (baselineOriginX, baselineOriginY);
}
}
TextLayout::Line& glyphLine = layout->getLine (currentLine);
auto& glyphLine = layout->getLine (currentLine);
DWRITE_FONT_METRICS dwFontMetrics;
glyphRun->fontFace->GetMetrics (&dwFontMetrics);
@ -117,27 +115,27 @@ namespace DirectWriteTypeLayout
glyphLine.ascent = jmax (glyphLine.ascent, scaledFontSize (dwFontMetrics.ascent, dwFontMetrics, *glyphRun));
glyphLine.descent = jmax (glyphLine.descent, scaledFontSize (dwFontMetrics.descent, dwFontMetrics, *glyphRun));
TextLayout::Run* const glyphRunLayout = new TextLayout::Run (Range<int> (runDescription->textPosition,
runDescription->textPosition + runDescription->stringLength),
glyphRun->glyphCount);
auto glyphRunLayout = new TextLayout::Run (Range<int> (runDescription->textPosition,
runDescription->textPosition + runDescription->stringLength),
glyphRun->glyphCount);
glyphLine.runs.add (glyphRunLayout);
glyphRun->fontFace->GetMetrics (&dwFontMetrics);
const float totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent);
const float fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight;
auto totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent);
auto fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight;
glyphRunLayout->font = getFontForRun (*glyphRun, glyphRun->fontEmSize / fontHeightToEmSizeFactor);
glyphRunLayout->colour = getColourOf (static_cast<ID2D1SolidColorBrush*> (clientDrawingEffect));
const Point<float> lineOrigin (layout->getLine (currentLine).lineOrigin);
float x = baselineOriginX - lineOrigin.x;
auto lineOrigin = layout->getLine (currentLine).lineOrigin;
auto x = baselineOriginX - lineOrigin.x;
const float extraKerning = glyphRunLayout->font.getExtraKerningFactor()
* glyphRunLayout->font.getHeight();
auto extraKerning = glyphRunLayout->font.getExtraKerningFactor()
* glyphRunLayout->font.getHeight();
for (UINT32 i = 0; i < glyphRun->glyphCount; ++i)
{
const float advance = glyphRun->glyphAdvances[i];
auto advance = glyphRun->glyphAdvances[i];
if ((glyphRun->bidiLevel & 1) != 0)
x -= advance + extraKerning; // RTL text
@ -156,8 +154,8 @@ namespace DirectWriteTypeLayout
private:
const AttributedString& attributedString;
IDWriteFontCollection& fontCollection;
int currentLine;
float lastOriginY;
int currentLine = -1;
float lastOriginY = -10000.0f;
static float scaledFontSize (int n, const DWRITE_FONT_METRICS& metrics, const DWRITE_GLYPH_RUN& glyphRun) noexcept
{
@ -177,15 +175,15 @@ namespace DirectWriteTypeLayout
{
for (int i = 0; i < attributedString.getNumAttributes(); ++i)
{
const Font& font = attributedString.getAttribute(i).font;
auto& font = attributedString.getAttribute(i).font;
if (WindowsDirectWriteTypeface* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()))
if (auto* wt = dynamic_cast<WindowsDirectWriteTypeface*> (font.getTypeface()))
if (wt->getIDWriteFontFace() == glyphRun.fontFace)
return font.withHeight (fontHeight);
}
ComSmartPtr<IDWriteFont> dwFont;
HRESULT hr = fontCollection.GetFontFromFontFace (glyphRun.fontFace, dwFont.resetAndGetPointerAddress());
auto hr = fontCollection.GetFontFromFontFace (glyphRun.fontFace, dwFont.resetAndGetPointerAddress());
jassert (dwFont != nullptr);
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
@ -261,7 +259,7 @@ namespace DirectWriteTypeLayout
range.length = jmin (attr.range.getLength(), textLen - attr.range.getStart());
{
const String familyName (FontStyleHelpers::getConcreteFamilyName (attr.font));
auto familyName = FontStyleHelpers::getConcreteFamilyName (attr.font);
BOOL fontFound = false;
uint32 fontIndex;
@ -271,7 +269,7 @@ namespace DirectWriteTypeLayout
fontIndex = 0;
ComSmartPtr<IDWriteFontFamily> fontFamily;
HRESULT hr = fontCollection.GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress());
auto hr = fontCollection.GetFontFamily (fontIndex, fontFamily.resetAndGetPointerAddress());
ComSmartPtr<IDWriteFont> dwFont;
uint32 fontFacesCount = 0;
@ -290,12 +288,12 @@ namespace DirectWriteTypeLayout
textLayout.SetFontStretch (dwFont->GetStretch(), range);
textLayout.SetFontStyle (dwFont->GetStyle(), range);
const float fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
auto fontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
textLayout.SetFontSize (attr.font.getHeight() * fontHeightToEmSizeFactor, range);
}
{
const Colour col (attr.colour);
auto col = attr.colour;
ComSmartPtr<ID2D1SolidColorBrush> d2dBrush;
renderTarget.CreateSolidColorBrush (D2D1::ColorF (col.getFloatRed(),
col.getFloatGreen(),
@ -308,7 +306,7 @@ namespace DirectWriteTypeLayout
}
}
bool setupLayout (const AttributedString& text, const float maxWidth, const float maxHeight,
bool setupLayout (const AttributedString& text, float maxWidth, float maxHeight,
ID2D1RenderTarget& renderTarget, IDWriteFactory& directWriteFactory,
IDWriteFontCollection& fontCollection, ComSmartPtr<IDWriteTextLayout>& textLayout)
{
@ -324,14 +322,14 @@ namespace DirectWriteTypeLayout
fontIndex = 0;
ComSmartPtr<IDWriteFontFamily> dwFontFamily;
HRESULT hr = fontCollection.GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress());
auto hr = fontCollection.GetFontFamily (fontIndex, dwFontFamily.resetAndGetPointerAddress());
ComSmartPtr<IDWriteFont> dwFont;
hr = dwFontFamily->GetFirstMatchingFont (DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, DWRITE_FONT_STYLE_NORMAL,
dwFont.resetAndGetPointerAddress());
jassert (dwFont != nullptr);
const float defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
auto defaultFontHeightToEmSizeFactor = getFontHeightToEmSizeFactor (*dwFont);
ComSmartPtr<IDWriteTextFormat> dwTextFormat;
hr = directWriteFactory.CreateTextFormat (defaultFont.getTypefaceName().toWideCharPointer(), &fontCollection,
@ -348,7 +346,7 @@ namespace DirectWriteTypeLayout
hr = dwTextFormat->SetTrimming (&trimming, trimmingSign);
}
const int textLen = text.getText().length();
auto textLen = text.getText().length();
hr = directWriteFactory.CreateTextLayout (text.getText().toWideCharPointer(), textLen, dwTextFormat,
maxWidth, maxHeight, textLayout.resetAndGetPointerAddress());
@ -356,7 +354,7 @@ namespace DirectWriteTypeLayout
if (FAILED (hr) || textLayout == nullptr)
return false;
const int numAttributes = text.getNumAttributes();
auto numAttributes = text.getNumAttributes();
for (int i = 0; i < numAttributes; ++i)
addAttributedRange (text.getAttribute (i), *textLayout, textLen, renderTarget, fontCollection);
@ -376,7 +374,7 @@ namespace DirectWriteTypeLayout
return;
UINT32 actualLineCount = 0;
HRESULT hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount);
auto hr = dwTextLayout->GetLineMetrics (nullptr, 0, &actualLineCount);
layout.ensureStorageAllocated (actualLineCount);
@ -388,13 +386,13 @@ namespace DirectWriteTypeLayout
HeapBlock<DWRITE_LINE_METRICS> dwLineMetrics (actualLineCount);
hr = dwTextLayout->GetLineMetrics (dwLineMetrics, actualLineCount, &actualLineCount);
int lastLocation = 0;
const int numLines = jmin ((int) actualLineCount, layout.getNumLines());
auto numLines = jmin ((int) actualLineCount, layout.getNumLines());
float yAdjustment = 0;
const float extraLineSpacing = text.getLineSpacing();
auto extraLineSpacing = text.getLineSpacing();
for (int i = 0; i < numLines; ++i)
{
TextLayout::Line& line = layout.getLine (i);
auto& line = layout.getLine (i);
line.stringRange = Range<int> (lastLocation, (int) lastLocation + dwLineMetrics[i].length);
line.lineOrigin.y += yAdjustment;
yAdjustment += extraLineSpacing;
@ -422,7 +420,7 @@ namespace DirectWriteTypeLayout
static bool canAllTypefacesBeUsedInLayout (const AttributedString& text)
{
const int numCharacterAttributes = text.getNumAttributes();
auto numCharacterAttributes = text.getNumAttributes();
for (int i = 0; i < numCharacterAttributes; ++i)
if (dynamic_cast<WindowsDirectWriteTypeface*> (text.getAttribute(i).font.getTypeface()) == nullptr)

View File

@ -36,7 +36,8 @@ namespace
uint32 index = 0;
BOOL exists = false;
HRESULT hr = names->FindLocaleName (L"en-us", &index, &exists);
auto hr = names->FindLocaleName (L"en-us", &index, &exists);
if (! exists)
index = 0;
@ -53,7 +54,7 @@ namespace
{
jassert (family != nullptr);
ComSmartPtr<IDWriteLocalizedStrings> familyNames;
HRESULT hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress());
auto hr = family->GetFamilyNames (familyNames.resetAndGetPointerAddress());
jassert (SUCCEEDED (hr)); ignoreUnused (hr);
return getLocalisedName (familyNames);
}
@ -62,7 +63,7 @@ namespace
{
jassert (font != nullptr);
ComSmartPtr<IDWriteLocalizedStrings> faceNames;
HRESULT hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress());
auto hr = font->GetFaceNames (faceNames.resetAndGetPointerAddress());
jassert (SUCCEEDED (hr)); ignoreUnused (hr);
return getLocalisedName (faceNames);
}
@ -106,12 +107,12 @@ public:
if (d2dFactory != nullptr)
{
D2D1_RENDER_TARGET_PROPERTIES d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE,
D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0, 0,
D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
D2D1_FEATURE_LEVEL_DEFAULT);
auto d2dRTProp = D2D1::RenderTargetProperties (D2D1_RENDER_TARGET_TYPE_SOFTWARE,
D2D1::PixelFormat (DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0, 0,
D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
D2D1_FEATURE_LEVEL_DEFAULT);
d2dFactory->CreateDCRenderTarget (&d2dRTProp, directWriteRenderTarget.resetAndGetPointerAddress());
}
@ -142,14 +143,14 @@ class WindowsDirectWriteTypeface : public Typeface
{
public:
WindowsDirectWriteTypeface (const Font& font, IDWriteFontCollection* fontCollection)
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
unitsToHeightScaleFactor (1.0f), heightToPointsFactor (1.0f), ascent (0.0f)
: Typeface (font.getTypefaceName(), font.getTypefaceStyle())
{
jassert (fontCollection != nullptr);
BOOL fontFound = false;
uint32 fontIndex = 0;
HRESULT hr = fontCollection->FindFamilyName (font.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound);
auto hr = fontCollection->FindFamilyName (font.getTypefaceName().toWideCharPointer(), &fontIndex, &fontFound);
if (! fontFound)
fontIndex = 0;
@ -190,18 +191,18 @@ public:
designUnitsPerEm = dwFontMetrics.designUnitsPerEm;
ascent = std::abs ((float) dwFontMetrics.ascent);
const float totalSize = ascent + std::abs ((float) dwFontMetrics.descent);
auto totalSize = ascent + std::abs ((float) dwFontMetrics.descent);
ascent /= totalSize;
unitsToHeightScaleFactor = designUnitsPerEm / totalSize;
HDC tempDC = GetDC (0);
float dpi = (GetDeviceCaps (tempDC, LOGPIXELSX) + GetDeviceCaps (tempDC, LOGPIXELSY)) / 2.0f;
auto tempDC = GetDC (0);
auto dpi = (GetDeviceCaps (tempDC, LOGPIXELSX) + GetDeviceCaps (tempDC, LOGPIXELSY)) / 2.0f;
heightToPointsFactor = (dpi / GetDeviceCaps (tempDC, LOGPIXELSY)) * unitsToHeightScaleFactor;
ReleaseDC (0, tempDC);
const float pathAscent = (1024.0f * dwFontMetrics.ascent) / designUnitsPerEm;
const float pathDescent = (1024.0f * dwFontMetrics.descent) / designUnitsPerEm;
const float pathScale = 1.0f / (std::abs (pathAscent) + std::abs (pathDescent));
auto pathAscent = (1024.0f * dwFontMetrics.ascent) / designUnitsPerEm;
auto pathDescent = (1024.0f * dwFontMetrics.descent) / designUnitsPerEm;
auto pathScale = 1.0f / (std::abs (pathAscent) + std::abs (pathDescent));
pathTransform = AffineTransform::scale (pathScale);
}
}
@ -214,8 +215,8 @@ public:
float getStringWidth (const String& text)
{
const CharPointer_UTF32 textUTF32 (text.toUTF32());
const size_t len = textUTF32.length();
auto textUTF32 = text.toUTF32();
auto len = textUTF32.length();
HeapBlock<UINT16> glyphIndices (len);
dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices);
@ -224,6 +225,7 @@ public:
dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false);
float x = 0;
for (size_t i = 0; i < len; ++i)
x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm;
@ -234,8 +236,8 @@ public:
{
xOffsets.add (0);
const CharPointer_UTF32 textUTF32 (text.toUTF32());
const size_t len = textUTF32.length();
auto textUTF32 = text.toUTF32();
auto len = textUTF32.length();
HeapBlock<UINT16> glyphIndices (len);
dwFontFace->GetGlyphIndices (textUTF32, (UINT32) len, glyphIndices);
@ -243,6 +245,7 @@ public:
dwFontFace->GetDesignGlyphMetrics (glyphIndices, (UINT32) len, dwGlyphMetrics, false);
float x = 0;
for (size_t i = 0; i < len; ++i)
{
x += (float) dwGlyphMetrics[i].advanceWidth / designUnitsPerEm;
@ -254,10 +257,11 @@ public:
bool getOutlineForGlyph (int glyphNumber, Path& path)
{
jassert (path.isEmpty()); // we might need to apply a transform to the path, so this must be empty
UINT16 glyphIndex = (UINT16) glyphNumber;
auto glyphIndex = (UINT16) glyphNumber;
ComSmartPtr<PathGeometrySink> pathGeometrySink (new PathGeometrySink());
dwFontFace->GetGlyphRunOutline (1024.0f, &glyphIndex, nullptr, nullptr, 1, false, false, pathGeometrySink);
dwFontFace->GetGlyphRunOutline (1024.0f, &glyphIndex, nullptr, nullptr,
1, false, false, pathGeometrySink);
path = pathGeometrySink->path;
if (! pathTransform.isIdentity())
@ -273,8 +277,8 @@ public:
private:
SharedResourcePointer<Direct2DFactories> factories;
ComSmartPtr<IDWriteFontFace> dwFontFace;
float unitsToHeightScaleFactor, heightToPointsFactor, ascent;
int designUnitsPerEm;
float unitsToHeightScaleFactor = 1.0f, heightToPointsFactor = 1.0f, ascent = 0;
int designUnitsPerEm = 0;
AffineTransform pathTransform;
struct PathGeometrySink : public ComBaseClassHelper<IDWriteGeometrySink>

View File

@ -63,14 +63,14 @@ namespace TTFNameExtractor
const int64 directoryOffset, const int64 offsetOfStringStorage)
{
String result;
const int64 oldPos = input.getPosition();
auto oldPos = input.getPosition();
input.setPosition (directoryOffset + offsetOfStringStorage + ByteOrder::swapIfLittleEndian (nameRecord.offsetFromStorageArea));
const int stringLength = (int) ByteOrder::swapIfLittleEndian (nameRecord.stringLength);
const int platformID = ByteOrder::swapIfLittleEndian (nameRecord.platformID);
auto stringLength = (int) ByteOrder::swapIfLittleEndian (nameRecord.stringLength);
auto platformID = ByteOrder::swapIfLittleEndian (nameRecord.platformID);
if (platformID == 0 || platformID == 3)
{
const int numChars = stringLength / 2 + 1;
auto numChars = stringLength / 2 + 1;
HeapBlock<uint16> buffer;
buffer.calloc (numChars + 1);
input.read (buffer, stringLength);
@ -165,10 +165,8 @@ namespace FontEnumerators
const String fontName (lpelfe->elfLogFont.lfFaceName);
fontName.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
HDC dc = CreateCompatibleDC (0);
EnumFontFamiliesEx (dc, &lf,
(FONTENUMPROCW) &fontEnum2,
lParam, 0);
auto dc = CreateCompatibleDC (0);
EnumFontFamiliesEx (dc, &lf, (FONTENUMPROCW) &fontEnum2, lParam, 0);
DeleteDC (dc);
}
@ -191,7 +189,7 @@ StringArray Font::findAllTypefaceNames()
for (uint32 i = 0; i < fontFamilyCount; ++i)
{
HRESULT hr = factories->systemFonts->GetFontFamily (i, fontFamily.resetAndGetPointerAddress());
auto hr = factories->systemFonts->GetFontFamily (i, fontFamily.resetAndGetPointerAddress());
if (SUCCEEDED (hr))
results.addIfNotAlreadyThere (getFontFamilyName (fontFamily));
@ -200,7 +198,7 @@ StringArray Font::findAllTypefaceNames()
else
#endif
{
HDC dc = CreateCompatibleDC (0);
auto dc = CreateCompatibleDC (0);
{
LOGFONTW lf = { 0 };
@ -237,7 +235,8 @@ StringArray Font::findAllTypefaceStyles (const String& family)
{
BOOL fontFound = false;
uint32 fontIndex = 0;
HRESULT hr = factories->systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound);
auto hr = factories->systemFonts->FindFamilyName (family.toWideCharPointer(), &fontIndex, &fontFound);
if (! fontFound)
fontIndex = 0;
@ -302,7 +301,7 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
static DefaultFontNames defaultNames;
Font newFont (font);
const String& faceName = font.getTypefaceName();
auto& faceName = font.getTypefaceName();
if (faceName == getDefaultSansSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSans);
else if (faceName == getDefaultSerifFontName()) newFont.setTypefaceName (defaultNames.defaultSerif);
@ -318,22 +317,14 @@ Typeface::Ptr Font::getDefaultTypefaceForFont (const Font& font)
class WindowsTypeface : public Typeface
{
public:
WindowsTypeface (const Font& font)
: Typeface (font.getTypefaceName(), font.getTypefaceStyle()),
fontH (0), previousFontH (0),
dc (CreateCompatibleDC (0)), memoryFont (0),
ascent (1.0f), heightToPointsFactor (1.0f),
defaultGlyph (-1)
WindowsTypeface (const Font& font) : Typeface (font.getTypefaceName(),
font.getTypefaceStyle())
{
loadFont();
}
WindowsTypeface (const void* data, size_t dataSize)
: Typeface (String(), String()),
fontH (0), previousFontH (0),
dc (CreateCompatibleDC (0)), memoryFont (0),
ascent (1.0f), heightToPointsFactor (1.0f),
defaultGlyph (-1)
: Typeface (String(), String())
{
DWORD numInstalled = 0;
memoryFont = AddFontMemResourceEx (const_cast<void*> (data), (DWORD) dataSize,
@ -362,8 +353,8 @@ public:
float getStringWidth (const String& text)
{
const CharPointer_UTF16 utf16 (text.toUTF16());
const size_t numChars = utf16.length();
auto utf16 = text.toUTF16();
auto numChars = utf16.length();
HeapBlock<uint16> results (numChars);
float x = 0;
@ -377,10 +368,10 @@ public:
return x;
}
void getGlyphPositions (const String& text, Array <int>& resultGlyphs, Array <float>& xOffsets)
void getGlyphPositions (const String& text, Array<int>& resultGlyphs, Array<float>& xOffsets)
{
const CharPointer_UTF16 utf16 (text.toUTF16());
const size_t numChars = utf16.length();
auto utf16 = text.toUTF16();
auto numChars = utf16.length();
HeapBlock<uint16> results (numChars);
float x = 0;
@ -408,8 +399,8 @@ public:
GLYPHMETRICS gm;
// (although GetGlyphOutline returns a DWORD, it may be -1 on failure, so treat it as signed int..)
const int bufSize = (int) GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX,
&gm, 0, 0, &identityMatrix);
auto bufSize = (int) GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX,
&gm, 0, 0, &identityMatrix);
if (bufSize > 0)
{
@ -417,18 +408,18 @@ public:
GetGlyphOutline (dc, (UINT) glyphNumber, GGO_NATIVE | GGO_GLYPH_INDEX, &gm,
bufSize, data, &identityMatrix);
const TTPOLYGONHEADER* pheader = reinterpret_cast<TTPOLYGONHEADER*> (data.getData());
auto pheader = reinterpret_cast<const TTPOLYGONHEADER*> (data.getData());
const float scaleX = 1.0f / tm.tmHeight;
const float scaleY = -scaleX;
auto scaleX = 1.0f / tm.tmHeight;
auto scaleY = -scaleX;
while ((char*) pheader < data + bufSize)
{
glyphPath.startNewSubPath (scaleX * pheader->pfxStart.x.value,
scaleY * pheader->pfxStart.y.value);
const TTPOLYCURVE* curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
const char* const curveEnd = ((const char*) pheader) + pheader->cb;
auto curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
auto curveEnd = ((const char*) pheader) + pheader->cb;
while ((const char*) curve < curveEnd)
{
@ -442,10 +433,10 @@ public:
{
for (int i = 0; i < curve->cpfx - 1; ++i)
{
const float x2 = scaleX * curve->apfx[i].x.value;
const float y2 = scaleY * curve->apfx[i].y.value;
float x3 = scaleX * curve->apfx[i + 1].x.value;
float y3 = scaleY * curve->apfx[i + 1].y.value;
auto x2 = scaleX * curve->apfx[i].x.value;
auto y2 = scaleY * curve->apfx[i].y.value;
auto x3 = scaleX * curve->apfx[i + 1].x.value;
auto y3 = scaleY * curve->apfx[i + 1].y.value;
if (i < curve->cpfx - 2)
{
@ -471,32 +462,19 @@ public:
private:
static const MAT2 identityMatrix;
HFONT fontH;
HGDIOBJ previousFontH;
HDC dc;
HFONT fontH = {};
HGDIOBJ previousFontH = {};
HDC dc { CreateCompatibleDC (0) };
TEXTMETRIC tm;
HANDLE memoryFont;
float ascent, heightToPointsFactor;
int defaultGlyph, heightInPoints;
HANDLE memoryFont = {};
float ascent = 1.0f, heightToPointsFactor = 1.0f;
int defaultGlyph = -1, heightInPoints = 0;
std::unordered_map<uint64, float> kerningPairs;
struct KerningPair
static uint64 kerningPairIndex (int glyph1, int glyph2)
{
int glyph1, glyph2;
float kerning;
bool operator== (const KerningPair& other) const noexcept
{
return glyph1 == other.glyph1 && glyph2 == other.glyph2;
}
bool operator< (const KerningPair& other) const noexcept
{
return glyph1 < other.glyph1
|| (glyph1 == other.glyph1 && glyph2 < other.glyph2);
}
};
SortedSet<KerningPair> kerningPairs;
return (((uint64) (uint32) glyph1) << 32) | (uint64) (uint32) glyph2;
}
void loadFont()
{
@ -514,15 +492,15 @@ private:
lf.lfHeight = -256;
name.copyToUTF16 (lf.lfFaceName, sizeof (lf.lfFaceName));
HFONT standardSizedFont = CreateFontIndirect (&lf);
auto standardSizedFont = CreateFontIndirect (&lf);
if (standardSizedFont != 0)
{
if ((previousFontH = SelectObject (dc, standardSizedFont)) != 0)
{
fontH = standardSizedFont;
OUTLINETEXTMETRIC otm;
if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
{
heightInPoints = otm.otmEMSquare;
@ -537,41 +515,42 @@ private:
if (GetTextMetrics (dc, &tm))
{
float dpi = (GetDeviceCaps (dc, LOGPIXELSX) + GetDeviceCaps (dc, LOGPIXELSY)) / 2.0f;
auto dpi = (GetDeviceCaps (dc, LOGPIXELSX) + GetDeviceCaps (dc, LOGPIXELSY)) / 2.0f;
heightToPointsFactor = (dpi / GetDeviceCaps (dc, LOGPIXELSY)) * heightInPoints / (float) tm.tmHeight;
ascent = tm.tmAscent / (float) tm.tmHeight;
defaultGlyph = getGlyphForChar (dc, tm.tmDefaultChar);
createKerningPairs (dc, (float) tm.tmHeight);
std::unordered_map<int, int> glyphsForChars;
defaultGlyph = getGlyphForChar (dc, glyphsForChars, tm.tmDefaultChar);
createKerningPairs (dc, glyphsForChars, (float) tm.tmHeight);
}
}
void createKerningPairs (HDC hdc, const float height)
void createKerningPairs (HDC hdc, std::unordered_map<int, int>& glyphsForChars, float height)
{
HeapBlock<KERNINGPAIR> rawKerning;
const DWORD numKPs = GetKerningPairs (hdc, 0, 0);
auto numKPs = GetKerningPairs (hdc, 0, 0);
rawKerning.calloc (numKPs);
GetKerningPairs (hdc, numKPs, rawKerning);
kerningPairs.ensureStorageAllocated ((int) numKPs);
std::unordered_map<int, int> widthsForGlyphs;
for (DWORD i = 0; i < numKPs; ++i)
{
KerningPair kp;
kp.glyph1 = getGlyphForChar (hdc, rawKerning[i].wFirst);
kp.glyph2 = getGlyphForChar (hdc, rawKerning[i].wSecond);
auto glyph1 = getGlyphForChar (hdc, glyphsForChars, rawKerning[i].wFirst);
auto glyph2 = getGlyphForChar (hdc, glyphsForChars, rawKerning[i].wSecond);
auto standardWidth = getGlyphWidth (hdc, widthsForGlyphs, glyph1);
const int standardWidth = getGlyphWidth (hdc, kp.glyph1);
kp.kerning = (standardWidth + rawKerning[i].iKernAmount) / height;
kerningPairs.add (kp);
kp.glyph2 = -1; // add another entry for the standard width version..
kp.kerning = standardWidth / height;
kerningPairs.add (kp);
kerningPairs[kerningPairIndex (glyph1, glyph2)] = (standardWidth + rawKerning[i].iKernAmount) / height;
kerningPairs[kerningPairIndex (glyph1, -1)] = standardWidth / height;
}
}
static int getGlyphForChar (HDC dc, juce_wchar character)
static int getGlyphForChar (HDC dc, std::unordered_map<int, int>& cache, juce_wchar character)
{
auto existing = cache.find ((int) character);
if (existing != cache.end())
return existing->second;
const WCHAR charToTest[] = { (WCHAR) character, 0 };
WORD index = 0;
@ -579,9 +558,22 @@ private:
|| index == 0xffff)
return -1;
cache[(int) character] = index;
return index;
}
static int getGlyphWidth (HDC dc, std::unordered_map<int, int>& cache, int glyphNumber)
{
auto existing = cache.find (glyphNumber);
if (existing != cache.end())
return existing->second;
auto width = getGlyphWidth (dc, glyphNumber);
cache[glyphNumber] = width;
return width;
}
static int getGlyphWidth (HDC dc, int glyphNumber)
{
GLYPHMETRICS gm;
@ -590,28 +582,21 @@ private:
return gm.gmCellIncX;
}
float getKerning (HDC hdc, const int glyph1, const int glyph2)
float getKerning (HDC hdc, int glyph1, int glyph2)
{
KerningPair kp;
kp.glyph1 = glyph1;
kp.glyph2 = glyph2;
int index = kerningPairs.indexOf (kp);
auto pair = kerningPairs.find (kerningPairIndex (glyph1, glyph2));
if (index < 0)
{
kp.glyph2 = -1;
index = kerningPairs.indexOf (kp);
if (pair != kerningPairs.end())
return pair->second;
if (index < 0)
{
kp.glyph2 = -1;
kp.kerning = getGlyphWidth (hdc, kp.glyph1) / (float) tm.tmHeight;
kerningPairs.add (kp);
return kp.kerning;
}
}
auto single = kerningPairs.find (kerningPairIndex (glyph1, -1));
return kerningPairs.getReference (index).kerning;
if (single != kerningPairs.end())
return single->second;
auto width = getGlyphWidth (hdc, glyph1) / (float) tm.tmHeight;
kerningPairs[kerningPairIndex (glyph1, -1)] = width;
return width;
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsTypeface)

View File

@ -46,14 +46,10 @@ public:
Justification (int justificationFlags) noexcept : flags (justificationFlags) {}
/** Creates a copy of another Justification object. */
Justification (const Justification& other) noexcept : flags (other.flags) {}
Justification (const Justification&) = default;
/** Copies another Justification object. */
Justification& operator= (const Justification& other) noexcept
{
flags = other.flags;
return *this;
}
Justification& operator= (const Justification&) = default;
bool operator== (const Justification& other) const noexcept { return flags == other.flags; }
bool operator!= (const Justification& other) const noexcept { return flags != other.flags; }

View File

@ -27,17 +27,6 @@
namespace juce
{
RectanglePlacement::RectanglePlacement (const RectanglePlacement& other) noexcept
: flags (other.flags)
{
}
RectanglePlacement& RectanglePlacement::operator= (const RectanglePlacement& other) noexcept
{
flags = other.flags;
return *this;
}
bool RectanglePlacement::operator== (const RectanglePlacement& other) const noexcept
{
return flags == other.flags;

View File

@ -45,13 +45,13 @@ public:
inline RectanglePlacement (int placementFlags) noexcept : flags (placementFlags) {}
/** Creates a default RectanglePlacement object, which is equivalent to using the 'centred' flag. */
inline RectanglePlacement() noexcept : flags (centred) {}
inline RectanglePlacement() = default;
/** Creates a copy of another RectanglePlacement object. */
RectanglePlacement (const RectanglePlacement&) noexcept;
RectanglePlacement (const RectanglePlacement&) = default;
/** Copies another RectanglePlacement object. */
RectanglePlacement& operator= (const RectanglePlacement&) noexcept;
RectanglePlacement& operator= (const RectanglePlacement&) = default;
bool operator== (const RectanglePlacement&) const noexcept;
bool operator!= (const RectanglePlacement&) const noexcept;
@ -169,7 +169,7 @@ public:
private:
//==============================================================================
int flags;
int flags { centred };
};
} // namespace juce