1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-11 23:54:18 +00:00
JUCE/src/gui/graphics/drawables/juce_DrawableImage.cpp

203 lines
5.9 KiB
C++

/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-9 by Raw Material Software Ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the GNU General
Public License (Version 2), as published by the Free Software Foundation.
A copy of the license is included in the JUCE distribution, or can be found
online at www.gnu.org/licenses.
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.rawmaterialsoftware.com/juce for more information.
==============================================================================
*/
#include "../../../core/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_DrawableImage.h"
#include "../imaging/juce_ImageCache.h"
#include "../imaging/juce_ImageFileFormat.h"
#include "../../../io/streams/juce_MemoryOutputStream.h"
//==============================================================================
DrawableImage::DrawableImage()
: image (0),
canDeleteImage (false),
opacity (1.0f),
overlayColour (0x00000000)
{
}
DrawableImage::~DrawableImage()
{
clearImage();
}
//==============================================================================
void DrawableImage::clearImage()
{
if (canDeleteImage && image != 0)
ImageCache::releaseOrDelete (image);
image = 0;
}
void DrawableImage::setImage (const Image& imageToCopy)
{
clearImage();
image = new Image (imageToCopy);
canDeleteImage = true;
}
void DrawableImage::setImage (Image* imageToUse,
const bool releaseWhenNotNeeded)
{
clearImage();
image = imageToUse;
canDeleteImage = releaseWhenNotNeeded;
}
void DrawableImage::setOpacity (const float newOpacity)
{
opacity = newOpacity;
}
void DrawableImage::setOverlayColour (const Colour& newOverlayColour)
{
overlayColour = newOverlayColour;
}
//==============================================================================
void DrawableImage::render (const Drawable::RenderingContext& context) const
{
if (image != 0)
{
if (opacity > 0.0f && ! overlayColour.isOpaque())
{
context.g.setOpacity (context.opacity * opacity);
context.g.drawImageTransformed (image, image->getBounds(),
context.transform, false);
}
if (! overlayColour.isTransparent())
{
context.g.setColour (overlayColour.withMultipliedAlpha (context.opacity));
context.g.drawImageTransformed (image, image->getBounds(),
context.transform, true);
}
}
}
const Rectangle<float> DrawableImage::getBounds() const
{
if (image == 0)
return Rectangle<float>();
return Rectangle<float> (0, 0, (float) image->getWidth(), (float) image->getHeight());
}
bool DrawableImage::hitTest (float x, float y) const
{
return image != 0
&& x >= 0.0f
&& y >= 0.0f
&& x < image->getWidth()
&& y < image->getHeight()
&& image->getPixelAt (roundToInt (x), roundToInt (y)).getAlpha() >= 127;
}
Drawable* DrawableImage::createCopy() const
{
DrawableImage* const di = new DrawableImage();
di->opacity = opacity;
di->overlayColour = overlayColour;
if (image != 0)
{
if ((! canDeleteImage) || ! ImageCache::isImageInCache (image))
{
di->setImage (*image);
}
else
{
ImageCache::incReferenceCount (image);
di->setImage (image, true);
}
}
return di;
}
//==============================================================================
ValueTree DrawableImage::createValueTree() const throw()
{
ValueTree v (T("Image"));
if (getName().isNotEmpty())
v.setProperty ("id", getName(), 0);
if (opacity < 1.0f)
v.setProperty ("opacity", (double) opacity, 0);
if (! overlayColour.isTransparent())
v.setProperty ("overlay", String::toHexString ((int) overlayColour.getARGB()), 0);
if (image != 0)
{
MemoryOutputStream imageData;
PNGImageFormat pngFormat;
if (pngFormat.writeImageToStream (*image, imageData))
{
String base64 (MemoryBlock (imageData.getData(), imageData.getDataSize()).toBase64Encoding());
for (int i = (base64.length() & ~127); i >= 0; i -= 128)
base64 = base64.substring (0, i) + "\n" + base64.substring (i);
v.setProperty ("data", base64, 0);
}
}
return v;
}
DrawableImage* DrawableImage::createFromValueTree (const ValueTree& tree) throw()
{
if (! tree.hasType ("Image"))
return 0;
DrawableImage* di = new DrawableImage();
di->setName (tree ["id"]);
di->opacity = tree.hasProperty ("opacity") ? (float) tree ["opacity"] : 1.0f;
di->overlayColour = Colour (tree ["overlay"].toString().getHexValue32());
MemoryBlock imageData;
if (imageData.fromBase64Encoding (tree ["data"]))
{
Image* const im = ImageFileFormat::loadFrom (imageData.getData(), (int) imageData.getSize());
if (im == 0)
return false;
di->setImage (im, true);
}
return di;
}
END_JUCE_NAMESPACE