| @@ -296,7 +296,7 @@ protected: | |||||
| dataBlock.writeInt (0); // clr used | dataBlock.writeInt (0); // clr used | ||||
| dataBlock.writeInt (0); // clr important | dataBlock.writeInt (0); // clr important | ||||
| const Image::BitmapData bitmap (image, 0, 0, w, h); | |||||
| const Image::BitmapData bitmap (image, false); | |||||
| const int alphaThreshold = 5; | const int alphaThreshold = 5; | ||||
| int y; | int y; | ||||
| @@ -266,7 +266,7 @@ private: | |||||
| data.write (type, 4); | data.write (type, 4); | ||||
| data.writeIntBigEndian (8 + 4 * w * h); | data.writeIntBigEndian (8 + 4 * w * h); | ||||
| const Image::BitmapData bitmap (image, 0, 0, w, h); | |||||
| const Image::BitmapData bitmap (image, false); | |||||
| int y; | int y; | ||||
| for (y = 0; y < h; ++y) | for (y = 0; y < h; ++y) | ||||
| @@ -132,7 +132,7 @@ public: | |||||
| glPixelStorei (GL_UNPACK_ALIGNMENT, 4); | glPixelStorei (GL_UNPACK_ALIGNMENT, 4); | ||||
| Image::BitmapData srcData (image, 0, 0, image.getWidth(), image.getHeight()); | |||||
| Image::BitmapData srcData (image, false); | |||||
| glTexImage2D (GL_TEXTURE_2D, 0, 4, image.getWidth(), image.getHeight(), | glTexImage2D (GL_TEXTURE_2D, 0, 4, image.getWidth(), image.getHeight(), | ||||
| 0, GL_RGB, | 0, GL_RGB, | ||||
| @@ -192,9 +192,7 @@ private: | |||||
| .rotated (bouncingNumber[3]) | .rotated (bouncingNumber[3]) | ||||
| .scaled (bouncingNumber[2] + 4.0f, bouncingNumber[2] + 4.0f) | .scaled (bouncingNumber[2] + 4.0f, bouncingNumber[2] + 4.0f) | ||||
| .translated (bouncingPointX[2], bouncingPointY[2])); | .translated (bouncingPointX[2], bouncingPointY[2])); | ||||
| g.reduceClipRegion (argbImage, | |||||
| Rectangle<int> (0, 0, argbImage.getWidth(), argbImage.getHeight()), | |||||
| transform); | |||||
| g.reduceClipRegion (argbImage, transform); | |||||
| } | } | ||||
| void drawPaths (Graphics& g, bool /*solid*/, bool linearGradient, bool radialGradient) | void drawPaths (Graphics& g, bool /*solid*/, bool linearGradient, bool radialGradient) | ||||
| @@ -268,8 +266,7 @@ private: | |||||
| .followedBy (getTransform())); | .followedBy (getTransform())); | ||||
| g.setOpacity ((float) owner.opacitySlider->getValue()); | g.setOpacity ((float) owner.opacitySlider->getValue()); | ||||
| g.drawImageTransformed (image, image.getBounds(), | |||||
| transform, false); | |||||
| g.drawImageTransformed (image, transform, false); | |||||
| } | } | ||||
| void drawTiling (Graphics& g, const Image& image) | void drawTiling (Graphics& g, const Image& image) | ||||
| @@ -68,7 +68,7 @@ | |||||
| @see Logger::outputDebugString | @see Logger::outputDebugString | ||||
| */ | */ | ||||
| #define DBG(dbgtext) Logger::outputDebugString (dbgtext); | |||||
| #define DBG(dbgtext) JUCE_NAMESPACE::Logger::outputDebugString (dbgtext); | |||||
| //============================================================================== | //============================================================================== | ||||
| // Assertions.. | // Assertions.. | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 39 | |||||
| #define JUCE_BUILDNUMBER 40 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -96,7 +96,7 @@ public: | |||||
| if (dnd != 0) | if (dnd != 0) | ||||
| { | { | ||||
| dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image(), true); | |||||
| dnd->startDragging (Toolbar::toolbarDragDescriptor, getParentComponent(), Image::null, true); | |||||
| ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent()); | ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getParentComponent()); | ||||
| @@ -199,7 +199,7 @@ private: | |||||
| void clearIcon() | void clearIcon() | ||||
| { | { | ||||
| icon = Image(); | |||||
| icon = Image::null; | |||||
| } | } | ||||
| void updateIcon (const bool onlyUpdateIfCached) | void updateIcon (const bool onlyUpdateIfCached) | ||||
| @@ -68,7 +68,7 @@ void ImagePreviewComponent::timerCallback() | |||||
| { | { | ||||
| stopTimer(); | stopTimer(); | ||||
| currentThumbnail = Image(); | |||||
| currentThumbnail = Image::null; | |||||
| currentDetails = String::empty; | currentDetails = String::empty; | ||||
| repaint(); | repaint(); | ||||
| @@ -502,7 +502,7 @@ void Component::setBufferedToImage (const bool shouldBeBuffered) | |||||
| { | { | ||||
| if (shouldBeBuffered != flags.bufferToImageFlag) | if (shouldBeBuffered != flags.bufferToImageFlag) | ||||
| { | { | ||||
| bufferedImage_ = Image(); | |||||
| bufferedImage_ = Image::null; | |||||
| flags.bufferToImageFlag = shouldBeBuffered; | flags.bufferToImageFlag = shouldBeBuffered; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1478,7 +1478,7 @@ void Component::repaint() | |||||
| void Component::repaint (const int x, const int y, | void Component::repaint (const int x, const int y, | ||||
| const int w, const int h) | const int w, const int h) | ||||
| { | { | ||||
| bufferedImage_ = Image(); | |||||
| bufferedImage_ = Image::null; | |||||
| if (flags.visibleFlag) | if (flags.visibleFlag) | ||||
| internalRepaint (x, y, w, h); | internalRepaint (x, y, w, h); | ||||
| @@ -1334,7 +1334,7 @@ void PopupMenu::addCommandItem (ApplicationCommandManager* commandManager, | |||||
| : info.shortName, | : info.shortName, | ||||
| target != 0 && (info.flags & ApplicationCommandInfo::isDisabled) == 0, | target != 0 && (info.flags & ApplicationCommandInfo::isDisabled) == 0, | ||||
| (info.flags & ApplicationCommandInfo::isTicked) != 0, | (info.flags & ApplicationCommandInfo::isTicked) != 0, | ||||
| Image(), | |||||
| Image::null, | |||||
| Colours::black, | Colours::black, | ||||
| false, | false, | ||||
| 0, 0, | 0, 0, | ||||
| @@ -1369,7 +1369,7 @@ void PopupMenu::addCustomItem (const int itemResultId, | |||||
| addSeparatorIfPending(); | addSeparatorIfPending(); | ||||
| items.add (new Item (itemResultId, String::empty, true, false, Image(), | |||||
| items.add (new Item (itemResultId, String::empty, true, false, Image::null, | |||||
| Colours::black, false, customComponent, 0, 0)); | Colours::black, false, customComponent, 0, 0)); | ||||
| } | } | ||||
| @@ -119,7 +119,7 @@ public: | |||||
| const String& itemText, | const String& itemText, | ||||
| bool isActive = true, | bool isActive = true, | ||||
| bool isTicked = false, | bool isTicked = false, | ||||
| const Image& iconToUse = Image()); | |||||
| const Image& iconToUse = Image::null); | |||||
| /** Adds an item that represents one of the commands in a command manager object. | /** Adds an item that represents one of the commands in a command manager object. | ||||
| @@ -145,7 +145,7 @@ public: | |||||
| const Colour& itemTextColour, | const Colour& itemTextColour, | ||||
| bool isActive = true, | bool isActive = true, | ||||
| bool isTicked = false, | bool isTicked = false, | ||||
| const Image& iconToUse = Image()); | |||||
| const Image& iconToUse = Image::null); | |||||
| /** Appends a custom menu item. | /** Appends a custom menu item. | ||||
| @@ -183,7 +183,7 @@ public: | |||||
| void addSubMenu (const String& subMenuName, | void addSubMenu (const String& subMenuName, | ||||
| const PopupMenu& subMenu, | const PopupMenu& subMenu, | ||||
| bool isActive = true, | bool isActive = true, | ||||
| const Image& iconToUse = Image(), | |||||
| const Image& iconToUse = Image::null, | |||||
| bool isTicked = false); | bool isTicked = false); | ||||
| /** Appends a separator to the menu, to help break it up into sections. | /** Appends a separator to the menu, to help break it up into sections. | ||||
| @@ -90,7 +90,7 @@ public: | |||||
| */ | */ | ||||
| void startDragging (const String& sourceDescription, | void startDragging (const String& sourceDescription, | ||||
| Component* sourceComponent, | Component* sourceComponent, | ||||
| const Image& dragImage = Image(), | |||||
| const Image& dragImage = Image::null, | |||||
| bool allowDraggingToOtherJuceWindows = false, | bool allowDraggingToOtherJuceWindows = false, | ||||
| const Point<int>* imageOffsetFromMouse = 0); | const Point<int>* imageOffsetFromMouse = 0); | ||||
| @@ -117,7 +117,7 @@ public: | |||||
| const int height = getHeight() / 2; | const int height = getHeight() / 2; | ||||
| colours = Image (Image::RGB, width, height, false); | colours = Image (Image::RGB, width, height, false); | ||||
| Image::BitmapData pixels (colours, 0, 0, width, height, true); | |||||
| Image::BitmapData pixels (colours, true); | |||||
| for (int y = 0; y < height; ++y) | for (int y = 0; y < height; ++y) | ||||
| { | { | ||||
| @@ -155,7 +155,7 @@ public: | |||||
| if (lastHue != h) | if (lastHue != h) | ||||
| { | { | ||||
| lastHue = h; | lastHue = h; | ||||
| colours = Image(); | |||||
| colours = Image::null; | |||||
| repaint(); | repaint(); | ||||
| } | } | ||||
| @@ -164,7 +164,7 @@ public: | |||||
| void resized() | void resized() | ||||
| { | { | ||||
| colours = Image(); | |||||
| colours = Image::null; | |||||
| updateMarker(); | updateMarker(); | ||||
| } | } | ||||
| @@ -275,9 +275,7 @@ void MagnifierComponent::paint (Graphics& g) | |||||
| } | } | ||||
| g.setImageResamplingQuality (quality); | g.setImageResamplingQuality (quality); | ||||
| g.drawImageTransformed (temp, temp.getBounds(), | |||||
| AffineTransform::scale ((float) scaleFactor, (float) scaleFactor), | |||||
| false); | |||||
| g.drawImageTransformed (temp, AffineTransform::scale ((float) scaleFactor, (float) scaleFactor), false); | |||||
| } | } | ||||
| void MagnifierComponent::childBoundsChanged (Component* c) | void MagnifierComponent::childBoundsChanged (Component* c) | ||||
| @@ -201,7 +201,7 @@ void CallOutBox::updatePosition (const Rectangle<int>& newAreaToPointTo, const R | |||||
| void CallOutBox::refreshPath() | void CallOutBox::refreshPath() | ||||
| { | { | ||||
| repaint(); | repaint(); | ||||
| background = Image(); | |||||
| background = Image::null; | |||||
| outline.clear(); | outline.clear(); | ||||
| const float gap = 4.5f; | const float gap = 4.5f; | ||||
| @@ -92,7 +92,7 @@ bool FillType::operator!= (const FillType& other) const | |||||
| void FillType::setColour (const Colour& newColour) throw() | void FillType::setColour (const Colour& newColour) throw() | ||||
| { | { | ||||
| gradient = 0; | gradient = 0; | ||||
| image = Image(); | |||||
| image = Image::null; | |||||
| colour = newColour; | colour = newColour; | ||||
| } | } | ||||
| @@ -104,7 +104,7 @@ void FillType::setGradient (const ColourGradient& newGradient) | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| image = Image(); | |||||
| image = Image::null; | |||||
| gradient = new ColourGradient (newGradient); | gradient = new ColourGradient (newGradient); | ||||
| colour = Colours::black; | colour = Colours::black; | ||||
| } | } | ||||
| @@ -105,10 +105,10 @@ bool Graphics::reduceClipRegion (const Path& path, const AffineTransform& transf | |||||
| return ! context->isClipEmpty(); | return ! context->isClipEmpty(); | ||||
| } | } | ||||
| bool Graphics::reduceClipRegion (const Image& image, const Rectangle<int>& sourceClipRegion, const AffineTransform& transform) | |||||
| bool Graphics::reduceClipRegion (const Image& image, const AffineTransform& transform) | |||||
| { | { | ||||
| saveStateIfPending(); | saveStateIfPending(); | ||||
| context->clipToImageAlpha (image, sourceClipRegion, transform); | |||||
| context->clipToImageAlpha (image, transform); | |||||
| return ! context->isClipEmpty(); | return ! context->isClipEmpty(); | ||||
| } | } | ||||
| @@ -667,7 +667,7 @@ void Graphics::drawImage (const Image& imageToDraw, | |||||
| if (imageToDraw.isValid() && context->clipRegionIntersects (Rectangle<int> (dx, dy, dw, dh))) | if (imageToDraw.isValid() && context->clipRegionIntersects (Rectangle<int> (dx, dy, dw, dh))) | ||||
| { | { | ||||
| drawImageTransformed (imageToDraw, Rectangle<int> (sx, sy, sw, sh), | |||||
| drawImageTransformed (imageToDraw.getClippedImage (Rectangle<int> (sx, sy, sw, sh)), | |||||
| AffineTransform::scale (dw / (float) sw, dh / (float) sh) | AffineTransform::scale (dw / (float) sw, dh / (float) sh) | ||||
| .translated ((float) dx, (float) dy), | .translated ((float) dx, (float) dy), | ||||
| fillAlphaChannelWithCurrentBrush); | fillAlphaChannelWithCurrentBrush); | ||||
| @@ -675,24 +675,21 @@ void Graphics::drawImage (const Image& imageToDraw, | |||||
| } | } | ||||
| void Graphics::drawImageTransformed (const Image& imageToDraw, | void Graphics::drawImageTransformed (const Image& imageToDraw, | ||||
| const Rectangle<int>& imageSubRegion, | |||||
| const AffineTransform& transform, | const AffineTransform& transform, | ||||
| const bool fillAlphaChannelWithCurrentBrush) const | const bool fillAlphaChannelWithCurrentBrush) const | ||||
| { | { | ||||
| if (imageToDraw.isValid() && ! context->isClipEmpty()) | if (imageToDraw.isValid() && ! context->isClipEmpty()) | ||||
| { | { | ||||
| const Rectangle<int> srcClip (imageSubRegion.getIntersection (imageToDraw.getBounds())); | |||||
| if (fillAlphaChannelWithCurrentBrush) | if (fillAlphaChannelWithCurrentBrush) | ||||
| { | { | ||||
| context->saveState(); | context->saveState(); | ||||
| context->clipToImageAlpha (imageToDraw, srcClip, transform); | |||||
| context->clipToImageAlpha (imageToDraw, transform); | |||||
| fillAll(); | fillAll(); | ||||
| context->restoreState(); | context->restoreState(); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| context->drawImage (imageToDraw, srcClip, transform, false); | |||||
| context->drawImage (imageToDraw, transform, false); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -492,18 +492,11 @@ public: | |||||
| int sourceX, int sourceY, int sourceWidth, int sourceHeight, | int sourceX, int sourceY, int sourceWidth, int sourceHeight, | ||||
| bool fillAlphaChannelWithCurrentBrush = false) const; | bool fillAlphaChannelWithCurrentBrush = false) const; | ||||
| /** Draws part of an image, having applied an affine transform to it. | |||||
| /** Draws an image, having applied an affine transform to it. | |||||
| This lets you throw the image around in some wacky ways, rotate it, shear, | This lets you throw the image around in some wacky ways, rotate it, shear, | ||||
| scale it, etc. | scale it, etc. | ||||
| A subregion is specified within the source image, and all transformations | |||||
| will be treated as relative to the origin of this sub-region. So, for example if | |||||
| your subregion is (50, 50, 100, 100), and your transform is a translation of (20, 20), | |||||
| the resulting pixel drawn at (20, 20) in the destination context is from (50, 50) in | |||||
| your image. If you want to use the whole image, then Image::getBounds() returns a | |||||
| suitable rectangle to use as the imageSubRegion parameter. | |||||
| Images are composited using the context's current opacity, so if you | Images are composited using the context's current opacity, so if you | ||||
| don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) | don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f) | ||||
| (or setColour() with an opaque colour) before drawing images. | (or setColour() with an opaque colour) before drawing images. | ||||
| @@ -511,10 +504,12 @@ public: | |||||
| If fillAlphaChannelWithCurrentBrush is set to true, then the image's RGB channels | If fillAlphaChannelWithCurrentBrush is set to true, then the image's RGB channels | ||||
| are ignored and it is filled with the current brush, masked by its alpha channel. | are ignored and it is filled with the current brush, masked by its alpha channel. | ||||
| If you want to render only a subsection of an image, use Image::getClippedImage() to | |||||
| create the section that you need. | |||||
| @see setImageResamplingQuality, drawImage | @see setImageResamplingQuality, drawImage | ||||
| */ | */ | ||||
| void drawImageTransformed (const Image& imageToDraw, | void drawImageTransformed (const Image& imageToDraw, | ||||
| const Rectangle<int>& imageSubRegion, | |||||
| const AffineTransform& transform, | const AffineTransform& transform, | ||||
| bool fillAlphaChannelWithCurrentBrush = false) const; | bool fillAlphaChannelWithCurrentBrush = false) const; | ||||
| @@ -588,15 +583,11 @@ public: | |||||
| @param image the image whose alpha-channel should be used. If the image doesn't | @param image the image whose alpha-channel should be used. If the image doesn't | ||||
| have an alpha-channel, it is treated as entirely opaque. | have an alpha-channel, it is treated as entirely opaque. | ||||
| @param sourceClipRegion a subsection of the image that should be used. To use the | |||||
| entire image, just pass a rectangle of bounds | |||||
| (0, 0, image.getWidth(), image.getHeight()). | |||||
| @param transform a matrix to apply to the image | @param transform a matrix to apply to the image | ||||
| @returns true if the resulting clipping region is non-zero in size | @returns true if the resulting clipping region is non-zero in size | ||||
| @see reduceClipRegion | @see reduceClipRegion | ||||
| */ | */ | ||||
| bool reduceClipRegion (const Image& image, const Rectangle<int>& sourceClipRegion, | |||||
| const AffineTransform& transform); | |||||
| bool reduceClipRegion (const Image& image, const AffineTransform& transform); | |||||
| /** Excludes a rectangle to stop it being drawn into. */ | /** Excludes a rectangle to stop it being drawn into. */ | ||||
| void excludeClipRegion (const Rectangle<int>& rectangleToExclude); | void excludeClipRegion (const Rectangle<int>& rectangleToExclude); | ||||
| @@ -71,7 +71,7 @@ public: | |||||
| virtual bool clipToRectangleList (const RectangleList& clipRegion) = 0; | virtual bool clipToRectangleList (const RectangleList& clipRegion) = 0; | ||||
| virtual void excludeClipRectangle (const Rectangle<int>& r) = 0; | virtual void excludeClipRectangle (const Rectangle<int>& r) = 0; | ||||
| virtual void clipToPath (const Path& path, const AffineTransform& transform) = 0; | virtual void clipToPath (const Path& path, const AffineTransform& transform) = 0; | ||||
| virtual void clipToImageAlpha (const Image& sourceImage, const Rectangle<int>& srcClip, const AffineTransform& transform) = 0; | |||||
| virtual void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) = 0; | |||||
| virtual bool clipRegionIntersects (const Rectangle<int>& r) = 0; | virtual bool clipRegionIntersects (const Rectangle<int>& r) = 0; | ||||
| virtual const Rectangle<int> getClipBounds() const = 0; | virtual const Rectangle<int> getClipBounds() const = 0; | ||||
| @@ -89,8 +89,7 @@ public: | |||||
| virtual void fillRect (const Rectangle<int>& r, bool replaceExistingContents) = 0; | virtual void fillRect (const Rectangle<int>& r, bool replaceExistingContents) = 0; | ||||
| virtual void fillPath (const Path& path, const AffineTransform& transform) = 0; | virtual void fillPath (const Path& path, const AffineTransform& transform) = 0; | ||||
| virtual void drawImage (const Image& sourceImage, const Rectangle<int>& srcClip, | |||||
| const AffineTransform& transform, bool fillEntireClipAsTiles) = 0; | |||||
| virtual void drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles) = 0; | |||||
| virtual void drawLine (const Line <float>& line) = 0; | virtual void drawLine (const Line <float>& line) = 0; | ||||
| virtual void drawVerticalLine (int x, float top, float bottom) = 0; | virtual void drawVerticalLine (int x, float top, float bottom) = 0; | ||||
| @@ -140,7 +140,7 @@ void LowLevelGraphicsPostScriptRenderer::clipToPath (const Path& path, const Aff | |||||
| out << "clip\n"; | out << "clip\n"; | ||||
| } | } | ||||
| void LowLevelGraphicsPostScriptRenderer::clipToImageAlpha (const Image& /*sourceImage*/, const Rectangle<int>& /*srcClip*/, const AffineTransform& /*transform*/) | |||||
| void LowLevelGraphicsPostScriptRenderer::clipToImageAlpha (const Image& /*sourceImage*/, const AffineTransform& /*transform*/) | |||||
| { | { | ||||
| needToClip = true; | needToClip = true; | ||||
| jassertfalse; // xxx | jassertfalse; // xxx | ||||
| @@ -454,11 +454,10 @@ void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im, | |||||
| out << "\n>}\n"; | out << "\n>}\n"; | ||||
| } | } | ||||
| void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const Rectangle<int>& srcClip, | |||||
| const AffineTransform& transform, const bool /*fillEntireClipAsTiles*/) | |||||
| void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform, const bool /*fillEntireClipAsTiles*/) | |||||
| { | { | ||||
| const int w = jmin (sourceImage.getWidth(), srcClip.getRight()); | |||||
| const int h = jmin (sourceImage.getHeight(), srcClip.getBottom()); | |||||
| const int w = sourceImage.getWidth(); | |||||
| const int h = sourceImage.getHeight(); | |||||
| writeClip(); | writeClip(); | ||||
| @@ -468,7 +467,6 @@ void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, co | |||||
| RectangleList imageClip; | RectangleList imageClip; | ||||
| sourceImage.createSolidAreaMask (imageClip, 0.5f); | sourceImage.createSolidAreaMask (imageClip, 0.5f); | ||||
| imageClip.clipTo (srcClip); | |||||
| out << "newpath "; | out << "newpath "; | ||||
| int itemsOnLine = 0; | int itemsOnLine = 0; | ||||
| @@ -491,7 +489,7 @@ void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, co | |||||
| out << w << ' ' << h << " scale\n"; | out << w << ' ' << h << " scale\n"; | ||||
| out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n"; | out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n"; | ||||
| writeImage (sourceImage, srcClip.getX(), srcClip.getY(), srcClip.getWidth(), srcClip.getHeight()); | |||||
| writeImage (sourceImage, 0, 0, w, h); | |||||
| out << "false 3 colorimage grestore\n"; | out << "false 3 colorimage grestore\n"; | ||||
| needToClip = true; | needToClip = true; | ||||
| @@ -54,7 +54,7 @@ public: | |||||
| bool clipToRectangleList (const RectangleList& clipRegion); | bool clipToRectangleList (const RectangleList& clipRegion); | ||||
| void excludeClipRectangle (const Rectangle<int>& r); | void excludeClipRectangle (const Rectangle<int>& r); | ||||
| void clipToPath (const Path& path, const AffineTransform& transform); | void clipToPath (const Path& path, const AffineTransform& transform); | ||||
| void clipToImageAlpha (const Image& sourceImage, const Rectangle<int>& srcClip, const AffineTransform& transform); | |||||
| void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform); | |||||
| void saveState(); | void saveState(); | ||||
| void restoreState(); | void restoreState(); | ||||
| @@ -72,8 +72,7 @@ public: | |||||
| void fillRect (const Rectangle<int>& r, bool replaceExistingContents); | void fillRect (const Rectangle<int>& r, bool replaceExistingContents); | ||||
| void fillPath (const Path& path, const AffineTransform& transform); | void fillPath (const Path& path, const AffineTransform& transform); | ||||
| void drawImage (const Image& sourceImage, const Rectangle<int>& srcClip, | |||||
| const AffineTransform& transform, bool fillEntireClipAsTiles); | |||||
| void drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles); | |||||
| void drawLine (const Line <float>& line); | void drawLine (const Line <float>& line); | ||||
| @@ -986,7 +986,7 @@ public: | |||||
| virtual const Ptr excludeClipRectangle (const Rectangle<int>& r) = 0; | virtual const Ptr excludeClipRectangle (const Rectangle<int>& r) = 0; | ||||
| virtual const Ptr clipToPath (const Path& p, const AffineTransform& transform) = 0; | virtual const Ptr clipToPath (const Path& p, const AffineTransform& transform) = 0; | ||||
| virtual const Ptr clipToEdgeTable (const EdgeTable& et) = 0; | virtual const Ptr clipToEdgeTable (const EdgeTable& et) = 0; | ||||
| virtual const Ptr clipToImageAlpha (const Image& image, const Rectangle<int>& srcClip, const AffineTransform& t, const bool betterQuality) = 0; | |||||
| virtual const Ptr clipToImageAlpha (const Image& image, const AffineTransform& t, const bool betterQuality) = 0; | |||||
| virtual bool clipRegionIntersects (const Rectangle<int>& r) const = 0; | virtual bool clipRegionIntersects (const Rectangle<int>& r) const = 0; | ||||
| virtual const Rectangle<int> getClipBounds() const = 0; | virtual const Rectangle<int> getClipBounds() const = 0; | ||||
| @@ -1224,9 +1224,9 @@ public: | |||||
| return edgeTable.isEmpty() ? 0 : this; | return edgeTable.isEmpty() ? 0 : this; | ||||
| } | } | ||||
| const Ptr clipToImageAlpha (const Image& image, const Rectangle<int>& srcClip, const AffineTransform& transform, const bool betterQuality) | |||||
| const Ptr clipToImageAlpha (const Image& image, const AffineTransform& transform, const bool betterQuality) | |||||
| { | { | ||||
| const Image::BitmapData srcData (image, srcClip.getX(), srcClip.getY(), srcClip.getWidth(), srcClip.getHeight()); | |||||
| const Image::BitmapData srcData (image, false); | |||||
| if (transform.isOnlyTranslation()) | if (transform.isOnlyTranslation()) | ||||
| { | { | ||||
| @@ -1416,9 +1416,9 @@ public: | |||||
| return Ptr (new ClipRegion_EdgeTable (clip))->clipToEdgeTable (et); | return Ptr (new ClipRegion_EdgeTable (clip))->clipToEdgeTable (et); | ||||
| } | } | ||||
| const Ptr clipToImageAlpha (const Image& image, const Rectangle<int>& srcClip, const AffineTransform& transform, const bool betterQuality) | |||||
| const Ptr clipToImageAlpha (const Image& image, const AffineTransform& transform, const bool betterQuality) | |||||
| { | { | ||||
| return Ptr (new ClipRegion_EdgeTable (clip))->clipToImageAlpha (image, srcClip, transform, betterQuality); | |||||
| return Ptr (new ClipRegion_EdgeTable (clip))->clipToImageAlpha (image, transform, betterQuality); | |||||
| } | } | ||||
| bool clipRegionIntersects (const Rectangle<int>& r) const | bool clipRegionIntersects (const Rectangle<int>& r) const | ||||
| @@ -1803,20 +1803,20 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| void clipToImageAlpha (const Image& image, const Rectangle<int>& srcClip, const AffineTransform& t) | |||||
| void clipToImageAlpha (const Image& image, const AffineTransform& t) | |||||
| { | { | ||||
| if (clip != 0) | if (clip != 0) | ||||
| { | { | ||||
| if (image.hasAlphaChannel()) | if (image.hasAlphaChannel()) | ||||
| { | { | ||||
| cloneClipIfMultiplyReferenced(); | cloneClipIfMultiplyReferenced(); | ||||
| clip = clip->clipToImageAlpha (image, srcClip, t.translated ((float) xOffset, (float) yOffset), | |||||
| clip = clip->clipToImageAlpha (image, t.translated ((float) xOffset, (float) yOffset), | |||||
| interpolationQuality != Graphics::lowResamplingQuality); | interpolationQuality != Graphics::lowResamplingQuality); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| Path p; | Path p; | ||||
| p.addRectangle (srcClip); | |||||
| p.addRectangle (image.getBounds()); | |||||
| clipToPath (p, t); | clipToPath (p, t); | ||||
| } | } | ||||
| } | } | ||||
| @@ -1839,7 +1839,7 @@ public: | |||||
| { | { | ||||
| if (fillType.isColour()) | if (fillType.isColour()) | ||||
| { | { | ||||
| Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); | |||||
| Image::BitmapData destData (image, true); | |||||
| clip->fillRectWithColour (destData, r.translated (xOffset, yOffset), fillType.colour.getPixelARGB(), replaceContents); | clip->fillRectWithColour (destData, r.translated (xOffset, yOffset), fillType.colour.getPixelARGB(), replaceContents); | ||||
| } | } | ||||
| else | else | ||||
| @@ -1859,7 +1859,7 @@ public: | |||||
| { | { | ||||
| if (fillType.isColour()) | if (fillType.isColour()) | ||||
| { | { | ||||
| Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); | |||||
| Image::BitmapData destData (image, true); | |||||
| clip->fillRectWithColour (destData, r.translated ((float) xOffset, (float) yOffset), fillType.colour.getPixelARGB()); | clip->fillRectWithColour (destData, r.translated ((float) xOffset, (float) yOffset), fillType.colour.getPixelARGB()); | ||||
| } | } | ||||
| else | else | ||||
| @@ -1898,7 +1898,7 @@ public: | |||||
| if (shapeToFill != 0) | if (shapeToFill != 0) | ||||
| { | { | ||||
| Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); | |||||
| Image::BitmapData destData (image, true); | |||||
| if (fillType.isGradient()) | if (fillType.isGradient()) | ||||
| { | { | ||||
| @@ -1923,7 +1923,7 @@ public: | |||||
| } | } | ||||
| else if (fillType.isTiledImage()) | else if (fillType.isTiledImage()) | ||||
| { | { | ||||
| renderImage (image, fillType.image, fillType.image.getBounds(), fillType.transform, shapeToFill); | |||||
| renderImage (image, fillType.image, fillType.transform, shapeToFill); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -1933,13 +1933,12 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void renderImage (Image& destImage, const Image& sourceImage, const Rectangle<int>& srcClip, | |||||
| const AffineTransform& t, const SoftwareRendererClasses::ClipRegionBase* const tiledFillClipRegion) | |||||
| void renderImage (Image& destImage, const Image& sourceImage, const AffineTransform& t, const SoftwareRendererClasses::ClipRegionBase* const tiledFillClipRegion) | |||||
| { | { | ||||
| const AffineTransform transform (t.translated ((float) xOffset, (float) yOffset)); | const AffineTransform transform (t.translated ((float) xOffset, (float) yOffset)); | ||||
| const Image::BitmapData destData (destImage, 0, 0, destImage.getWidth(), destImage.getHeight(), true); | |||||
| const Image::BitmapData srcData (sourceImage, srcClip.getX(), srcClip.getY(), srcClip.getWidth(), srcClip.getHeight()); | |||||
| const Image::BitmapData destData (destImage, true); | |||||
| const Image::BitmapData srcData (sourceImage, false); | |||||
| const int alpha = fillType.colour.getAlpha(); | const int alpha = fillType.colour.getAlpha(); | ||||
| const bool betterQuality = (interpolationQuality != Graphics::lowResamplingQuality); | const bool betterQuality = (interpolationQuality != Graphics::lowResamplingQuality); | ||||
| @@ -1960,7 +1959,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| SoftwareRendererClasses::ClipRegionBase::Ptr c (new SoftwareRendererClasses::ClipRegion_EdgeTable (Rectangle<int> (tx, ty, srcClip.getWidth(), srcClip.getHeight()).getIntersection (destImage.getBounds()))); | |||||
| SoftwareRendererClasses::ClipRegionBase::Ptr c (new SoftwareRendererClasses::ClipRegion_EdgeTable (Rectangle<int> (tx, ty, sourceImage.getWidth(), sourceImage.getHeight()).getIntersection (destImage.getBounds()))); | |||||
| c = clip->applyClipTo (c); | c = clip->applyClipTo (c); | ||||
| if (c != 0) | if (c != 0) | ||||
| @@ -1981,7 +1980,7 @@ public: | |||||
| else | else | ||||
| { | { | ||||
| Path p; | Path p; | ||||
| p.addRectangle (srcClip); | |||||
| p.addRectangle (sourceImage.getBounds()); | |||||
| SoftwareRendererClasses::ClipRegionBase::Ptr c (clip->clone()); | SoftwareRendererClasses::ClipRegionBase::Ptr c (clip->clone()); | ||||
| c = c->clipToPath (p, transform); | c = c->clipToPath (p, transform); | ||||
| @@ -2058,9 +2057,9 @@ void LowLevelGraphicsSoftwareRenderer::clipToPath (const Path& path, const Affin | |||||
| currentState->clipToPath (path, transform); | currentState->clipToPath (path, transform); | ||||
| } | } | ||||
| void LowLevelGraphicsSoftwareRenderer::clipToImageAlpha (const Image& sourceImage, const Rectangle<int>& srcClip, const AffineTransform& transform) | |||||
| void LowLevelGraphicsSoftwareRenderer::clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) | |||||
| { | { | ||||
| currentState->clipToImageAlpha (sourceImage, srcClip, transform); | |||||
| currentState->clipToImageAlpha (sourceImage, transform); | |||||
| } | } | ||||
| bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (const Rectangle<int>& r) | bool LowLevelGraphicsSoftwareRenderer::clipRegionIntersects (const Rectangle<int>& r) | ||||
| @@ -2126,12 +2125,9 @@ void LowLevelGraphicsSoftwareRenderer::fillPath (const Path& path, const AffineT | |||||
| currentState->fillPath (image, path, transform); | currentState->fillPath (image, path, transform); | ||||
| } | } | ||||
| void LowLevelGraphicsSoftwareRenderer::drawImage (const Image& sourceImage, const Rectangle<int>& srcClip, | |||||
| const AffineTransform& transform, const bool fillEntireClipAsTiles) | |||||
| void LowLevelGraphicsSoftwareRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform, const bool fillEntireClipAsTiles) | |||||
| { | { | ||||
| jassert (sourceImage.getBounds().contains (srcClip)); | |||||
| currentState->renderImage (image, sourceImage, srcClip, transform, | |||||
| currentState->renderImage (image, sourceImage, transform, | |||||
| fillEntireClipAsTiles ? currentState->clip : 0); | fillEntireClipAsTiles ? currentState->clip : 0); | ||||
| } | } | ||||
| @@ -54,7 +54,7 @@ public: | |||||
| bool clipToRectangleList (const RectangleList& clipRegion); | bool clipToRectangleList (const RectangleList& clipRegion); | ||||
| void excludeClipRectangle (const Rectangle<int>& r); | void excludeClipRectangle (const Rectangle<int>& r); | ||||
| void clipToPath (const Path& path, const AffineTransform& transform); | void clipToPath (const Path& path, const AffineTransform& transform); | ||||
| void clipToImageAlpha (const Image& sourceImage, const Rectangle<int>& srcClip, const AffineTransform& transform); | |||||
| void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform); | |||||
| bool clipRegionIntersects (const Rectangle<int>& r); | bool clipRegionIntersects (const Rectangle<int>& r); | ||||
| const Rectangle<int> getClipBounds() const; | const Rectangle<int> getClipBounds() const; | ||||
| @@ -72,8 +72,7 @@ public: | |||||
| void fillRect (const Rectangle<int>& r, bool replaceExistingContents); | void fillRect (const Rectangle<int>& r, bool replaceExistingContents); | ||||
| void fillPath (const Path& path, const AffineTransform& transform); | void fillPath (const Path& path, const AffineTransform& transform); | ||||
| void drawImage (const Image& sourceImage, const Rectangle<int>& srcClip, | |||||
| const AffineTransform& transform, bool fillEntireClipAsTiles); | |||||
| void drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles); | |||||
| void drawLine (const Line <float>& line); | void drawLine (const Line <float>& line); | ||||
| @@ -108,13 +108,13 @@ void DrawableImage::render (const Drawable::RenderingContext& context) const | |||||
| if (opacity > 0.0f && ! overlayColour.isOpaque()) | if (opacity > 0.0f && ! overlayColour.isOpaque()) | ||||
| { | { | ||||
| context.g.setOpacity (context.opacity * opacity); | context.g.setOpacity (context.opacity * opacity); | ||||
| context.g.drawImageTransformed (image, image.getBounds(), t, false); | |||||
| context.g.drawImageTransformed (image, t, false); | |||||
| } | } | ||||
| if (! overlayColour.isTransparent()) | if (! overlayColour.isTransparent()) | ||||
| { | { | ||||
| context.g.setColour (overlayColour.withMultipliedAlpha (context.opacity)); | context.g.setColour (overlayColour.withMultipliedAlpha (context.opacity)); | ||||
| context.g.drawImageTransformed (image, image.getBounds(), t, true); | |||||
| context.g.drawImageTransformed (image, t, true); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -66,8 +66,8 @@ void DropShadowEffect::applyEffect (Image& image, Graphics& g) | |||||
| Image shadowImage (Image::SingleChannel, w, h, false); | Image shadowImage (Image::SingleChannel, w, h, false); | ||||
| const Image::BitmapData srcData (image, 0, 0, w, h); | |||||
| const Image::BitmapData destData (shadowImage, 0, 0, w, h, true); | |||||
| const Image::BitmapData srcData (image, false); | |||||
| const Image::BitmapData destData (shadowImage, true); | |||||
| const int filter = roundToInt (63.0f / radius); | const int filter = roundToInt (63.0f / radius); | ||||
| const int radiusMinus1 = roundToInt ((radius - 1.0f) * 63.0f); | const int radiusMinus1 = roundToInt ((radius - 1.0f) * 63.0f); | ||||
| @@ -33,8 +33,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| GIFLoader::GIFLoader (InputStream& in) | GIFLoader::GIFLoader (InputStream& in) | ||||
| : image (0), | |||||
| input (in), | |||||
| : input (in), | |||||
| dataBlockIsZero (false), | dataBlockIsZero (false), | ||||
| fresh (false), | fresh (false), | ||||
| finished (false) | finished (false) | ||||
| @@ -99,9 +98,7 @@ GIFLoader::GIFLoader (InputStream& in) | |||||
| image = Image ((transparent >= 0) ? Image::ARGB : Image::RGB, | image = Image ((transparent >= 0) ? Image::ARGB : Image::RGB, | ||||
| imageWidth, imageHeight, (transparent >= 0)); | imageWidth, imageHeight, (transparent >= 0)); | ||||
| readImage (imageWidth, imageHeight, | |||||
| (buf[8] & 0x40) != 0, | |||||
| transparent); | |||||
| readImage ((buf[8] & 0x40) != 0, transparent); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -361,8 +358,7 @@ int GIFLoader::readLZWByte (const bool initialise, const int inputCodeSize) | |||||
| return code; | return code; | ||||
| } | } | ||||
| bool GIFLoader::readImage (const int width, const int height, | |||||
| const int interlace, const int transparent) | |||||
| bool GIFLoader::readImage (const int interlace, const int transparent) | |||||
| { | { | ||||
| unsigned char c; | unsigned char c; | ||||
| @@ -381,7 +377,7 @@ bool GIFLoader::readImage (const int width, const int height, | |||||
| int index; | int index; | ||||
| int xpos = 0, ypos = 0, pass = 0; | int xpos = 0, ypos = 0, pass = 0; | ||||
| const Image::BitmapData destData (image, 0, 0, width, height, true); | |||||
| const Image::BitmapData destData (image, true); | |||||
| uint8* p = destData.data; | uint8* p = destData.data; | ||||
| const bool hasAlpha = image.hasAlphaChannel(); | const bool hasAlpha = image.hasAlphaChannel(); | ||||
| @@ -409,7 +405,7 @@ bool GIFLoader::readImage (const int width, const int height, | |||||
| p += destData.pixelStride; | p += destData.pixelStride; | ||||
| ++xpos; | ++xpos; | ||||
| if (xpos == width) | |||||
| if (xpos == destData.width) | |||||
| { | { | ||||
| xpos = 0; | xpos = 0; | ||||
| @@ -423,7 +419,7 @@ bool GIFLoader::readImage (const int width, const int height, | |||||
| case 3: ypos += 2; break; | case 3: ypos += 2; break; | ||||
| } | } | ||||
| while (ypos >= height) | |||||
| while (ypos >= destData.height) | |||||
| { | { | ||||
| ++pass; | ++pass; | ||||
| @@ -444,7 +440,7 @@ bool GIFLoader::readImage (const int width, const int height, | |||||
| p = destData.getPixelPointer (xpos, ypos); | p = destData.getPixelPointer (xpos, ypos); | ||||
| } | } | ||||
| if (ypos >= height) | |||||
| if (ypos >= destData.height) | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -69,7 +69,7 @@ private: | |||||
| int processExtension (int type, int& transparent); | int processExtension (int type, int& transparent); | ||||
| int readLZWByte (bool initialise, int input_code_size); | int readLZWByte (bool initialise, int input_code_size); | ||||
| int getCode (int code_size, bool initialise); | int getCode (int code_size, bool initialise); | ||||
| bool readImage (int width, int height, int interlace, int transparent); | |||||
| bool readImage (int interlace, int transparent); | |||||
| static inline int makeWord (const uint8 a, const uint8 b) { return (b << 8) | a; } | static inline int makeWord (const uint8 a, const uint8 b) { return (b << 8) | a; } | ||||
| GIFLoader (const GIFLoader&); | GIFLoader (const GIFLoader&); | ||||
| @@ -302,7 +302,7 @@ const Image JPEGImageFormat::decodeImage (InputStream& in) | |||||
| image = Image (Image::RGB, width, height, false); | image = Image (Image::RGB, width, height, false); | ||||
| const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect) | const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect) | ||||
| const Image::BitmapData destData (image, 0, 0, width, height, true); | |||||
| const Image::BitmapData destData (image, true); | |||||
| for (int y = 0; y < height; ++y) | for (int y = 0; y < height; ++y) | ||||
| { | { | ||||
| @@ -405,7 +405,7 @@ bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out) | |||||
| JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct, | JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct, | ||||
| JPOOL_IMAGE, strideBytes, 1); | JPOOL_IMAGE, strideBytes, 1); | ||||
| const Image::BitmapData srcData (image, 0, 0, jpegCompStruct.image_width, jpegCompStruct.image_height); | |||||
| const Image::BitmapData srcData (image, false); | |||||
| while (jpegCompStruct.next_scanline < jpegCompStruct.image_height) | while (jpegCompStruct.next_scanline < jpegCompStruct.image_height) | ||||
| { | { | ||||
| @@ -168,7 +168,7 @@ const Image PNGImageFormat::decodeImage (InputStream& in) | |||||
| if (pngInfoStruct == 0) | if (pngInfoStruct == 0) | ||||
| { | { | ||||
| png_destroy_read_struct (&pngReadStruct, 0, 0); | png_destroy_read_struct (&pngReadStruct, 0, 0); | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| png_set_error_fn (pngReadStruct, 0, PNGHelpers::errorCallback, PNGHelpers::errorCallback ); | png_set_error_fn (pngReadStruct, 0, PNGHelpers::errorCallback, PNGHelpers::errorCallback ); | ||||
| @@ -226,7 +226,7 @@ const Image PNGImageFormat::decodeImage (InputStream& in) | |||||
| hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect) | hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect) | ||||
| const Image::BitmapData destData (image, 0, 0, (int) width, (int) height, true); | |||||
| const Image::BitmapData destData (image, true); | |||||
| uint8* srcRow = tempBuffer; | uint8* srcRow = tempBuffer; | ||||
| uint8* destRow = destData.data; | uint8* destRow = destData.data; | ||||
| @@ -304,7 +304,7 @@ bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out) | |||||
| png_set_shift (pngWriteStruct, &sig_bit); | png_set_shift (pngWriteStruct, &sig_bit); | ||||
| png_set_packing (pngWriteStruct); | png_set_packing (pngWriteStruct); | ||||
| const Image::BitmapData srcData (image, 0, 0, width, height); | |||||
| const Image::BitmapData srcData (image, false); | |||||
| for (int y = 0; y < height; ++y) | for (int y = 0; y < height; ++y) | ||||
| { | { | ||||
| @@ -95,6 +95,57 @@ Image::SharedImage* Image::SharedImage::createSoftwareImage (Image::PixelFormat | |||||
| return new SoftwareSharedImage (format, width, height, clearImage); | return new SoftwareSharedImage (format, width, height, clearImage); | ||||
| } | } | ||||
| //============================================================================== | |||||
| class SubsectionSharedImage : public Image::SharedImage | |||||
| { | |||||
| public: | |||||
| SubsectionSharedImage (Image::SharedImage* const image_, const Rectangle<int>& area_) | |||||
| : Image::SharedImage (image_->getPixelFormat(), area_.getWidth(), area_.getHeight()), | |||||
| image (image_), area (area_) | |||||
| { | |||||
| pixelStride = image_->getPixelStride(); | |||||
| lineStride = image_->getLineStride(); | |||||
| imageData = image_->getPixelData (area_.getX(), area_.getY()); | |||||
| } | |||||
| ~SubsectionSharedImage() {} | |||||
| Image::ImageType getType() const | |||||
| { | |||||
| return Image::SoftwareImage; | |||||
| } | |||||
| LowLevelGraphicsContext* createLowLevelContext() | |||||
| { | |||||
| LowLevelGraphicsContext* g = image->createLowLevelContext(); | |||||
| g->clipToRectangle (area); | |||||
| g->setOrigin (area.getX(), area.getY()); | |||||
| return g; | |||||
| } | |||||
| SharedImage* clone() | |||||
| { | |||||
| return new SubsectionSharedImage (image->clone(), area); | |||||
| } | |||||
| private: | |||||
| const ReferenceCountedObjectPtr<Image::SharedImage> image; | |||||
| const Rectangle<int> area; | |||||
| }; | |||||
| const Image Image::getClippedImage (const Rectangle<int>& area) const | |||||
| { | |||||
| if (area.contains (getBounds())) | |||||
| return *this; | |||||
| const Rectangle<int> validArea (area.getIntersection (getBounds())); | |||||
| if (validArea.isEmpty()) | |||||
| return Image::null; | |||||
| return Image (new SubsectionSharedImage (image, validArea)); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| Image::Image() | Image::Image() | ||||
| { | { | ||||
| @@ -128,6 +179,8 @@ Image::~Image() | |||||
| { | { | ||||
| } | } | ||||
| const Image Image::null; | |||||
| LowLevelGraphicsContext* Image::createLowLevelContext() const | LowLevelGraphicsContext* Image::createLowLevelContext() const | ||||
| { | { | ||||
| return image == 0 ? 0 : image->createLowLevelContext(); | return image == 0 ? 0 : image->createLowLevelContext(); | ||||
| @@ -231,6 +284,16 @@ Image::BitmapData::BitmapData (const Image& image, const int x, const int y, con | |||||
| jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= image.getWidth() && y + h <= image.getHeight()); | jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= image.getWidth() && y + h <= image.getHeight()); | ||||
| } | } | ||||
| Image::BitmapData::BitmapData (const Image& image, bool /*needsToBeWritable*/) | |||||
| : data (image.image == 0 ? 0 : image.image->imageData), | |||||
| pixelFormat (image.getFormat()), | |||||
| lineStride (image.image == 0 ? 0 : image.image->lineStride), | |||||
| pixelStride (image.image == 0 ? 0 : image.image->pixelStride), | |||||
| width (image.getWidth()), | |||||
| height (image.getHeight()) | |||||
| { | |||||
| } | |||||
| Image::BitmapData::~BitmapData() | Image::BitmapData::~BitmapData() | ||||
| { | { | ||||
| } | } | ||||
| @@ -139,6 +139,11 @@ public: | |||||
| */ | */ | ||||
| inline bool isNull() const throw() { return image == 0; } | inline bool isNull() const throw() { return image == 0; } | ||||
| /** A null Image object that can be used when you need to return an invalid image. | |||||
| This object is the equivalient to an Image created with the default constructor. | |||||
| */ | |||||
| static const Image null; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the image's width (in pixels). */ | /** Returns the image's width (in pixels). */ | ||||
| int getWidth() const throw() { return image == 0 ? 0 : image->width; } | int getWidth() const throw() { return image == 0 ? 0 : image->width; } | ||||
| @@ -206,6 +211,19 @@ public: | |||||
| */ | */ | ||||
| void duplicateIfShared(); | void duplicateIfShared(); | ||||
| /** Returns an image which refers to a subsection of this image. | |||||
| This will not make a copy of the original - the new image will keep a reference to it, so that | |||||
| if the original image is changed, the contents of the subsection will also change. Likewise if you | |||||
| draw into the subimage, you'll also be drawing onto that area of the original image. Note that if | |||||
| you use operator= to make the original Image object refer to something else, the subsection image | |||||
| won't pick up this change, it'll remain pointing at the original. | |||||
| The area passed-in will be clipped to the bounds of this image, so this may return a smaller | |||||
| image than the area you asked for, or even a null image if the area was out-of-bounds. | |||||
| */ | |||||
| const Image getClippedImage (const Rectangle<int>& area) const; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the colour of one of the pixels in the image. | /** Returns the colour of one of the pixels in the image. | ||||
| @@ -276,6 +294,7 @@ public: | |||||
| public: | public: | ||||
| BitmapData (Image& image, int x, int y, int w, int h, bool needsToBeWritable); | BitmapData (Image& image, int x, int y, int w, int h, bool needsToBeWritable); | ||||
| BitmapData (const Image& image, int x, int y, int w, int h); | BitmapData (const Image& image, int x, int y, int w, int h); | ||||
| BitmapData (const Image& image, bool needsToBeWritable); | |||||
| ~BitmapData(); | ~BitmapData(); | ||||
| /** Returns a pointer to the start of a line in the image. | /** Returns a pointer to the start of a line in the image. | ||||
| @@ -382,6 +401,13 @@ public: | |||||
| static SharedImage* createNativeImage (PixelFormat format, int width, int height, bool clearImage); | static SharedImage* createNativeImage (PixelFormat format, int width, int height, bool clearImage); | ||||
| static SharedImage* createSoftwareImage (PixelFormat format, int width, int height, bool clearImage); | static SharedImage* createSoftwareImage (PixelFormat format, int width, int height, bool clearImage); | ||||
| const PixelFormat getPixelFormat() const throw() { return format; } | |||||
| int getWidth() const throw() { return width; } | |||||
| int getHeight() const throw() { return height; } | |||||
| int getPixelStride() const throw() { return pixelStride; } | |||||
| int getLineStride() const throw() { return lineStride; } | |||||
| uint8* getPixelData (int x, int y) const throw(); | |||||
| protected: | protected: | ||||
| friend class Image; | friend class Image; | ||||
| friend class Image::BitmapData; | friend class Image::BitmapData; | ||||
| @@ -391,8 +417,6 @@ public: | |||||
| uint8* imageData; | uint8* imageData; | ||||
| var userTag; | var userTag; | ||||
| uint8* getPixelData (int x, int y) const throw(); | |||||
| SharedImage (const SharedImage&); | SharedImage (const SharedImage&); | ||||
| SharedImage& operator= (const SharedImage&); | SharedImage& operator= (const SharedImage&); | ||||
| }; | }; | ||||
| @@ -63,7 +63,7 @@ public: | |||||
| return item->image; | return item->image; | ||||
| } | } | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| void addImageToCache (const Image& image, const int64 hashCode) | void addImageToCache (const Image& image, const int64 hashCode) | ||||
| @@ -136,7 +136,7 @@ const Image ImageCache::getFromHashCode (const int64 hashCode) | |||||
| if (Pimpl::getInstanceWithoutCreating() != 0) | if (Pimpl::getInstanceWithoutCreating() != 0) | ||||
| return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode); | return Pimpl::getInstanceWithoutCreating()->getFromHashCode (hashCode); | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| void ImageCache::addImageToCache (const Image& image, const int64 hashCode) | void ImageCache::addImageToCache (const Image& image, const int64 hashCode) | ||||
| @@ -143,7 +143,7 @@ void ImageConvolutionKernel::applyToImage (Image& destImage, | |||||
| const Image::BitmapData destData (destImage, area.getX(), area.getY(), area.getWidth(), area.getHeight(), true); | const Image::BitmapData destData (destImage, area.getX(), area.getY(), area.getWidth(), area.getHeight(), true); | ||||
| uint8* line = destData.data; | uint8* line = destData.data; | ||||
| const Image::BitmapData srcData (sourceImage, 0, 0, sourceImage.getWidth(), sourceImage.getHeight()); | |||||
| const Image::BitmapData srcData (sourceImage, false); | |||||
| if (destData.pixelStride == 4) | if (destData.pixelStride == 4) | ||||
| { | { | ||||
| @@ -106,7 +106,7 @@ const Image ImageFileFormat::loadFrom (InputStream& input) | |||||
| if (format != 0) | if (format != 0) | ||||
| return format->decodeImage (input); | return format->decodeImage (input); | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| const Image ImageFileFormat::loadFrom (const File& file) | const Image ImageFileFormat::loadFrom (const File& file) | ||||
| @@ -119,7 +119,7 @@ const Image ImageFileFormat::loadFrom (const File& file) | |||||
| return loadFrom (b); | return loadFrom (b); | ||||
| } | } | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| const Image ImageFileFormat::loadFrom (const void* rawData, const int numBytes) | const Image ImageFileFormat::loadFrom (const void* rawData, const int numBytes) | ||||
| @@ -130,7 +130,7 @@ const Image ImageFileFormat::loadFrom (const void* rawData, const int numBytes) | |||||
| return loadFrom (stream); | return loadFrom (stream); | ||||
| } | } | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -622,7 +622,7 @@ public: | |||||
| const uint32 bShiftL = jmax (0, getShiftNeeded (bMask)); | const uint32 bShiftL = jmax (0, getShiftNeeded (bMask)); | ||||
| const uint32 bShiftR = jmax (0, -getShiftNeeded (bMask)); | const uint32 bShiftR = jmax (0, -getShiftNeeded (bMask)); | ||||
| const Image::BitmapData srcData (Image (this), 0, 0, width, height); | |||||
| const Image::BitmapData srcData (Image (this), false); | |||||
| for (int y = sy; y < sy + dh; ++y) | for (int y = sy; y < sy + dh; ++y) | ||||
| { | { | ||||
| @@ -1819,7 +1819,7 @@ private: | |||||
| else if (Time::getApproximateMillisecondCounter() > lastTimeImageUsed + 3000) | else if (Time::getApproximateMillisecondCounter() > lastTimeImageUsed + 3000) | ||||
| { | { | ||||
| stopTimer(); | stopTimer(); | ||||
| image = Image(); | |||||
| image = Image::null; | |||||
| } | } | ||||
| } | } | ||||
| @@ -3137,7 +3137,7 @@ void MouseCursor::showInAllWindows() const | |||||
| //============================================================================== | //============================================================================== | ||||
| const Image juce_createIconForFile (const File& file) | const Image juce_createIconForFile (const File& file) | ||||
| { | { | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| Image::SharedImage* Image::SharedImage::createNativeImage (PixelFormat format, int width, int height, bool clearImage) | Image::SharedImage* Image::SharedImage::createNativeImage (PixelFormat format, int width, int height, bool clearImage) | ||||
| @@ -878,7 +878,7 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void* windowToAttachTo) | |||||
| //============================================================================== | //============================================================================== | ||||
| const Image juce_createIconForFile (const File& file) | const Image juce_createIconForFile (const File& file) | ||||
| { | { | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -76,7 +76,7 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const Image::BitmapData srcData (juceImage, 0, 0, juceImage.getWidth(), juceImage.getHeight()); | |||||
| const Image::BitmapData srcData (juceImage, false); | |||||
| CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); | CGDataProviderRef provider = CGDataProviderCreateWithData (0, srcData.data, srcData.lineStride * srcData.height, 0); | ||||
| @@ -234,7 +234,7 @@ public: | |||||
| lastClipRectIsValid = false; | lastClipRectIsValid = false; | ||||
| } | } | ||||
| void clipToImageAlpha (const Image& sourceImage, const Rectangle<int>& srcClip, const AffineTransform& transform) | |||||
| void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) | |||||
| { | { | ||||
| if (! transform.isSingularity()) | if (! transform.isSingularity()) | ||||
| { | { | ||||
| @@ -245,19 +245,11 @@ public: | |||||
| CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace); | CGImageRef image = CoreGraphicsImage::createImage (singleChannelImage, true, greyColourSpace); | ||||
| if (srcClip != sourceImage.getBounds()) | |||||
| { | |||||
| CGImageRef fullImage = image; | |||||
| image = CGImageCreateWithImageInRect (fullImage, CGRectMake (srcClip.getX(), srcClip.getY(), | |||||
| srcClip.getWidth(), srcClip.getHeight())); | |||||
| CGImageRelease (fullImage); | |||||
| } | |||||
| flip(); | flip(); | ||||
| AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, srcClip.getHeight()).followedBy (transform)); | |||||
| AffineTransform t (AffineTransform::scale (1.0f, -1.0f).translated (0, sourceImage.getHeight()).followedBy (transform)); | |||||
| applyTransform (t); | applyTransform (t); | ||||
| CGRect r = CGRectMake (0, 0, srcClip.getWidth(), srcClip.getHeight()); | |||||
| CGRect r = CGRectMake (0, 0, sourceImage.getWidth(), sourceImage.getHeight()); | |||||
| CGContextClipToMask (context, r, image); | CGContextClipToMask (context, r, image); | ||||
| applyTransform (t.inverted()); | applyTransform (t.inverted()); | ||||
| @@ -383,7 +375,7 @@ public: | |||||
| { | { | ||||
| CGContextSaveGState (context); | CGContextSaveGState (context); | ||||
| CGContextClipToRect (context, cgRect); | CGContextClipToRect (context, cgRect); | ||||
| drawImage (state->fillType.image, state->fillType.image.getBounds(), state->fillType.transform, true); | |||||
| drawImage (state->fillType.image, state->fillType.transform, true); | |||||
| CGContextRestoreGState (context); | CGContextRestoreGState (context); | ||||
| } | } | ||||
| } | } | ||||
| @@ -416,33 +408,24 @@ public: | |||||
| if (state->fillType.isGradient()) | if (state->fillType.isGradient()) | ||||
| drawGradient(); | drawGradient(); | ||||
| else | else | ||||
| drawImage (state->fillType.image, state->fillType.image.getBounds(), state->fillType.transform, true); | |||||
| drawImage (state->fillType.image, state->fillType.transform, true); | |||||
| } | } | ||||
| CGContextRestoreGState (context); | CGContextRestoreGState (context); | ||||
| } | } | ||||
| void drawImage (const Image& sourceImage, const Rectangle<int>& srcClip, | |||||
| const AffineTransform& transform, const bool fillEntireClipAsTiles) | |||||
| void drawImage (const Image& sourceImage, const AffineTransform& transform, const bool fillEntireClipAsTiles) | |||||
| { | { | ||||
| jassert (sourceImage.getBounds().contains (srcClip)); | |||||
| CGImageRef fullImage = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace); | |||||
| CGImageRef image = fullImage; | |||||
| if (srcClip != sourceImage.getBounds()) | |||||
| { | |||||
| image = CGImageCreateWithImageInRect (fullImage, CGRectMake (srcClip.getX(), srcClip.getY(), | |||||
| srcClip.getWidth(), srcClip.getHeight())); | |||||
| CGImageRelease (fullImage); | |||||
| } | |||||
| const int iw = sourceImage.getWidth(); | |||||
| const int ih = sourceImage.getHeight(); | |||||
| CGImageRef image = CoreGraphicsImage::createImage (sourceImage, false, rgbColourSpace); | |||||
| CGContextSaveGState (context); | CGContextSaveGState (context); | ||||
| CGContextSetAlpha (context, state->fillType.getOpacity()); | CGContextSetAlpha (context, state->fillType.getOpacity()); | ||||
| flip(); | flip(); | ||||
| applyTransform (AffineTransform::scale (1.0f, -1.0f).translated (0, srcClip.getHeight()).followedBy (transform)); | |||||
| CGRect imageRect = CGRectMake (0, 0, srcClip.getWidth(), srcClip.getHeight()); | |||||
| applyTransform (AffineTransform::scale (1.0f, -1.0f).translated (0, ih).followedBy (transform)); | |||||
| CGRect imageRect = CGRectMake (0, 0, iw, ih); | |||||
| if (fillEntireClipAsTiles) | if (fillEntireClipAsTiles) | ||||
| { | { | ||||
| @@ -459,8 +442,6 @@ public: | |||||
| { | { | ||||
| // Fallback to manually doing a tiled fill on 10.4 | // Fallback to manually doing a tiled fill on 10.4 | ||||
| CGRect clip = CGRectIntegral (CGContextGetClipBoundingBox (context)); | CGRect clip = CGRectIntegral (CGContextGetClipBoundingBox (context)); | ||||
| const int iw = srcClip.getWidth(); | |||||
| const int ih = srcClip.getHeight(); | |||||
| int x = 0, y = 0; | int x = 0, y = 0; | ||||
| while (x > clip.origin.x) x -= iw; | while (x > clip.origin.x) x -= iw; | ||||
| @@ -877,7 +877,7 @@ private: | |||||
| void timerCallback() | void timerCallback() | ||||
| { | { | ||||
| stopTimer(); | stopTimer(); | ||||
| image = Image(); | |||||
| image = Image::null; | |||||
| } | } | ||||
| private: | private: | ||||
| @@ -2356,7 +2356,7 @@ static const Image createImageFromHBITMAP (HBITMAP bitmap) | |||||
| SelectObject (dc, bitmap); | SelectObject (dc, bitmap); | ||||
| im = Image (Image::ARGB, bm.bmWidth, bm.bmHeight, true); | im = Image (Image::ARGB, bm.bmWidth, bm.bmHeight, true); | ||||
| Image::BitmapData imageData (im, 0, 0, bm.bmWidth, bm.bmHeight, true); | |||||
| Image::BitmapData imageData (im, true); | |||||
| for (int y = bm.bmHeight; --y >= 0;) | for (int y = bm.bmHeight; --y >= 0;) | ||||
| { | { | ||||
| @@ -2403,7 +2403,7 @@ static const Image createImageFromHICON (HICON icon) | |||||
| } | } | ||||
| } | } | ||||
| return Image(); | |||||
| return Image::null; | |||||
| } | } | ||||
| static HICON createHICONFromImage (const Image& image, const BOOL isIcon, int hotspotX, int hotspotY) | static HICON createHICONFromImage (const Image& image, const BOOL isIcon, int hotspotX, int hotspotY) | ||||