mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
A few code cleanups
This commit is contained in:
parent
33c0940d74
commit
78b0ab6442
3 changed files with 116 additions and 120 deletions
|
|
@ -88,13 +88,13 @@ File PropertiesFile::Options::getDefaultFile() const
|
|||
dir = dir.getChildFile (folderName);
|
||||
|
||||
#elif JUCE_LINUX || JUCE_ANDROID
|
||||
const File dir (File (commonToAllUsers ? "/var" : "~")
|
||||
auto dir = File (commonToAllUsers ? "/var" : "~")
|
||||
.getChildFile (folderName.isNotEmpty() ? folderName
|
||||
: ("." + applicationName)));
|
||||
: ("." + applicationName));
|
||||
|
||||
#elif JUCE_WINDOWS
|
||||
File dir (File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory
|
||||
: File::userApplicationDataDirectory));
|
||||
auto dir = File::getSpecialLocation (commonToAllUsers ? File::commonApplicationDataDirectory
|
||||
: File::userApplicationDataDirectory);
|
||||
|
||||
if (dir == File())
|
||||
return {};
|
||||
|
|
@ -112,16 +112,14 @@ File PropertiesFile::Options::getDefaultFile() const
|
|||
//==============================================================================
|
||||
PropertiesFile::PropertiesFile (const File& f, const Options& o)
|
||||
: PropertySet (o.ignoreCaseOfKeyNames),
|
||||
file (f), options (o),
|
||||
loadedOk (false), needsWriting (false)
|
||||
file (f), options (o)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
||||
PropertiesFile::PropertiesFile (const Options& o)
|
||||
: PropertySet (o.ignoreCaseOfKeyNames),
|
||||
file (o.getDefaultFile()), options (o),
|
||||
loadedOk (false), needsWriting (false)
|
||||
file (o.getDefaultFile()), options (o)
|
||||
{
|
||||
reload();
|
||||
}
|
||||
|
|
@ -196,16 +194,14 @@ bool PropertiesFile::loadAsXml()
|
|||
{
|
||||
forEachXmlChildElementWithTagName (*doc, e, PropertyFileConstants::valueTag)
|
||||
{
|
||||
const String name (e->getStringAttribute (PropertyFileConstants::nameAttribute));
|
||||
auto name = e->getStringAttribute (PropertyFileConstants::nameAttribute);
|
||||
|
||||
if (name.isNotEmpty())
|
||||
{
|
||||
getAllProperties().set (name,
|
||||
e->getFirstChildElement() != nullptr
|
||||
? e->getFirstChildElement()->createDocument ("", true)
|
||||
: e->getStringAttribute (PropertyFileConstants::valueAttribute));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -222,15 +218,15 @@ bool PropertiesFile::loadAsXml()
|
|||
bool PropertiesFile::saveAsXml()
|
||||
{
|
||||
XmlElement doc (PropertyFileConstants::fileTag);
|
||||
const StringPairArray& props = getAllProperties();
|
||||
auto& props = getAllProperties();
|
||||
|
||||
for (int i = 0; i < props.size(); ++i)
|
||||
{
|
||||
XmlElement* const e = doc.createNewChildElement (PropertyFileConstants::valueTag);
|
||||
auto* e = doc.createNewChildElement (PropertyFileConstants::valueTag);
|
||||
e->setAttribute (PropertyFileConstants::nameAttribute, props.getAllKeys() [i]);
|
||||
|
||||
// if the value seems to contain xml, store it as such..
|
||||
if (XmlElement* const childElement = XmlDocument::parse (props.getAllValues() [i]))
|
||||
if (auto* childElement = XmlDocument::parse (props.getAllValues() [i]))
|
||||
e->addChildElement (childElement);
|
||||
else
|
||||
e->setAttribute (PropertyFileConstants::valueAttribute, props.getAllValues() [i]);
|
||||
|
|
@ -241,7 +237,7 @@ bool PropertiesFile::saveAsXml()
|
|||
if (pl != nullptr && ! pl->isLocked())
|
||||
return false; // locking failure..
|
||||
|
||||
if (doc.writeToFile (file, String()))
|
||||
if (doc.writeToFile (file, {}))
|
||||
{
|
||||
needsWriting = false;
|
||||
return true;
|
||||
|
|
@ -256,7 +252,7 @@ bool PropertiesFile::loadAsBinary()
|
|||
|
||||
if (fileStream.openedOk())
|
||||
{
|
||||
const int magicNumber = fileStream.readInt();
|
||||
auto magicNumber = fileStream.readInt();
|
||||
|
||||
if (magicNumber == PropertyFileConstants::magicNumberCompressed)
|
||||
{
|
||||
|
|
@ -280,10 +276,10 @@ bool PropertiesFile::loadAsBinary (InputStream& input)
|
|||
|
||||
while (--numValues >= 0 && ! in.isExhausted())
|
||||
{
|
||||
const String key (in.readString());
|
||||
const String value (in.readString());
|
||||
|
||||
auto key = in.readString();
|
||||
auto value = in.readString();
|
||||
jassert (key.isNotEmpty());
|
||||
|
||||
if (key.isNotEmpty())
|
||||
getAllProperties().set (key, value);
|
||||
}
|
||||
|
|
@ -299,48 +295,59 @@ bool PropertiesFile::saveAsBinary()
|
|||
return false; // locking failure..
|
||||
|
||||
TemporaryFile tempFile (file);
|
||||
ScopedPointer<OutputStream> out (tempFile.getFile().createOutputStream());
|
||||
|
||||
if (out != nullptr)
|
||||
{
|
||||
FileOutputStream out (tempFile.getFile());
|
||||
|
||||
if (! out.openedOk())
|
||||
return false;
|
||||
|
||||
if (options.storageFormat == storeAsCompressedBinary)
|
||||
{
|
||||
out->writeInt (PropertyFileConstants::magicNumberCompressed);
|
||||
out->flush();
|
||||
out.writeInt (PropertyFileConstants::magicNumberCompressed);
|
||||
out.flush();
|
||||
|
||||
out = new GZIPCompressorOutputStream (out.release(), 9, true);
|
||||
GZIPCompressorOutputStream zipped (out, 9);
|
||||
|
||||
if (! writeToStream (zipped))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// have you set up the storage option flags correctly?
|
||||
jassert (options.storageFormat == storeAsBinary);
|
||||
|
||||
out->writeInt (PropertyFileConstants::magicNumber);
|
||||
out.writeInt (PropertyFileConstants::magicNumber);
|
||||
|
||||
if (! writeToStream (out))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const StringPairArray& props = getAllProperties();
|
||||
const int numProperties = props.size();
|
||||
const StringArray& keys = props.getAllKeys();
|
||||
const StringArray& values = props.getAllValues();
|
||||
if (! tempFile.overwriteTargetFileWithTemporary())
|
||||
return false;
|
||||
|
||||
out->writeInt (numProperties);
|
||||
|
||||
for (int i = 0; i < numProperties; ++i)
|
||||
{
|
||||
out->writeString (keys[i]);
|
||||
out->writeString (values[i]);
|
||||
}
|
||||
|
||||
out.reset();
|
||||
|
||||
if (tempFile.overwriteTargetFileWithTemporary())
|
||||
{
|
||||
needsWriting = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertiesFile::writeToStream (OutputStream& out)
|
||||
{
|
||||
auto& props = getAllProperties();
|
||||
auto& keys = props.getAllKeys();
|
||||
auto& values = props.getAllValues();
|
||||
auto numProperties = props.size();
|
||||
|
||||
if (! out.writeInt (numProperties))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < numProperties; ++i)
|
||||
{
|
||||
if (! out.writeString (keys[i])) return false;
|
||||
if (! out.writeString (values[i])) return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PropertiesFile::timerCallback()
|
||||
|
|
@ -351,7 +358,6 @@ void PropertiesFile::timerCallback()
|
|||
void PropertiesFile::propertyChanged()
|
||||
{
|
||||
sendChangeMessage();
|
||||
|
||||
needsWriting = true;
|
||||
|
||||
if (options.millisecondsBeforeSaving > 0)
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ private:
|
|||
//==============================================================================
|
||||
File file;
|
||||
Options options;
|
||||
bool loadedOk, needsWriting;
|
||||
bool loadedOk = false, needsWriting = false;
|
||||
|
||||
typedef const ScopedPointer<InterProcessLock::ScopedLockType> ProcessScopedLock;
|
||||
InterProcessLock::ScopedLockType* createProcessLock() const;
|
||||
|
|
@ -245,6 +245,7 @@ private:
|
|||
bool loadAsXml();
|
||||
bool loadAsBinary();
|
||||
bool loadAsBinary (InputStream&);
|
||||
bool writeToStream (OutputStream&);
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertiesFile)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class TranslationOrTransform
|
|||
{
|
||||
public:
|
||||
TranslationOrTransform (Point<int> origin) noexcept
|
||||
: offset (origin), isOnlyTranslated (true), isRotated (false)
|
||||
: offset (origin)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ public:
|
|||
|
||||
AffineTransform complexTransform;
|
||||
Point<int> offset;
|
||||
bool isOnlyTranslated, isRotated;
|
||||
bool isOnlyTranslated = true, isRotated = false;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -155,7 +155,7 @@ public:
|
|||
|
||||
static GlyphCache& getInstance()
|
||||
{
|
||||
GlyphCache*& g = getSingletonPointer();
|
||||
auto& g = getSingletonPointer();
|
||||
|
||||
if (g == nullptr)
|
||||
g = new GlyphCache();
|
||||
|
|
@ -169,13 +169,13 @@ public:
|
|||
const ScopedLock sl (lock);
|
||||
glyphs.clear();
|
||||
addNewGlyphSlots (120);
|
||||
hits.set (0);
|
||||
misses.set (0);
|
||||
hits = 0;
|
||||
misses = 0;
|
||||
}
|
||||
|
||||
void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, Point<float> pos)
|
||||
{
|
||||
if (ReferenceCountedObjectPtr<CachedGlyphType> glyph = findOrCreateGlyph (font, glyphNumber))
|
||||
if (auto glyph = findOrCreateGlyph (font, glyphNumber))
|
||||
{
|
||||
glyph->lastAccessCount = ++accessCounter;
|
||||
glyph->draw (target, pos);
|
||||
|
|
@ -186,14 +186,14 @@ public:
|
|||
{
|
||||
const ScopedLock sl (lock);
|
||||
|
||||
if (CachedGlyphType* g = findExistingGlyph (font, glyphNumber))
|
||||
if (auto* g = findExistingGlyph (font, glyphNumber))
|
||||
{
|
||||
++hits;
|
||||
return g;
|
||||
}
|
||||
|
||||
++misses;
|
||||
CachedGlyphType* g = getGlyphForReuse();
|
||||
auto* g = getGlyphForReuse();
|
||||
jassert (g != nullptr);
|
||||
g->generate (font, glyphNumber);
|
||||
return g;
|
||||
|
|
@ -205,31 +205,27 @@ private:
|
|||
Atomic<int> accessCounter, hits, misses;
|
||||
CriticalSection lock;
|
||||
|
||||
CachedGlyphType* findExistingGlyph (const Font& font, int glyphNumber) const
|
||||
CachedGlyphType* findExistingGlyph (const Font& font, int glyphNumber) const noexcept
|
||||
{
|
||||
for (int i = 0; i < glyphs.size(); ++i)
|
||||
{
|
||||
CachedGlyphType* const g = glyphs.getUnchecked (i);
|
||||
|
||||
for (auto* g : glyphs)
|
||||
if (g->glyph == glyphNumber && g->font == font)
|
||||
return g;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CachedGlyphType* getGlyphForReuse()
|
||||
{
|
||||
if (hits.value + misses.value > glyphs.size() * 16)
|
||||
if (hits.get() + misses.get() > glyphs.size() * 16)
|
||||
{
|
||||
if (misses.value * 2 > hits.value)
|
||||
if (misses.get() * 2 > hits.get())
|
||||
addNewGlyphSlots (32);
|
||||
|
||||
hits.set (0);
|
||||
misses.set (0);
|
||||
hits = 0;
|
||||
misses = 0;
|
||||
}
|
||||
|
||||
if (CachedGlyphType* g = findLeastRecentlyUsedGlyph())
|
||||
if (auto* g = findLeastRecentlyUsedGlyph())
|
||||
return g;
|
||||
|
||||
addNewGlyphSlots (32);
|
||||
|
|
@ -247,17 +243,15 @@ private:
|
|||
CachedGlyphType* findLeastRecentlyUsedGlyph() const noexcept
|
||||
{
|
||||
CachedGlyphType* oldest = nullptr;
|
||||
int oldestCounter = std::numeric_limits<int>::max();
|
||||
auto oldestCounter = std::numeric_limits<int>::max();
|
||||
|
||||
for (int i = glyphs.size() - 1; --i >= 0;)
|
||||
for (auto* g : glyphs)
|
||||
{
|
||||
CachedGlyphType* const glyph = glyphs.getUnchecked(i);
|
||||
|
||||
if (glyph->lastAccessCount <= oldestCounter
|
||||
&& glyph->getReferenceCount() == 1)
|
||||
if (g->lastAccessCount <= oldestCounter
|
||||
&& g->getReferenceCount() == 1)
|
||||
{
|
||||
oldestCounter = glyph->lastAccessCount;
|
||||
oldest = glyph;
|
||||
oldestCounter = g->lastAccessCount;
|
||||
oldest = g;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +273,7 @@ template <class RendererType>
|
|||
class CachedGlyphEdgeTable : public ReferenceCountedObject
|
||||
{
|
||||
public:
|
||||
CachedGlyphEdgeTable() : glyph (0), lastAccessCount (0) {}
|
||||
CachedGlyphEdgeTable() {}
|
||||
|
||||
void draw (RendererType& state, Point<float> pos) const
|
||||
{
|
||||
|
|
@ -290,10 +284,10 @@ public:
|
|||
state.fillEdgeTable (*edgeTable, pos.x, roundToInt (pos.y));
|
||||
}
|
||||
|
||||
void generate (const Font& newFont, const int glyphNumber)
|
||||
void generate (const Font& newFont, int glyphNumber)
|
||||
{
|
||||
font = newFont;
|
||||
Typeface* const typeface = newFont.getTypeface();
|
||||
auto* typeface = newFont.getTypeface();
|
||||
snapToIntegerCoordinate = typeface->isHinted();
|
||||
glyph = glyphNumber;
|
||||
|
||||
|
|
@ -305,8 +299,8 @@ public:
|
|||
|
||||
Font font;
|
||||
ScopedPointer<EdgeTable> edgeTable;
|
||||
int glyph, lastAccessCount;
|
||||
bool snapToIntegerCoordinate;
|
||||
int glyph = 0, lastAccessCount = 0;
|
||||
bool snapToIntegerCoordinate = false;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable)
|
||||
};
|
||||
|
|
@ -405,22 +399,21 @@ struct FloatRectangleRasterisingInfo
|
|||
namespace GradientPixelIterators
|
||||
{
|
||||
/** Iterates the colour of pixels in a linear gradient */
|
||||
class Linear
|
||||
struct Linear
|
||||
{
|
||||
public:
|
||||
Linear (const ColourGradient& gradient, const AffineTransform& transform,
|
||||
const PixelARGB* const colours, const int numColours)
|
||||
const PixelARGB* colours, int numColours)
|
||||
: lookupTable (colours),
|
||||
numEntries (numColours)
|
||||
{
|
||||
jassert (numColours >= 0);
|
||||
Point<float> p1 (gradient.point1);
|
||||
Point<float> p2 (gradient.point2);
|
||||
auto p1 = gradient.point1;
|
||||
auto p2 = gradient.point2;
|
||||
|
||||
if (! transform.isIdentity())
|
||||
{
|
||||
const Line<float> l (p2, p1);
|
||||
Point<float> p3 = l.getPointAlongLine (0.0f, 100.0f);
|
||||
auto p3 = l.getPointAlongLine (0.0f, 100.0f);
|
||||
|
||||
p1.applyTransform (transform);
|
||||
p2.applyTransform (transform);
|
||||
|
|
@ -451,7 +444,7 @@ namespace GradientPixelIterators
|
|||
}
|
||||
}
|
||||
|
||||
forcedinline void setY (const int y) noexcept
|
||||
forcedinline void setY (int y) noexcept
|
||||
{
|
||||
if (vertical)
|
||||
linePix = lookupTable[jlimit (0, numEntries, (y * scale - start) >> (int) numScaleBits)];
|
||||
|
|
@ -459,13 +452,12 @@ namespace GradientPixelIterators
|
|||
start = roundToInt ((y - yTerm) * grad);
|
||||
}
|
||||
|
||||
inline PixelARGB getPixel (const int x) const noexcept
|
||||
inline PixelARGB getPixel (int x) const noexcept
|
||||
{
|
||||
return vertical ? linePix
|
||||
: lookupTable[jlimit (0, numEntries, (x * scale - start) >> (int) numScaleBits)];
|
||||
}
|
||||
|
||||
private:
|
||||
const PixelARGB* const lookupTable;
|
||||
const int numEntries;
|
||||
PixelARGB linePix;
|
||||
|
|
@ -479,39 +471,37 @@ namespace GradientPixelIterators
|
|||
|
||||
//==============================================================================
|
||||
/** Iterates the colour of pixels in a circular radial gradient */
|
||||
class Radial
|
||||
struct Radial
|
||||
{
|
||||
public:
|
||||
Radial (const ColourGradient& gradient, const AffineTransform&,
|
||||
const PixelARGB* const colours, const int numColours)
|
||||
const PixelARGB* colours, int numColours)
|
||||
: lookupTable (colours),
|
||||
numEntries (numColours),
|
||||
gx1 (gradient.point1.x),
|
||||
gy1 (gradient.point1.y)
|
||||
{
|
||||
jassert (numColours >= 0);
|
||||
const Point<float> diff (gradient.point1 - gradient.point2);
|
||||
auto diff = gradient.point1 - gradient.point2;
|
||||
maxDist = diff.x * diff.x + diff.y * diff.y;
|
||||
invScale = numEntries / std::sqrt (maxDist);
|
||||
jassert (roundToInt (std::sqrt (maxDist) * invScale) <= numEntries);
|
||||
}
|
||||
|
||||
forcedinline void setY (const int y) noexcept
|
||||
forcedinline void setY (int y) noexcept
|
||||
{
|
||||
dy = y - gy1;
|
||||
dy *= dy;
|
||||
}
|
||||
|
||||
inline PixelARGB getPixel (const int px) const noexcept
|
||||
inline PixelARGB getPixel (int px) const noexcept
|
||||
{
|
||||
double x = px - gx1;
|
||||
auto x = px - gx1;
|
||||
x *= x;
|
||||
x += dy;
|
||||
|
||||
return lookupTable[x >= maxDist ? numEntries : roundToInt (std::sqrt (x) * invScale)];
|
||||
}
|
||||
|
||||
protected:
|
||||
const PixelARGB* const lookupTable;
|
||||
const int numEntries;
|
||||
const double gx1, gy1;
|
||||
|
|
@ -522,11 +512,10 @@ namespace GradientPixelIterators
|
|||
|
||||
//==============================================================================
|
||||
/** Iterates the colour of pixels in a skewed radial gradient */
|
||||
class TransformedRadial : public Radial
|
||||
struct TransformedRadial : public Radial
|
||||
{
|
||||
public:
|
||||
TransformedRadial (const ColourGradient& gradient, const AffineTransform& transform,
|
||||
const PixelARGB* const colours, const int numColours)
|
||||
const PixelARGB* colours, int numColours)
|
||||
: Radial (gradient, transform, colours, numColours),
|
||||
inverseTransform (transform.inverted())
|
||||
{
|
||||
|
|
@ -534,17 +523,17 @@ namespace GradientPixelIterators
|
|||
tM00 = inverseTransform.mat00;
|
||||
}
|
||||
|
||||
forcedinline void setY (const int y) noexcept
|
||||
forcedinline void setY (int y) noexcept
|
||||
{
|
||||
const float floatY = (float) y;
|
||||
auto floatY = (float) y;
|
||||
lineYM01 = inverseTransform.mat01 * floatY + inverseTransform.mat02 - gx1;
|
||||
lineYM11 = inverseTransform.mat11 * floatY + inverseTransform.mat12 - gy1;
|
||||
}
|
||||
|
||||
inline PixelARGB getPixel (const int px) const noexcept
|
||||
inline PixelARGB getPixel (int px) const noexcept
|
||||
{
|
||||
double x = px;
|
||||
const double y = tM10 * x + lineYM11;
|
||||
auto y = tM10 * x + lineYM11;
|
||||
x = tM00 * x + lineYM01;
|
||||
x *= x;
|
||||
x += y * y;
|
||||
|
|
@ -629,7 +618,7 @@ namespace EdgeTableFillers
|
|||
blendLine (dest, p, width);
|
||||
}
|
||||
|
||||
forcedinline void handleEdgeTableLineFull (const int x, const int width) const noexcept
|
||||
forcedinline void handleEdgeTableLineFull (int x, int width) const noexcept
|
||||
{
|
||||
auto* dest = getPixel (x);
|
||||
|
||||
|
|
@ -677,7 +666,7 @@ namespace EdgeTableFillers
|
|||
PixelRGB filler[4];
|
||||
bool areRGBComponentsEqual;
|
||||
|
||||
forcedinline PixelType* getPixel (const int x) const noexcept
|
||||
forcedinline PixelType* getPixel (int x) const noexcept
|
||||
{
|
||||
return addBytesToPointer (linePixels, x * destData.pixelStride);
|
||||
}
|
||||
|
|
@ -699,7 +688,7 @@ namespace EdgeTableFillers
|
|||
{
|
||||
if (width >> 5)
|
||||
{
|
||||
const int* const intFiller = reinterpret_cast<const int*> (filler);
|
||||
auto intFiller = reinterpret_cast<const int*> (filler);
|
||||
|
||||
while (width > 8 && (((pointer_sized_int) dest) & 7) != 0)
|
||||
{
|
||||
|
|
@ -710,7 +699,7 @@ namespace EdgeTableFillers
|
|||
|
||||
while (width > 4)
|
||||
{
|
||||
int* d = reinterpret_cast<int*> (dest);
|
||||
auto d = reinterpret_cast<int*> (dest);
|
||||
*d++ = intFiller[0];
|
||||
*d++ = intFiller[1];
|
||||
*d++ = intFiller[2];
|
||||
|
|
@ -946,12 +935,12 @@ namespace EdgeTableFillers
|
|||
DestPixelType* linePixels;
|
||||
SrcPixelType* sourceLineStart;
|
||||
|
||||
forcedinline DestPixelType* getDestPixel (int const x) const noexcept
|
||||
forcedinline DestPixelType* getDestPixel (int x) const noexcept
|
||||
{
|
||||
return addBytesToPointer (linePixels, x * destData.pixelStride);
|
||||
}
|
||||
|
||||
forcedinline SrcPixelType const* getSrcPixel (int const x) const noexcept
|
||||
forcedinline SrcPixelType const* getSrcPixel (int x) const noexcept
|
||||
{
|
||||
return addBytesToPointer (sourceLineStart, x * srcData.pixelStride);
|
||||
}
|
||||
|
|
@ -2460,7 +2449,7 @@ public:
|
|||
{
|
||||
jassert (! replaceContents); // that option is just for solid colours
|
||||
|
||||
ColourGradient g2 (*(fillType.gradient));
|
||||
auto g2 = *(fillType.gradient);
|
||||
g2.multiplyOpacity (fillType.getOpacity());
|
||||
auto t = transform.getTransformWith (fillType.transform).translated (-0.5f, -0.5f);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue