From ed6acb6956fcb8f21959c037592625cc550d140e Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Sun, 6 Feb 2011 18:52:50 +0000 Subject: [PATCH] Misc Android development. --- juce_amalgamated.cpp | 197 ++++++++++++++---- juce_amalgamated.h | 4 +- src/core/juce_PlatformUtilities.h | 2 +- src/core/juce_StandardHeader.h | 2 +- .../android/java/ComponentPeerView.java | 2 - src/native/android/java/JuceAppActivity.java | 14 ++ src/native/android/juce_android_Fonts.cpp | 88 ++++++-- .../android/juce_android_GraphicsContext.cpp | 66 ++++-- src/native/android/juce_android_Misc.cpp | 11 +- .../android/juce_android_NativeCode.cpp | 31 ++- src/native/android/juce_android_Windowing.cpp | 1 - 11 files changed, 322 insertions(+), 96 deletions(-) diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 71a77bfd2b..7f070e2bef 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -278666,6 +278666,7 @@ BEGIN_JUCE_NAMESPACE JAVACLASS (rectClass, "android/graphics/Rect") \ JAVACLASS (regionClass, "android/graphics/Region") \ JAVACLASS (shaderClass, "android/graphics/Shader") \ + JAVACLASS (typefaceClass, "android/graphics/Typeface") \ JAVACLASS (shaderTileModeClass, "android/graphics/Shader$TileMode") \ JAVACLASS (linearGradientClass, "android/graphics/LinearGradient") \ JAVACLASS (radialGradientClass, "android/graphics/RadialGradient") \ @@ -278676,6 +278677,8 @@ BEGIN_JUCE_NAMESPACE METHOD (activityClass, createNewView, "createNewView", "()Lcom/juce/ComponentPeerView;") \ METHOD (activityClass, deleteView, "deleteView", "(Lcom/juce/ComponentPeerView;)V") \ METHOD (activityClass, postMessage, "postMessage", "(J)V") \ + METHOD (activityClass, getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \ + METHOD (activityClass, setClipboardContent, "setClipboardContent", "(Ljava/lang/String;)V") \ \ METHOD (fileClass, fileExists, "exists", "()Z") \ \ @@ -278702,6 +278705,7 @@ BEGIN_JUCE_NAMESPACE METHOD (canvasClass, drawBitmap, "drawBitmap", "(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/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") \ METHOD (canvasClass, getClipBounds, "getClipBounds", "(Landroid/graphics/Rect;)Z") \ METHOD (canvasClass, getClipBounds2, "getClipBounds", "()Landroid/graphics/Rect;") \ METHOD (canvasClass, getMatrix, "getMatrix", "()Landroid/graphics/Matrix;") \ @@ -278709,10 +278713,15 @@ BEGIN_JUCE_NAMESPACE METHOD (canvasClass, restore, "restore", "()V") \ METHOD (canvasClass, saveLayerAlpha, "saveLayerAlpha", "(FFFFII)I") \ \ - METHOD (paintClass, paintClassConstructor, "", "()V") \ + METHOD (paintClass, paintClassConstructor, "", "(I)V") \ METHOD (paintClass, setColor, "setColor", "(I)V") \ METHOD (paintClass, setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \ - METHOD (paintClass, setAntiAlias, "setAntiAlias", "(Z)V") \ + 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;") \ @@ -278726,6 +278735,8 @@ BEGIN_JUCE_NAMESPACE \ METHOD (matrixClass, matrixClassConstructor, "", "()V") \ METHOD (matrixClass, setValues, "setValues", "([F)V") \ +\ + STATICMETHOD (typefaceClass, create, "create", "(Ljava/lang/String;I)Landroid/graphics/Typeface;") \ \ METHOD (rectClass, rectConstructor, "", "(IIII)V") \ FIELD (rectClass, rectLeft, "left", "I") \ @@ -278972,6 +278983,13 @@ static const LocalRef javaString (const String& s) return LocalRef (getEnv()->NewStringUTF (s.toUTF8())); } +static const LocalRef javaStringFromChar (const juce_wchar c) +{ + char utf8[5] = { 0 }; + CharPointer_UTF8 (utf8).write (c); + return LocalRef (getEnv()->NewStringUTF (utf8)); +} + class AndroidJavaCallbacks { public: @@ -279030,6 +279048,15 @@ public: String appFile, appDataDir; int screenWidth, screenHeight; + jobject createPaint() + { + const jint constructorFlags = 1 /*ANTI_ALIAS_FLAG*/ + | 2 /*FILTER_BITMAP_FLAG*/ + | 4 /*DITHER_FLAG*/ + | 128 /*SUBPIXEL_TEXT_FLAG*/; + return getEnv()->NewObject (paintClass, paintClassConstructor, constructorFlags); + } + #define DECLARE_JNI_CLASS(className, path) jclass className; JUCE_JNI_CLASSES (DECLARE_JNI_CLASS); #undef DECLARE_JNI_CLASS @@ -279078,7 +279105,6 @@ JUCE_JNI_CALLBACK (JuceAppActivity, quitApp, void, (JNIEnv* env, jobject activit void PlatformUtilities::beep() { - // TODO } void Logger::outputDebugString (const String& text) @@ -279089,16 +279115,14 @@ void Logger::outputDebugString (const String& text) void SystemClipboard::copyTextToClipboard (const String& text) { - // TODO + const LocalRef t (javaString (text)); + android.activity.callVoidMethod (android.setClipboardContent, t.get()); } const String SystemClipboard::getTextFromClipboard() { - String result; - - // TODO - - return result; + const LocalRef text ((jstring) android.activity.callObjectMethod (android.getClipboardContent)); + return juceString (text); } #endif @@ -280688,48 +280712,95 @@ const StringArray Font::findAllTypefaceNames() { StringArray results; - // TODO + Array fonts; + File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, "*.ttf"); + + for (int i = 0; i < fonts.size(); ++i) + results.add (fonts.getReference(i).getFileNameWithoutExtension()); return results; } void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback) { - // TODO - defaultSans = "Verdana"; - defaultSerif = "Times"; - defaultFixed = "Lucida Console"; - defaultFallback = "Tahoma"; + defaultSans = "sans"; + defaultSerif = "serif"; + defaultFixed = "monospace"; + defaultFallback = "sans"; } class AndroidTypeface : public Typeface { public: AndroidTypeface (const Font& font) - : Typeface (font.getTypefaceName()) + : Typeface (font.getTypefaceName()), + ascent (0), + descent (0) { - // TODO - } + jint flags = 0; + if (font.isBold()) flags = 1; + if (font.isItalic()) flags += 2; - float getAscent() const - { - return 0; // TODO - } + typeface = GlobalRef (getEnv()->CallStaticObjectMethod (android.typefaceClass, android.create, + javaString (getName()).get(), flags)); - float getDescent() const - { - return 0; // TODO + paint = GlobalRef (android.createPaint()); + const LocalRef ignored (paint.callObjectMethod (android.setTypeface, typeface.get())); + + const float standardSize = 256.0f; + paint.callVoidMethod (android.setTextSize, standardSize); + ascent = std::abs (paint.callFloatMethod (android.ascent)) / standardSize; + descent = paint.callFloatMethod (android.descent) / standardSize; + + const float height = ascent + descent; + unitsToHeightScaleFactor = 1.0f / (height * standardSize); } + float getAscent() const { return ascent; } + float getDescent() const { return descent; } + float getStringWidth (const String& text) { - // TODO - return 0; + JNIEnv* env = getEnv(); + const int numChars = text.length(); + jfloatArray widths = env->NewFloatArray (numChars); + + const int numDone = paint.callIntMethod (android.getTextWidths, javaString (text).get(), widths); + + HeapBlock localWidths (numDone); + env->GetFloatArrayRegion (widths, 0, numDone, localWidths); + env->DeleteLocalRef (widths); + + float x = 0; + for (int i = 0; i < numDone; ++i) + x += localWidths[i]; + + return x * unitsToHeightScaleFactor; } void getGlyphPositions (const String& text, Array& glyphs, Array& xOffsets) { - // TODO + JNIEnv* env = getEnv(); + const int numChars = text.length(); + jfloatArray widths = env->NewFloatArray (numChars); + + const int numDone = paint.callIntMethod (android.getTextWidths, javaString (text).get(), widths); + + HeapBlock localWidths (numDone); + env->GetFloatArrayRegion (widths, 0, numDone, localWidths); + env->DeleteLocalRef (widths); + + String::CharPointerType s (text.getCharPointer()); + + xOffsets.add (0); + + float x = 0; + for (int i = 0; i < numDone; ++i) + { + glyphs.add ((int) s.getAndAdvance()); + x += localWidths[i]; + xOffsets.add (x * unitsToHeightScaleFactor); + } } bool getOutlineForGlyph (int glyphNumber, Path& destPath) @@ -280738,6 +280809,9 @@ public: return false; } + GlobalRef typeface, paint; + float ascent, descent, unitsToHeightScaleFactor; + private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidTypeface); }; @@ -280818,12 +280892,13 @@ public: const Rectangle getClipBounds() const { JNIEnv* env = getEnv(); - const LocalRef rect (canvas.callObjectMethod (android.getClipBounds2)); + jobject rect = canvas.callObjectMethod (android.getClipBounds2); const int left = env->GetIntField (rect, android.rectLeft); const int top = env->GetIntField (rect, android.rectTop); const int right = env->GetIntField (rect, android.rectRight); const int bottom = env->GetIntField (rect, android.rectBottom); + env->DeleteLocalRef (rect); return Rectangle (left, top, right - left, bottom - top); } @@ -280883,22 +280958,39 @@ public: void setFont (const Font& newFont) { + if (currentState->font != newFont) + { + currentState->font = newFont; + currentState->typefaceNeedsUpdate = true; + } } const Font getFont() { - return Font(); + return currentState->font; } void drawGlyph (int glyphNumber, const AffineTransform& transform) { + if (transform.isOnlyTranslation()) + { + canvas.callVoidMethod (android.drawText, javaStringFromChar ((juce_wchar) glyphNumber).get(), + transform.getTranslationX(), transform.getTranslationY(), + currentState->getPaintForTypeface()); + } + else + { + saveState(); + addTransform (transform); + drawGlyph (glyphNumber, AffineTransform::identity); + restoreState(); + } } void saveState() { (void) canvas.callIntMethod (android.save); stateStack.add (new SavedState (*currentState)); - } void restoreState() @@ -280930,36 +281022,33 @@ public: { public: SavedState() - : font (1.0f), needsUpdate (true) + : font (1.0f), fillNeedsUpdate (true), typefaceNeedsUpdate (true) { } SavedState (const SavedState& other) - : fillType (other.fillType), font (other.font), needsUpdate (true) + : fillType (other.fillType), font (other.font), fillNeedsUpdate (true), typefaceNeedsUpdate (true) { } void setFillType (const FillType& newType) { - needsUpdate = true; + fillNeedsUpdate = true; fillType = newType; } jobject getPaint() { - if (needsUpdate) + if (fillNeedsUpdate) { JNIEnv* env = getEnv(); if (paint.get() == 0) - { - paint = GlobalRef (env->NewObject (android.paintClass, android.paintClassConstructor)); - paint.callVoidMethod (android.setAntiAlias, true); - } + paint = GlobalRef (android.createPaint()); if (fillType.isColour()) { - paint.callObjectMethod (android.setShader, (jobject) 0); + env->DeleteLocalRef (paint.callObjectMethod (android.setShader, (jobject) 0)); paint.callVoidMethod (android.setColor, colourToInt (fillType.colour)); } else if (fillType.isGradient()) @@ -281011,7 +281100,7 @@ public: env->DeleteLocalRef (positionsArray); env->CallVoidMethod (shader, android.setLocalMatrix, createMatrix (env, fillType.transform).get()); - paint.callObjectMethod (android.setShader, shader); + env->DeleteLocalRef (paint.callObjectMethod (android.setShader, shader)); env->DeleteLocalRef (shader); } @@ -281023,11 +281112,30 @@ public: return paint.get(); } - private: + jobject getPaintForTypeface() + { + jobject p = getPaint(); + + if (typefaceNeedsUpdate) + { + typefaceNeedsUpdate = false; + const Typeface::Ptr t (font.getTypeface()); + AndroidTypeface* atf = dynamic_cast (t.getObject()); + + if (atf != 0) + { + paint.callObjectMethod (android.setTypeface, atf->typeface.get()); + paint.callVoidMethod (android.setTextSize, font.getHeight()); + } + } + + return p; + } + FillType fillType; Font font; GlobalRef paint; - bool needsUpdate; + bool fillNeedsUpdate, typefaceNeedsUpdate; }; private: @@ -281103,7 +281211,7 @@ private: const int numRects = list.getNumRectangles(); for (int i = 0; i < numRects; ++i) - env->CallVoidMethod (region, android.regionUnion, createRect (env, list.getRectangle(i)).get()); + env->CallBooleanMethod (region, android.regionUnion, createRect (env, list.getRectangle(i)).get()); return LocalRef (region); } @@ -281191,7 +281299,6 @@ public: view.callVoidMethod (android.getLocationOnScreen, pos); jint coords[2]; - jint i, sum = 0; env->GetIntArrayRegion (pos, 0, 2, coords); env->DeleteLocalRef (pos); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 79fda20482..6a9609a296 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 27 +#define JUCE_BUILDNUMBER 28 /** Current Juce version number. @@ -16735,7 +16735,7 @@ private: /** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object using RAII. */ -class ScopedAutoReleasePool +class JUCE_API ScopedAutoReleasePool { public: ScopedAutoReleasePool(); diff --git a/src/core/juce_PlatformUtilities.h b/src/core/juce_PlatformUtilities.h index 3a6ac4b7b4..49f9ec1806 100644 --- a/src/core/juce_PlatformUtilities.h +++ b/src/core/juce_PlatformUtilities.h @@ -207,7 +207,7 @@ private: /** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object using RAII. */ -class ScopedAutoReleasePool +class JUCE_API ScopedAutoReleasePool { public: ScopedAutoReleasePool(); diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 7dbbf28c0d..9cfe808816 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 27 +#define JUCE_BUILDNUMBER 28 /** Current Juce version number. diff --git a/src/native/android/java/ComponentPeerView.java b/src/native/android/java/ComponentPeerView.java index 9f8e120852..10ee4e4a8c 100644 --- a/src/native/android/java/ComponentPeerView.java +++ b/src/native/android/java/ComponentPeerView.java @@ -54,8 +54,6 @@ public class ComponentPeerView extends View @Override public boolean onTouchEvent (MotionEvent event) { - System.out.println (event.toString()); - switch (event.getAction()) { case MotionEvent.ACTION_DOWN: handleMouseDown (event.getX(), event.getY(), event.getEventTime()); return true; diff --git a/src/native/android/java/JuceAppActivity.java b/src/native/android/java/JuceAppActivity.java index 8287e8e762..ebd2d033b5 100644 --- a/src/native/android/java/JuceAppActivity.java +++ b/src/native/android/java/JuceAppActivity.java @@ -29,6 +29,7 @@ import android.app.Activity; import android.os.Bundle; import android.content.*; import android.view.*; +import android.text.ClipboardManager; import com.juce.ComponentPeerView; //============================================================================== @@ -128,4 +129,17 @@ public class JuceAppActivity extends Activity { } } + + //============================================================================== + public String getClipboardContent() + { + ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); + return clipboard.getText().toString(); + } + + public void setClipboardContent (String newText) + { + ClipboardManager clipboard = (ClipboardManager) getSystemService (CLIPBOARD_SERVICE); + clipboard.setText (newText); + } } diff --git a/src/native/android/juce_android_Fonts.cpp b/src/native/android/juce_android_Fonts.cpp index a71161244b..6928de215f 100644 --- a/src/native/android/juce_android_Fonts.cpp +++ b/src/native/android/juce_android_Fonts.cpp @@ -33,18 +33,21 @@ const StringArray Font::findAllTypefaceNames() { StringArray results; - // TODO + Array fonts; + File ("/system/fonts").findChildFiles (fonts, File::findFiles, false, "*.ttf"); + + for (int i = 0; i < fonts.size(); ++i) + results.add (fonts.getReference(i).getFileNameWithoutExtension()); return results; } void Font::getPlatformDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed, String& defaultFallback) { - // TODO - defaultSans = "Verdana"; - defaultSerif = "Times"; - defaultFixed = "Lucida Console"; - defaultFallback = "Tahoma"; + defaultSans = "sans"; + defaultSerif = "serif"; + defaultFixed = "monospace"; + defaultFallback = "sans"; } //============================================================================== @@ -52,30 +55,74 @@ class AndroidTypeface : public Typeface { public: AndroidTypeface (const Font& font) - : Typeface (font.getTypefaceName()) + : Typeface (font.getTypefaceName()), + ascent (0), + descent (0) { - // TODO - } + jint flags = 0; + if (font.isBold()) flags = 1; + if (font.isItalic()) flags += 2; - float getAscent() const - { - return 0; // TODO - } + typeface = GlobalRef (getEnv()->CallStaticObjectMethod (android.typefaceClass, android.create, + javaString (getName()).get(), flags)); - float getDescent() const - { - return 0; // TODO + paint = GlobalRef (android.createPaint()); + const LocalRef ignored (paint.callObjectMethod (android.setTypeface, typeface.get())); + + const float standardSize = 256.0f; + paint.callVoidMethod (android.setTextSize, standardSize); + ascent = std::abs (paint.callFloatMethod (android.ascent)) / standardSize; + descent = paint.callFloatMethod (android.descent) / standardSize; + + const float height = ascent + descent; + unitsToHeightScaleFactor = 1.0f / (height * standardSize); } + float getAscent() const { return ascent; } + float getDescent() const { return descent; } + float getStringWidth (const String& text) { - // TODO - return 0; + JNIEnv* env = getEnv(); + const int numChars = text.length(); + jfloatArray widths = env->NewFloatArray (numChars); + + const int numDone = paint.callIntMethod (android.getTextWidths, javaString (text).get(), widths); + + HeapBlock localWidths (numDone); + env->GetFloatArrayRegion (widths, 0, numDone, localWidths); + env->DeleteLocalRef (widths); + + float x = 0; + for (int i = 0; i < numDone; ++i) + x += localWidths[i]; + + return x * unitsToHeightScaleFactor; } void getGlyphPositions (const String& text, Array& glyphs, Array& xOffsets) { - // TODO + JNIEnv* env = getEnv(); + const int numChars = text.length(); + jfloatArray widths = env->NewFloatArray (numChars); + + const int numDone = paint.callIntMethod (android.getTextWidths, javaString (text).get(), widths); + + HeapBlock localWidths (numDone); + env->GetFloatArrayRegion (widths, 0, numDone, localWidths); + env->DeleteLocalRef (widths); + + String::CharPointerType s (text.getCharPointer()); + + xOffsets.add (0); + + float x = 0; + for (int i = 0; i < numDone; ++i) + { + glyphs.add ((int) s.getAndAdvance()); + x += localWidths[i]; + xOffsets.add (x * unitsToHeightScaleFactor); + } } bool getOutlineForGlyph (int glyphNumber, Path& destPath) @@ -84,6 +131,9 @@ public: return false; } + GlobalRef typeface, paint; + float ascent, descent, unitsToHeightScaleFactor; + private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidTypeface); }; diff --git a/src/native/android/juce_android_GraphicsContext.cpp b/src/native/android/juce_android_GraphicsContext.cpp index f98a70eaf5..55988fe18b 100644 --- a/src/native/android/juce_android_GraphicsContext.cpp +++ b/src/native/android/juce_android_GraphicsContext.cpp @@ -92,12 +92,13 @@ public: const Rectangle getClipBounds() const { JNIEnv* env = getEnv(); - const LocalRef rect (canvas.callObjectMethod (android.getClipBounds2)); + jobject rect = canvas.callObjectMethod (android.getClipBounds2); const int left = env->GetIntField (rect, android.rectLeft); const int top = env->GetIntField (rect, android.rectTop); const int right = env->GetIntField (rect, android.rectRight); const int bottom = env->GetIntField (rect, android.rectBottom); + env->DeleteLocalRef (rect); return Rectangle (left, top, right - left, bottom - top); } @@ -159,15 +160,33 @@ public: void setFont (const Font& newFont) { + if (currentState->font != newFont) + { + currentState->font = newFont; + currentState->typefaceNeedsUpdate = true; + } } const Font getFont() { - return Font(); + return currentState->font; } void drawGlyph (int glyphNumber, const AffineTransform& transform) { + if (transform.isOnlyTranslation()) + { + canvas.callVoidMethod (android.drawText, javaStringFromChar ((juce_wchar) glyphNumber).get(), + transform.getTranslationX(), transform.getTranslationY(), + currentState->getPaintForTypeface()); + } + else + { + saveState(); + addTransform (transform); + drawGlyph (glyphNumber, AffineTransform::identity); + restoreState(); + } } //============================================================================== @@ -175,7 +194,6 @@ public: { (void) canvas.callIntMethod (android.save); stateStack.add (new SavedState (*currentState)); - } void restoreState() @@ -207,36 +225,33 @@ public: { public: SavedState() - : font (1.0f), needsUpdate (true) + : font (1.0f), fillNeedsUpdate (true), typefaceNeedsUpdate (true) { } SavedState (const SavedState& other) - : fillType (other.fillType), font (other.font), needsUpdate (true) + : fillType (other.fillType), font (other.font), fillNeedsUpdate (true), typefaceNeedsUpdate (true) { } void setFillType (const FillType& newType) { - needsUpdate = true; + fillNeedsUpdate = true; fillType = newType; } jobject getPaint() { - if (needsUpdate) + if (fillNeedsUpdate) { JNIEnv* env = getEnv(); if (paint.get() == 0) - { - paint = GlobalRef (env->NewObject (android.paintClass, android.paintClassConstructor)); - paint.callVoidMethod (android.setAntiAlias, true); - } + paint = GlobalRef (android.createPaint()); if (fillType.isColour()) { - paint.callObjectMethod (android.setShader, (jobject) 0); + env->DeleteLocalRef (paint.callObjectMethod (android.setShader, (jobject) 0)); paint.callVoidMethod (android.setColor, colourToInt (fillType.colour)); } else if (fillType.isGradient()) @@ -288,7 +303,7 @@ public: env->DeleteLocalRef (positionsArray); env->CallVoidMethod (shader, android.setLocalMatrix, createMatrix (env, fillType.transform).get()); - paint.callObjectMethod (android.setShader, shader); + env->DeleteLocalRef (paint.callObjectMethod (android.setShader, shader)); env->DeleteLocalRef (shader); } @@ -300,11 +315,30 @@ public: return paint.get(); } - private: + jobject getPaintForTypeface() + { + jobject p = getPaint(); + + if (typefaceNeedsUpdate) + { + typefaceNeedsUpdate = false; + const Typeface::Ptr t (font.getTypeface()); + AndroidTypeface* atf = dynamic_cast (t.getObject()); + + if (atf != 0) + { + paint.callObjectMethod (android.setTypeface, atf->typeface.get()); + paint.callVoidMethod (android.setTextSize, font.getHeight()); + } + } + + return p; + } + FillType fillType; Font font; GlobalRef paint; - bool needsUpdate; + bool fillNeedsUpdate, typefaceNeedsUpdate; }; private: @@ -380,7 +414,7 @@ private: const int numRects = list.getNumRectangles(); for (int i = 0; i < numRects; ++i) - env->CallVoidMethod (region, android.regionUnion, createRect (env, list.getRectangle(i)).get()); + env->CallBooleanMethod (region, android.regionUnion, createRect (env, list.getRectangle(i)).get()); return LocalRef (region); } diff --git a/src/native/android/juce_android_Misc.cpp b/src/native/android/juce_android_Misc.cpp index 742226277c..1efc893cf2 100644 --- a/src/native/android/juce_android_Misc.cpp +++ b/src/native/android/juce_android_Misc.cpp @@ -56,7 +56,6 @@ JUCE_JNI_CALLBACK (JuceAppActivity, quitApp, void, (JNIEnv* env, jobject activit //============================================================================== void PlatformUtilities::beep() { - // TODO } //============================================================================== @@ -69,16 +68,14 @@ void Logger::outputDebugString (const String& text) //============================================================================== void SystemClipboard::copyTextToClipboard (const String& text) { - // TODO + const LocalRef t (javaString (text)); + android.activity.callVoidMethod (android.setClipboardContent, t.get()); } const String SystemClipboard::getTextFromClipboard() { - String result; - - // TODO - - return result; + const LocalRef text ((jstring) android.activity.callObjectMethod (android.getClipboardContent)); + return juceString (text); } diff --git a/src/native/android/juce_android_NativeCode.cpp b/src/native/android/juce_android_NativeCode.cpp index 57e8650221..69e062c635 100644 --- a/src/native/android/juce_android_NativeCode.cpp +++ b/src/native/android/juce_android_NativeCode.cpp @@ -107,6 +107,7 @@ BEGIN_JUCE_NAMESPACE JAVACLASS (rectClass, "android/graphics/Rect") \ JAVACLASS (regionClass, "android/graphics/Region") \ JAVACLASS (shaderClass, "android/graphics/Shader") \ + JAVACLASS (typefaceClass, "android/graphics/Typeface") \ JAVACLASS (shaderTileModeClass, "android/graphics/Shader$TileMode") \ JAVACLASS (linearGradientClass, "android/graphics/LinearGradient") \ JAVACLASS (radialGradientClass, "android/graphics/RadialGradient") \ @@ -118,6 +119,8 @@ BEGIN_JUCE_NAMESPACE METHOD (activityClass, createNewView, "createNewView", "()Lcom/juce/ComponentPeerView;") \ METHOD (activityClass, deleteView, "deleteView", "(Lcom/juce/ComponentPeerView;)V") \ METHOD (activityClass, postMessage, "postMessage", "(J)V") \ + METHOD (activityClass, getClipboardContent, "getClipboardContent", "()Ljava/lang/String;") \ + METHOD (activityClass, setClipboardContent, "setClipboardContent", "(Ljava/lang/String;)V") \ \ METHOD (fileClass, fileExists, "exists", "()Z") \ \ @@ -144,6 +147,7 @@ BEGIN_JUCE_NAMESPACE METHOD (canvasClass, drawBitmap, "drawBitmap", "(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/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") \ METHOD (canvasClass, getClipBounds, "getClipBounds", "(Landroid/graphics/Rect;)Z") \ METHOD (canvasClass, getClipBounds2, "getClipBounds", "()Landroid/graphics/Rect;") \ METHOD (canvasClass, getMatrix, "getMatrix", "()Landroid/graphics/Matrix;") \ @@ -151,10 +155,15 @@ BEGIN_JUCE_NAMESPACE METHOD (canvasClass, restore, "restore", "()V") \ METHOD (canvasClass, saveLayerAlpha, "saveLayerAlpha", "(FFFFII)I") \ \ - METHOD (paintClass, paintClassConstructor, "", "()V") \ + METHOD (paintClass, paintClassConstructor, "", "(I)V") \ METHOD (paintClass, setColor, "setColor", "(I)V") \ METHOD (paintClass, setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \ - METHOD (paintClass, setAntiAlias, "setAntiAlias", "(Z)V") \ + 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;") \ @@ -168,6 +177,8 @@ BEGIN_JUCE_NAMESPACE \ METHOD (matrixClass, matrixClassConstructor, "", "()V") \ METHOD (matrixClass, setValues, "setValues", "([F)V") \ +\ + STATICMETHOD (typefaceClass, create, "create", "(Ljava/lang/String;I)Landroid/graphics/Typeface;") \ \ METHOD (rectClass, rectConstructor, "", "(IIII)V") \ FIELD (rectClass, rectLeft, "left", "I") \ @@ -422,6 +433,13 @@ static const LocalRef javaString (const String& s) return LocalRef (getEnv()->NewStringUTF (s.toUTF8())); } +static const LocalRef javaStringFromChar (const juce_wchar c) +{ + char utf8[5] = { 0 }; + CharPointer_UTF8 (utf8).write (c); + return LocalRef (getEnv()->NewStringUTF (utf8)); +} + //============================================================================== class AndroidJavaCallbacks @@ -483,6 +501,15 @@ public: String appFile, appDataDir; int screenWidth, screenHeight; + jobject createPaint() + { + const jint constructorFlags = 1 /*ANTI_ALIAS_FLAG*/ + | 2 /*FILTER_BITMAP_FLAG*/ + | 4 /*DITHER_FLAG*/ + | 128 /*SUBPIXEL_TEXT_FLAG*/; + return getEnv()->NewObject (paintClass, paintClassConstructor, constructorFlags); + } + //============================================================================== #define DECLARE_JNI_CLASS(className, path) jclass className; JUCE_JNI_CLASSES (DECLARE_JNI_CLASS); diff --git a/src/native/android/juce_android_Windowing.cpp b/src/native/android/juce_android_Windowing.cpp index d38ecbbcc9..483809afc1 100644 --- a/src/native/android/juce_android_Windowing.cpp +++ b/src/native/android/juce_android_Windowing.cpp @@ -94,7 +94,6 @@ public: view.callVoidMethod (android.getLocationOnScreen, pos); jint coords[2]; - jint i, sum = 0; env->GetIntArrayRegion (pos, 0, 2, coords); env->DeleteLocalRef (pos);