Integrating android support.

This commit is contained in:
Pere Pujal i Carabantes 2016-03-13 00:39:15 +01:00
parent 51f2e90c7d
commit d38b4abd68
8 changed files with 822 additions and 93 deletions

87
src/android_mbstowcs.c Normal file
View file

@ -0,0 +1,87 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt)
*/
/*
refer to https://tools.ietf.org/html/rfc3629
Char. number range | UTF-8 octet sequence
(hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
#include "android_mbstowcs.h"
#include <string.h>
// This implementation may be simple, but can work fine for all of Android devices
size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n){
int length = strnlen (s, n);
// w is the index of pwcs, s is the index of s
int w = 0, c = 0;
while (1) {
pwcs[w] = '\0';
char first = s[c];
int len = 0;
if ((first & 0x80) == 0) {
pwcs[w] = (wchar_t)s[c];
len = 1;
}
else if ((first & 0xe0) == 0xc0) {
pwcs[w] |= first & 0x1f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+1] & 0x3f;
len = 2;
}
else if ((first & 0xf0) == 0xe0) {
pwcs[w] |= first & 0x0f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+1] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+2] & 0x3f;
len = 3;
}
else if ((first & 0xf8) == 0xf0) {
pwcs[w] |= first & 0x07;
pwcs[w] <<= 6;
pwcs[w] |= s[c+1] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+2] & 0x3f;
pwcs[w] <<= 6;
pwcs[w] |= s[c+3] & 0x3f;
len = 4;
}
else {
return -1;
}
c += len;
w++;
if (c > length){
pwcs[w] = '\0';
return -1;
}
if (c == length){
pwcs[w] = '\0';
return w;
}
}
}

36
src/android_mbstowcs.h Normal file
View file

@ -0,0 +1,36 @@
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt)
*/
/*
Why we need android_wchar.h here?
Actually, Android NDK has wchar.h header file, and implements related functions.
However, it is likely that Bionic C library implements those funtions in a very simple
(or wrong ?) way on old Android devices ( API < 21), while they come to work on the new Android devices (API >= 21).
Thus, tuxpaint im.c file depends on "mbstowcs" function which cannot work properly on old Android devices.
Anyway, using our own implementation of "mbstowcs" can fix this problem.
*/
#ifndef TUXPAINT_ANDROID_SUPPORT_MBSTOWCS_H
#define TUXPAINT_ANDROID_SUPPORT_MBSTOWCS_H
#include <wchar.h>
#undef mbsrtowcs
// redefine mbstowcs function
size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n);
#endif

77
src/android_print.c Normal file
View file

@ -0,0 +1,77 @@
/* android_print.cpp */
/* printing support for Tux Paint */
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt)
*/
// Based on JNI and PrintHelper class
// https://developer.android.com/reference/android/support/v4/print/PrintHelper.html
// https://developer.android.com/training/printing/photos.html
#include "android_print.h"
#include "jni.h"
// Since Print work is based on Java PrintHelper class, which may not be supported on some old versions
int IsPrinterAvailable( void )
{
JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mPrintHelperClass = (*mEnv)->FindClass(mEnv, "android/support/v4/print/PrintHelper");
if (mPrintHelperClass == NULL)
return 0;
jmethodID mSupportMethod = (*mEnv)->GetStaticMethodID(mEnv, mPrintHelperClass, "systemSupportsPrint", "()Z");
jboolean support = (*mEnv)->CallStaticBooleanMethod(mEnv, mPrintHelperClass, mSupportMethod);
return support ? 1 : 0;
}
// This function is based on
// (1) convert surface to Java BitMap object
// (2) call Java PrintHelper to do print job.
const char *SurfacePrint(SDL_Surface *surface)
{
JNIEnv *mEnv = Android_JNI_GetEnv();
jclass mBitmapClass = (*mEnv)->FindClass(mEnv, "android/graphics/Bitmap");
jmethodID mCreateMethod = (*mEnv)->GetStaticMethodID(mEnv, mBitmapClass, "createBitmap", "([IIILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jintArray mSurfaceArray = (*mEnv)->NewIntArray(mEnv, surface->w * surface->h);
(*mEnv)->SetIntArrayRegion(mEnv,mSurfaceArray, 0, surface->w * surface->h, surface->pixels);
jclass mConfigClass = (*mEnv)->FindClass(mEnv, "android/graphics/Bitmap$Config");
jfieldID mConfigField = (*mEnv)->GetStaticFieldID(mEnv, mConfigClass , "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
jobject mConfig = (*mEnv)->GetStaticObjectField(mEnv, mConfigClass, mConfigField);
jobject mBitMap = (*mEnv)->CallStaticObjectMethod(mEnv, mBitmapClass, mCreateMethod, mSurfaceArray, surface->w, surface->h, mConfig);
jobject mContext = (jobject)SDL_AndroidGetActivity();
jclass mPrintClass = (*mEnv)->FindClass(mEnv, "android/support/v4/print/PrintHelper");
// sometimes android v4 support library may be not ready
if (mPrintClass == NULL)
return "There is no android v4 support library.";
jmethodID mInitMethod = (*mEnv)->GetMethodID(mEnv, mPrintClass, "<init>", "(Landroid/content/Context;)V");
jobject mPrint = (*mEnv)->NewObject(mEnv, mPrintClass, mInitMethod, mContext);
jmethodID mPrintMethod = (*mEnv)->GetMethodID(mEnv, mPrintClass, "printBitmap", "(Ljava/lang/String;Landroid/graphics/Bitmap;)V");
jstring mString = (*mEnv)->NewStringUTF(mEnv, "TuxPaint");
(*mEnv)->CallVoidMethod(mEnv, mPrint, mPrintMethod, mString, mBitMap);
// clean up
(*mEnv)->DeleteLocalRef(mEnv, mSurfaceArray);
(*mEnv)->DeleteLocalRef(mEnv, mConfig);
(*mEnv)->DeleteLocalRef(mEnv, mPrint);
(*mEnv)->DeleteLocalRef(mEnv, mString);
return NULL;
}

31
src/android_print.h Normal file
View file

@ -0,0 +1,31 @@
/* android_print.h */
/* printing support for Tux Paint */
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt)
*/
#ifndef __ANDROID_PRINT_H__
#define __ANDROID_PRINT_H__
#include "SDL.h"
extern const char *SurfacePrint(SDL_Surface *surface);
extern int IsPrinterAvailable(void);
#endif /* __ANDROID_PRINT__ */

View file

@ -1 +1,8 @@
/* #define DEBUG */
#define DEBUG
#ifdef __ANDROID__
#include <android/log.h>
#define LOG_TAG "TuxPaint"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
#endif

File diff suppressed because it is too large Load diff