1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-19 01:04:20 +00:00

Fixed an image anti-aliasing problem. Created some new methods in AudioIODeviceType to create device-specific types. Tidied up some win32 DLL build problems. Added support for drag-and-drop from iTunes on mac.

This commit is contained in:
Julian Storer 2011-02-04 12:20:04 +00:00
parent c26ac47dff
commit 571a2626da
27 changed files with 1095 additions and 413 deletions

View file

@ -34,8 +34,11 @@ class AndroidLowLevelGraphicsContext : public LowLevelGraphicsContext
{
public:
AndroidLowLevelGraphicsContext (const GlobalRef& canvas_)
: canvas (canvas_)
: canvas (canvas_),
currentState (new SavedState()),
{
paintStack.add (new GlobalRef());
setFill (Colours::black);
}
~AndroidLowLevelGraphicsContext()
@ -47,10 +50,12 @@ public:
//==============================================================================
void setOrigin (int x, int y)
{
canvas.callVoidMethod (android.translate, (float) x, (float) y);
}
void addTransform (const AffineTransform& transform)
{
canvas.callVoidMethod (android.concat, createMatrix (canvas.getEnv(), transform));
}
float getScaleFactor()
@ -60,12 +65,12 @@ public:
bool clipToRectangle (const Rectangle<int>& r)
{
return true;
return canvas.callBooleanMethod (android.clipRect, (float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom());
}
bool clipToRectangleList (const RectangleList& clipRegion)
{
return true;
return canvas.callBooleanMethod (android.clipRegion, createRegion (canvas.getEnv(), clipRegion));
}
void excludeClipRectangle (const Rectangle<int>& r)
@ -74,6 +79,7 @@ public:
void clipToPath (const Path& path, const AffineTransform& transform)
{
(void) canvas.callBooleanMethod (android.clipPath, createPath (canvas.getEnv(), path, transform));
}
void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform)
@ -82,40 +88,31 @@ public:
bool clipRegionIntersects (const Rectangle<int>& r)
{
return true;
return getClipBounds().intersects (r);
}
const Rectangle<int> getClipBounds() const
{
return Rectangle<int> (0, 0, 1000, 1000);
jobject rect = canvas.callObjectMethod (android.getClipBounds2);
const int left = canvas.getEnv()->GetIntField (rect, android.rectLeft);
const int top = canvas.getEnv()->GetIntField (rect, android.rectTop);
const int right = canvas.getEnv()->GetIntField (rect, android.rectRight);
const int bottom = canvas.getEnv()->GetIntField (rect, android.rectBottom);
return Rectangle<int> (left, top, right - left, bottom - top);
}
bool isClipEmpty() const
{
return false;
}
void saveState()
{
}
void restoreState()
{
}
void beginTransparencyLayer (float opacity)
{
}
void endTransparencyLayer()
{
return ! canvas.callBooleanMethod (android.getClipBounds,
canvas.getEnv()->NewObject (android.rectClass, android.rectConstructor, 0, 0, 0, 0));
}
//==============================================================================
void setFill (const FillType& fillType)
{
currentPaint = android.env->NewObject (android.paintClass, android.paintClassConstructor);
currentPaint.callVoidMethod (android.setColor, fillType.colour.getARGB());
currentState->setFillType (fillType);
}
void setOpacity (float newOpacity)
@ -131,11 +128,13 @@ public:
{
canvas.callVoidMethod (android.drawRect,
(float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom(),
currentPaint.get());
getCurrentPaint().get());
}
void fillPath (const Path& path, const AffineTransform& transform)
{
canvas.callVoidMethod (android.drawPath, createPath (canvas.getEnv(), path, transform),
getCurrentPaint().get());
}
void drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles)
@ -144,14 +143,19 @@ public:
void drawLine (const Line <float>& line)
{
canvas.callVoidMethod (android.drawLine, line.getStartX(), line.getStartY(),
line.getEndX(), line.getEndY(),
getCurrentPaint().get());
}
void drawVerticalLine (int x, float top, float bottom)
{
canvas.callVoidMethod (android.drawRect, (float) x, top, x + 1.0f, bottom, getCurrentPaint().get());
}
void drawHorizontalLine (int y, float left, float right)
{
canvas.callVoidMethod (android.drawRect, left, (float) y, right, y + 1.0f, getCurrentPaint().get());
}
void setFont (const Font& newFont)
@ -167,8 +171,212 @@ public:
{
}
//==============================================================================
void saveState()
{
(void) canvas.callIntMethod (android.save);
stateStack.add (new SavedState (*currentState));
}
void restoreState()
{
canvas.callVoidMethod (android.restore);
SavedState* const top = stateStack.getLast();
if (top != 0)
{
currentState = top;
stateStack.removeLast (1, false);
}
else
{
jassertfalse; // trying to pop with an empty stack!
}
}
void beginTransparencyLayer (float opacity)
{
}
void endTransparencyLayer()
{
}
class SavedState
{
public:
SavedState()
: font (1.0f), needsUpdate (true)
{
}
SavedState (const SavedState& other)
: fillType (other.fillType), font (other.font), needsUpdate (true)
{
}
void setFillType (const FillType& newType)
{
needsUpdate = true;
fillType = newType;
}
jobject getPaint (JNIEnv* env)
{
if (needsUpdate)
{
if (paint.get() == 0)
paint = GlobalRef (env, env->NewObject (android.paintClass, android.paintClassConstructor));
if (fillType.isColour())
{
paint.callVoidMethod (android.setShader, (jobject) 0);
paint.callVoidMethod (android.setColor, colourToInt (fillType.colour));
}
else if (fillType.isGradient())
{
const ColourGradient& g = fillType.gradient;
const Point<float> p1 (g.point1);
const Point<float> p2 (g.point2);
const int numColours = g.getNumColours();
jintArray coloursArray = env->NewIntArray (numColours);
jfloatArray positionsArray = env->NewFloatArray (numColours);
{
HeapBlock<int> colours (numColours);
HeapBlock<float> positions (numColours);
for (int i = 0; i < numColours; ++i)
{
colours[i] = g.getColour (i);
positions[i] = (float) g.getColourPosition(i);
}
env->SetIntArrayRegion (coloursArray, 0, numColours, colours.getData());
env->SetFloatArrayRegion (positionsArray, 0, numColours, positions.getData());
}
jobject tileMode = xxxx
jobject shader;
if (fillType.gradient->isRadial)
{
shader = env->NewObject (android.radialGradientClass,
android.radialGradientConstructor,
p1.getX(), p1.getY(),
p1.getDistanceFrom (p2),
coloursArray, positionsArray,
tileMode));
}
else
{
shader = env->NewObject (android.linearGradientClass,
android.linearGradientConstructor,
p1.getX(), p1.getY(), p2.getX(), p2.getY(),
coloursArray, positionsArray,
tileMode));
}
env->CallVoidMethod (shader, android.setLocalMatrix, createMatrix (fillType.transform));
paint.callVoidMethod (android.setShader, shader);
}
else
{x
}
}
return paint.get();
}
private:
FillType fillType;
Font font;
GlobalRef paint;
bool needsUpdate;
};
private:
GlobalRef canvas, currentPaint;
GlobalRef canvas;
ScopedPointer <SavedState> currentState;
OwnedArray <SavedState> stateStack;
GlobalRef& getCurrentPaint() throw() { return *paintStack.getUnchecked (paintStack.size() - 1); }
static jobject createPath (JNIEnv* env, const Path& path)
{
jobject p = env->NewObject (android.pathClass, android.pathClassConstructor);
Path::Iterator i (path);
while (i.next())
{
switch (i.elementType)
{
case Path::Iterator::startNewSubPath: env->CallVoidMethod (p, android.moveTo, i.x1, i.y1); break;
case Path::Iterator::lineTo: env->CallVoidMethod (p, android.lineTo, i.x1, i.y1); break;
case Path::Iterator::quadraticTo: env->CallVoidMethod (p, android.quadTo, i.x1, i.y1, i.x2, i.y2); break;
case Path::Iterator::cubicTo: env->CallVoidMethod (p, android.cubicTo, i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); break;
case Path::Iterator::closePath: env->CallVoidMethod (p, android.closePath); break;
default: jassertfalse; break;
}
}
return p;
}
static jobject createPath (JNIEnv* env, const Path& path, const AffineTransform& transform)
{
if (transform.isIdentity())
return createPath (env, path);
Path tempPath (path);
tempPath.applyTransform (transform);
return createPath (env, tempPath);
}
static jobject createMatrix (JNIEnv* env, const AffineTransform& t)
{
jobject m = env->NewObject (android.matrixClass, android.matrixClassConstructor);
jfloat values[9] = { t.mat00, t.mat01, t.mat02,
t.mat10, t.mat11, t.mat12,
0.0f, 0.0f, 1.0f };
jfloatArray javaArray = env->NewFloatArray (9);
env->SetFloatArrayRegion (javaArray, 0, 9, values);
env->CallVoidMethod (m, android.setValues, javaArray);
env->DeleteLocalRef (javaArray);
return m;
}
static jobject createRect (JNIEnv* env, const Rectangle<int>& r)
{
return env->NewObject (android.rectClass, android.rectConstructor,
r.getX(), r.getY(), r.getRight(), r.getBottom());
}
static jobject createRegion (JNIEnv* env, const RectangleList& list)
{
jobject region = env->NewObject (android.regionClass, android.regionConstructor);
const int numRects = list.getNumRectangles();
for (int i = 0; i < numRects; ++i)
env->CallVoidMethod (region, android.regionUnion, createRect (env, list.getRectangle(i)));
return region;
}
static int colourToInt (const Colour& col) throw()
{
return col.getARGB();
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidLowLevelGraphicsContext);
};