Tux Paint

Tux Paint是一个免费的、获奖的绘画项目,适合3至12岁的儿童(例如,学前班和K-6)。(Tux Paint is a free, award-winning drawing program for children ages 3 to 12 (for example, preschool and K-6).)

  • Owner: tux4kids/Tuxpaint-Android
  • Platform: Android, iOS, Linux, Mac, Windows
  • License::
  • Category::
  • Topic:
  • Like:
    0
      Compare:

Github stars Tracking Chart

Tux Paint是一个免费的、获奖的绘画项目,适合3至12岁的儿童(例如,学前班和K-6)。

Tux Paint在世界各地的学校中用作计算机知识绘图活动。 它结合了易于使用的界面,有趣的声音效果和鼓励儿童使用该程序的鼓励卡通吉祥物。

孩子们会看到一块空白的画布和各种绘画工具,以帮助他们发挥创意。

特性

多平台

Tux Paint适用于macOS(10.7及更高版本)、Windows(Windows95至Windows 10)、Linux、Android和其他系统。还提供非官方Apple iOS(iPhone / iPad)版本。

简单的界面
  • 提供了许多有用的绘图工具。 (参见下面的绘图工具。)
  • 绘图画布是固定大小的,因此用户在制作新照片时无需担心“像素”或“英寸”。
  • 整个程序适合小到640x480的屏幕,并且可以全屏显示,以隐藏计算机的底层“桌面”界面。 (默认为800x600模式,但也可以在较大尺寸和纵向或横向模式下运行。)
  • 使用缩略图完成图像的加载和保存,因此不需要了解底层操作系统的文件系统结构。甚至文件名都是不必要的。
娱乐界面
  • 选择和使用工具时会播放有趣的声音效果。
  • Linux企鹅Tux的卡通版本出现在底部,提供提示,提示和信息。
绘图工具
  • 油漆刷
    • 各种刷子可用
    • 家长/老师可以添加更多画笔
    • 画笔可以动画
    • 刷子可以根据绘制的方向改变形状
    • 可以创建和使用替代调色板
    • 颜色选择器,用于从图纸中选择颜色(0.9.23中的新功能)
  • 橡皮图章
    • 可提供数百张照片和卡通图章
    • 家长/老师可以添加更多邮票和创建类别
    • 邮票可以具有描述性文本和声音样本(名称,事实等)和/或分配给它们的声音效果
    • 邮票可以调整大小,翻转和镜像
    • 支持全彩色和Alpha透明度(32bpp RGBA)的光栅位图(便携式网络图形(“PNG”))
    • 支持矢量图形(可缩放矢量图形(“SVG”))
  • 线工具
    • 使用Paint Brush的画笔
    • 'Rubberband'显示移动鼠标时绘制线条的位置
  • 形状工具
    • 绘制各种填充和未填充的多边形形状
    • 旋转形状(可以为年幼的孩子禁用此功能)
  • 文本和标签工具
    • 附带各种字体
    • 可以更改粗体,斜体和大小
    • 家长/老师可以添加更多字体
    • 支持多种语言(参见下面的国际字符输入)
    • 可以稍后移动或编辑标签
  • '魔术'(特效)工具
    • 百叶窗--把百叶窗拉下来, 或者穿过图片
    • 块 - 转动部分图片'块状'
    • 模糊 - 使用鼠标模糊部分图片
    • 砖 - 绘制逼真的大或小砖图案
    • 书法 - 一种平滑的笔刷,根据你的击打速度改变厚度
    • 卡通 - 使图片的部分看起来像卡通
    • 粉笔 - 使图片的部分看起来像粉笔画
    • 颜色和白色 - 使图片单调
    • 色彩偏移 - 混淆图片的颜色
    • 五彩纸屑 - 在你的照片上扔五彩纸屑
    • 变暗 - 使图像部分的颜色变暗
    • 失真 - 略微改变画笔下画面的位置
    • 滴水 - 使图片的一部分看起来像滴水一样
    • 边缘 - 勾勒出yur图片中形状的边缘
    • 浮雕 - 给出图像的边缘高光和阴影
    • 填充 - “填充”具有特定颜色的区域
    • 鱼眼 - 通过鱼眼镜头查看照片的部分内容
    • 翻转 - 垂直翻转图像
    • 花 - 画出弯曲的花朵
    • 泡沫 - 涂抹泡沫气泡,随着鼠标的移动而增长
    • 折叠 - 折叠图片的角落
    • 玻璃瓷砖 - 通过玻璃砖看你的图纸
    • 草 - 在屏幕上绘制现实的草丛并进入距离
    • 六角形马赛克 - 创建六边形图案
    • 不规则马赛克 - 将你的照片变成碎片马赛克
    • 万花筒 - 四个对称刷子
    • 光 - 在你的照片上绘制明亮的光束
    • 变亮 - 淡化图片部分的颜色
    • 金属漆 - 涂料闪亮的金属色
    • 镜像 - 水平翻转图像
    • 马赛克 - 使您的照片成为马赛克的颜色
    • 负片 - 反转图片部分的颜色
    • 噪音 - 为您的照片添加随机噪音
    • 透视 - 弯曲您的图片以从不同的角度查看它
    • 毕加索 - 一种三合一的画笔,可以齐心喷漆
    • 拼图 - 将图片的各个部分移动,就像它是一个滑动拼图
    • ROYGBIV彩虹 - 画出七种纯色的彩虹弧
    • Rails - 绘制连接火车轨道
    • 雨 - 为你的照片添加雨滴
    • 彩虹 - 使用画笔绘制彩虹中的所有颜色
    • 真彩虹 - 根据彩虹的真实照片绘制彩色圆弧
    • 涟漪 - 在你的图像上波纹起伏
    • 玫瑰花饰 - 三个刷子以莲座图案绘制
    • Shift - 移动整个画面
    • 剪影 - 将图片的一部分变成轮廓
    • 涂抹 - 推动周围的颜色,好像弄湿了油漆
    • 雪球 - 用雪球覆盖你的照片
    • 雪花 - 用雪花覆盖你的照片
    • 方形马赛克 - 创建正方形图案
    • 字符串V - 绘制V形弦乐艺术
    • String corner - 绘制字符串艺术
    • 字符串边缘 - 围绕您的边缘绘制字符串艺术
    • 电视 - 让你的照片看起来像是在电视上
    • 色调 - 更改图片部分的颜色
    • 牙膏 - 用彩色凝胶涂料
    • 龙卷风 - 为您的照片添加龙卷风漏斗
    • 小波 - 上下摆动你的图片
    • 波浪 - 将你的照片摆动到一边
    • 湿漆 - 用湿的,脏污的油漆画
    • 缩放 - 缩放整个画面
    • ...此外,程序员可以使用插件界面轻松快速地创建新的“Magic”工具!
  • 橡皮
    • 多级撤消
      撤消操作本身可以使用“重做”按钮撤消
命令
  • 保存
    • 将图片保存到虚拟“图画书”
    • 单击保存:不使用文件浏览器对话框或文件名提示
    • 如果保存已打开的图片,请选择保存它(如桌面程序中的“保存”),或保存新图片(如“另存为”)
  • 打开
    • 通过在虚拟“图画书”中选择其缩略图来打开上一个图形
    • 删除以前保存的图片
  • 幻灯片
    • 查看多个已保存图纸的幻灯片
    • 控制播放速度;创建类演示文稿或简单的循环动画
    • 使用箭头键或鼠标前进或后退
  • 起步
    • 包括各种着色书风格的图像
    • 包括摄影场景,其中包含您在其间绘制的前景和背景元素
    • 支持矢量图形(可缩放矢量图形(“SVG”))
    • 支持Kid Pix模板(“KPX”文件)
  • 打印
    • 在打印机上打印图片
翻译
  • Tux Paint的部件目前已被翻译成130多种语言,包括英语、简体中文和繁体中文等。

Main metrics

Overview
Name With Ownertux4kids/Tuxpaint-Android
Primary LanguageC
Program languageMakefile (Language Count: 38)
PlatformAndroid, iOS, Linux, Mac, Windows
License:
所有者活动
Created At2015-08-27 23:17:22
Pushed At2025-06-01 20:59:17
Last Commit At2025-06-01 16:59:05
Release Count23
Last Release Name0.9.35 (Posted on )
First Release Name0.9.23-beta_10 (Posted on 2017-09-21 20:04:55)
用户参与
Stargazers Count65
Watchers Count11
Fork Count32
Commits Count422
Has Issues Enabled
Issues Count0
Issue Open Count0
Pull Requests Count34
Pull Requests Open Count3
Pull Requests Close Count5
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private

Tux Paint-Android

This is Tux Paint on Android.

Background

Tux Paint has been ported from SDL1 to SDL2.
Thus Tux Paint-Android will try to port current Tux Paint to Android platform.
At the start this Tux Paint source code was based on tuxpaint-sdl2
maintained by Pere Pujal i Carabantes with head commit b48c069b2ff6a0cabf82ec086ff6ef563eaaf3d3, now it has been synced back and forth several times.
As it is currently(2016/01/23) it has been synced also with the work made in the official(SDL1.2 based) work.
https://sourceforge.net/u/perepujal/tuxpaint/ci/sdl2.0/tree/

The main work made by Jianwei Zhang on GSoC 2015 includes:

  1. port SDL2, SDL2_image, SDL2_ttf, SDL2_mixer, libpng, gettext, FriBiDi libraries to Android.
  2. based on these libraries and SDL2 Android template project, port current Tux Paint source code to Android.
  3. extend Tux Paint further to make Tux Paint welcomed on Android.

Project

  • Tux Paint-Android/
    • AndroidManifest.xml
      package manifest. Among others, it contains the class name of the main Activity and the package name of the application.
    • build.properties
    • build.xml
      build description file, used by ant. The actual application name is specified here.
      deprecated since the build changed to gradle.
    • default.properties
      holds the target ABI for the application, android-12 and up
    • project.properties
      holds the target ABI for the application, android-12 and up
    • assets/
      The resources folder
    • assets/tuxpaint.zip
      The resources for Tux Paint, including images, sounds etc.
      Note that starting mid October 2016 tuxpaint.zip is no longer in the repository, now it is generated by the mkzip_assets.sh script.
      and starting April 2017 it is no more used, its contents are put uncompressed into the assets folder, to fill the assets folder run
      cd jni/tuxpaint && sh ./mkzipassets.sh
      You will need make and gettext installed for it to perform right.
    • res/
      directory holding resources for your application
    • res/drawable-*
      directories holding icons for different phone hardware.
    • res/values/strings.xml
      strings used in your application, including the application name shown on the phone.
    • res/values-**/strings.xml
      translations to different languages.
    • src/org/libsdl/app/SDLActivity.java
      the Java class handling the initialization and binding to SDL2.
    • src/org/tuxpaint/app/tuxpaintActivity.java
      the Java class handling something related with Tux Paint
    • src/org/tuxpaint/app/ConfigActivity.java
      the Java class handling configuration related with Tux Paint
    • jni/
      directory holding native code
    • jni/Android.mk
      Android makefile that can call recursively the Android.mk files in all subdirectories
    • jni/Application.mk
    • jni/SDL2/
      directory holding the SDL2 library files
    • jni/SDL2_image/
      directory holding the SDL2_image library files
    • jni/SDL2_ttf/
      directory holding the SDL2_ttf library files
    • jni/SDL2_mixer/
      directory holding the SDL2_mixer library files
    • jni/fribidi/
      directory holding the fribidi library files
    • jni/libintl-lite/
      directory holding the intl library files
    • jni/platform_external_libpng/
      directory holding the libpng library files
    • jni/glib/
      directory holding the glib library files
    • jni/harfbuzz/
      directory holding the harfbuzz library files
    • jni/libffi/
      directory holding the libffi library files
    • jni/iconv/
      directory holding the iconv library files
    • jni/pango/
      directory holding the pango library files
    • jni/cairo/
      directory holding the cairo library files
    • jni/pixman/
      directory holding the pixman library files
    • jni/platform_external_libxml2/
      directory holding the xml2 library files
    • jni/SDL2_Pango/
      directory holding the SDL2_Pango library files
    • jni/gdk-pixbuf/
      directory holding the gdk-pixbuf library files
    • jni/libcroco/
      directory holding the libcroco library files
    • jni/librsvg/
      directory holding the librsvg library files
    • jni/tuxpaint/
      directory holding the tuxpaint source files
    • jni/tuxpaint/Android.mk
      Android makefile for creating the tuxpaint shared library

As part of changing the buid process from ant to gradle, the previous paths now hangs on app/src/main/

  • settings.gradle
    Indicates the directory gradle should build
  • build.gradle
    Common gradle configuration
  • app/build.gradle
    Configuration specific to the app directory

Dependencies

From official Library Requirements, Tux Paint requires:

  • SDL
  • SDL_image (for PNG support)
  • SDL_ttf (for fonts)
  • SDL_mixer (optional, for sound)
  • SDL_pango (optional, for improved text rendering)
  • Cairo (optional, for SVG support)
  • FriBiDi (optional, for bidirectional text input)
  • libRSVG (optional, for SVG support)
  • libPNG
  • libpaper (for POSIX printing)
  • gettext (for multilingual support)

For making Tux Paint working on Android, currently these libraries have been downloaded and built :

However, these libraries will depend on more libraries, thus another libraries have been downloaded and built :

Note: libpaper will not be compiled, since it may be not fit for Android.

Features

  • Features support
    • Tools: Paint, Stamp, Lines, Shapes, Text, Label, Magic, Undo, Redo, Eraser, New, Open, Save, Print and Quit
    • Stamp: All
    • Brushed: All
    • Shapes: All
    • Color: All
    • Sound: Enabled
    • Magic plugins: All
    • i18n: Enabled
    • SDL2_Pango: Enabled
    • Screen keybord: Enabled
    • RSVG: Enabled

Build

  • Linux system
  • Android SDK
    android-support-v4.jar from the sdk/extras/... directory, copy it into the libs directory
  • Android NDK
  • Tuxpaint-Android source code
  • Eclipse & ADT (optional)
  • Git (optional)

Install&Run

If you want to (re)fill the assets dir run:

cd app/src/main/jni/tuxpaint && ./mkzip_assets.sh

If you have gradle, then run from the base directory:

	gradle build

If you have ant, deprecated, then:
Recover the build.xml and project.properties files from a previous version, for example from
https://github.com/tux4kids/Tuxpaint-Android/tree/4a51d97dad140f044b2f653ebf43636dda1798cd
and put them into app/src/main, then run

	cd app/src/main
	ln -s java src
	ndk-build
	ant debug
	ant debug install

If you have Eclipse, then run:

  1. right click Tux Paint-Android project
  2. Run As -> Android Application

Tips for Play

  1. Sometimes if you cannot save your painted work, you should make sure:
    • you shall have a storage in /mnt/sdcard/tuxpaint. You can check whether this path can be accessable with command:
    adb shell
    cd /mnt/sdcard/tuxpaint
    
    • you shall have your Android device disconnected with your PC sometimes when you are using an old Android device.
  2. While tuxpaint can start with some default resources, you can further use your own resources for painting (supposing /mnt/sdcard/tuxpaint/ is your datadir):
    • In the folder /mnt/sdcard/tuxpaint/brushes, you can add some images which will be shown and used on brushes tool;
    • In the folder /mnt/sdcard/tuxpaint/fonts, you can add some extra fonts which will be used on texts and labels tool;
    • In the folder /mnt/sdcard/tuxpaint/stamps, you can add some stamps which will be shown and used on stamps tool;
    • In the folder /mnt/sdcard/tuxpaint/starters, you can add some images which will be shown and used when New menu is clicked;
  3. Your work will be hosted in the folder /mnt/sdcard/TuxPaint/saved (supposing /mnt/sdcard/tuxpaint/ is your savedir).
  4. Different from PC, you can paint with your two fingers or more! This is really interesting :)

Test

  • Moto ME525: Android 2.3.6
  • Moto G2: Android 5.0.2
  • MI PAD: Android 4.4.4
  • Wiko Wax: Android 4.3
  • Blackview 6000 Android 7.0

Develop

If you want to develop futher Tux Paint on the Android, there are some points which might be helpful:

  1. Before you come to develop, you shall know a few about Linux, C, Java, JNI and NDK.
  2. If you meet some issues or problems, please check following Issues&Solutions section;
  3. Since setlocale is not implemented well by Android, please avoid to use this function;
  4. For onscreen keybord on the Android, if you have not set property onscreen-keyboard and onscreen-keyboard-layout in the config file, Tux Paint will try to use Android keybord; otherwise, Tux Paint will follow your decision. You can disable keybord by setting onscreen-keyboard to false, you can also use tuxpaint's keybord by setting onscreen-keyboard-layout to $layout-name in the osk folder.
  5. For debug the Tux Paint, you shall compile with DEBUG macro in the src/debug.h. And then, you can
  • eithor read the log file /mnt/sdcard/tuxpaint/tuxpaint.log;
  • or use LOGE and LOGI to get message from the LogCat.
  1. If you want to set or disable the property of Tux Paint, you can modify the configure file tuxpaint.cfg in assets/tuxpaint.zip of this project to create a new apk. But a better approach is that you can only create or modify the configure file tuxpaint.cfg in the /mnt/sdcard/Android/data/org.tuxpaint/files/ directly on your test Android devices.
  2. Although the dependent libraries of Tux Paint have been compiled successfully, some functions of these libraries may not run as supposed or may even get crashed. Thus, please do not trust these compiled libraries too much and be careful. When something becomes strange, test by yourself.

Bugs&Comments

Send bugs and comments to Tux Paint developer's mailing list:

tuxpaint-devel@lists.sourceforge.net

Issues&Solutions

Issue 1: No such file or directory "SDL2/SDL.h"

Problem: NDK compilation failed with following error message.

In file included from jni/tuxpaint/src/tuxpaint.c:332:0:
jni/tuxpaint/src/postscript_print.h:38:22: fatal error: SDL2/SDL.h: No such file or directory
#include "SDL2/SDL.h"

Solution: The reason is that Make build system of SDL2 will export its headers in the $(DESTDIR)$(includedir)/SDL2/ (see line 140 of SDL2 Makefile.in.
Thus other applications shall use headers with #include SDL2/SDL.h.
However, current Android.mk of SDL2 only exports its headers under include folder, which means we can only include SDL.h
To enable including headers with prefix SDL2, we create a new folder named SDL2 under the include folder, and then copy all SDL2 related headers (including SDL2_image and others) to this SDL2 folder.
Then we can include SDL.h either SDL.h or SDL2/SDL.h

Issue 2: Missing source file "parse.c" and header file "tp_magic_api.h"

Problem: NDK compilation failed with following error message.

make: *** No rule to make target "jni/tuxpaint/src/parse.c", needed
by "obj/local/armeabi/objs/tuxpaint/src/parse.o". Stop.

Solution: parse.c is generated from parse.gperf by Makefile (see line 1025).
Here compile another Tux Paint in linux system with Makefile
and then copy generated parse.c to jni/tuxpaint/src folder.

tp_magic_api.h is generated from tp_magic_api.h.in by Makefile.
Here compile another Tux Paint in linux system with Makefile
and then copy generated tp_magic_api.h to jni/tuxpaint/src folder.

Issue 3: Full screen is required.

Problem: Generally the default window screen is 800x600 instead of full screen.
However, if only fullscreen=yes is enabled in the tuxpaint.conf, it cannot work as supposed.

Solution: To enable full screen for Android, both fullscreen=yes and native=yes will be set in the config file.

Issue 4: Android KeyEvent.KEYCODE_BACK cannot be handled successfully.

Problem: The reason is that KeyEvent.KEYCODE_BACK in the Android will be changed into SDLK_AC_BACK in the SDL2.0, which is not processed by Tux Paint.

Solution: From source code, we can find that the function of SDLK_AC_BACK is similar with SDLK_ESCAPE, which is processed by Tux Paint, thus add SDLK_AC_BACK to place where SDLK_ESCAPE exists.

Issue 5: Android 2.3.6 cannot save pictures when USB storage is connected on.

Problem: When Android phone is connected to PC by USB, Android 5.0.2 can save pictures successfully, while Android 2.3.6 will fail. The error message from debug is that "Permission denied".

Solution: See http://stackoverflow.com/questions/8854359/exception-open-failed-eacces-permission-denied-on-android, the solution is that to disconnect Android phone from PC. This works !

Issue 6: Brushes and Stamps cannot be loaded from Android assets folder.

Problem: If all image resource is put in the Android assets folder, most images can be loaded successfully except brushes and Stamps resources.
The reason is that dir walk operation (see dirwalk.c tp_ftw method) requires to traverse directories.
However all images are compressed in the apk file and current NDK AAssetsManager
seems not support directory traverse operation well.

Previous solution: All images and other resources will be compressed into tuxpaint.zip file in the assets folder.
tuxpaintActivity java class will decompress tuxpaint.zip into /data/data/org.tuxpaint/files folder,
then dir walk operation defined in dirwalk.c will work as supposed to load resource.
This solution had the problem that, in multiuser Androids, plain users(i.e. not owner) got Tux Paint crashed as they were denied from reading /data/data/org.tuxpaint/files

Current solution: All stuff are put uncompressed into the assets folder, then we use a custom fopen to access it, see the files in jni/tp-assets-fopen.
This current solution has the problem that the directories in the assets are hardcoded in the Tux Paint's code.

Issue 7: How to save pictures.

Problem: Generally completed pictures will be saved in the HOME on the linux platforms, which is ~/.tuxpaint folder. However there is no HOME system enviroment on the Android.

Solution: On the Android, there are three approaches to deal with saving files.
First is to use application internal storage, such as /data/data/your.app.package/files.
Second is to use application external storage, such as /mnt/sdcard/Android/data/your.app.package/files.
Third is also to use application external storage, such as /mnt/sdcard/your.app.

Here Tux Paint will be set to search the tuxpaint.cfg config file in the first and second path.
However, we recommend users not to rely on the config file in the second path, since sometime external path may not be support.
Instead, if users want to set different configuration, they can achieve this on the screen, which will affect the config file in the first path.

Anyway, the save dir and data dir will be set in the config file there. The default save and data dirs will be set the third path, which generally both are /mnt/sdcard/tuxpaint. But users can set different save dir and data dir if they want.

Issue 8: NDK android-21 make old Android devices crashed

Problem: According to (1) http://stackoverflow.com/questions/27091001/how-to-use-mkfifo-using-androids-ndk/27093163#27093163
and (2) https://code.google.com/p/android/issues/detail?id=73725.
If Tux Paint is compiled based NDK android-21, some old Android devices will crashed.

Solution: Insead of android-21, set APP_PLATFORM in jni/Application.mk to android-19 (or other low version).

Issue 9: Failed loading some magic plugin libraries due to too many libraries on old Android devices.

Problem: In Android 2.3.6, magic plugin libraries are compilied successfullt.
However, when lauching Tux Paint, some warning words come to show that:

Failed loading xxx.so: Cannot load library: alloc_info[279]:1231 too many libraries when loading xxx.so

But in Android 5.0.2, there are no warning words about this case.
According to http://stackoverflow.com/questions/14876835/android-maximum-shared-library-size/22143184#22143184, the number of shared libraries loaded by bionic has a limit defined by SO_MAX.
In Android 4.2, SO_MAX is 128. From Android 4.3, SO_MAX is removed.

Solution: The maximal allowable number for Android 2.3.6 is unknown yet, but it seems not too big.
Some solutions are found but seem useless for Tux Paint.
From warning words, the result is that some magic plugin libraries will not be loaded, which means Android old devices will miss some magic tools.
Anyway, the best soultion may be to use Android devices with new versions :(

Issue 10: magic plugin libraries shall be compiled with name "libxxx.so"
Problem: In the Makfile, magic plugin tools will be compiled into shared libraries.
In the Linux platform, these libraries will be named xxx.so instead of traditional libxxx.so.
In the Android platform, these libraries can also be named xxx.so with follow words in the Android.mk file:

	LOCAL_MODULE_FILENAME := xxx

Then, all of these xxx.so will be compiled into libs folder of Tux Paint project and be packed into tuxpaint.apk.

However, there is a strange problem that even xxx.so is in the tuxpaint.apk, xxx.so will not be uncompressed into
/data/data/org.tuxpaint/lib. It seems that Android system only allow libxxx.so.

Solution: Since Android only acccept libxxx.so rather than xxx.so, Android.mk will use following word.

	LOCAL_MODULE := xxx

Then, all of these libxxx.so will be compiled, packed and unpacked.
Besides that, when tuxpaint does load these shared libraries, the prefix 'lib` shall be exclued:

	#if defined(__ANDROID__)
	    strcpy(objname, objname + 3);
	#endif

Issue 11: plugin /data/data/org.tuxpaint/lib/libSDL2.so is missing "get_tool_count" and other functions

Problem: There are some error messages which show that libSDL2.so and some other libraries are missing magic plugin method.
The reason is that all compiled libraries will be put into /data/data/org.tuxpaint/lib/ folder, including dependent libraries, tuxpaint main libraries and tuxpaint plugin magic libraries.
However, tuxpaint will try to load those non-magic libraries in the defined magic library path, which cause mistake.

Solution: Since tuxpaint can tolerate the non-magic library even it complains, so let it go :)

Issue 12: Annoying joystick events from Android accelerometer

Problem: SDL2 will add Android accelerometer as a joystick device by default.
SDLActivity java class gets the sensor information and send this to native SDL2 library, and then send to Tux Paint, which will cause Tux Paint run joystick related method.
However, the accelerometer information may be useless for Tux Paint, since joystic events come so frequencely that will disturb current paint activity.

Solution: SDL2 will still take accelerometer as default joystick device.
But SDLActivity java class will not register sensor listener so that the SDL2 native library cannot get accelerometer information and will not send any joystick events to disturb tuxpaint.
Tux Paint will require no modification.

Issue 13: Screen keyboard gets weird on old Android device due to mbstowcs

Problem: It is very stange that screen keyboard gets weird on Android 4.4.4, while it runs well on Android 5.0.2.
This is caused by mbstowcs function in the src/im.c. The reason may be that the Bionic C library on the old Android device implements mbstowcs very simply. Refer to https://github.com/android/platform_bionic/commit/29c7f0b4d18f812267c2194b85204e19e41d0387, we can find that previous mbstowcs may cause the problem.

size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* /*ps*/) {
 const char* s = *src;
 const char* s2 = reinterpret_cast<const char*>(memchr(s, 0, len));

 if (s2 != NULL) {
 len = (size_t)(s2 - s) + 1U;
 }

 if (dst) {
 memcpy(reinterpret_cast<char*>(dst), s, len );
 }

 *src = s + len;
 return len;
}

Solution: We implement our own implementation of mbstowcs function for Tux Paint. For more information, please check out android_mbstowcs.h and android_mbstowcs.h.

Issue 14: Android has not support "setlocale" which will cause gettext not work.

Problem: Refer to (1) https://www.crystax.net/en/android/ndk, and (2) https://groups.google.com/forum/#!searchin/android-ndk/libintl.h$20/android-ndk/DPDArDwwNyI/U48vdovtPAAJ, NDK seems not to provide locale support in its C and C++ runtimes.
More accurately, refer to official Bionic C library https://github.com/android/platform_bionic:

    static bool __is_supported_locale(const char* locale) {
        return (strcmp(locale, "") == 0, strcmp(locale, "C") == 0, strcmp(locale, "C.UTF-8") == 0, strcmp(locale, "en_US.UTF-8") == 0, strcmp(locale, "POSIX") == 0);
    }

    char* setlocale(int category, const char* locale_name) {
        // Is "category" valid?
        if (category < LC_CTYPE, category > LC_IDENTIFICATION) {
        errno = EINVAL;
        return NULL;
        }
        // Caller wants to set the locale rather than just query?
        if (locale_name != NULL) {
        if (!__is_supported_locale(locale_name)) {
        // We don't support this locale.
        errno = ENOENT;
        return NULL;
        }
        __bionic_current_locale_is_utf8 = (strstr(locale_name, "UTF-8") != NULL);
        }
        return const_cast<char*>(__bionic_current_locale_is_utf8 ? "C.UTF-8" : "C");
    }

Current NDK Bionic really implement setlocale but not supports well :(

This issue will cause another problem that since gettext library depends on setlocale,
gettext can be compiled into Android, but cannot run as expected.

Solution: Refer to http://blog.stuff-o-matic.com/post/2013/09/07/Porting-a-C-game-to-Android%2C-the-case-of-Andy-s-Super-Great-Park,
libintl-lite http://sourceforge.net/projects/libintl-lite/ can work.
Currently Tux Paint-Android has used and extended this library instead of gettext.

Issue 15: simplified-chinese cannot show properly.

Problem: While traditional-chinese, japanese and other languages can work, simplified-chinese cannot work yet.

Solution: zh_CN.ttf is not included in current tuxpaint source code.
Instead, this can be downloaded from official tuxpaint website.
Thus, we will include this file into the assets folder.

Issue 16: Some input text from Android system onscreen keyborad cannot show, while some can succeed.

Problem: This is very strange that some text can show on screen, while some cannot.

Solution:
After debugging carefully, the reason is iswprintf function.
This function is used to test for a printable wide-character code.
However this function seems not implemented well by Bionic C library.
There is a comment in the bionic implementation https://github.com/android/platform_bionic/blob/master/libc/bionic/wctype.cpp

// TODO: these only work for the ASCII range; rewrite to dlsym icu4c? http://b/14499654

Because of this unstable behaviour, this function for testing will not be commented on the Android.

Issue 17: glib2 fails to compile due to valgrind

Problem:: Some error messages about CMP/MOV are shown.
The code below in valgrind.h will cause this issue.

    #if defined(PLAT_arm_linux)
        #define __SPECIAL_INSTRUCTION_PREAMBLE                    \
            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"

Solution: Although the reason is found, the corresponding solution cannot achieve yet. Instead, an alternative approach is that these valgrind related code in the glib2 will be commentted to disable valgrind.
Currently exploring the solution of adding the -marm flag to compile glib, will this break x86 builds?

Issue 18: libharfbuzz_ng seems not be accessable by pango during "System.loadLibrary" call

Problem: It is very strange that libharfbuzz_ng and pango library can compile successfully.
But pango cannot locate symbol hb_ft_face_create_cached of harfbuzz_ng when Tux Paint app starts to dynamically load libpango.so by System.loadLibrary.
Again sometimes cairo will also meet this issue that it cannot locate some symbols of png.

The reason may be that two libraries with same name in system lib path and local app lib path will have different versions.
For example, there is already libharfbuzz_ng in /system/lib folder, which is pre-builted and hosted by Android phone. On the other hand, we compile another version of libharfbuzz_ng for Tux Paint and host this in the apk.
And a strange behavior which is found but not confirmed is that System.loadLibrary seems to search libharfbuzz_ng in system path and then user app path. This will cause that compiled libharfbuzz_ng for tuxpaint is not loaded as we supposed, and the system libharfbuzz_ng seems a little old and not implement some new functions yet.

So Android already does pre-built so many libraries but only does export a few headers (see section Stable APIs of NDK Programmer's Guide). We have to build required libraries by ourselves.

Solution: To prevent loading those system libraries, we will add prefix tuxpaint_ for all of libraries execept SDL2 related libraries.

Issue 19: Tux Paint will crash when starting in the even number.

Problem: Tux Paint run well in the first time.
However when we quit normally and start Tux Paint again in the second time, it will crash.
The LogCate will out the following message:

A/libc(9473): invalid address or address of corrupt block 0xb7c09448 passed to try_realloc_chunk
A/libc(9473): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 10750 (SDLThread)

But when we try to start it again in the third time, it will succeed again.

Solution: It seems that Tux Paint will not quit normally when it does quit operation.
We can still find Tux Paint process there by following command:

adb shell
ps, grep tuxpaint

And if testing further with ps -t $(threadid), we can find that:

After Tux Paint starts successfully, there are many threads.

ffffffff 00000000 S org.tuxpaint
ffffffff 00000000 S Heap thread poo
ffffffff 00000000 S Heap thread poo
ffffffff 00000000 S Heap thread poo
ffffffff 00000000 S Signal Catcher
ffffffff 00000000 S JDWP
ffffffff 00000000 S ReferenceQueueD
ffffffff 00000000 S FinalizerDaemon
ffffffff 00000000 S FinalizerWatchd
ffffffff 00000000 S HeapTrimmerDaem
ffffffff 00000000 S GCDaemon
ffffffff 00000000 S Binder_1
ffffffff 00000000 S Binder_2
ffffffff 00000000 S RenderThread
ffffffff 00000000 S GL updater
ffffffff 00000000 R SDLThread
ffffffff 00000000 S Thread-37689
ffffffff 00000000 S Thread-37690
ffffffff 00000000 S AudioTrack
ffffffff 00000000 S Thread-37692
ffffffff 00000000 S GL updater
ffffffff 00000000 S Binder_3

After Tux Paint does quit operation, there are still many threads, but real work threads about Tux Paint quit indeed.
SDLThread is the thread for running native Tux Paint code, which indeed quits.

ffffffff 00000000 S org.tuxpaint
ffffffff 00000000 S Heap thread poo
ffffffff 00000000 S Heap thread poo
ffffffff 00000000 S Heap thread poo
ffffffff 00000000 S Signal Catcher
ffffffff 00000000 S JDWP
ffffffff 00000000 S ReferenceQueueD
ffffffff 00000000 S FinalizerDaemon
ffffffff 00000000 S FinalizerWatchd
ffffffff 00000000 S HeapTrimmerDaem
ffffffff 00000000 S GCDaemon
ffffffff 00000000 S Binder_1
ffffffff 00000000 S Binder_2
ffffffff 00000000 S RenderThread
ffffffff 00000000 S AudioTrack
ffffffff 00000000 S Binder_3

So this imcomplete quit operation will cause Tux Paint cannot start in the even number.
The patch is very simple that will force Tux Paint process quit in the SDLActivity class:

     public static void handleNativeExit() {
         SDLActivity.mSDLThread = null;
-        mSingleton.finish();
+//        mSingleton.finish();
+        System.exit(0);
     }

This can work fine, but seems not be the best approach.
A more reasonable approach shall be to make Tux Paint quit automatically by themselves.

Issue 20: Printing feature

Problem: Tux paint on Linux platform depends on lpr command (see postscript_print.h).
however currently it is not sure whether it can work for Android platform.
The Tux Paint on other platform depend on different native system APIs (see win32_print.h BeOS_print.h macosx_print.h).

Solution: Refer to https://developer.android.com/reference/android/support/v4/print/PrintHelper.html and https://developer.android.com/training/printing/photos.html, we use JNI and Android PrintHelper to support print feature on the Android.
However, another issue coming likely is that PrintHelper seems to depend on Android 4.4 SDK http://www.techotopia.com/index.php/Printing_with_the_Android_Printing_Framework#Options_for_Building_Print_Support_into_Android_Apps.

Issue 21: Label edit feature fails

Problem: start a new draw, go to the label tool, type "abc", save and close tuxpaint, now start again the same draw and try to edit the "abc" string to anything else, the string is corrupted.
Morever, it will not fail in the Android 5.0 devices, while it failed in the Android 4.x devices.

The reason seems that NDK Bionic does not implement well for fprintf and fscanf functions in the old Android devices. Tuxpaint tries to save and reload label information with following code:

	for (i = 0; i < current_node->save_texttool_len; i++)
	{
	  fprintf(lfi, "%lc", (wint_t) current_node->save_texttool_str[i]);
	}

and

            for(l = 0; l < new_node->save_texttool_len; l++)
                {
                    fscanf(lfi, "%lc", &tmp_char);
                    new_node->save_texttool_str[l] = tmp_char;
                }

However, %lc seems not to be parsed in a right way on the old Android devices.

Solution: Instead changing wchar_t to wint_t, here we change wchar_t to int so that it is easy to save and load the int value from the tmp file. This approach may be not very reasonable, but it works fine in practice.

Issue 22: ANDROID_API macro redefined warnings

If you build with ndk >= r15 the lowest supported SdkVersion is 14, you will get warnings about macro ANDROID_API redefined but it will compile anyway. Note that in order to get support for older Androids you need to compile with ndk r14b and uncomment the line in app/src/main/jni/Application.mk setting NDK_TOOLCHAIN_VERSION to 4.9

Issues and temporary Solution:

Issue 1: Some ttf fonts cannot show well for English words when default language is foreign language.

Problem: For example, if default language is Chinese, the Chinese words are rendered properly when we are using TEXT or LABEL tool.
However, if we want to enter some English words, sometimes these words can show well, while sometimes these words will become squares.
The reason seems that some fonts only support one language, which will cause other language cannot be rendered.