Browse Source

Changes to Image::BitmapData constructors, replacing the bool with a more explicit enum for the read/write mode. Some win32 dLL declarator changes. Android work. Small Quicktime fix.

tags/2021-05-28
Julian Storer 14 years ago
parent
commit
3dfbb0d713
37 changed files with 1210 additions and 425 deletions
  1. +1
    -1
      extras/JuceDemo/Source/demos/OpenGLDemo.cpp
  2. +7
    -0
      extras/audio plugins/demo/Source/PluginProcessor.cpp
  3. +1
    -1
      extras/audio plugins/demo/Source/PluginProcessor.h
  4. +0
    -5
      juce.h
  5. +496
    -188
      juce_amalgamated.cpp
  6. +37
    -22
      juce_amalgamated.h
  7. +1
    -1
      src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp
  8. +1
    -1
      src/audio/midi/juce_MidiBuffer.h
  9. +5
    -4
      src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm
  10. +3
    -1
      src/core/juce_Initialisation.cpp
  11. +1
    -1
      src/core/juce_StandardHeader.h
  12. +1
    -1
      src/events/juce_MessageManager.cpp
  13. +1
    -1
      src/gui/components/code_editor/juce_CodeDocument.h
  14. +1
    -1
      src/gui/components/special/juce_ColourSelector.cpp
  15. +10
    -3
      src/gui/graphics/colour/juce_PixelFormats.h
  16. +6
    -6
      src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
  17. +26
    -24
      src/gui/graphics/effects/juce_DropShadowEffect.cpp
  18. +1
    -1
      src/gui/graphics/geometry/juce_RectangleList.h
  19. +1
    -1
      src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp
  20. +2
    -2
      src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp
  21. +2
    -2
      src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp
  22. +51
    -56
      src/gui/graphics/imaging/juce_Image.cpp
  23. +23
    -8
      src/gui/graphics/imaging/juce_Image.h
  24. +3
    -2
      src/gui/graphics/imaging/juce_ImageConvolutionKernel.cpp
  25. +2
    -2
      src/memory/juce_Atomic.h
  26. +34
    -2
      src/native/android/java/ComponentPeerView.java
  27. +109
    -4
      src/native/android/java/JuceAppActivity.java
  28. +8
    -2
      src/native/android/juce_android_Fonts.cpp
  29. +229
    -10
      src/native/android/juce_android_GraphicsContext.cpp
  30. +35
    -23
      src/native/android/juce_android_Messaging.cpp
  31. +20
    -2
      src/native/android/juce_android_NativeCode.cpp
  32. +44
    -23
      src/native/android/juce_android_Windowing.cpp
  33. +11
    -1
      src/native/linux/juce_linux_Windowing.cpp
  34. +12
    -4
      src/native/mac/juce_mac_CoreGraphicsContext.mm
  35. +1
    -1
      src/native/windows/juce_win32_CameraDevice.cpp
  36. +3
    -3
      src/native/windows/juce_win32_Direct2DGraphicsContext.cpp
  37. +21
    -15
      src/native/windows/juce_win32_Windowing.cpp

+ 1
- 1
extras/JuceDemo/Source/demos/OpenGLDemo.cpp View File

@@ -128,7 +128,7 @@ public:
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
Image::BitmapData srcData (image, false);
Image::BitmapData srcData (image, Image::BitmapData::readOnly);
glTexImage2D (GL_TEXTURE_2D, 0, 4, image.getWidth(), image.getHeight(),
0, GL_RGB,


+ 7
- 0
extras/audio plugins/demo/Source/PluginProcessor.cpp View File

@@ -222,6 +222,13 @@ void JuceDemoPluginAudioProcessor::releaseResources()
keyboardState.reset();
}
void JuceDemoPluginAudioProcessor::reset()
{
// Use this method as the place to clear any delay lines, buffers, etc, as it
// means there's been a break in the audio's continuity.
delayBuffer.clear();
}
void JuceDemoPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
const int numSamples = buffer.getNumSamples();


+ 1
- 1
extras/audio plugins/demo/Source/PluginProcessor.h View File

@@ -28,8 +28,8 @@ public:
//==============================================================================
void prepareToPlay (double sampleRate, int samplesPerBlock);
void releaseResources();
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
void reset();
//==============================================================================
bool hasEditor() const { return true; }


+ 0
- 5
juce.h View File

@@ -73,11 +73,6 @@ BEGIN_JUCE_NAMESPACE
#pragma pack (pop)
#endif
#if defined (JUCE_DLL) && ! (JUCE_AMALGAMATED_TEMPLATE || defined (JUCE_DLL_BUILD))
#undef JUCE_LEAK_DETECTOR
#define JUCE_LEAK_DETECTOR(OwnerClass)
#endif
END_JUCE_NAMESPACE


+ 496
- 188
juce_amalgamated.cpp
File diff suppressed because it is too large
View File


+ 37
- 22
juce_amalgamated.h View File

@@ -73,7 +73,7 @@ namespace JuceDummyNamespace {}
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 28
#define JUCE_BUILDNUMBER 29

/** Current Juce version number.

@@ -2371,7 +2371,7 @@ inline Type Atomic<Type>::operator++() throw()
return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value)
: (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_ANDROID
return (Type) __atomic_inc ((volatile int*) &value);
return (Type) (__atomic_inc ((volatile int*) &value) + 1);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, 1);
#endif
@@ -2387,7 +2387,7 @@ inline Type Atomic<Type>::operator--() throw()
return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value)
: (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_ANDROID
return (Type) __atomic_dec ((volatile int*) &value);
return (Type) (__atomic_dec ((volatile int*) &value) - 1);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, -1);
#endif
@@ -26479,7 +26479,9 @@ public:
{
}

forcedinline uint32 getARGB() const throw() { return argb; }
forcedinline uint32 getARGB() const throw() { return argb; }
forcedinline uint32 getUnpremultipliedARGB() const throw() { PixelARGB p (argb); p.unpremultiply(); return p.getARGB(); }

forcedinline uint32 getRB() const throw() { return 0x00ff00ff & argb; }
forcedinline uint32 getAG() const throw() { return 0x00ff00ff & (argb >> 8); }

@@ -26710,7 +26712,9 @@ public:
b = (uint8) (argb);
}

forcedinline uint32 getARGB() const throw() { return 0xff000000 | b | (g << 8) | (r << 16); }
forcedinline uint32 getARGB() const throw() { return 0xff000000 | b | (g << 8) | (r << 16); }
forcedinline uint32 getUnpremultipliedARGB() const throw() { return getARGB(); }

forcedinline uint32 getRB() const throw() { return b | (uint32) (r << 16); }
forcedinline uint32 getAG() const throw() { return 0xff0000 | g; }

@@ -26872,7 +26876,9 @@ public:
a = (uint8) (argb >> 24);
}

forcedinline uint32 getARGB() const throw() { return (((uint32) a) << 24) | (((uint32) a) << 16) | (((uint32) a) << 8) | a; }
forcedinline uint32 getARGB() const throw() { return (((uint32) a) << 24) | (((uint32) a) << 16) | (((uint32) a) << 8) | a; }
forcedinline uint32 getUnpremultipliedARGB() const throw() { return (((uint32) a) << 24) | 0xffffff; }

forcedinline uint32 getRB() const throw() { return (((uint32) a) << 16) | a; }
forcedinline uint32 getAG() const throw() { return (((uint32) a) << 16) | a; }

@@ -28625,9 +28631,16 @@ public:
class BitmapData
{
public:
BitmapData (Image& image, int x, int y, int w, int h, bool needsToBeWritable);
enum ReadWriteMode
{
readOnly,
writeOnly,
readWrite
};

BitmapData (Image& image, int x, int y, int w, int h, ReadWriteMode mode);
BitmapData (const Image& image, int x, int y, int w, int h);
BitmapData (const Image& image, bool needsToBeWritable);
BitmapData (const Image& image, ReadWriteMode mode);
~BitmapData();

/** Returns a pointer to the start of a line in the image.
@@ -28655,9 +28668,20 @@ public:
void setPixelColour (int x, int y, const Colour& colour) const throw();

uint8* data;
const PixelFormat pixelFormat;
PixelFormat pixelFormat;
int lineStride, pixelStride, width, height;

/** Used internally by custom image types to manage pixel data lifetime. */
class BitmapDataReleaser
{
protected:
BitmapDataReleaser() {}
public:
virtual ~BitmapDataReleaser() {}
};

ScopedPointer<BitmapDataReleaser> dataReleaser;

private:
JUCE_DECLARE_NON_COPYABLE (BitmapData);
};
@@ -28717,6 +28741,7 @@ public:
virtual LowLevelGraphicsContext* createLowLevelContext() = 0;
virtual SharedImage* clone() = 0;
virtual ImageType getType() const = 0;
virtual void initialiseBitmapData (BitmapData& bitmapData, int x, int y, BitmapData::ReadWriteMode mode) = 0;

static SharedImage* createNativeImage (PixelFormat format, int width, int height, bool clearImage);
static SharedImage* createSoftwareImage (PixelFormat format, int width, int height, bool clearImage);
@@ -28724,17 +28749,12 @@ public:
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:
friend class Image;
friend class BitmapData;
const PixelFormat format;
const int width, height;
int pixelStride, lineStride;
uint8* imageData;
NamedValueSet userData;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedImage);
@@ -28938,7 +28958,7 @@ public:
const Path toPath() const;

/** An iterator for accessing all the rectangles in a RectangleList. */
class Iterator
class JUCE_API Iterator
{
public:

@@ -38944,7 +38964,7 @@ public:

@see MidiBuffer
*/
class Iterator
class JUCE_API Iterator
{
public:

@@ -50326,7 +50346,7 @@ public:

@see CodeDocument, SyntaxAnalyser
*/
class Iterator
class JUCE_API Iterator
{
public:
Iterator (CodeDocument* document);
@@ -66216,11 +66236,6 @@ private:
#pragma pack (pop)
#endif

#if defined (JUCE_DLL) && ! (JUCE_AMALGAMATED_TEMPLATE || defined (JUCE_DLL_BUILD))
#undef JUCE_LEAK_DETECTOR
#define JUCE_LEAK_DETECTOR(OwnerClass)
#endif

END_JUCE_NAMESPACE

#ifndef DONT_SET_USING_JUCE_NAMESPACE


+ 1
- 1
src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp View File

@@ -291,7 +291,7 @@ public:
startSampleInFile += samplesReceived;
numSamples -= samplesReceived;
if ((outFlags & kQTMovieAudioExtractionComplete) != 0 && numSamples > 0)
if (((outFlags & kQTMovieAudioExtractionComplete) != 0 || samplesReceived == 0) && numSamples > 0)
{
for (int j = numDestChannels; --j >= 0;)
if (destSamples[j] != 0)


+ 1
- 1
src/audio/midi/juce_MidiBuffer.h View File

@@ -170,7 +170,7 @@ public:
@see MidiBuffer
*/
class Iterator
class JUCE_API Iterator
{
public:
//==============================================================================


+ 5
- 4
src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm View File

@@ -265,6 +265,8 @@ public:
void setStateInformation (const void* data, int sizeInBytes);
void setCurrentProgramStateInformation (const void* data, int sizeInBytes);
void refreshParameterListFromPlugin();
private:
//==============================================================================
friend class AudioUnitPluginWindowCarbon;
@@ -287,7 +289,6 @@ private:
//==============================================================================
bool getComponentDescFromFile (const String& fileOrIdentifier);
void setPluginCallbacks();
void getParameterListFromPlugin();
//==============================================================================
OSStatus renderGetInput (AudioUnitRenderActionFlags* ioActionFlags,
@@ -535,7 +536,7 @@ bool AudioUnitPluginInstance::getComponentDescFromFile (const String& fileOrIden
//==============================================================================
void AudioUnitPluginInstance::initialise()
{
getParameterListFromPlugin();
refreshParameterListFromPlugin();
setPluginCallbacks();
int numIns, numOuts;
@@ -544,7 +545,7 @@ void AudioUnitPluginInstance::initialise()
setLatencySamples (0);
}
void AudioUnitPluginInstance::getParameterListFromPlugin()
void AudioUnitPluginInstance::refreshParameterListFromPlugin()
{
parameterIds.clear();
@@ -559,7 +560,7 @@ void AudioUnitPluginInstance::getParameterListFromPlugin()
parameterIds.insertMultiple (0, 0, paramListSize / sizeof (int));
AudioUnitGetProperty (audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global,
0, &parameterIds.getReference(0), &paramListSize);
0, parameterIds.getRawDataPointer(), &paramListSize);
}
}
}


+ 3
- 1
src/core/juce_Initialisation.cpp View File

@@ -231,7 +231,9 @@ public:
a.memoryBarrier();
a -= (Type) 5;
test.expect (a.get() == (Type) 20);
++a; ++a; --a;
test.expect (++a == (Type) 21);
++a;
test.expect (--a == (Type) 21);
test.expect (a.get() == (Type) 21);
a.memoryBarrier();


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -33,7 +33,7 @@
*/
#define JUCE_MAJOR_VERSION 1
#define JUCE_MINOR_VERSION 53
#define JUCE_BUILDNUMBER 28
#define JUCE_BUILDNUMBER 29
/** Current Juce version number.


+ 1
- 1
src/events/juce_MessageManager.cpp View File

@@ -127,7 +127,7 @@ void MessageManager::deliverMessage (Message* const message)
}
//==============================================================================
#if ! (JUCE_MAC || JUCE_IOS)
#if ! (JUCE_MAC || JUCE_IOS || JUCE_ANDROID)
void MessageManager::runDispatchLoop()
{
jassert (isThisTheMessageThread()); // must only be called by the message thread


+ 1
- 1
src/gui/components/code_editor/juce_CodeDocument.h View File

@@ -336,7 +336,7 @@ public:
@see CodeDocument, SyntaxAnalyser
*/
class Iterator
class JUCE_API Iterator
{
public:
Iterator (CodeDocument* document);


+ 1
- 1
src/gui/components/special/juce_ColourSelector.cpp View File

@@ -103,7 +103,7 @@ public:
const int height = getHeight() / 2;
colours = Image (Image::RGB, width, height, false);
Image::BitmapData pixels (colours, true);
Image::BitmapData pixels (colours, Image::BitmapData::writeOnly);
for (int y = 0; y < height; ++y)
{


+ 10
- 3
src/gui/graphics/colour/juce_PixelFormats.h View File

@@ -42,6 +42,7 @@
class PixelRGB;
class PixelAlpha;
//==============================================================================
/**
Represents a 32-bit ARGB pixel with premultiplied alpha, and can perform compositing
operations with it.
@@ -64,7 +65,9 @@ public:
{
}
forcedinline uint32 getARGB() const throw() { return argb; }
forcedinline uint32 getARGB() const throw() { return argb; }
forcedinline uint32 getUnpremultipliedARGB() const throw() { PixelARGB p (argb); p.unpremultiply(); return p.getARGB(); }
forcedinline uint32 getRB() const throw() { return 0x00ff00ff & argb; }
forcedinline uint32 getAG() const throw() { return 0x00ff00ff & (argb >> 8); }
@@ -300,7 +303,9 @@ public:
b = (uint8) (argb);
}
forcedinline uint32 getARGB() const throw() { return 0xff000000 | b | (g << 8) | (r << 16); }
forcedinline uint32 getARGB() const throw() { return 0xff000000 | b | (g << 8) | (r << 16); }
forcedinline uint32 getUnpremultipliedARGB() const throw() { return getARGB(); }
forcedinline uint32 getRB() const throw() { return b | (uint32) (r << 16); }
forcedinline uint32 getAG() const throw() { return 0xff0000 | g; }
@@ -464,7 +469,9 @@ public:
a = (uint8) (argb >> 24);
}
forcedinline uint32 getARGB() const throw() { return (((uint32) a) << 24) | (((uint32) a) << 16) | (((uint32) a) << 8) | a; }
forcedinline uint32 getARGB() const throw() { return (((uint32) a) << 24) | (((uint32) a) << 16) | (((uint32) a) << 8) | a; }
forcedinline uint32 getUnpremultipliedARGB() const throw() { return (((uint32) a) << 24) | 0xffffff; }
forcedinline uint32 getRB() const throw() { return (((uint32) a) << 16) | a; }
forcedinline uint32 getAG() const throw() { return (((uint32) a) << 16) | a; }


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

@@ -1273,7 +1273,7 @@ public:
const Ptr clipToImageAlpha (const Image& image, const AffineTransform& transform, const bool betterQuality)
{
const Image::BitmapData srcData (image, false);
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
if (transform.isOnlyTranslation())
{
@@ -2010,7 +2010,7 @@ public:
{
if (fillType.isColour())
{
Image::BitmapData destData (image, true);
Image::BitmapData destData (image, Image::BitmapData::readWrite);
clip->fillRectWithColour (destData, r.translated (xOffset, yOffset), fillType.colour.getPixelARGB(), replaceContents);
}
else
@@ -2039,7 +2039,7 @@ public:
{
if (fillType.isColour())
{
Image::BitmapData destData (image, true);
Image::BitmapData destData (image, Image::BitmapData::readWrite);
clip->fillRectWithColour (destData, r.translated ((float) xOffset, (float) yOffset), fillType.colour.getPixelARGB());
}
else
@@ -2087,7 +2087,7 @@ public:
if (shapeToFill != 0)
{
Image::BitmapData destData (image, true);
Image::BitmapData destData (image, Image::BitmapData::readWrite);
if (fillType.isGradient())
{
@@ -2125,8 +2125,8 @@ public:
{
const AffineTransform transform (getTransformWith (t));
const Image::BitmapData destData (image, true);
const Image::BitmapData srcData (sourceImage, false);
const Image::BitmapData destData (image, Image::BitmapData::readWrite);
const Image::BitmapData srcData (sourceImage, Image::BitmapData::readOnly);
const int alpha = fillType.colour.getAlpha();
const bool betterQuality = (interpolationQuality != Graphics::lowResamplingQuality);


+ 26
- 24
src/gui/graphics/effects/juce_DropShadowEffect.cpp View File

@@ -66,38 +66,40 @@ void DropShadowEffect::applyEffect (Image& image, Graphics& g, float alpha)
Image shadowImage (Image::SingleChannel, w, h, false);
const Image::BitmapData srcData (image, false);
const Image::BitmapData destData (shadowImage, true);
const int filter = roundToInt (63.0f / radius);
const int radiusMinus1 = roundToInt ((radius - 1.0f) * 63.0f);
for (int x = w; --x >= 0;)
{
int shadowAlpha = 0;
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
const Image::BitmapData destData (shadowImage, Image::BitmapData::readWrite);
const PixelARGB* src = ((const PixelARGB*) srcData.data) + x;
uint8* shadowPix = destData.data + x;
const int filter = roundToInt (63.0f / radius);
const int radiusMinus1 = roundToInt ((radius - 1.0f) * 63.0f);
for (int y = h; --y >= 0;)
for (int x = w; --x >= 0;)
{
shadowAlpha = ((shadowAlpha * radiusMinus1 + (src->getAlpha() << 6)) * filter) >> 12;
int shadowAlpha = 0;
*shadowPix = (uint8) shadowAlpha;
src = (const PixelARGB*) (((const uint8*) src) + srcData.lineStride);
shadowPix += destData.lineStride;
}
}
const PixelARGB* src = ((const PixelARGB*) srcData.data) + x;
uint8* shadowPix = destData.data + x;
for (int y = h; --y >= 0;)
{
int shadowAlpha = 0;
uint8* shadowPix = destData.getLinePointer (y);
for (int y = h; --y >= 0;)
{
shadowAlpha = ((shadowAlpha * radiusMinus1 + (src->getAlpha() << 6)) * filter) >> 12;
for (int x = w; --x >= 0;)
*shadowPix = (uint8) shadowAlpha;
src = addBytesToPointer (src, srcData.lineStride);
shadowPix += destData.lineStride;
}
}
for (int y = h; --y >= 0;)
{
shadowAlpha = ((shadowAlpha * radiusMinus1 + (*shadowPix << 6)) * filter) >> 12;
*shadowPix++ = (uint8) shadowAlpha;
int shadowAlpha = 0;
uint8* shadowPix = destData.getLinePointer (y);
for (int x = w; --x >= 0;)
{
shadowAlpha = ((shadowAlpha * radiusMinus1 + (*shadowPix << 6)) * filter) >> 12;
*shadowPix++ = (uint8) shadowAlpha;
}
}
}


+ 1
- 1
src/gui/graphics/geometry/juce_RectangleList.h View File

@@ -214,7 +214,7 @@ public:
//==============================================================================
/** An iterator for accessing all the rectangles in a RectangleList. */
class Iterator
class JUCE_API Iterator
{
public:
//==============================================================================


+ 1
- 1
src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp View File

@@ -400,7 +400,7 @@ private:
int index;
int xpos = 0, ypos = 0, pass = 0;
const Image::BitmapData destData (image, true);
const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
uint8* p = destData.data;
const bool hasAlpha = image.hasAlphaChannel();


+ 2
- 2
src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp View File

@@ -307,7 +307,7 @@ const Image JPEGImageFormat::decodeImage (InputStream& in)
image.getProperties()->set ("originalImageHadAlpha", false);
const bool hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect)
const Image::BitmapData destData (image, true);
const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
for (int y = 0; y < height; ++y)
{
@@ -411,7 +411,7 @@ bool JPEGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
JPOOL_IMAGE, strideBytes, 1);
const Image::BitmapData srcData (image, false);
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
{


+ 2
- 2
src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp View File

@@ -234,7 +234,7 @@ const Image PNGImageFormat::decodeImage (InputStream& in)
image.getProperties()->set ("originalImageHadAlpha", image.hasAlphaChannel());
hasAlphaChan = image.hasAlphaChannel(); // (the native image creator may not give back what we expect)
const Image::BitmapData destData (image, true);
const Image::BitmapData destData (image, Image::BitmapData::writeOnly);
uint8* srcRow = tempBuffer;
uint8* destRow = destData.data;
@@ -313,7 +313,7 @@ bool PNGImageFormat::writeImageToStream (const Image& image, OutputStream& out)
png_set_shift (pngWriteStruct, &sig_bit);
png_set_packing (pngWriteStruct);
const Image::BitmapData srcData (image, false);
const Image::BitmapData srcData (image, Image::BitmapData::readOnly);
for (int y = 0; y < height; ++y)
{


+ 51
- 56
src/gui/graphics/imaging/juce_Image.cpp View File

@@ -46,23 +46,16 @@ Image::SharedImage::~SharedImage()
{
}
inline uint8* Image::SharedImage::getPixelData (const int x, const int y) const throw()
{
return imageData + lineStride * y + pixelStride * x;
}
//==============================================================================
class SoftwareSharedImage : public Image::SharedImage
{
public:
SoftwareSharedImage (const Image::PixelFormat format_, const int width_, const int height_, const bool clearImage)
: Image::SharedImage (format_, width_, height_)
: Image::SharedImage (format_, width_, height_),
pixelStride (format_ == Image::RGB ? 3 : ((format_ == Image::ARGB) ? 4 : 1)),
lineStride ((pixelStride * jmax (1, width_) + 3) & ~3)
{
pixelStride = format_ == Image::RGB ? 3 : ((format_ == Image::ARGB) ? 4 : 1);
lineStride = (pixelStride * jmax (1, width) + 3) & ~3;
imageDataAllocated.allocate (lineStride * jmax (1, height), clearImage);
imageData = imageDataAllocated;
imageData.allocate (lineStride * jmax (1, height_), clearImage);
}
Image::ImageType getType() const
@@ -75,6 +68,14 @@ public:
return new LowLevelGraphicsSoftwareRenderer (Image (this));
}
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/)
{
bitmap.data = imageData + x * pixelStride + y * lineStride;
bitmap.pixelFormat = format;
bitmap.lineStride = lineStride;
bitmap.pixelStride = pixelStride;
}
Image::SharedImage* clone()
{
SoftwareSharedImage* s = new SoftwareSharedImage (format, width, height, false);
@@ -83,7 +84,8 @@ public:
}
private:
HeapBlock<uint8> imageDataAllocated;
HeapBlock<uint8> imageData;
const int pixelStride, lineStride;
JUCE_LEAK_DETECTOR (SoftwareSharedImage);
};
@@ -101,9 +103,6 @@ public:
: 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());
}
Image::ImageType getType() const
@@ -119,6 +118,11 @@ public:
return g;
}
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode mode)
{
image->initialiseBitmapData (bitmap, x + area.getX(), y + area.getY(), mode);
}
Image::SharedImage* clone()
{
return new SubsectionSharedImage (image->clone(), area);
@@ -220,7 +224,7 @@ const Image Image::convertedToFormat (PixelFormat newFormat) const
}
else
{
const BitmapData destData (newImage, 0, 0, w, h, true);
const BitmapData destData (newImage, 0, 0, w, h, BitmapData::writeOnly);
const BitmapData srcData (*this, 0, 0, w, h);
for (int y = 0; y < h; ++y)
@@ -254,37 +258,39 @@ NamedValueSet* Image::getProperties() const
}
//==============================================================================
Image::BitmapData::BitmapData (Image& image, const int x, const int y, const int w, const int h, const bool /*makeWritable*/)
: data (image.image == 0 ? 0 : image.image->getPixelData (x, y)),
pixelFormat (image.getFormat()),
lineStride (image.image == 0 ? 0 : image.image->lineStride),
pixelStride (image.image == 0 ? 0 : image.image->pixelStride),
width (w),
Image::BitmapData::BitmapData (Image& image, const int x, const int y, const int w, const int h, BitmapData::ReadWriteMode mode)
: width (w),
height (h)
{
jassert (data != 0);
// The BitmapData class must be given a valid image, and a valid rectangle within it!
jassert (image.image != 0);
jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= image.getWidth() && y + h <= image.getHeight());
image.image->initialiseBitmapData (*this, x, y, mode);
jassert (data != 0 && pixelStride > 0 && lineStride != 0);
}
Image::BitmapData::BitmapData (const Image& image, const int x, const int y, const int w, const int h)
: data (image.image == 0 ? 0 : image.image->getPixelData (x, y)),
pixelFormat (image.getFormat()),
lineStride (image.image == 0 ? 0 : image.image->lineStride),
pixelStride (image.image == 0 ? 0 : image.image->pixelStride),
width (w),
: width (w),
height (h)
{
// The BitmapData class must be given a valid image, and a valid rectangle within it!
jassert (image.image != 0);
jassert (x >= 0 && y >= 0 && w > 0 && h > 0 && x + w <= image.getWidth() && y + h <= image.getHeight());
image.image->initialiseBitmapData (*this, x, y, readOnly);
jassert (data != 0 && pixelStride > 0 && lineStride != 0);
}
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()),
Image::BitmapData::BitmapData (const Image& image, BitmapData::ReadWriteMode mode)
: width (image.getWidth()),
height (image.getHeight())
{
// The BitmapData class must be given a valid image!
jassert (image.image != 0);
image.image->initialiseBitmapData (*this, 0, 0, mode);
jassert (data != 0 && pixelStride > 0 && lineStride != 0);
}
Image::BitmapData::~BitmapData()
@@ -299,21 +305,10 @@ const Colour Image::BitmapData::getPixelColour (const int x, const int y) const
switch (pixelFormat)
{
case Image::ARGB:
{
PixelARGB p (*(const PixelARGB*) pixel);
p.unpremultiply();
return Colour (p.getARGB());
}
case Image::RGB:
return Colour (((const PixelRGB*) pixel)->getARGB());
case Image::SingleChannel:
return Colour ((uint8) 0, (uint8) 0, (uint8) 0, *pixel);
default:
jassertfalse;
break;
case Image::ARGB: return Colour (((const PixelARGB*) pixel)->getUnpremultipliedARGB());
case Image::RGB: return Colour (((const PixelRGB*) pixel)->getUnpremultipliedARGB());
case Image::SingleChannel: return Colour (((const PixelAlpha*) pixel)->getUnpremultipliedARGB());
default: jassertfalse; break;
}
return Colour();
@@ -342,7 +337,7 @@ void Image::setPixelData (int x, int y, int w, int h,
if (Rectangle<int>::intersectRectangles (x, y, w, h, 0, 0, getWidth(), getHeight()))
{
const BitmapData dest (*this, x, y, w, h, true);
const BitmapData dest (*this, x, y, w, h, BitmapData::writeOnly);
for (int i = 0; i < h; ++i)
{
@@ -362,7 +357,7 @@ void Image::clear (const Rectangle<int>& area, const Colour& colourToClearTo)
{
const PixelARGB col (colourToClearTo.getPixelARGB());
const BitmapData destData (*this, clipped.getX(), clipped.getY(), clipped.getWidth(), clipped.getHeight(), true);
const BitmapData destData (*this, clipped.getX(), clipped.getY(), clipped.getWidth(), clipped.getHeight(), BitmapData::writeOnly);
uint8* dest = destData.data;
int dh = clipped.getHeight();
@@ -415,7 +410,7 @@ void Image::setPixelAt (const int x, const int y, const Colour& colour)
{
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()))
{
const BitmapData destData (*this, x, y, 1, 1, true);
const BitmapData destData (*this, x, y, 1, 1, BitmapData::writeOnly);
destData.setPixelColour (0, 0, colour);
}
}
@@ -425,7 +420,7 @@ void Image::multiplyAlphaAt (const int x, const int y, const float multiplier)
if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight())
&& hasAlphaChannel())
{
const BitmapData destData (*this, x, y, 1, 1, true);
const BitmapData destData (*this, x, y, 1, 1, BitmapData::readWrite);
if (isARGB())
((PixelARGB*) destData.data)->multiplyAlpha (multiplier);
@@ -438,7 +433,7 @@ void Image::multiplyAllAlphas (const float amountToMultiplyBy)
{
if (hasAlphaChannel())
{
const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), true);
const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite);
if (isARGB())
{
@@ -477,7 +472,7 @@ void Image::desaturate()
{
if (isARGB() || isRGB())
{
const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), true);
const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite);
if (isARGB())
{
@@ -601,7 +596,7 @@ void Image::moveImageSection (int dx, int dy,
const int maxX = jmax (dx, sx) + w;
const int maxY = jmax (dy, sy) + h;
const BitmapData destData (*this, minX, minY, maxX - minX, maxY - minY, true);
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);


+ 23
- 8
src/gui/graphics/imaging/juce_Image.h View File

@@ -292,9 +292,16 @@ public:
class BitmapData
{
public:
BitmapData (Image& image, int x, int y, int w, int h, bool needsToBeWritable);
enum ReadWriteMode
{
readOnly,
writeOnly,
readWrite
};
BitmapData (Image& image, int x, int y, int w, int h, ReadWriteMode mode);
BitmapData (const Image& image, int x, int y, int w, int h);
BitmapData (const Image& image, bool needsToBeWritable);
BitmapData (const Image& image, ReadWriteMode mode);
~BitmapData();
/** Returns a pointer to the start of a line in the image.
@@ -322,9 +329,21 @@ public:
void setPixelColour (int x, int y, const Colour& colour) const throw();
uint8* data;
const PixelFormat pixelFormat;
PixelFormat pixelFormat;
int lineStride, pixelStride, width, height;
//==============================================================================
/** Used internally by custom image types to manage pixel data lifetime. */
class BitmapDataReleaser
{
protected:
BitmapDataReleaser() {}
public:
virtual ~BitmapDataReleaser() {}
};
ScopedPointer<BitmapDataReleaser> dataReleaser;
private:
JUCE_DECLARE_NON_COPYABLE (BitmapData);
};
@@ -387,6 +406,7 @@ public:
virtual LowLevelGraphicsContext* createLowLevelContext() = 0;
virtual SharedImage* clone() = 0;
virtual ImageType getType() const = 0;
virtual void initialiseBitmapData (BitmapData& bitmapData, int x, int y, BitmapData::ReadWriteMode mode) = 0;
static SharedImage* createNativeImage (PixelFormat format, int width, int height, bool clearImage);
static SharedImage* createSoftwareImage (PixelFormat format, int width, int height, bool clearImage);
@@ -394,17 +414,12 @@ public:
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:
friend class Image;
friend class BitmapData;
const PixelFormat format;
const int width, height;
int pixelStride, lineStride;
uint8* imageData;
NamedValueSet userData;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedImage);


+ 3
- 2
src/gui/graphics/imaging/juce_ImageConvolutionKernel.cpp View File

@@ -134,10 +134,11 @@ void ImageConvolutionKernel::applyToImage (Image& destImage,
const int right = area.getRight();
const int bottom = area.getBottom();
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(),
Image::BitmapData::writeOnly);
uint8* line = destData.data;
const Image::BitmapData srcData (sourceImage, false);
const Image::BitmapData srcData (sourceImage, Image::BitmapData::readOnly);
if (destData.pixelStride == 4)
{


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

@@ -310,7 +310,7 @@ inline Type Atomic<Type>::operator++() throw()
return sizeof (Type) == 4 ? (Type) juce_InterlockedIncrement ((volatile long*) &value)
: (Type) juce_InterlockedIncrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_ANDROID
return (Type) __atomic_inc ((volatile int*) &value);
return (Type) (__atomic_inc ((volatile int*) &value) + 1);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, 1);
#endif
@@ -326,7 +326,7 @@ inline Type Atomic<Type>::operator--() throw()
return sizeof (Type) == 4 ? (Type) juce_InterlockedDecrement ((volatile long*) &value)
: (Type) juce_InterlockedDecrement64 ((volatile __int64*) &value);
#elif JUCE_ATOMICS_ANDROID
return (Type) __atomic_dec ((volatile int*) &value);
return (Type) (__atomic_dec ((volatile int*) &value) - 1);
#elif JUCE_ATOMICS_GCC
return (Type) __sync_add_and_fetch (&value, -1);
#endif


+ 34
- 2
src/native/android/java/ComponentPeerView.java View File

@@ -31,10 +31,16 @@ import android.graphics.*;
//==============================================================================
public class ComponentPeerView extends View
implements View.OnFocusChangeListener
{
public ComponentPeerView (Context context)
public ComponentPeerView (Context context, boolean opaque_)
{
super (context);
opaque = opaque_;
setFocusable (true);
setFocusableInTouchMode (true);
setOnFocusChangeListener (this);
requestFocus();
}
//==============================================================================
@@ -46,6 +52,14 @@ public class ComponentPeerView extends View
handlePaint (canvas);
}
@Override
public boolean isOpaque()
{
return opaque;
}
private boolean opaque;
//==============================================================================
private native void handleMouseDown (float x, float y, long time);
private native void handleMouseDrag (float x, float y, long time);
@@ -70,6 +84,7 @@ public class ComponentPeerView extends View
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh)
{
viewSizeChanged();
}
@Override
@@ -77,16 +92,33 @@ public class ComponentPeerView extends View
{
}
private native void viewSizeChanged();
@Override
public void onFocusChange (View v, boolean hasFocus)
{
if (v == this)
focusChanged (hasFocus);
}
private native void focusChanged (boolean hasFocus);
public void setViewName (String newName)
{
}
public boolean isVisible()
{
return true;
return getVisibility() == VISIBLE;
}
public void setVisible (boolean b)
{
setVisibility (b ? VISIBLE : INVISIBLE);
}
public boolean containsPoint (int x, int y)
{
return true; //xxx needs to check overlapping views
}
}

+ 109
- 4
src/native/android/java/JuceAppActivity.java View File

@@ -27,11 +27,16 @@ package com.juce;
import android.app.Activity;
import android.os.Bundle;
import android.content.*;
import android.view.*;
import android.content.Context;
import android.view.ViewGroup;
import android.view.Display;
import android.view.WindowManager;
import android.graphics.Paint;
import android.graphics.Path;
import android.text.ClipboardManager;
import com.juce.ComponentPeerView;
//==============================================================================
public class JuceAppActivity extends Activity
{
@@ -106,9 +111,9 @@ public class JuceAppActivity extends Activity
//==============================================================================
private ViewHolder viewHolder;
public ComponentPeerView createNewView()
public ComponentPeerView createNewView (boolean opaque)
{
ComponentPeerView v = new ComponentPeerView (this);
ComponentPeerView v = new ComponentPeerView (this, opaque);
viewHolder.addView (v);
return v;
}
@@ -123,6 +128,8 @@ public class JuceAppActivity extends Activity
public ViewHolder (Context context)
{
super (context);
setDescendantFocusability (ViewGroup.FOCUS_AFTER_DESCENDANTS);
setFocusable (false);
}
protected void onLayout (boolean changed, int left, int top, int right, int bottom)
@@ -130,6 +137,11 @@ public class JuceAppActivity extends Activity
}
}
public void excludeClipRegion (android.graphics.Canvas canvas, float left, float top, float right, float bottom)
{
canvas.clipRect (left, top, right, bottom, android.graphics.Region.Op.DIFFERENCE);
}
//==============================================================================
public String getClipboardContent()
{
@@ -142,4 +154,97 @@ public class JuceAppActivity extends Activity
ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE);
clipboard.setText (newText);
}
//==============================================================================
/*class PathGrabber extends Path
{
public PathGrabber()
{
pathString = new StringBuilder();
}
@Override
public void addPath (Path src)
{
}
@Override
public void addPath (Path src, float dx, float dy)
{
}
@Override
public void close()
{
pathString.append ('c');
}
@Override
public void moveTo (float x, float y)
{
pathString.append ('m');
pathString.append (String.valueOf (x));
pathString.append (String.valueOf (y));
}
@Override
public void lineTo (float x, float y)
{
pathString.append ('l');
pathString.append (String.valueOf (x));
pathString.append (String.valueOf (y));
}
@Override
public void quadTo (float x1, float y1, float x2, float y2)
{
pathString.append ('q');
pathString.append (String.valueOf (x1));
pathString.append (String.valueOf (y1));
pathString.append (String.valueOf (x2));
pathString.append (String.valueOf (y2));
}
@Override
public void cubicTo (float x1, float y1, float x2, float y2, float x3, float y3)
{
pathString.append ('b');
pathString.append (String.valueOf (x1));
pathString.append (String.valueOf (y1));
pathString.append (String.valueOf (x2));
pathString.append (String.valueOf (y2));
pathString.append (String.valueOf (x3));
pathString.append (String.valueOf (y3));
}
@Override
public void reset()
{
rewind();
}
@Override
public void rewind()
{
pathString.setLength (0);
}
public String getJucePath()
{
if (getFillType() == FillType.EVEN_ODD)
return "z" + pathString.toString();
else
return "n" + pathString.toString();
}
private StringBuilder pathString;
}*/
public String createPathForGlyph (Paint paint, char c)
{
/*PathGrabber pg = new PathGrabber();
paint.getTextPath (String.valueOf (c), 0, 1, 0, 0, pg);
return pg.getJucePath();*/
return "";
}
}

+ 8
- 2
src/native/android/juce_android_Fonts.cpp View File

@@ -127,8 +127,14 @@ public:
bool getOutlineForGlyph (int glyphNumber, Path& destPath)
{
// TODO
return false;
LocalRef<jstring> s ((jstring) android.activity.callObjectMethod (android.createPathForGlyph, paint.get(), (jchar) glyphNumber));
if (s == 0)
return false;
const String ourString (juceString (s));
destPath.restoreFromString (ourString);
return ourString.isNotEmpty();
}
GlobalRef typeface, paint;


+ 229
- 10
src/native/android/juce_android_GraphicsContext.cpp View File

@@ -27,22 +27,141 @@
// compiled on its own).
#if JUCE_INCLUDED_FILE
//==============================================================================
class AndroidImage : public Image::SharedImage
{
public:
//==============================================================================
AndroidImage (const int width_, const int height_, const bool clearImage)
: Image::SharedImage (Image::ARGB, width_, height_)
{
JNIEnv* env = getEnv();
jobject mode = env->GetStaticObjectField (android.bitmapConfigClass, android.ARGB_8888);
bitmap = GlobalRef (env->CallStaticObjectMethod (android.bitmapClass, android.createBitmap, width_, height_, mode));
env->DeleteLocalRef (mode);
}
AndroidImage (const int width_, const int height_, const GlobalRef& bitmap_)
: Image::SharedImage (Image::ARGB, width_, height_),
bitmap (bitmap_)
{
}
~AndroidImage()
{
bitmap.callVoidMethod (android.recycle);
}
Image::ImageType getType() const { return Image::NativeImage; }
LowLevelGraphicsContext* createLowLevelContext();
void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode mode)
{
bm.lineStride = width * sizeof (jint);
bm.pixelStride = sizeof (jint);
bm.pixelFormat = Image::ARGB;
bm.dataReleaser = new CopyHandler (*this, bm, x, y, mode);
}
SharedImage* clone()
{
JNIEnv* env = getEnv();
jobject mode = env->GetStaticObjectField (android.bitmapConfigClass, android.ARGB_8888);
GlobalRef newCopy (bitmap.callObjectMethod (android.bitmapCopy, mode, true));
env->DeleteLocalRef (mode);
return new AndroidImage (width, height, newCopy);
}
//==============================================================================
GlobalRef bitmap;
private:
class CopyHandler : public Image::BitmapData::BitmapDataReleaser
{
public:
CopyHandler (AndroidImage& owner_, Image::BitmapData& bitmapData_,
const int x_, const int y_, const Image::BitmapData::ReadWriteMode mode_)
: owner (owner_), bitmapData (bitmapData_), mode (mode_), x (x_), y (y_)
{
JNIEnv* env = getEnv();
intArray = env->NewIntArray (bitmapData.width * bitmapData.height);
if (mode != Image::BitmapData::writeOnly)
owner_.bitmap.callVoidMethod (android.getPixels, intArray, 0, bitmapData.width, x_, y_,
bitmapData.width, bitmapData.height);
bitmapData.data = (uint8*) env->GetIntArrayElements (intArray, 0);
if (mode != Image::BitmapData::writeOnly)
{
for (int yy = 0; yy < bitmapData.height; ++yy)
{
PixelARGB* p = (PixelARGB*) bitmapData.getLinePointer (yy);
for (int xx = 0; xx < bitmapData.width; ++xx)
p[xx].premultiply();
}
}
}
~CopyHandler()
{
JNIEnv* env = getEnv();
if (mode != Image::BitmapData::readOnly)
{
for (int yy = 0; yy < bitmapData.height; ++yy)
{
PixelARGB* p = (PixelARGB*) bitmapData.getLinePointer (yy);
for (int xx = 0; xx < bitmapData.width; ++xx)
p[xx].unpremultiply();
}
}
env->ReleaseIntArrayElements (intArray, (jint*) bitmapData.data, 0);
if (mode != Image::BitmapData::readOnly)
owner.bitmap.callVoidMethod (android.setPixels, intArray, 0, bitmapData.width, x, y,
bitmapData.width, bitmapData.height);
env->DeleteLocalRef (intArray);
}
private:
AndroidImage& owner;
Image::BitmapData& bitmapData;
jintArray intArray;
const Image::BitmapData::ReadWriteMode mode;
const int x, y;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CopyHandler);
};
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidImage);
};
Image::SharedImage* Image::SharedImage::createNativeImage (PixelFormat format, int width, int height, bool clearImage)
{
if (format == Image::SingleChannel)
return createSoftwareImage (format, width, height, clearImage);
else
return new AndroidImage (width, height, clearImage);
}
//==============================================================================
class AndroidLowLevelGraphicsContext : public LowLevelGraphicsContext
{
public:
AndroidLowLevelGraphicsContext (const GlobalRef& canvas_)
AndroidLowLevelGraphicsContext (jobject canvas_)
: canvas (canvas_),
currentState (new SavedState())
{
setFill (Colours::black);
}
~AndroidLowLevelGraphicsContext()
{
}
bool isVectorDevice() const { return false; }
//==============================================================================
@@ -68,11 +187,19 @@ public:
bool clipToRectangleList (const RectangleList& clipRegion)
{
return canvas.callBooleanMethod (android.clipRegion, createRegion (getEnv(), clipRegion).get());
RectangleList excluded (getClipBounds());
excluded.subtract (clipRegion);
const int numRects = excluded.getNumRectangles();
for (int i = 0; i < numRects; ++i)
excludeClipRectangle (excluded.getRectangle(i));
}
void excludeClipRectangle (const Rectangle<int>& r)
{
android.activity.callVoidMethod (android.excludeClipRegion, canvas.get(),
(float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom());
}
void clipToPath (const Path& path, const AffineTransform& transform)
@@ -82,6 +209,7 @@ public:
void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform)
{
// TODO xxx
}
bool clipRegionIntersects (const Rectangle<int>& r)
@@ -117,10 +245,12 @@ public:
void setOpacity (float newOpacity)
{
currentState->setAlpha (newOpacity);
}
void setInterpolationQuality (Graphics::ResamplingQuality quality)
{
// TODO xxx
}
//==============================================================================
@@ -139,6 +269,60 @@ public:
void drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles)
{
AndroidImage* androidImage = dynamic_cast <AndroidImage*> (sourceImage.getSharedImage());
if (androidImage != 0)
{
JNIEnv* env = getEnv();
canvas.callVoidMethod (android.drawBitmap, androidImage->bitmap.get(),
createMatrix (env, transform).get(), getImagePaint());
}
else
{
if (transform.isOnlyTranslation())
{
JNIEnv* env = getEnv();
Image::BitmapData bm (sourceImage, Image::BitmapData::readOnly);
jintArray imageData = env->NewIntArray (bm.width * bm.height);
jint* dest = env->GetIntArrayElements (imageData, 0);
if (dest != 0)
{
const uint8* srcLine = bm.getLinePointer (0);
jint* dstLine = dest;
for (int y = 0; y < bm.height; ++y)
{
switch (bm.pixelFormat)
{
case Image::ARGB: copyPixels (dstLine, (PixelARGB*) srcLine, bm.width, bm.pixelStride); break;
case Image::RGB: copyPixels (dstLine, (PixelRGB*) srcLine, bm.width, bm.pixelStride); break;
case Image::SingleChannel: copyPixels (dstLine, (PixelAlpha*) srcLine, bm.width, bm.pixelStride); break;
default: jassertfalse; break;
}
srcLine += bm.lineStride;
dstLine += bm.width;
}
canvas.callVoidMethod (android.drawMemoryBitmap, imageData, 0, bm.width,
transform.getTranslationX(), transform.getTranslationY(),
bm.width, bm.height, true, getImagePaint());
env->ReleaseIntArrayElements (imageData, dest, 0);
env->DeleteLocalRef (imageData);
}
}
else
{
saveState();
addTransform (transform);
drawImage (sourceImage, AffineTransform::identity, fillEntireClipAsTiles);
restoreState();
}
}
}
void drawLine (const Line <float>& line)
@@ -215,10 +399,12 @@ public:
void beginTransparencyLayer (float opacity)
{
// TODO xxx
}
void endTransparencyLayer()
{
// TODO xxx
}
class SavedState
@@ -240,6 +426,12 @@ public:
fillType = newType;
}
void setAlpha (float alpha)
{
fillNeedsUpdate = true;
fillType.colour = fillType.colour.withAlpha (alpha);
}
jobject getPaint()
{
if (fillNeedsUpdate)
@@ -299,6 +491,7 @@ public:
tileMode);
}
env->DeleteLocalRef (tileMode);
env->DeleteLocalRef (coloursArray);
env->DeleteLocalRef (positionsArray);
@@ -309,6 +502,7 @@ public:
}
else
{
}
}
@@ -330,11 +524,22 @@ public:
paint.callObjectMethod (android.setTypeface, atf->typeface.get());
paint.callVoidMethod (android.setTextSize, font.getHeight());
}
fillNeedsUpdate = true;
paint.callVoidMethod (android.setAlpha, (jint) fillType.colour.getAlpha());
}
return p;
}
jobject getImagePaint()
{
jobject p = getPaint();
paint.callVoidMethod (android.setAlpha, (jint) fillType.colour.getAlpha());
fillNeedsUpdate = true;
return p;
}
FillType fillType;
Font font;
GlobalRef paint;
@@ -347,10 +552,8 @@ private:
ScopedPointer <SavedState> currentState;
OwnedArray <SavedState> stateStack;
jobject getCurrentPaint() const
{
return currentState->getPaint();
}
jobject getCurrentPaint() const { return currentState->getPaint(); }
jobject getImagePaint() const { return currentState->getImagePaint(); }
static const LocalRef<jobject> createPath (JNIEnv* env, const Path& path)
{
@@ -424,8 +627,24 @@ private:
return col.getARGB();
}
template <class PixelType>
static void copyPixels (jint* const dest, const PixelType* src, const int width, const int pixelStride) throw()
{
for (int x = 0; x < width; ++x)
{
dest[x] = src->getUnpremultipliedARGB();
src = addBytesToPointer (src, pixelStride);
}
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidLowLevelGraphicsContext);
};
LowLevelGraphicsContext* AndroidImage::createLowLevelContext()
{
jobject canvas = getEnv()->NewObject (android.canvasClass, android.canvasBitmapConstructor, bitmap.get());
return new AndroidLowLevelGraphicsContext (canvas);
}
#endif

+ 35
- 23
src/native/android/juce_android_Messaging.cpp View File

@@ -29,31 +29,14 @@
//==============================================================================
void MessageManager::doPlatformSpecificInitialisation()
{
}
void MessageManager::doPlatformSpecificShutdown()
{
}
void MessageManager::doPlatformSpecificInitialisation() {}
void MessageManager::doPlatformSpecificShutdown() {}
//==============================================================================
bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages)
{
// TODO
/*
The idea here is that this will check the system message queue, pull off a
message if there is one, deliver it, and return true if a message was delivered.
If the queue's empty, return false.
If the message is one of our special ones (i.e. a Message object being delivered,
this must call MessageManager::getInstance()->deliverMessage() to deliver it
*/
Logger::outputDebugString ("*** Modal loops are not possible in Android!! Exiting...");
exit (1);
return true;
}
@@ -61,14 +44,16 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages
//==============================================================================
bool juce_postMessageToSystemQueue (Message* message)
{
message->incReferenceCount();
getEnv()->CallVoidMethod (android.activity, android.postMessage, (jlong) (pointer_sized_uint) message);
return true;
}
JUCE_JNI_CALLBACK (JuceAppActivity, deliverMessage, void, (jobject activity, jlong value))
{
Message* m = (Message*) (pointer_sized_uint) value;
MessageManager::getInstance()->deliverMessage ((Message*) (pointer_sized_uint) value);
Message* const message = (Message*) (pointer_sized_uint) value;
MessageManager::getInstance()->deliverMessage (message);
message->decReferenceCount();
}
//==============================================================================
@@ -115,4 +100,31 @@ void MessageManager::broadcastMessage (const String&)
{
}
void MessageManager::runDispatchLoop()
{
}
class QuitCallback : public CallbackMessage
{
public:
QuitCallback() {}
void messageCallback()
{
android.activity.callVoidMethod (android.finish);
}
};
void MessageManager::stopDispatchLoop()
{
(new QuitCallback())->post();
quitMessagePosted = true;
}
bool MessageManager::runDispatchLoopUntil (int millisecondsToRunFor)
{
juce_dispatchNextMessageOnSystemQueue (false);
return false;
}
#endif

+ 20
- 2
src/native/android/juce_android_NativeCode.cpp View File

@@ -103,6 +103,8 @@ BEGIN_JUCE_NAMESPACE
JAVACLASS (canvasClass, "android/graphics/Canvas") \
JAVACLASS (paintClass, "android/graphics/Paint") \
JAVACLASS (pathClass, "android/graphics/Path") \
JAVACLASS (bitmapClass, "android/graphics/Bitmap") \
JAVACLASS (bitmapConfigClass, "android/graphics/Bitmap$Config") \
JAVACLASS (matrixClass, "android/graphics/Matrix") \
JAVACLASS (rectClass, "android/graphics/Rect") \
JAVACLASS (regionClass, "android/graphics/Region") \
@@ -116,11 +118,14 @@ BEGIN_JUCE_NAMESPACE
#define JUCE_JNI_METHODS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \
\
STATICMETHOD (activityClass, printToConsole, "printToConsole", "(Ljava/lang/String;)V") \
METHOD (activityClass, createNewView, "createNewView", "()Lcom/juce/ComponentPeerView;") \
METHOD (activityClass, createNewView, "createNewView", "(Z)Lcom/juce/ComponentPeerView;") \
METHOD (activityClass, deleteView, "deleteView", "(Lcom/juce/ComponentPeerView;)V") \
METHOD (activityClass, postMessage, "postMessage", "(J)V") \
METHOD (activityClass, finish, "finish", "()V") \
METHOD (activityClass, getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \
METHOD (activityClass, setClipboardContent, "setClipboardContent", "(Ljava/lang/String;)V") \
METHOD (activityClass, excludeClipRegion, "excludeClipRegion", "(Landroid/graphics/Canvas;FFFF)V") \
METHOD (activityClass, createPathForGlyph, "createPathForGlyph", "(Landroid/graphics/Paint;C)Ljava/lang/String;") \
\
METHOD (fileClass, fileExists, "exists", "()Z") \
\
@@ -137,7 +142,9 @@ BEGIN_JUCE_NAMESPACE
METHOD (componentPeerViewClass, isVisible, "isVisible", "()Z") \
METHOD (componentPeerViewClass, hasFocus, "hasFocus", "()Z") \
METHOD (componentPeerViewClass, invalidate, "invalidate", "(IIII)V") \
METHOD (componentPeerViewClass, containsPoint, "containsPoint", "(II)Z") \
\
METHOD (canvasClass, canvasBitmapConstructor, "<init>", "(Landroid/graphics/Bitmap;)V") \
METHOD (canvasClass, drawRect, "drawRect", "(FFFFLandroid/graphics/Paint;)V") \
METHOD (canvasClass, translate, "translate", "(FF)V") \
METHOD (canvasClass, clipPath, "clipPath", "(Landroid/graphics/Path;)Z") \
@@ -145,6 +152,7 @@ BEGIN_JUCE_NAMESPACE
METHOD (canvasClass, clipRegion, "clipRegion", "(Landroid/graphics/Region;)Z") \
METHOD (canvasClass, concat, "concat", "(Landroid/graphics/Matrix;)V") \
METHOD (canvasClass, drawBitmap, "drawBitmap", "(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/graphics/Paint;)V") \
METHOD (canvasClass, drawMemoryBitmap, "drawBitmap", "([IIIFFIIZLandroid/graphics/Paint;)V") \
METHOD (canvasClass, drawLine, "drawLine", "(FFFFLandroid/graphics/Paint;)V") \
METHOD (canvasClass, drawPath, "drawPath", "(Landroid/graphics/Path;Landroid/graphics/Paint;)V") \
METHOD (canvasClass, drawText, "drawText", "(Ljava/lang/String;FFLandroid/graphics/Paint;)V") \
@@ -157,13 +165,13 @@ BEGIN_JUCE_NAMESPACE
\
METHOD (paintClass, paintClassConstructor, "<init>", "(I)V") \
METHOD (paintClass, setColor, "setColor", "(I)V") \
METHOD (paintClass, setAlpha, "setAlpha", "(I)V") \
METHOD (paintClass, setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \
METHOD (paintClass, setTypeface, "setTypeface", "(Landroid/graphics/Typeface;)Landroid/graphics/Typeface;") \
METHOD (paintClass, ascent, "ascent", "()F") \
METHOD (paintClass, descent, "descent", "()F") \
METHOD (paintClass, setTextSize, "setTextSize", "(F)V") \
METHOD (paintClass, getTextWidths, "getTextWidths", "(Ljava/lang/String;[F)I") \
METHOD (paintClass, getTextPath, "getTextPath", "(Ljava/lang/String;IIFFLandroid/graphics/Path;)V") \
\
METHOD (shaderClass, setLocalMatrix, "setLocalMatrix", "(Landroid/graphics/Matrix;)V") \
STATICFIELD (shaderTileModeClass, clampMode, "CLAMP", "Landroid/graphics/Shader$TileMode;") \
@@ -174,6 +182,13 @@ BEGIN_JUCE_NAMESPACE
METHOD (pathClass, quadTo, "quadTo", "(FFFF)V") \
METHOD (pathClass, cubicTo, "cubicTo", "(FFFFFF)V") \
METHOD (pathClass, closePath, "close", "()V") \
\
STATICMETHOD (bitmapClass, createBitmap, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;") \
STATICFIELD (bitmapConfigClass, ARGB_8888, "ARGB_8888", "Landroid/graphics/Bitmap$Config;") \
METHOD (bitmapClass, bitmapCopy, "copy", "(Landroid/graphics/Bitmap$Config;Z)Landroid/graphics/Bitmap;") \
METHOD (bitmapClass, getPixels, "getPixels", "([IIIIIII)V") \
METHOD (bitmapClass, setPixels, "setPixels", "([IIIIIII)V") \
METHOD (bitmapClass, recycle, "recycle", "()V") \
\
METHOD (matrixClass, matrixClassConstructor, "<init>", "()V") \
METHOD (matrixClass, setValues, "setValues", "([F)V") \
@@ -315,7 +330,10 @@ public:
inline void clear()
{
if (obj != 0)
{
getEnv()->DeleteGlobalRef (obj);
obj = 0;
}
}
inline GlobalRef& operator= (const GlobalRef& other)


+ 44
- 23
src/native/android/juce_android_Windowing.cpp View File

@@ -27,7 +27,6 @@
// compiled on its own).
#if JUCE_INCLUDED_FILE
static ModifierKeys currentModifiers;
//==============================================================================
class AndroidComponentPeer : public ComponentPeer
@@ -36,8 +35,10 @@ public:
//==============================================================================
AndroidComponentPeer (Component* const component, const int windowStyleFlags)
: ComponentPeer (component, windowStyleFlags),
view (android.activity.callObjectMethod (android.createNewView))
view (android.activity.callObjectMethod (android.createNewView, component->isOpaque()))
{
if (isFocused())
handleFocusGain();
}
~AndroidComponentPeer()
@@ -88,7 +89,7 @@ public:
const Point<int> getScreenPosition() const
{
JNIEnv* const env = getEnv();
/*JNIEnv* const env = getEnv();
jintArray pos = env->NewIntArray (2);
view.callVoidMethod (android.getLocationOnScreen, pos);
@@ -97,7 +98,10 @@ public:
env->GetIntArrayRegion (pos, 0, 2, coords);
env->DeleteLocalRef (pos);
return Point<int> (coords[0], coords[1]);
return Point<int> (coords[0], coords[1]);*/
return Point<int> (view.callIntMethod (android.getLeft),
view.callIntMethod (android.getTop));
}
const Point<int> localToGlobal (const Point<int>& relativePosition)
@@ -138,10 +142,9 @@ public:
bool contains (const Point<int>& position, bool trueIfInAChildWindow) const
{
// TODO
return isPositiveAndBelow (position.getX(), component->getWidth())
&& isPositiveAndBelow (position.getY(), component->getHeight());
&& isPositiveAndBelow (position.getY(), component->getHeight())
&& ((! trueIfInAChildWindow) || view.callBooleanMethod (android.containsPoint, position.getX(), position.getY()));
}
const BorderSize<int> getFrameSize() const
@@ -162,6 +165,8 @@ public:
if (makeActive)
grabFocus();
handleBroughtToFront();
}
void toBehind (ComponentPeer* other)
@@ -172,21 +177,24 @@ public:
//==============================================================================
void handleMouseDownCallback (float x, float y, int64 time)
{
lastMousePos.setXY ((int) x, (int) y);
currentModifiers = currentModifiers.withoutMouseButtons();
handleMouseEvent (0, Point<int> ((int) x, (int) y), currentModifiers, time);
handleMouseEvent (0, lastMousePos, currentModifiers, time);
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
handleMouseEvent (0, Point<int> ((int) x, (int) y), currentModifiers, time);
handleMouseEvent (0, lastMousePos, currentModifiers, time);
}
void handleMouseDragCallback (float x, float y, int64 time)
{
handleMouseEvent (0, Point<int> ((int) x, (int) y), currentModifiers, time);
lastMousePos.setXY ((int) x, (int) y);
handleMouseEvent (0, lastMousePos, currentModifiers, time);
}
void handleMouseUpCallback (float x, float y, int64 time)
{
lastMousePos.setXY ((int) x, (int) y);
currentModifiers = currentModifiers.withoutMouseButtons();
handleMouseEvent (0, Point<int> ((int) x, (int) y), currentModifiers, time);
handleMouseEvent (0, lastMousePos, currentModifiers, time);
}
//==============================================================================
@@ -197,7 +205,15 @@ public:
void grabFocus()
{
(void) view.callBooleanMethod (android.requestFocus);
view.callBooleanMethod (android.requestFocus);
}
void handleFocusChangeCallback (bool hasFocus)
{
if (hasFocus)
handleFocusGain();
else
handleFocusLoss();
}
void textInputRequired (const Point<int>& position)
@@ -208,8 +224,7 @@ public:
//==============================================================================
void handlePaintCallback (JNIEnv* env, jobject canvas)
{
GlobalRef canvasRef (canvas);
AndroidLowLevelGraphicsContext g (canvasRef);
AndroidLowLevelGraphicsContext g (canvas);
handlePaint (g);
}
@@ -243,6 +258,9 @@ public:
return 0;
}
static ModifierKeys currentModifiers;
static Point<int> lastMousePos;
private:
//==============================================================================
GlobalRef view;
@@ -250,6 +268,9 @@ private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidComponentPeer);
};
ModifierKeys AndroidComponentPeer::currentModifiers = 0;
Point<int> AndroidComponentPeer::lastMousePos;
//==============================================================================
#define JUCE_VIEW_CALLBACK(returnType, javaMethodName, params, juceMethodInvocation) \
JUCE_JNI_CALLBACK (ComponentPeerView, javaMethodName, returnType, params) \
@@ -269,6 +290,12 @@ JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv*, jobject view, jfloat x, jfl
JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv*, jobject view, jfloat x, jfloat y, jlong time),
handleMouseUpCallback ((float) x, (float) y, (int64) time))
JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv*, jobject view),
handleMovedOrResized())
JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv*, jobject view, jboolean hasFocus),
handleFocusChangeCallback (hasFocus))
//==============================================================================
ComponentPeer* Component::createNewPeer (int styleFlags, void*)
{
@@ -298,8 +325,7 @@ void Desktop::createMouseInputSources()
const Point<int> MouseInputSource::getCurrentMousePosition()
{
// TODO
return Point<int>();
return AndroidComponentPeer::lastMousePos;
}
void Desktop::setMousePosition (const Point<int>& newPosition)
@@ -316,12 +342,12 @@ bool KeyPress::isKeyCurrentlyDown (const int keyCode)
void ModifierKeys::updateCurrentModifiers() throw()
{
// not needed
currentModifiers = AndroidComponentPeer::currentModifiers;
}
const ModifierKeys ModifierKeys::getCurrentModifiersRealtime() throw()
{
return currentModifiers;
return AndroidComponentPeer::currentModifiers;
}
//==============================================================================
@@ -340,11 +366,6 @@ bool AlertWindow::showNativeDialogBox (const String& title,
}
//==============================================================================
Image::SharedImage* Image::SharedImage::createNativeImage (PixelFormat format, int width, int height, bool clearImage)
{
return createSoftwareImage (format, width, height, clearImage);
}
void Desktop::setScreenSaverEnabled (const bool isEnabled)
{
// TODO


+ 11
- 1
src/native/linux/juce_linux_Windowing.cpp View File

@@ -585,6 +585,14 @@ public:
return new LowLevelGraphicsSoftwareRenderer (Image (this));
}
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/)
{
bitmap.data = imageData + x * pixelStride + y * lineStride;
bitmap.pixelFormat = format;
bitmap.lineStride = lineStride;
bitmap.pixelStride = pixelStride;
}
SharedImage* clone()
{
jassertfalse;
@@ -622,7 +630,7 @@ public:
const uint32 bShiftL = jmax (0, getShiftNeeded (bMask));
const uint32 bShiftR = jmax (0, -getShiftNeeded (bMask));
const Image::BitmapData srcData (Image (this), false);
const Image::BitmapData srcData (Image (this), Image::BitmapData::readOnly);
for (int y = sy; y < sy + dh; ++y)
{
@@ -656,6 +664,8 @@ private:
const int imageDepth;
HeapBlock <uint8> imageDataAllocated;
HeapBlock <char> imageData16Bit;
int pixelStride, lineStride;
uint8* imageData;
GC gc;


+ 12
- 4
src/native/mac/juce_mac_CoreGraphicsContext.mm View File

@@ -38,8 +38,7 @@ public:
pixelStride = format_ == Image::RGB ? 3 : ((format_ == Image::ARGB) ? 4 : 1);
lineStride = (pixelStride * jmax (1, width) + 3) & ~3;
imageDataAllocated.allocate (lineStride * jmax (1, height), clearImage);
imageData = imageDataAllocated;
imageData.allocate (lineStride * jmax (1, height), clearImage);
CGColorSpaceRef colourSpace = (format == Image::SingleChannel) ? CGColorSpaceCreateDeviceGray()
: CGColorSpaceCreateDeviceRGB();
@@ -58,6 +57,14 @@ public:
Image::ImageType getType() const { return Image::NativeImage; }
LowLevelGraphicsContext* createLowLevelContext();
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/)
{
bitmap.data = imageData + x * pixelStride + y * lineStride;
bitmap.pixelFormat = format;
bitmap.lineStride = lineStride;
bitmap.pixelStride = pixelStride;
}
SharedImage* clone()
{
CoreGraphicsImage* im = new CoreGraphicsImage (format, width, height, false);
@@ -77,7 +84,7 @@ public:
}
else
{
const Image::BitmapData srcData (juceImage, false);
const Image::BitmapData srcData (juceImage, Image::BitmapData::readOnly);
CGDataProviderRef provider;
if (mustOutliveSource)
@@ -126,7 +133,8 @@ public:
//==============================================================================
CGContextRef context;
HeapBlock<uint8> imageDataAllocated;
HeapBlock<uint8> imageData;
int pixelStride, lineStride;
private:
static CGBitmapInfo getCGImageFlags (const Image::PixelFormat& format)


+ 1
- 1
src/native/windows/juce_win32_CameraDevice.cpp View File

@@ -212,7 +212,7 @@ public:
const ScopedLock sl (imageSwapLock);
{
const Image::BitmapData destData (loadingImage, 0, 0, width, height, true);
const Image::BitmapData destData (loadingImage, 0, 0, width, height, Image::BitmapData::writeOnly);
for (int i = 0; i < height; ++i)
memcpy (destData.getLinePointer ((height - 1) - i),


+ 3
- 3
src/native/windows/juce_win32_Direct2DGraphicsContext.cpp View File

@@ -243,7 +243,7 @@ public:
D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties();
Image img (image.convertedToFormat (Image::ARGB));
Image::BitmapData bd (img, false);
Image::BitmapData bd (img, Image::BitmapData::readOnly);
bp.pixelFormat = renderingTarget->GetPixelFormat();
bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
@@ -479,7 +479,7 @@ public:
D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties();
maskImage = image.convertedToFormat (Image::ARGB);
Image::BitmapData bd (this->image, false); // xxx should be maskImage?
Image::BitmapData bd (this->image, Image::BitmapData::readOnly); // xxx should be maskImage?
bp.pixelFormat = owner.renderingTarget->GetPixelFormat();
bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
@@ -658,7 +658,7 @@ public:
D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties();
this->image = image.convertedToFormat (Image::ARGB);
Image::BitmapData bd (this->image, false);
Image::BitmapData bd (this->image, Image::BitmapData::readOnly);
bp.pixelFormat = owner.renderingTarget->GetPixelFormat();
bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;


+ 21
- 15
src/native/windows/juce_win32_Windowing.cpp View File

@@ -145,13 +145,6 @@ const int KeyPress::rewindKey = 0x30003;
class WindowsBitmapImage : public Image::SharedImage
{
public:
//==============================================================================
HBITMAP hBitmap;
HGDIOBJ previousBitmap;
BITMAPV4HEADER bitmapInfo;
HDC hdc;
unsigned char* bitmapData;
//==============================================================================
WindowsBitmapImage (const Image::PixelFormat format_,
const int w, const int h, const bool clearImage)
@@ -160,6 +153,7 @@ public:
jassert (format_ == Image::RGB || format_ == Image::ARGB);
pixelStride = (format_ == Image::RGB) ? 3 : 4;
lineStride = -((w * pixelStride + 3) & ~3);
zerostruct (bitmapInfo);
bitmapInfo.bV4Size = sizeof (BITMAPV4HEADER);
@@ -182,19 +176,14 @@ public:
bitmapInfo.bV4V4Compression = BI_RGB;
}
lineStride = -((w * pixelStride + 3) & ~3);
HDC dc = GetDC (0);
hdc = CreateCompatibleDC (dc);
ReleaseDC (0, dc);
SetMapMode (hdc, MM_TEXT);
hBitmap = CreateDIBSection (hdc,
(BITMAPINFO*) &(bitmapInfo),
DIB_RGB_COLORS,
(void**) &bitmapData,
0, 0);
hBitmap = CreateDIBSection (hdc, (BITMAPINFO*) &(bitmapInfo), DIB_RGB_COLORS,
(void**) &bitmapData, 0, 0);
previousBitmap = SelectObject (hdc, hBitmap);
@@ -218,6 +207,14 @@ public:
return new LowLevelGraphicsSoftwareRenderer (Image (this));
}
void initialiseBitmapData (Image::BitmapData& bitmap, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/)
{
bitmap.data = imageData + x * pixelStride + y * lineStride;
bitmap.pixelFormat = format;
bitmap.lineStride = lineStride;
bitmap.pixelStride = pixelStride;
}
Image::SharedImage* clone()
{
WindowsBitmapImage* im = new WindowsBitmapImage (format, width, height, false);
@@ -318,6 +315,15 @@ public:
}
}
//==============================================================================
HBITMAP hBitmap;
HGDIOBJ previousBitmap;
BITMAPV4HEADER bitmapInfo;
HDC hdc;
uint8* bitmapData;
int pixelStride, lineStride;
uint8* imageData;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsBitmapImage);
};
@@ -342,7 +348,7 @@ namespace IconConverters
SelectObject (dc, bitmap);
im = Image (Image::ARGB, bm.bmWidth, bm.bmHeight, true);
Image::BitmapData imageData (im, true);
Image::BitmapData imageData (im, Image::BitmapData::writeOnly);
for (int y = bm.bmHeight; --y >= 0;)
{


Loading…
Cancel
Save