Browse Source

Implemented support for Android OpenGL native ARGB pixel format.

tags/2021-05-28
Timur Doumler 10 years ago
parent
commit
be9a2ff1bb
10 changed files with 377 additions and 180 deletions
  1. +14
    -2
      modules/juce_core/native/java/JuceAppActivity.java
  2. +28
    -11
      modules/juce_graphics/colour/juce_Colour.cpp
  3. +13
    -0
      modules/juce_graphics/colour/juce_Colour.h
  4. +302
    -150
      modules/juce_graphics/colour/juce_PixelFormats.h
  5. +2
    -2
      modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp
  6. +3
    -3
      modules/juce_graphics/images/juce_Image.cpp
  7. +3
    -3
      modules/juce_gui_basics/native/juce_android_Windowing.cpp
  8. +4
    -0
      modules/juce_opengl/native/juce_OpenGL_android.h
  9. +8
    -1
      modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp
  10. +0
    -8
      modules/juce_opengl/opengl/juce_OpenGLTexture.cpp

+ 14
- 2
modules/juce_core/native/java/JuceAppActivity.java View File

@@ -331,15 +331,26 @@ public class JuceAppActivity extends Activity
setFocusableInTouchMode (true);
setOnFocusChangeListener (this);
requestFocus();
// swap red and blue colours to match internal opengl texture format
ColorMatrix colorMatrix = new ColorMatrix();
float[] colorTransform =
{0, 0, 1.0f, 0, 0,
0, 1.0f, 0, 0, 0,
1.0f, 0, 0, 0, 0,
0, 0, 0, 1.0f, 0};
colorMatrix.set (colorTransform);
ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter (colorMatrix);
paint.setColorFilter (colorFilter);
}
//==============================================================================
private native void handlePaint (long host, Canvas canvas);
private native void handlePaint (long host, Canvas canvas, Paint paint);
@Override
public void onDraw (Canvas canvas)
{
handlePaint (host, canvas);
handlePaint (host, canvas, paint);
}
@Override
@@ -350,6 +361,7 @@ public class JuceAppActivity extends Activity
private boolean opaque;
private long host;
private Paint paint = new Paint();
//==============================================================================
private native void handleMouseDown (long host, int index, float x, float y, long time);


+ 28
- 11
modules/juce_graphics/colour/juce_Colour.cpp View File

@@ -136,7 +136,7 @@ namespace ColourHelpers
//==============================================================================
Colour::Colour() noexcept
: argb (0)
: argb (0, 0, 0, 0)
{
}
@@ -151,11 +151,12 @@ Colour& Colour::operator= (const Colour& other) noexcept
return *this;
}
bool Colour::operator== (const Colour& other) const noexcept { return argb.getARGB() == other.argb.getARGB(); }
bool Colour::operator!= (const Colour& other) const noexcept { return argb.getARGB() != other.argb.getARGB(); }
bool Colour::operator== (const Colour& other) const noexcept { return argb.getNativeARGB() == other.argb.getNativeARGB(); }
bool Colour::operator!= (const Colour& other) const noexcept { return argb.getNativeARGB() != other.argb.getNativeARGB(); }
//==============================================================================
Colour::Colour (const uint32 col) noexcept : argb (col)
Colour::Colour (const uint32 col) noexcept
: argb ((col >> 24) & 0xff, (col >> 16) & 0xff, (col >> 8) & 0xff, col & 0xff)
{
}
@@ -206,10 +207,26 @@ Colour::Colour (const float hue, const float saturation, const float brightness,
{
}
Colour::Colour (PixelARGB argb_) noexcept
: argb (argb_)
{
}
Colour::Colour (PixelRGB rgb) noexcept
: argb (Colour (rgb.getInARGBMaskOrder()).argb)
{
}
Colour::Colour (PixelAlpha alpha) noexcept
: argb (Colour (alpha.getInARGBMaskOrder()).argb)
{
}
Colour::~Colour() noexcept
{
}
//==============================================================================
const PixelARGB Colour::getPixelARGB() const noexcept
{
@@ -220,7 +237,7 @@ const PixelARGB Colour::getPixelARGB() const noexcept
uint32 Colour::getARGB() const noexcept
{
return argb.getARGB();
return argb.getInARGBMaskOrder();
}
//==============================================================================
@@ -238,7 +255,7 @@ Colour Colour::withAlpha (const uint8 newAlpha) const noexcept
{
PixelARGB newCol (argb);
newCol.setAlpha (newAlpha);
return Colour (newCol.getARGB());
return Colour (newCol);
}
Colour Colour::withAlpha (const float newAlpha) const noexcept
@@ -247,7 +264,7 @@ Colour Colour::withAlpha (const float newAlpha) const noexcept
PixelARGB newCol (argb);
newCol.setAlpha (ColourHelpers::floatToUInt8 (newAlpha));
return Colour (newCol.getARGB());
return Colour (newCol);
}
Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noexcept
@@ -256,7 +273,7 @@ Colour Colour::withMultipliedAlpha (const float alphaMultiplier) const noexcept
PixelARGB newCol (argb);
newCol.setAlpha ((uint8) jmin (0xff, roundToInt (alphaMultiplier * newCol.getAlpha())));
return Colour (newCol.getARGB());
return Colour (newCol);
}
//==============================================================================
@@ -294,7 +311,7 @@ Colour Colour::interpolatedWith (Colour other, float proportionOfOther) const no
c1.tween (c2, (uint32) roundToInt (proportionOfOther * 255.0f));
c1.unpremultiply();
return Colour (c1.getARGB());
return Colour (c1);
}
//==============================================================================
@@ -428,7 +445,7 @@ Colour Colour::contrasting (Colour colour1,
//==============================================================================
String Colour::toString() const
{
return String::toHexString ((int) argb.getARGB());
return String::toHexString ((int) argb.getInARGBMaskOrder());
}
Colour Colour::fromString (StringRef encodedColourString)
@@ -438,7 +455,7 @@ Colour Colour::fromString (StringRef encodedColourString)
String Colour::toDisplayString (const bool includeAlphaValue) const
{
return String::toHexString ((int) (argb.getARGB() & (includeAlphaValue ? 0xffffffff : 0xffffff)))
return String::toHexString ((int) (argb.getInARGBMaskOrder() & (includeAlphaValue ? 0xffffffff : 0xffffff)))
.paddedLeft ('0', includeAlphaValue ? 8 : 6)
.toUpperCase();
}

+ 13
- 0
modules/juce_graphics/colour/juce_Colour.h View File

@@ -115,6 +115,19 @@ public:
float brightness,
float alpha) noexcept;
/** Creates a colour using a PixedARGB object. This function assumes that the argb pixel is
not premultiplied.
*/
Colour (PixelARGB argb) noexcept;
/** Creates a colour using a PixedRGB object.
*/
Colour (PixelRGB rgb) noexcept;
/** Creates a colour using a PixedAlpha object.
*/
Colour (PixelAlpha alpha) noexcept;
/** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha.
The floating point values must be between 0.0 and 1.0.


+ 302
- 150
modules/juce_graphics/colour/juce_PixelFormats.h View File

@@ -46,7 +46,7 @@ inline uint32 clampPixelComponents (uint32 x) noexcept
//==============================================================================
/**
Represents a 32-bit ARGB pixel with premultiplied alpha, and can perform compositing
Represents a 32-bit INTERNAL pixel with premultiplied alpha, and can perform compositing
operations with it.
This is used internally by the imaging classes.
@@ -60,13 +60,6 @@ public:
PixelARGB() noexcept {}
~PixelARGB() noexcept {}
/** Creates a pixel from a 32-bit argb value.
*/
PixelARGB (const uint32 argbValue) noexcept
: argb (argbValue)
{
}
PixelARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) noexcept
{
components.b = b;
@@ -75,30 +68,81 @@ public:
components.a = a;
}
forcedinline uint32 getARGB() const noexcept { return argb; }
forcedinline uint32 getUnpremultipliedARGB() const noexcept { PixelARGB p (argb); p.unpremultiply(); return p.getARGB(); }
//==============================================================================
/** Returns a uint32 which represents the pixel in a platform dependent format. */
forcedinline uint32 getNativeARGB() const noexcept { return internal; }
/** Returns a uint32 which will be in argb order as if constructed with the following mask operation
((alpha << 24) | (red << 16) | (green << 8) | blue). */
forcedinline uint32 getInARGBMaskOrder() const noexcept
{
#if JUCE_ANDROID
return (uint32) ((components.a << 24) | (components.r << 16) | (components.g << 8) | (components.b << 0));
#else
return getNativeARGB();
#endif
}
/** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
inline uint32 getInARGBMemoryOrder() const noexcept
{
#if JUCE_BIG_ENDIAN
return getInARGBMaskOrder();
#else
return (uint32) ((components.b << 24) | (components.g << 16) | (components.r << 8) | components.a);
#endif
}
/** Return channels with an even index and insert zero bytes between them. This is useful for blending
operations. The exact channels which are returned is platform dependent. */
forcedinline uint32 getEvenBytes() const noexcept { return 0x00ff00ff & internal; }
forcedinline uint32 getRB() const noexcept { return 0x00ff00ff & argb; }
forcedinline uint32 getAG() const noexcept { return 0x00ff00ff & (argb >> 8); }
/** Return channels with an odd index and insert zero bytes between them. This is useful for blending
operations. The exact channels which are returned is platform dependent. */
forcedinline uint32 getOddBytes() const noexcept { return 0x00ff00ff & (internal >> 8); }
forcedinline uint8 getAlpha() const noexcept { return components.a; }
forcedinline uint8 getRed() const noexcept { return components.r; }
forcedinline uint8 getGreen() const noexcept { return components.g; }
forcedinline uint8 getBlue() const noexcept { return components.b; }
//==============================================================================
forcedinline uint8 getAlpha() const noexcept { return components.a; }
forcedinline uint8 getRed() const noexcept { return components.r; }
forcedinline uint8 getGreen() const noexcept { return components.g; }
forcedinline uint8 getBlue() const noexcept { return components.b; }
#if JUCE_GCC && ! JUCE_CLANG
// NB these are here as a workaround because GCC refuses to bind to packed values.
forcedinline uint8& getAlpha() noexcept { return comps [indexA]; }
forcedinline uint8& getRed() noexcept { return comps [indexR]; }
forcedinline uint8& getGreen() noexcept { return comps [indexG]; }
forcedinline uint8& getBlue() noexcept { return comps [indexB]; }
forcedinline uint8& getAlpha() noexcept { return comps [indexA]; }
forcedinline uint8& getRed() noexcept { return comps [indexR]; }
forcedinline uint8& getGreen() noexcept { return comps [indexG]; }
forcedinline uint8& getBlue() noexcept { return comps [indexB]; }
#else
forcedinline uint8& getAlpha() noexcept { return components.a; }
forcedinline uint8& getRed() noexcept { return components.r; }
forcedinline uint8& getGreen() noexcept { return components.g; }
forcedinline uint8& getBlue() noexcept { return components.b; }
forcedinline uint8& getAlpha() noexcept { return components.a; }
forcedinline uint8& getRed() noexcept { return components.r; }
forcedinline uint8& getGreen() noexcept { return components.g; }
forcedinline uint8& getBlue() noexcept { return components.b; }
#endif
//==============================================================================
/** Copies another pixel colour over this one.
This doesn't blend it - this colour is simply replaced by the other one.
*/
template <class Pixel>
forcedinline void set (const Pixel& src) noexcept
{
internal = src.getNativeARGB();
}
//==============================================================================
/** Sets the pixel's colour from individual components. */
void setARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) noexcept
{
components.b = b;
components.g = g;
components.r = r;
components.a = a;
}
//==============================================================================
/** Blends another pixel onto this one.
This takes into account the opacity of the pixel being overlaid, and blends
@@ -107,10 +151,15 @@ public:
template <class Pixel>
forcedinline void blend (const Pixel& src) noexcept
{
const uint32 alpha = (uint32) (0x100 - src.getAlpha());
uint32 rb = src.getRB() + maskPixelComponents (getRB() * alpha);
uint32 ag = src.getAG() + maskPixelComponents (getAG() * alpha);
argb = clampPixelComponents (rb) + (clampPixelComponents (ag) << 8);
uint32 rb = src.getEvenBytes();
uint32 ag = src.getOddBytes();
const uint32 alpha = 0x100 - (ag >> 16);
rb += maskPixelComponents (getEvenBytes() * alpha);
ag += maskPixelComponents (getOddBytes() * alpha);
internal = clampPixelComponents (rb) | (clampPixelComponents (ag) << 8);
}
/** Blends another pixel onto this one.
@@ -129,14 +178,15 @@ public:
template <class Pixel>
forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
{
uint32 ag = maskPixelComponents (extraAlpha * src.getAG());
uint32 rb = maskPixelComponents (extraAlpha * src.getEvenBytes());
uint32 ag = maskPixelComponents (extraAlpha * src.getOddBytes());
const uint32 alpha = 0x100 - (ag >> 16);
ag += maskPixelComponents (getAG() * alpha);
uint32 rb = maskPixelComponents (extraAlpha * src.getRB())
+ maskPixelComponents (getRB() * alpha);
rb += maskPixelComponents (getEvenBytes() * alpha);
ag += maskPixelComponents (getOddBytes() * alpha);
argb = clampPixelComponents(rb) + (clampPixelComponents (ag) << 8);
internal = clampPixelComponents (rb) | (clampPixelComponents (ag) << 8);
}
/** Blends another pixel with this one, creating a colour that is somewhere
@@ -145,29 +195,20 @@ public:
template <class Pixel>
forcedinline void tween (const Pixel& src, const uint32 amount) noexcept
{
uint32 drb = getRB();
drb += (((src.getRB() - drb) * amount) >> 8);
drb &= 0x00ff00ff;
uint32 dEvenBytes = getEvenBytes();
dEvenBytes += (((src.getEvenBytes() - dEvenBytes) * amount) >> 8);
dEvenBytes &= 0x00ff00ff;
uint32 dag = getAG();
dag += (((src.getAG() - dag) * amount) >> 8);
dag &= 0x00ff00ff;
dag <<= 8;
uint32 dOddBytes = getOddBytes();
dOddBytes += (((src.getOddBytes() - dOddBytes) * amount) >> 8);
dOddBytes &= 0x00ff00ff;
dOddBytes <<= 8;
dag |= drb;
argb = dag;
}
/** Copies another pixel colour over this one.
This doesn't blend it - this colour is simply replaced by the other one.
*/
template <class Pixel>
forcedinline void set (const Pixel& src) noexcept
{
argb = src.getARGB();
dOddBytes |= dEvenBytes;
internal = dOddBytes;
}
//==============================================================================
/** Replaces the colour's alpha value with another one. */
forcedinline void setAlpha (const uint8 newAlpha) noexcept
{
@@ -177,10 +218,12 @@ public:
/** Multiplies the colour's alpha value with another one. */
forcedinline void multiplyAlpha (int multiplier) noexcept
{
// increment alpha by 1, so that if multiplier == 255 (full alpha),
// this function will not change the values.
++multiplier;
argb = ((((uint32) multiplier) * getAG()) & 0xff00ff00)
| (((((uint32) multiplier) * getRB()) >> 8) & 0x00ff00ff);
internal = ((((uint32) multiplier) * getOddBytes()) & 0xff00ff00)
| (((((uint32) multiplier) * getEvenBytes()) >> 8) & 0x00ff00ff);
}
forcedinline void multiplyAlpha (const float multiplier) noexcept
@@ -188,14 +231,8 @@ public:
multiplyAlpha ((int) (multiplier * 255.0f));
}
/** Sets the pixel's colour from individual components. */
void setARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) noexcept
{
components.b = b;
components.g = g;
components.r = r;
components.a = a;
}
inline PixelARGB getUnpremultiplied() const noexcept { PixelARGB p (internal); p.unpremultiply(); return p; }
/** Premultiplies the pixel's RGB values by its alpha. */
forcedinline void premultiply() noexcept
@@ -257,41 +294,53 @@ public:
}
}
/** Returns a uint32 which when written to memory, will be in the order r, g, b, a. */
inline uint32 getInRGBAMemoryOrder() const noexcept
{
#if JUCE_BIG_ENDIAN
return (((uint32) components.r) << 24) | (((uint32) components.g) << 16) | (((uint32) components.b) << 8) | components.a;
#else
return (((uint32) components.a) << 24) | (((uint32) components.b) << 16) | (((uint32) components.g) << 8) | components.r;
#endif
}
//==============================================================================
/** The indexes of the different components in the byte layout of this type of colour. */
#if JUCE_ANDROID
#if JUCE_BIG_ENDIAN
enum { indexA = 0, indexR = 3, indexG = 2, indexB = 1 };
#else
enum { indexA = 3, indexR = 0, indexG = 1, indexB = 2 };
#endif
#else
#if JUCE_BIG_ENDIAN
enum { indexA = 0, indexR = 1, indexG = 2, indexB = 3 };
#else
enum { indexA = 3, indexR = 2, indexG = 1, indexB = 0 };
#endif
#endif
private:
//==============================================================================
PixelARGB (const uint32 internalValue) noexcept
: internal (internalValue)
{
}
//==============================================================================
struct Components
{
#if JUCE_ANDROID
#if JUCE_BIG_ENDIAN
uint8 a, b, g, r;
#else
uint8 r, g, b, a;
#endif
#else
#if JUCE_BIG_ENDIAN
uint8 a, r, g, b;
#else
uint8 b, g, r, a;
#endif
#endif
} JUCE_PACKED;
union
{
uint32 argb;
uint32 internal;
Components components;
#if JUCE_GCC
uint8 comps[4];
uint8 comps[4]; // helper struct needed because gcc does not allow references to packed union members
#endif
};
}
@@ -316,23 +365,64 @@ public:
PixelRGB() noexcept {}
~PixelRGB() noexcept {}
/** Creates a pixel from a 32-bit argb value.
//==============================================================================
/** Returns a uint32 which represents the pixel in a platform dependent format which is compatible
with the native format of a PixelARGB.
(The argb format is that used by PixelARGB)
*/
PixelRGB (const uint32 argb) noexcept
@see PixelARGB::getNativeARGB */
forcedinline uint32 getNativeARGB() const noexcept
{
#if JUCE_ANDROID
return (uint32) ((0xff << 24) | r | (g << 8) | (b << 16));
#else
return (uint32) ((0xff << 24) | b | (g << 8) | (r << 16));
#endif
}
/** Returns a uint32 which will be in argb order as if constructed with the following mask operation
((alpha << 24) | (red << 16) | (green << 8) | blue). */
forcedinline uint32 getInARGBMaskOrder() const noexcept
{
#if JUCE_ANDROID
return (uint32) ((0xff << 24) | (r << 16) | (g << 8) | (b << 0));
#else
return getNativeARGB();
#endif
}
/** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
inline uint32 getInARGBMemoryOrder() const noexcept
{
r = (uint8) (argb >> 16);
g = (uint8) (argb >> 8);
b = (uint8) (argb);
#if JUCE_BIG_ENDIAN
return getInARGBMaskOrder();
#else
return (uint32) ((b << 24) | (g << 16) | (r << 8) | 0xff);
#endif
}
forcedinline uint32 getARGB() const noexcept { return 0xff000000 | b | (((uint32) g) << 8) | (((uint32) r) << 16); }
forcedinline uint32 getUnpremultipliedARGB() const noexcept { return getARGB(); }
/** Return channels with an even index and insert zero bytes between them. This is useful for blending
operations. The exact channels which are returned is platform dependent but compatible with the
return value of getEvenBytes of the PixelARGB class.
forcedinline uint32 getRB() const noexcept { return b | (uint32) (r << 16); }
forcedinline uint32 getAG() const noexcept { return (uint32) (0xff0000 | g); }
@see PixelARGB::getEvenBytes */
forcedinline uint32 getEvenBytes() const noexcept
{
#if JUCE_ANDROID
return (uint32) (r | (b << 16));
#else
return (uint32) (b | (r << 16));
#endif
}
/** Return channels with an odd index and insert zero bytes between them. This is useful for blending
operations. The exact channels which are returned is platform dependent but compatible with the
return value of getOddBytes of the PixelARGB class.
@see PixelARGB::getOddBytes */
forcedinline uint32 getOddBytes() const noexcept { return (uint32)0xff0000 | g; }
//==============================================================================
forcedinline uint8 getAlpha() const noexcept { return 0xff; }
forcedinline uint8 getRed() const noexcept { return r; }
forcedinline uint8 getGreen() const noexcept { return g; }
@@ -342,6 +432,30 @@ public:
forcedinline uint8& getGreen() noexcept { return g; }
forcedinline uint8& getBlue() noexcept { return b; }
//==============================================================================
/** Copies another pixel colour over this one.
This doesn't blend it - this colour is simply replaced by the other one.
Because PixelRGB has no alpha channel, any alpha value in the source pixel
is thrown away.
*/
template <class Pixel>
forcedinline void set (const Pixel& src) noexcept
{
b = src.getBlue();
g = src.getGreen();
r = src.getRed();
}
/** Sets the pixel's colour from individual components. */
void setARGB (const uint8, const uint8 red, const uint8 green, const uint8 blue) noexcept
{
r = red;
g = green;
b = blue;
}
//==============================================================================
/** Blends another pixel onto this one.
This takes into account the opacity of the pixel being overlaid, and blends
@@ -352,12 +466,20 @@ public:
{
const uint32 alpha = (uint32) (0x100 - src.getAlpha());
uint32 rb = clampPixelComponents (src.getRB() + maskPixelComponents (getRB() * alpha));
uint32 ag = src.getAG() + (g * alpha >> 8);
// getEvenBytes returns 0x00rr00bb on non-android
uint32 rb = clampPixelComponents (src.getEvenBytes() + maskPixelComponents (getEvenBytes() * alpha));
// getOddBytes returns 0x00aa00gg on non-android
uint32 ag = clampPixelComponents (src.getOddBytes() + ((g * alpha) >> 8));
g = (uint8) (ag & 0xff);
#if JUCE_ANDROID
b = (uint8) (rb >> 16);
r = (uint8) (rb & 0xff);
#else
r = (uint8) (rb >> 16);
g = (uint8) clampPixelComponents (ag);
b = (uint8) rb;
b = (uint8) (rb & 0xff);
#endif
}
forcedinline void blend (const PixelRGB src) noexcept
@@ -373,16 +495,23 @@ public:
template <class Pixel>
forcedinline void blend (const Pixel& src, uint32 extraAlpha) noexcept
{
uint32 ag = maskPixelComponents (extraAlpha * src.getAG());
uint32 ag = maskPixelComponents (extraAlpha * src.getOddBytes());
uint32 rb = maskPixelComponents (extraAlpha * src.getEvenBytes());
const uint32 alpha = 0x100 - (ag >> 16);
ag += g * alpha >> 8;
uint32 rb = clampPixelComponents (maskPixelComponents (extraAlpha * src.getRB())
+ maskPixelComponents (getRB() * alpha));
ag = clampPixelComponents (ag + (g * alpha >> 8));
rb = clampPixelComponents (rb + maskPixelComponents (getEvenBytes() * alpha));
b = (uint8) rb;
g = (uint8) clampPixelComponents (ag);
g = (uint8) (ag & 0xff);
#if JUCE_ANDROID
b = (uint8) (rb >> 16);
r = (uint8) (rb & 0xff);
#else
r = (uint8) (rb >> 16);
b = (uint8) (rb & 0xff);
#endif
}
/** Blends another pixel with this one, creating a colour that is somewhere
@@ -391,31 +520,24 @@ public:
template <class Pixel>
forcedinline void tween (const Pixel& src, const uint32 amount) noexcept
{
uint32 drb = getRB();
drb += (((src.getRB() - drb) * amount) >> 8);
uint32 dEvenBytes = getEvenBytes();
dEvenBytes += (((src.getEvenBytes() - dEvenBytes) * amount) >> 8);
uint32 dag = getAG();
dag += (((src.getAG() - dag) * amount) >> 8);
uint32 dOddBytes = getOddBytes();
dOddBytes += (((src.getOddBytes() - dOddBytes) * amount) >> 8);
b = (uint8) drb;
g = (uint8) dag;
r = (uint8) (drb >> 16);
}
g = (uint8) (dOddBytes & 0xff); // dOddBytes = 0x00aa00gg
/** Copies another pixel colour over this one.
This doesn't blend it - this colour is simply replaced by the other one.
Because PixelRGB has no alpha channel, any alpha value in the source pixel
is thrown away.
*/
template <class Pixel>
forcedinline void set (const Pixel& src) noexcept
{
b = src.getBlue();
g = src.getGreen();
r = src.getRed();
#if JUCE_ANDROID
r = (uint8) (dEvenBytes & 0xff); // dEvenBytes = 0x00bb00rr
b = (uint8) (dEvenBytes >> 16);
#else
b = (uint8) (dEvenBytes & 0xff); // dEvenBytes = 0x00rr00bb
r = (uint8) (dEvenBytes >> 16);
#endif
}
//==============================================================================
/** This method is included for compatibility with the PixelARGB class. */
forcedinline void setAlpha (const uint8) noexcept {}
@@ -425,14 +547,6 @@ public:
/** Multiplies the colour's alpha value with another one. */
forcedinline void multiplyAlpha (float) noexcept {}
/** Sets the pixel's colour from individual components. */
void setARGB (const uint8, const uint8 red, const uint8 green, const uint8 blue) noexcept
{
r = red;
g = green;
b = blue;
}
/** Premultiplies the pixel's RGB values by its alpha. */
forcedinline void premultiply() noexcept {}
@@ -454,6 +568,20 @@ public:
private:
//==============================================================================
PixelRGB (const uint32 internal) noexcept
{
#if JUCE_ANDROID
b = (uint8) (internal >> 16);
g = (uint8) (internal >> 8);
r = (uint8) (internal);
#else
r = (uint8) (internal >> 16);
g = (uint8) (internal >> 8);
b = (uint8) (internal);
#endif
}
//==============================================================================
#if JUCE_MAC
uint8 r, g, b;
#else
@@ -486,21 +614,36 @@ public:
PixelAlpha() noexcept {}
~PixelAlpha() noexcept {}
/** Creates a pixel from a 32-bit argb value.
//==============================================================================
/** Returns a uint32 which represents the pixel in a platform dependent format which is compatible
with the native format of a PixelARGB.
(The argb format is that used by PixelARGB)
*/
PixelAlpha (const uint32 argb) noexcept
{
a = (uint8) (argb >> 24);
}
@see PixelARGB::getNativeARGB */
forcedinline uint32 getNativeARGB() const noexcept { return (uint32) ((a << 24) | (a << 16) | (a << 8) | a); }
/** Returns a uint32 which will be in argb order as if constructed with the following mask operation
((alpha << 24) | (red << 16) | (green << 8) | blue). */
forcedinline uint32 getInARGBMaskOrder() const noexcept { return getNativeARGB(); }
/** Returns a uint32 which when written to memory, will be in the order a, r, g, b. In other words,
if the return-value is read as a uint8 array then the elements will be in the order of a, r, g, b*/
inline uint32 getInARGBMemoryOrder() const noexcept { return getNativeARGB(); }
forcedinline uint32 getARGB() const noexcept { return (((uint32) a) << 24) | (((uint32) a) << 16) | (((uint32) a) << 8) | a; }
forcedinline uint32 getUnpremultipliedARGB() const noexcept { return (((uint32) a) << 24) | 0xffffff; }
/** Return channels with an even index and insert zero bytes between them. This is useful for blending
operations. The exact channels which are returned is platform dependent but compatible with the
return value of getEvenBytes of the PixelARGB class.
forcedinline uint32 getRB() const noexcept { return (((uint32) a) << 16) | a; }
forcedinline uint32 getAG() const noexcept { return (((uint32) a) << 16) | a; }
@see PixelARGB::getEvenBytes */
forcedinline uint32 getEvenBytes() const noexcept { return (uint32) ((a << 16) | a); }
/** Return channels with an odd index and insert zero bytes between them. This is useful for blending
operations. The exact channels which are returned is platform dependent but compatible with the
return value of getOddBytes of the PixelARGB class.
@see PixelARGB::getOddBytes */
forcedinline uint32 getOddBytes() const noexcept { return (uint32) ((a << 16) | a); }
//==============================================================================
forcedinline uint8 getAlpha() const noexcept { return a; }
forcedinline uint8& getAlpha() noexcept { return a; }
@@ -508,6 +651,24 @@ public:
forcedinline uint8 getGreen() const noexcept { return 0; }
forcedinline uint8 getBlue() const noexcept { return 0; }
//==============================================================================
/** Copies another pixel colour over this one.
This doesn't blend it - this colour is simply replaced by the other one.
*/
template <class Pixel>
forcedinline void set (const Pixel& src) noexcept
{
a = src.getAlpha();
}
/** Sets the pixel's colour from individual components. */
forcedinline void setARGB (const uint8 a_, const uint8 /*r*/, const uint8 /*g*/, const uint8 /*b*/) noexcept
{
a = a_;
}
//==============================================================================
/** Blends another pixel onto this one.
This takes into account the opacity of the pixel being overlaid, and blends
@@ -542,16 +703,7 @@ public:
a += ((src.getAlpha() - a) * amount) >> 8;
}
/** Copies another pixel colour over this one.
This doesn't blend it - this colour is simply replaced by the other one.
*/
template <class Pixel>
forcedinline void set (const Pixel& src) noexcept
{
a = src.getAlpha();
}
//==============================================================================
/** Replaces the colour's alpha value with another one. */
forcedinline void setAlpha (const uint8 newAlpha) noexcept
{
@@ -570,12 +722,6 @@ public:
a = (uint8) (a * multiplier);
}
/** Sets the pixel's colour from individual components. */
forcedinline void setARGB (const uint8 a_, const uint8 /*r*/, const uint8 /*g*/, const uint8 /*b*/) noexcept
{
a = a_;
}
/** Premultiplies the pixel's RGB values by its alpha. */
forcedinline void premultiply() noexcept {}
@@ -589,6 +735,12 @@ public:
enum { indexA = 0 };
private:
//==============================================================================
PixelAlpha (const uint32 internal) noexcept
{
a = (uint8) (internal >> 24);
}
//==============================================================================
uint8 a;
}


+ 2
- 2
modules/juce_graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp View File

@@ -433,11 +433,11 @@ void LowLevelGraphicsPostScriptRenderer::writeImage (const Image& im,
{
PixelARGB p (*(const PixelARGB*) pixelData);
p.unpremultiply();
pixel = Colours::white.overlaidWith (Colour (p.getARGB()));
pixel = Colours::white.overlaidWith (Colour (p));
}
else if (im.isRGB())
{
pixel = Colour (((const PixelRGB*) pixelData)->getARGB());
pixel = Colour (*((const PixelRGB*) pixelData));
}
else
{


+ 3
- 3
modules/juce_graphics/images/juce_Image.cpp View File

@@ -407,9 +407,9 @@ Colour Image::BitmapData::getPixelColour (const int x, const int y) const noexce
switch (pixelFormat)
{
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());
case Image::ARGB: return Colour ( ((const PixelARGB*) pixel)->getUnpremultiplied());
case Image::RGB: return Colour (*((const PixelRGB*) pixel));
case Image::SingleChannel: return Colour (*((const PixelAlpha*) pixel));
default: jassertfalse; break;
}


+ 3
- 3
modules/juce_gui_basics/native/juce_android_Windowing.cpp View File

@@ -413,7 +413,7 @@ public:
}
//==============================================================================
void handlePaintCallback (JNIEnv* env, jobject canvas)
void handlePaintCallback (JNIEnv* env, jobject canvas, jobject paint)
{
jobject rect = env->CallObjectMethod (canvas, CanvasMinimal.getClipBounds);
const int left = env->GetIntField (rect, RectClass.left);
@@ -449,7 +449,7 @@ public:
env->CallVoidMethod (canvas, CanvasMinimal.drawBitmap, (jintArray) buffer.get(), 0, clip.getWidth(),
(jfloat) clip.getX(), (jfloat) clip.getY(),
clip.getWidth(), clip.getHeight(), true, (jobject) 0);
clip.getWidth(), clip.getHeight(), true, paint);
}
}
@@ -575,7 +575,7 @@ int64 AndroidComponentPeer::touchesDown = 0;
peer->juceMethodInvocation; \
}
JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject view, jlong host, jobject canvas), handlePaintCallback (env, canvas))
JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject view, jlong host, jobject canvas, jobject paint), handlePaintCallback (env, canvas, paint))
JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point<float> ((float) x, (float) y), (int64) time))


+ 4
- 0
modules/juce_opengl/native/juce_OpenGL_android.h View File

@@ -49,6 +49,10 @@ public:
contextList.add (this);
}
Rectangle<int> bounds = component.getTopLevelComponent()
->getLocalArea (&component, component.getLocalBounds());
bounds *= component.getDesktopScaleFactor();
updateWindowPosition (component.getTopLevelComponent()
->getLocalArea (&component, component.getLocalBounds()));
}


+ 8
- 1
modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp View File

@@ -1162,7 +1162,14 @@ struct StateHelpers
v[1].x = v[3].x = (GLshort) (x + w);
v[2].y = v[3].y = (GLshort) (y + h);
const GLuint rgba = colour.getInRGBAMemoryOrder();
#if JUCE_BIG_ENDIAN
const GLuint rgba = (GLuint) ((colour.getRed() << 24) | (colour.getGreen() << 16)
| (colour.getBlue() << 8) | colour.getAlpha());
#else
const GLuint rgba = (GLuint) ((colour.getAlpha() << 24) | (colour.getBlue() << 16)
| (colour.getGreen() << 8) | colour.getRed());
#endif
v[0].colour = rgba;
v[1].colour = rgba;
v[2].colour = rgba;


+ 0
- 8
modules/juce_opengl/opengl/juce_OpenGLTexture.cpp View File

@@ -110,15 +110,7 @@ struct Flipper
PixelARGB* const dst = (PixelARGB*) (dataCopy + w * (h - 1 - y));
for (int x = 0; x < w; ++x)
{
#if JUCE_ANDROID
PixelType s (src[x]);
dst[x].setARGB (s.getAlpha(), s.getBlue(), s.getGreen(), s.getRed());
#else
dst[x].set (src[x]);
#endif
}
srcData += lineStride;
}


Loading…
Cancel
Save