Re-ran indent on all .c & .h source code files
Like so --
find . -name "*.c" -or -name "*.h" -exec indent -nbfda -npcs -npsl -bli0 --no-tabs {} \;
The `indent` invocation differs from the last one noted in
CHANGES.txt (from 2006!?), in that I've added "--no-tabs",
to ensure indents are all space-based.
This commit is contained in:
parent
09f332367f
commit
cc05925d9e
99 changed files with 31659 additions and 27102 deletions
|
|
@ -19,25 +19,26 @@
|
|||
#include <android/asset_manager_jni.h>
|
||||
#include "android_assets.h"
|
||||
|
||||
AAssetManager * asset_manager = NULL;
|
||||
char* nativelibdir = NULL;
|
||||
AAssetManager *asset_manager = NULL;
|
||||
char *nativelibdir = NULL;
|
||||
|
||||
AAssetDir * open_asset_dir(char * dirname)
|
||||
AAssetDir *open_asset_dir(char *dirname)
|
||||
{
|
||||
return AAssetManager_openDir(asset_manager, dirname);
|
||||
}
|
||||
|
||||
char* get_nativelibdir()
|
||||
char *get_nativelibdir()
|
||||
{
|
||||
return nativelibdir;
|
||||
return nativelibdir;
|
||||
}
|
||||
|
||||
void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_file_names)
|
||||
void load_assets_dir(char *dirname, tp_ftw_str ** ffilenames,
|
||||
unsigned *num_file_names)
|
||||
{
|
||||
AAssetDir* assetDir = AAssetManager_openDir(asset_manager, dirname);
|
||||
const char* filename = (const char*)NULL;
|
||||
tp_ftw_str * filenames = NULL;
|
||||
|
||||
AAssetDir *assetDir = AAssetManager_openDir(asset_manager, dirname);
|
||||
const char *filename = (const char *) NULL;
|
||||
tp_ftw_str *filenames = NULL;
|
||||
|
||||
unsigned max_file_names = 0;
|
||||
int fulllen = 0;
|
||||
*num_file_names = 0;
|
||||
|
|
@ -46,7 +47,7 @@ void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_f
|
|||
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
|
||||
fulllen = strlen(filename) + 1;
|
||||
|
||||
if (*num_file_names == max_file_names)
|
||||
|
|
@ -66,7 +67,12 @@ void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_f
|
|||
*ffilenames = filenames;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv * env, jclass clazz, jobject mgr)
|
||||
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv *
|
||||
env,
|
||||
jclass
|
||||
clazz,
|
||||
jobject
|
||||
mgr)
|
||||
{
|
||||
asset_manager = AAssetManager_fromJava(env, mgr);
|
||||
|
||||
|
|
@ -76,7 +82,12 @@ JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv * env,
|
|||
return 1;
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv * env, jclass clazz, jstring path)
|
||||
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv *
|
||||
env,
|
||||
jclass
|
||||
clazz,
|
||||
jstring
|
||||
path)
|
||||
{
|
||||
const char *cpath = (*env)->GetStringUTFChars(env, path, NULL);
|
||||
nativelibdir = strdup(cpath);
|
||||
|
|
@ -84,21 +95,24 @@ JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv * env,
|
|||
}
|
||||
|
||||
|
||||
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count, const char *restrict const locale))
|
||||
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, const char *dirname,
|
||||
void (*fn)(SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count,
|
||||
const char *restrict const locale))
|
||||
{
|
||||
unsigned num_file_names = 0;
|
||||
char * dir = "data/brushes";
|
||||
char *dir = "data/brushes";
|
||||
char buf[TP_FTW_PATHSIZE];
|
||||
unsigned dirlen = strlen(dirname);
|
||||
|
||||
memcpy(buf, dir, dirlen);
|
||||
|
||||
tp_ftw_str * filenames = NULL;
|
||||
tp_ftw_str *filenames = NULL;
|
||||
|
||||
load_assets_dir(dirname, &filenames, &num_file_names);
|
||||
fn(screen, texture, renderer, dir, dirlen, filenames, num_file_names, NULL);
|
||||
|
|
@ -107,12 +121,14 @@ void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Re
|
|||
|
||||
|
||||
|
||||
void load_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count, const char *restrict const locale))
|
||||
void load_from_assets(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, const char *dirname,
|
||||
void (*fn)(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count,
|
||||
const char *restrict const locale))
|
||||
{
|
||||
unsigned num_file_names = 0;
|
||||
// char * dir = "data/stamps/cartoon/tux";
|
||||
|
|
@ -121,8 +137,9 @@ void load_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *
|
|||
|
||||
memcpy(buf, dirname, dirlen);
|
||||
|
||||
tp_ftw_str * filenames = NULL;
|
||||
tp_ftw_str *filenames = NULL;
|
||||
|
||||
load_assets_dir(dirname, &filenames, &num_file_names);
|
||||
fn(screen, texture, renderer, dirname, dirlen, filenames, num_file_names, NULL);
|
||||
fn(screen, texture, renderer, dirname, dirlen, filenames, num_file_names,
|
||||
NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#define TP_ANDROID_ASSETS
|
||||
#include <jni.h>
|
||||
#include "debug.h"
|
||||
#include "debug.h"
|
||||
#include "dirwalk.h"
|
||||
#include "progressbar.h"
|
||||
#include <android/asset_manager.h>
|
||||
|
|
@ -28,27 +28,43 @@
|
|||
#define ASSETS_BRUSHES_DIR "data/brushes"
|
||||
#define ASSETS_STAMPS_DIR "stamps/cartoon/tux"
|
||||
|
||||
AAssetDir * open_asset_dir(char * dirname);
|
||||
char* get_nativelibdir();
|
||||
AAssetDir *open_asset_dir(char *dirname);
|
||||
char *get_nativelibdir();
|
||||
|
||||
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count, const char *restrict const locale) );
|
||||
void load_brushes_from_assets(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, const char *dirname,
|
||||
void (*fn)(SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count,
|
||||
const char *restrict const locale));
|
||||
|
||||
void load_from_assets(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer, const char * dirname, void (*fn) (SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count, const char *restrict const locale) );
|
||||
void load_from_assets(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, const char *dirname,
|
||||
void (*fn)(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir,
|
||||
unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count,
|
||||
const char *restrict const locale));
|
||||
|
||||
void load_assets_dir(char * dirname, tp_ftw_str ** ffilenames, unsigned * num_file_names);
|
||||
void load_assets_dir(char *dirname, tp_ftw_str ** ffilenames,
|
||||
unsigned *num_file_names);
|
||||
|
||||
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv * env, jclass clazz, jobject mgr);
|
||||
JNIEXPORT jboolean Java_org_tuxpaint_tuxpaintActivity_managertojni(JNIEnv *
|
||||
env,
|
||||
jclass
|
||||
clazz,
|
||||
jobject
|
||||
mgr);
|
||||
|
||||
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv * env, jclass clazz, jstring path);
|
||||
JNIEXPORT void Java_org_tuxpaint_tuxpaintActivity_setnativelibdir(JNIEnv *
|
||||
env,
|
||||
jclass
|
||||
clazz,
|
||||
jstring
|
||||
path);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,58 +30,67 @@
|
|||
#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;
|
||||
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;
|
||||
}
|
||||
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++;
|
||||
c += len;
|
||||
w++;
|
||||
|
||||
if (c > length){
|
||||
pwcs[w] = '\0';
|
||||
return -1;
|
||||
}
|
||||
if (c == length){
|
||||
pwcs[w] = '\0';
|
||||
return w;
|
||||
}
|
||||
}
|
||||
if (c > length)
|
||||
{
|
||||
pwcs[w] = '\0';
|
||||
return -1;
|
||||
}
|
||||
if (c == length)
|
||||
{
|
||||
pwcs[w] = '\0';
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,6 @@ Anyway, using our own implementation of "mbstowcs" can fix this problem.
|
|||
#undef mbsrtowcs
|
||||
|
||||
// redefine mbstowcs function
|
||||
size_t mbstowcs(wchar_t * __restrict pwcs, const char * __restrict s, size_t n);
|
||||
size_t mbstowcs(wchar_t *__restrict pwcs, const char *__restrict s, size_t n);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
(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
|
||||
|
|
@ -31,58 +31,80 @@
|
|||
/* FIXME: Is this check still needed after the change from android/support/v4 to AndroidX
|
||||
and being Android 5 the minimum version we support? */
|
||||
// Since Print work is based on Java PrintHelper class, which may not be supported on some old versions
|
||||
int IsPrinterAvailable( void )
|
||||
int IsPrinterAvailable(void)
|
||||
{
|
||||
JNIEnv *mEnv = Android_JNI_GetEnv();
|
||||
jclass mPrintHelperClass = (*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");
|
||||
JNIEnv *mEnv = Android_JNI_GetEnv();
|
||||
jclass mPrintHelperClass =
|
||||
(*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");
|
||||
|
||||
if (mPrintHelperClass == NULL)
|
||||
return 0;
|
||||
if (mPrintHelperClass == NULL)
|
||||
return 0;
|
||||
|
||||
jmethodID mSupportMethod = (*mEnv)->GetStaticMethodID(mEnv, mPrintHelperClass, "systemSupportsPrint", "()Z");
|
||||
jboolean support = (*mEnv)->CallStaticBooleanMethod(mEnv, mPrintHelperClass, mSupportMethod);
|
||||
jmethodID mSupportMethod =
|
||||
(*mEnv)->GetStaticMethodID(mEnv, mPrintHelperClass, "systemSupportsPrint",
|
||||
"()Z");
|
||||
jboolean support =
|
||||
(*mEnv)->CallStaticBooleanMethod(mEnv, mPrintHelperClass, mSupportMethod);
|
||||
|
||||
return support ? 1 : 0;
|
||||
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)
|
||||
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);
|
||||
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, "androidx/print/PrintHelper");
|
||||
// sometimes android v4 support library may be not ready
|
||||
if (mPrintClass == NULL)
|
||||
return "There is no androidX 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");
|
||||
jobject mContext = (jobject) SDL_AndroidGetActivity();
|
||||
jclass mPrintClass = (*mEnv)->FindClass(mEnv, "androidx/print/PrintHelper");
|
||||
// sometimes android v4 support library may be not ready
|
||||
if (mPrintClass == NULL)
|
||||
return "There is no androidX 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");
|
||||
|
||||
/* Thanks to n.collins for the explaination on the int signature
|
||||
on https://stackoverflow.com/questions/13468041/android-how-to-call-java-method-from-jni-with-int-and-int-parameters --Pere */
|
||||
jmethodID msetScaleMode = (*mEnv)->GetMethodID(mEnv, mPrintClass, "setScaleMode", "(I)V");
|
||||
jfieldID mScaleModeField = (*mEnv)->GetStaticFieldID(mEnv, mPrintClass, "SCALE_MODE_FIT", "I");
|
||||
jint mScaleModeInt = (*mEnv)->GetStaticIntField(mEnv, mPrintClass, mScaleModeField);
|
||||
(*mEnv)->CallVoidMethod(mEnv, mPrint, msetScaleMode, mScaleModeInt);
|
||||
/* Thanks to n.collins for the explaination on the int signature
|
||||
on https://stackoverflow.com/questions/13468041/android-how-to-call-java-method-from-jni-with-int-and-int-parameters --Pere */
|
||||
jmethodID msetScaleMode =
|
||||
(*mEnv)->GetMethodID(mEnv, mPrintClass, "setScaleMode", "(I)V");
|
||||
jfieldID mScaleModeField =
|
||||
(*mEnv)->GetStaticFieldID(mEnv, mPrintClass, "SCALE_MODE_FIT", "I");
|
||||
jint mScaleModeInt =
|
||||
(*mEnv)->GetStaticIntField(mEnv, mPrintClass, mScaleModeField);
|
||||
(*mEnv)->CallVoidMethod(mEnv, mPrint, msetScaleMode, mScaleModeInt);
|
||||
|
||||
jstring mString = (*mEnv)->NewStringUTF(mEnv, "TuxPaint");
|
||||
(*mEnv)->CallVoidMethod(mEnv, mPrint, mPrintMethod, mString, mBitMap);
|
||||
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;
|
||||
// clean up
|
||||
(*mEnv)->DeleteLocalRef(mEnv, mSurfaceArray);
|
||||
(*mEnv)->DeleteLocalRef(mEnv, mConfig);
|
||||
(*mEnv)->DeleteLocalRef(mEnv, mPrint);
|
||||
(*mEnv)->DeleteLocalRef(mEnv, mString);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* android_print.h */
|
||||
|
||||
/* printing support for Tux Paint */
|
||||
|
||||
/* 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
|
||||
|
|
@ -17,15 +17,15 @@
|
|||
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 const char *SurfacePrint(SDL_Surface * surface);
|
||||
extern int IsPrinterAvailable(void);
|
||||
|
||||
#endif /* __ANDROID_PRINT__ */
|
||||
|
||||
#endif /* __ANDROID_PRINT__ */
|
||||
|
|
|
|||
|
|
@ -129,9 +129,8 @@
|
|||
/* h/t https://tutel.me/c/programming/questions/45349079/how+to+use+__attribute__fallthrough+correctly+in+gcc */
|
||||
#ifndef FALLTHROUGH
|
||||
#if defined(__GNUC__) && __GNUC__ >= 7
|
||||
#define FALL_THROUGH __attribute__ ((fallthrough))
|
||||
#define FALL_THROUGH __attribute__ ((fallthrough))
|
||||
#else
|
||||
#define FALL_THROUGH ((void)0)
|
||||
#define FALL_THROUGH ((void)0)
|
||||
#endif /* __GNUC__ >= 7 */
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ void do_setcursor(SDL_Cursor * c)
|
|||
void free_cursor(SDL_Cursor ** cursor)
|
||||
{
|
||||
if (*cursor)
|
||||
{
|
||||
SDL_FreeCursor(*cursor);
|
||||
*cursor = NULL;
|
||||
}
|
||||
{
|
||||
SDL_FreeCursor(*cursor);
|
||||
*cursor = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
598
src/dirwalk.c
598
src/dirwalk.c
|
|
@ -79,8 +79,10 @@ extern char *strcasestr(const char *haystack, const char *needle);
|
|||
* @param screen Screen surface, for animating progress bar.
|
||||
* FIXME
|
||||
*/
|
||||
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
|
||||
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files, unsigned i,
|
||||
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir, unsigned dirlen,
|
||||
tp_ftw_str * files, unsigned i,
|
||||
const char *restrict const locale)
|
||||
{
|
||||
dirlen = dirlen;
|
||||
|
|
@ -90,188 +92,209 @@ void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer
|
|||
#else
|
||||
while (i--)
|
||||
#endif
|
||||
{
|
||||
int loadable = 0;
|
||||
const char *restrict const cp = strchr(files[i].str, '.');
|
||||
|
||||
show_progress_bar_(screen, texture, renderer);
|
||||
if (cp)
|
||||
{
|
||||
int loadable = 0;
|
||||
const char *restrict const cp = strchr(files[i].str, '.');
|
||||
// need gcc 3.4 for the restrict in this location
|
||||
const char * /*restrict */ const suffixes[] =
|
||||
{ "ttc", "dfont", "pfa", "pfb", "otf", "ttf", };
|
||||
int j = sizeof suffixes / sizeof suffixes[0];
|
||||
|
||||
show_progress_bar_(screen, texture, renderer);
|
||||
if (cp)
|
||||
while (j--)
|
||||
{
|
||||
// only check part, because of potential .gz or .bz2 suffix
|
||||
if (!strncasecmp(cp + 1, suffixes[j], strlen(suffixes[j])))
|
||||
{
|
||||
// need gcc 3.4 for the restrict in this location
|
||||
const char * /*restrict */ const suffixes[] =
|
||||
{ "ttc", "dfont", "pfa", "pfb", "otf", "ttf", };
|
||||
int j = sizeof suffixes / sizeof suffixes[0];
|
||||
|
||||
while (j--)
|
||||
{
|
||||
// only check part, because of potential .gz or .bz2 suffix
|
||||
if (!strncasecmp(cp + 1, suffixes[j], strlen(suffixes[j])))
|
||||
{
|
||||
loadable = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
loadable = 1;
|
||||
break;
|
||||
}
|
||||
if (!loadable)
|
||||
}
|
||||
}
|
||||
if (!loadable)
|
||||
{
|
||||
if (strcasestr(files[i].str, "/rsrc"))
|
||||
loadable = 1;
|
||||
}
|
||||
// Loadable: TrueType (.ttf), OpenType (.otf), Type1 (.pfa and .pfb),
|
||||
// and various useless bitmap fonts. Compressed files (with .gz or .bz2)
|
||||
// should also work. A *.dfont is pretty much a Mac resource fork in a normal
|
||||
// file, and may load with some library versions.
|
||||
if (loadable)
|
||||
{
|
||||
char fname[512];
|
||||
TuxPaint_Font *font;
|
||||
|
||||
snprintf(fname, sizeof fname, "%s/%s", dir, files[i].str);
|
||||
#ifdef DEBUG
|
||||
printf("%s:%d - Loading font: %s (locale is: %s)\n", __FILE__, __LINE__, fname, (locale ? locale : "NULL")); //EP
|
||||
fflush(stdout);
|
||||
#endif
|
||||
if (locale && strstr(fname, "locale") && !all_locale_fonts)
|
||||
{
|
||||
char fname_check[512];
|
||||
|
||||
/* We're (probably) loading from our locale fonts folder; ONLY load our locale's font */
|
||||
snprintf(fname_check, sizeof fname_check, "%s/%s.ttf", dir, locale);
|
||||
#ifdef DEBUG
|
||||
printf("%s:%d - checking \"%s\" vs \"%s\"\n", __FILE__, __LINE__, fname_check, fname); //EP
|
||||
#endif
|
||||
if (strcmp(fname, fname_check) == 0)
|
||||
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
|
||||
else
|
||||
font = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
|
||||
}
|
||||
if (font)
|
||||
{
|
||||
const char *restrict const family =
|
||||
TuxPaint_Font_FontFaceFamilyName(font);
|
||||
const char *restrict const style =
|
||||
TuxPaint_Font_FontFaceStyleName(font);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
if (font->typ == FONT_TYPE_TTF)
|
||||
{
|
||||
if (strcasestr(files[i].str, "/rsrc"))
|
||||
loadable = 1;
|
||||
int numfaces = TTF_FontFaces(font->ttf_font);
|
||||
|
||||
if (numfaces != 1)
|
||||
printf("%s:%d - Found %d faces in %s, %s, %s\n", __FILE__,
|
||||
__LINE__, numfaces, files[i].str, family, style);
|
||||
|
||||
printf("%s:%d - success: tpf: 0x%x tpf->ttf_font: 0x%x\n", __FILE__, __LINE__, (unsigned int) (intptr_t) font, (unsigned int) (intptr_t) font->ttf_font); //EP added (intptr_t) to avoid warning on x64
|
||||
}
|
||||
// Loadable: TrueType (.ttf), OpenType (.otf), Type1 (.pfa and .pfb),
|
||||
// and various useless bitmap fonts. Compressed files (with .gz or .bz2)
|
||||
// should also work. A *.dfont is pretty much a Mac resource fork in a normal
|
||||
// file, and may load with some library versions.
|
||||
if (loadable)
|
||||
{
|
||||
char fname[512];
|
||||
TuxPaint_Font *font;
|
||||
|
||||
snprintf(fname, sizeof fname, "%s/%s", dir, files[i].str);
|
||||
#ifdef DEBUG
|
||||
printf("%s:%d - Loading font: %s (locale is: %s)\n", __FILE__, __LINE__, fname, (locale ? locale : "NULL")); //EP
|
||||
fflush(stdout);
|
||||
#endif
|
||||
if (locale && strstr(fname, "locale") && !all_locale_fonts)
|
||||
{
|
||||
char fname_check[512];
|
||||
|
||||
/* We're (probably) loading from our locale fonts folder; ONLY load our locale's font */
|
||||
snprintf(fname_check, sizeof fname_check, "%s/%s.ttf", dir, locale);
|
||||
#ifdef DEBUG
|
||||
printf("%s:%d - checking \"%s\" vs \"%s\"\n", __FILE__, __LINE__, fname_check, fname); //EP
|
||||
#endif
|
||||
if (strcmp(fname, fname_check) == 0)
|
||||
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
|
||||
else
|
||||
font = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
font = TuxPaint_Font_OpenFont("", fname, text_sizes[text_size]);
|
||||
}
|
||||
if (font)
|
||||
{
|
||||
const char *restrict const family = TuxPaint_Font_FontFaceFamilyName(font);
|
||||
const char *restrict const style = TuxPaint_Font_FontFaceStyleName(font);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
if (font->typ == FONT_TYPE_TTF)
|
||||
{
|
||||
int numfaces = TTF_FontFaces(font->ttf_font);
|
||||
|
||||
if (numfaces != 1)
|
||||
printf("%s:%d - Found %d faces in %s, %s, %s\n", __FILE__, __LINE__, numfaces, files[i].str, family, style);
|
||||
|
||||
printf("%s:%d - success: tpf: 0x%x tpf->ttf_font: 0x%x\n", __FILE__, __LINE__, (unsigned int)(intptr_t) font, (unsigned int)(intptr_t) font->ttf_font); //EP added (intptr_t) to avoid warning on x64
|
||||
}
|
||||
#ifndef NO_SDLPANGO
|
||||
else
|
||||
printf("%s:%d - success: tpf: 0x%x tpf->pango_context: 0x%x\n", __FILE__, __LINE__, (unsigned int)(intptr_t) font, (unsigned int)(intptr_t) font->pango_context);
|
||||
else
|
||||
printf("%s:%d - success: tpf: 0x%x tpf->pango_context: 0x%x\n",
|
||||
__FILE__, __LINE__, (unsigned int) (intptr_t) font,
|
||||
(unsigned int) (intptr_t) font->pango_context);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// These fonts crash Tux Paint via a library bug.
|
||||
int blacklisted = !strcmp("Zapfino", family) || !strcmp("Elvish Ring NFI", family);
|
||||
// These fonts crash Tux Paint via a library bug.
|
||||
int blacklisted = !strcmp("Zapfino", family)
|
||||
|| !strcmp("Elvish Ring NFI", family);
|
||||
|
||||
// First, the blacklist. We list font families that can crash Tux Paint
|
||||
// via bugs in the SDL_ttf library. We also test fonts to be sure that
|
||||
// they have both uppercase and lowercase letters. Note that we do not
|
||||
// test for "Aa", because it is OK if uppercase and lowercase are the
|
||||
// same (but not nice -- such fonts get a low score later).
|
||||
//
|
||||
// Most locales leave the blacklist strings alone: "QX" and "qx"
|
||||
// (it is less destructive to use the scoring strings instead)
|
||||
//
|
||||
// Locales that absolutely require all fonts to have some
|
||||
// extra characters should use "QX..." and "qx...", where "..."
|
||||
// are some characters you absolutely require in all fonts.
|
||||
//
|
||||
// Locales with absolutely NO use for ASCII may use "..." and "...",
|
||||
// where "..." are some characters you absolutely require in
|
||||
// all fonts. This would be the case for a locale in which it is
|
||||
// impossible for a user to type ASCII letters.
|
||||
//
|
||||
// Most translators should use scoring instead.
|
||||
if (!charset_works(font, gettext("qx")) || !charset_works(font, gettext("QX")))
|
||||
blacklisted = 1;
|
||||
// First, the blacklist. We list font families that can crash Tux Paint
|
||||
// via bugs in the SDL_ttf library. We also test fonts to be sure that
|
||||
// they have both uppercase and lowercase letters. Note that we do not
|
||||
// test for "Aa", because it is OK if uppercase and lowercase are the
|
||||
// same (but not nice -- such fonts get a low score later).
|
||||
//
|
||||
// Most locales leave the blacklist strings alone: "QX" and "qx"
|
||||
// (it is less destructive to use the scoring strings instead)
|
||||
//
|
||||
// Locales that absolutely require all fonts to have some
|
||||
// extra characters should use "QX..." and "qx...", where "..."
|
||||
// are some characters you absolutely require in all fonts.
|
||||
//
|
||||
// Locales with absolutely NO use for ASCII may use "..." and "...",
|
||||
// where "..." are some characters you absolutely require in
|
||||
// all fonts. This would be the case for a locale in which it is
|
||||
// impossible for a user to type ASCII letters.
|
||||
//
|
||||
// Most translators should use scoring instead.
|
||||
if (!charset_works(font, gettext("qx"))
|
||||
|| !charset_works(font, gettext("QX")))
|
||||
blacklisted = 1;
|
||||
|
||||
if (!blacklisted)
|
||||
{
|
||||
if (num_font_styles == num_font_styles_max)
|
||||
{
|
||||
num_font_styles_max = num_font_styles_max * 5 / 4 + 30;
|
||||
user_font_styles = realloc(user_font_styles, num_font_styles_max * sizeof *user_font_styles);
|
||||
}
|
||||
user_font_styles[num_font_styles] = malloc(sizeof *user_font_styles[num_font_styles]);
|
||||
user_font_styles[num_font_styles]->directory = strdup(dir);
|
||||
user_font_styles[num_font_styles]->filename = files[i].str; // steal it (mark NULL below)
|
||||
user_font_styles[num_font_styles]->family = strdup(family);
|
||||
user_font_styles[num_font_styles]->style = strdup(style);
|
||||
user_font_styles[num_font_styles]->score = 0;
|
||||
if (!blacklisted)
|
||||
{
|
||||
if (num_font_styles == num_font_styles_max)
|
||||
{
|
||||
num_font_styles_max = num_font_styles_max * 5 / 4 + 30;
|
||||
user_font_styles =
|
||||
realloc(user_font_styles,
|
||||
num_font_styles_max * sizeof *user_font_styles);
|
||||
}
|
||||
user_font_styles[num_font_styles] =
|
||||
malloc(sizeof *user_font_styles[num_font_styles]);
|
||||
user_font_styles[num_font_styles]->directory = strdup(dir);
|
||||
user_font_styles[num_font_styles]->filename = files[i].str; // steal it (mark NULL below)
|
||||
user_font_styles[num_font_styles]->family = strdup(family);
|
||||
user_font_styles[num_font_styles]->style = strdup(style);
|
||||
user_font_styles[num_font_styles]->score = 0;
|
||||
|
||||
// TODO: weight specification
|
||||
// TODO: weight specification
|
||||
|
||||
// Now we score fonts to ensure that the best ones will be placed at
|
||||
// the top of the list. The user will see them first. This sorting is
|
||||
// especially important for users who have scroll buttons disabled.
|
||||
// Translators should do whatever is needed to put crummy fonts last.
|
||||
// Now we score fonts to ensure that the best ones will be placed at
|
||||
// the top of the list. The user will see them first. This sorting is
|
||||
// especially important for users who have scroll buttons disabled.
|
||||
// Translators should do whatever is needed to put crummy fonts last.
|
||||
|
||||
// distinct uppercase and lowercase (e.g., 'o' vs. 'O')
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("oO"));
|
||||
// distinct uppercase and lowercase (e.g., 'o' vs. 'O')
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("oO"));
|
||||
|
||||
// common punctuation (e.g., '?', '!', '.', ',', etc.)
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext(",.?!"));
|
||||
// common punctuation (e.g., '?', '!', '.', ',', etc.)
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext(",.?!"));
|
||||
|
||||
// uncommon punctuation (e.g., '@', '#', '*', etc.)
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("`\%_@$~#{<(^&*"));
|
||||
// uncommon punctuation (e.g., '@', '#', '*', etc.)
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("`\%_@$~#{<(^&*"));
|
||||
|
||||
// digits (e.g., '0', '1' and '7')
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("017"));
|
||||
// digits (e.g., '0', '1' and '7')
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("017"));
|
||||
|
||||
// distinct circle-like characters (e.g., 'O' (capital oh) vs. '0' (zero))
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("O0"));
|
||||
// distinct circle-like characters (e.g., 'O' (capital oh) vs. '0' (zero))
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("O0"));
|
||||
|
||||
// distinct line-like characters (e.g., 'l' (lowercase elle) vs. '1' (one) vs. 'I' (capital aye))
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("1Il|"));
|
||||
// distinct line-like characters (e.g., 'l' (lowercase elle) vs. '1' (one) vs. 'I' (capital aye))
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("1Il|"));
|
||||
|
||||
// translation spares -- design not finalized
|
||||
// translation spares -- design not finalized
|
||||
#if 0
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<1>spare-1a"));
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<1>spare-1b"));
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<9>spare-9a")) * 9;
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, gettext("<9>spare-9b")) * 9;
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("<1>spare-1a"));
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("<1>spare-1b"));
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("<9>spare-9a")) * 9;
|
||||
user_font_styles[num_font_styles]->score +=
|
||||
charset_works(font, gettext("<9>spare-9b")) * 9;
|
||||
#endif
|
||||
|
||||
// this really should be dynamic, avoiding the need for a special build
|
||||
#ifdef OLPC_XO
|
||||
// Maybe German adds a "\xc2\xb7" (middle dot) and colon here? The key wouldn't change though.
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, "\xc3\x97\xc3\xb7"); // multiply and divide
|
||||
// Maybe German adds a "\xc2\xb7" (middle dot) and colon here? The key wouldn't change though.
|
||||
user_font_styles[num_font_styles]->score += charset_works(font, "\xc3\x97\xc3\xb7"); // multiply and divide
|
||||
#endif
|
||||
|
||||
// FIXME: add topology tests ('A' has one hole, 'B' has two holes, etc.)
|
||||
// FIXME: add topology tests ('A' has one hole, 'B' has two holes, etc.)
|
||||
|
||||
num_font_styles++;
|
||||
num_font_styles++;
|
||||
//printf("Accepted: %s, %s, %s, score(%d)\n", files[i].str, family, style, user_font_styles[num_font_styles]->score);
|
||||
files[i].str = NULL; // so free() won't crash -- we stole the memory
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Font is too defective: %s, %s, %s\n", files[i].str, family, style);
|
||||
#endif
|
||||
}
|
||||
TuxPaint_Font_CloseFont(font);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "could not open %s\n", files[i].str);
|
||||
#endif
|
||||
}
|
||||
files[i].str = NULL; // so free() won't crash -- we stole the memory
|
||||
}
|
||||
free(files[i].str);
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "Font is too defective: %s, %s, %s\n", files[i].str,
|
||||
family, style);
|
||||
#endif
|
||||
}
|
||||
TuxPaint_Font_CloseFont(font);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "could not open %s\n", files[i].str);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
free(files[i].str);
|
||||
}
|
||||
free(files);
|
||||
}
|
||||
|
||||
|
|
@ -305,10 +328,17 @@ int compare_ftw_str(const void *v1, const void *v2)
|
|||
* @param fn Callback function to invoke
|
||||
* @param locale Locale, to pass to callback function when applicable (i.e., for fonts), else NULL
|
||||
*/
|
||||
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, char *restrict const dir,
|
||||
unsigned dirlen, int rsrc, void (*fn) (SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
|
||||
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count, const char *restrict const locale),
|
||||
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, char *restrict const dir,
|
||||
unsigned dirlen, int rsrc, void (*fn)(SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const
|
||||
dir, unsigned dirlen,
|
||||
tp_ftw_str * files,
|
||||
unsigned count,
|
||||
const char *restrict const
|
||||
locale),
|
||||
const char *restrict const locale)
|
||||
{
|
||||
DIR *d;
|
||||
|
|
@ -335,173 +365,177 @@ void tp_ftw(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer
|
|||
AAssetDir *adir;
|
||||
|
||||
if (!d) /* Fallback into assets */
|
||||
{
|
||||
/* Remove the trailing '/' */
|
||||
dlen = strlen(dir) - 1;
|
||||
di = strndup(dir, dlen);
|
||||
adir = open_asset_dir(di);
|
||||
if (!adir)
|
||||
return;
|
||||
}
|
||||
{
|
||||
/* Remove the trailing '/' */
|
||||
dlen = strlen(dir) - 1;
|
||||
di = strndup(dir, dlen);
|
||||
adir = open_asset_dir(di);
|
||||
if (!adir)
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (!d)
|
||||
return;
|
||||
#endif
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct dirent *f;
|
||||
{
|
||||
struct dirent *f;
|
||||
|
||||
if (d)
|
||||
f = readdir(d);
|
||||
int filetype = TP_FTW_UNKNOWN;
|
||||
if (d)
|
||||
f = readdir(d);
|
||||
int filetype = TP_FTW_UNKNOWN;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
char *afilename;
|
||||
char *afilename;
|
||||
|
||||
if (!d)
|
||||
{
|
||||
afilename = AAssetDir_getNextFileName(adir);
|
||||
if (afilename)
|
||||
{
|
||||
f = malloc(sizeof(struct dirent));
|
||||
strncpy(f->d_name, afilename, sizeof(f->d_name));
|
||||
f->d_type = DT_REG;
|
||||
if (!d)
|
||||
{
|
||||
afilename = AAssetDir_getNextFileName(adir);
|
||||
if (afilename)
|
||||
{
|
||||
f = malloc(sizeof(struct dirent));
|
||||
strncpy(f->d_name, afilename, sizeof(f->d_name));
|
||||
f->d_type = DT_REG;
|
||||
|
||||
/* There is not _DIRENT_HAVE_D_NAMLEN currently on Android 4.3, but who knows in the future... */
|
||||
/* There is not _DIRENT_HAVE_D_NAMLEN currently on Android 4.3, but who knows in the future... */
|
||||
#if defined(_DIRENT_HAVE_D_NAMLEN)
|
||||
f->d_namlen = strlen(f->d_name);
|
||||
f->d_namlen = strlen(f->d_name);
|
||||
#endif
|
||||
|
||||
/* AAssetDir_getNextFileName() only lists files, not (sub)dirs,
|
||||
and we don't put any device or special file inside assets,
|
||||
so it is a regular file */
|
||||
filetype = TP_FTW_NORMAL;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!f)
|
||||
/* AAssetDir_getNextFileName() only lists files, not (sub)dirs,
|
||||
and we don't put any device or special file inside assets,
|
||||
so it is a regular file */
|
||||
filetype = TP_FTW_NORMAL;
|
||||
}
|
||||
else
|
||||
break;
|
||||
if (f->d_name[0] == '.')
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!f)
|
||||
break;
|
||||
if (f->d_name[0] == '.')
|
||||
continue;
|
||||
// Linux and BSD can often provide file type info w/o the stat() call
|
||||
#ifdef DT_UNKNOWN
|
||||
switch (f->d_type)
|
||||
{
|
||||
default:
|
||||
continue;
|
||||
case DT_REG:
|
||||
if (!rsrc) // if maybe opening resource files, need st_size
|
||||
filetype = TP_FTW_NORMAL;
|
||||
break;
|
||||
case DT_DIR:
|
||||
filetype = TP_FTW_DIRECTORY;
|
||||
break;
|
||||
case DT_UNKNOWN:
|
||||
case DT_LNK:
|
||||
;
|
||||
}
|
||||
switch (f->d_type)
|
||||
{
|
||||
default:
|
||||
continue;
|
||||
case DT_REG:
|
||||
if (!rsrc) // if maybe opening resource files, need st_size
|
||||
filetype = TP_FTW_NORMAL;
|
||||
break;
|
||||
case DT_DIR:
|
||||
filetype = TP_FTW_DIRECTORY;
|
||||
break;
|
||||
case DT_UNKNOWN:
|
||||
case DT_LNK:
|
||||
;
|
||||
}
|
||||
#else
|
||||
#warning Failed to see DT_UNKNOWN
|
||||
#endif
|
||||
|
||||
#if defined(_DIRENT_HAVE_D_NAMLEN) || defined(__APPLE__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
|
||||
d_namlen = f->d_namlen;
|
||||
d_namlen = f->d_namlen;
|
||||
#else
|
||||
d_namlen = strlen(f->d_name);
|
||||
d_namlen = strlen(f->d_name);
|
||||
#endif
|
||||
add_rsrc = 0;
|
||||
add_rsrc = 0;
|
||||
|
||||
if (filetype == TP_FTW_UNKNOWN)
|
||||
{
|
||||
struct stat sbuf;
|
||||
if (filetype == TP_FTW_UNKNOWN)
|
||||
{
|
||||
struct stat sbuf;
|
||||
|
||||
memcpy(dir + dirlen, f->d_name, d_namlen + 1);
|
||||
if (stat(dir, &sbuf))
|
||||
continue; // oh well... try the next one
|
||||
if (S_ISDIR(sbuf.st_mode))
|
||||
filetype = TP_FTW_DIRECTORY;
|
||||
else if (S_ISREG(sbuf.st_mode))
|
||||
{
|
||||
filetype = TP_FTW_NORMAL;
|
||||
if (rsrc && !sbuf.st_size)
|
||||
add_rsrc = 5; // 5 is length of "/rsrc"
|
||||
}
|
||||
else
|
||||
continue; // was a device file or somesuch
|
||||
}
|
||||
if (filetype == TP_FTW_NORMAL)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (num_file_names == max_file_names)
|
||||
{
|
||||
max_file_names = max_file_names * 5 / 4 + 30;
|
||||
file_names = realloc(file_names, max_file_names * sizeof *file_names);
|
||||
}
|
||||
cp = malloc(d_namlen + add_rsrc + 1);
|
||||
memcpy(cp, f->d_name, d_namlen);
|
||||
if (add_rsrc)
|
||||
memcpy(cp + d_namlen, "/rsrc", 6);
|
||||
else
|
||||
cp[d_namlen] = '\0';
|
||||
file_names[num_file_names].str = cp;
|
||||
file_names[num_file_names].len = d_namlen;
|
||||
num_file_names++;
|
||||
}
|
||||
if (filetype == TP_FTW_DIRECTORY)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (num_dir_names == max_dir_names)
|
||||
{
|
||||
max_dir_names = max_dir_names * 5 / 4 + 3;
|
||||
dir_names = realloc(dir_names, max_dir_names * sizeof *dir_names);
|
||||
}
|
||||
cp = malloc(d_namlen + 1);
|
||||
memcpy(cp, f->d_name, d_namlen + 1);
|
||||
dir_names[num_dir_names].str = cp;
|
||||
dir_names[num_dir_names].len = d_namlen;
|
||||
num_dir_names++;
|
||||
}
|
||||
memcpy(dir + dirlen, f->d_name, d_namlen + 1);
|
||||
if (stat(dir, &sbuf))
|
||||
continue; // oh well... try the next one
|
||||
if (S_ISDIR(sbuf.st_mode))
|
||||
filetype = TP_FTW_DIRECTORY;
|
||||
else if (S_ISREG(sbuf.st_mode))
|
||||
{
|
||||
filetype = TP_FTW_NORMAL;
|
||||
if (rsrc && !sbuf.st_size)
|
||||
add_rsrc = 5; // 5 is length of "/rsrc"
|
||||
}
|
||||
else
|
||||
continue; // was a device file or somesuch
|
||||
}
|
||||
if (filetype == TP_FTW_NORMAL)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (num_file_names == max_file_names)
|
||||
{
|
||||
max_file_names = max_file_names * 5 / 4 + 30;
|
||||
file_names = realloc(file_names, max_file_names * sizeof *file_names);
|
||||
}
|
||||
cp = malloc(d_namlen + add_rsrc + 1);
|
||||
memcpy(cp, f->d_name, d_namlen);
|
||||
if (add_rsrc)
|
||||
memcpy(cp + d_namlen, "/rsrc", 6);
|
||||
else
|
||||
cp[d_namlen] = '\0';
|
||||
file_names[num_file_names].str = cp;
|
||||
file_names[num_file_names].len = d_namlen;
|
||||
num_file_names++;
|
||||
}
|
||||
if (filetype == TP_FTW_DIRECTORY)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (num_dir_names == max_dir_names)
|
||||
{
|
||||
max_dir_names = max_dir_names * 5 / 4 + 3;
|
||||
dir_names = realloc(dir_names, max_dir_names * sizeof *dir_names);
|
||||
}
|
||||
cp = malloc(d_namlen + 1);
|
||||
memcpy(cp, f->d_name, d_namlen + 1);
|
||||
dir_names[num_dir_names].str = cp;
|
||||
dir_names[num_dir_names].len = d_namlen;
|
||||
num_dir_names++;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
show_progress_bar_(screen, texture, renderer);
|
||||
dir[dirlen] = '\0'; // repair it (clobbered for stat() call above)
|
||||
|
||||
if (1 || file_names) // Now ALWAYS calling callback function, so stamp loader can notice top-level directories (even if there are only subdirs, and no files, inside) -bjk 2007.05.16
|
||||
{
|
||||
{
|
||||
// let callee sort and keep the string
|
||||
#if 0
|
||||
qsort(file_names, num_file_names, sizeof *file_names, compare_ftw_str);
|
||||
while (num_file_names--)
|
||||
{
|
||||
free(file_names[num_file_names].str);
|
||||
}
|
||||
free(file_names);
|
||||
qsort(file_names, num_file_names, sizeof *file_names, compare_ftw_str);
|
||||
while (num_file_names--)
|
||||
{
|
||||
free(file_names[num_file_names].str);
|
||||
}
|
||||
free(file_names);
|
||||
#else
|
||||
#ifdef __ANDROID__
|
||||
if (dlen != dirlen) /* First case only happens in Android files coming from assets */
|
||||
fn(screen, texture, renderer, di, dlen, file_names, num_file_names, locale);
|
||||
else
|
||||
if (dlen != dirlen) /* First case only happens in Android files coming from assets */
|
||||
fn(screen, texture, renderer, di, dlen, file_names, num_file_names,
|
||||
locale);
|
||||
else
|
||||
#endif
|
||||
fn(screen, texture, renderer, dir, dirlen, file_names, num_file_names, locale);
|
||||
fn(screen, texture, renderer, dir, dirlen, file_names, num_file_names,
|
||||
locale);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (dir_names)
|
||||
{
|
||||
qsort(dir_names, num_dir_names, sizeof *dir_names, compare_ftw_str);
|
||||
while (num_dir_names--)
|
||||
{
|
||||
qsort(dir_names, num_dir_names, sizeof *dir_names, compare_ftw_str);
|
||||
while (num_dir_names--)
|
||||
{
|
||||
memcpy(dir + dirlen, dir_names[num_dir_names].str, dir_names[num_dir_names].len + 1);
|
||||
tp_ftw(screen, texture, renderer, dir, dirlen + dir_names[num_dir_names].len, rsrc, fn, locale);
|
||||
free(dir_names[num_dir_names].str);
|
||||
}
|
||||
free(dir_names);
|
||||
memcpy(dir + dirlen, dir_names[num_dir_names].str,
|
||||
dir_names[num_dir_names].len + 1);
|
||||
tp_ftw(screen, texture, renderer, dir,
|
||||
dirlen + dir_names[num_dir_names].len, rsrc, fn, locale);
|
||||
free(dir_names[num_dir_names].str);
|
||||
}
|
||||
free(dir_names);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,14 +45,23 @@ typedef struct tp_ftw_str
|
|||
} tp_ftw_str;
|
||||
|
||||
|
||||
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
|
||||
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files, unsigned i,
|
||||
void loadfont_callback(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const dir, unsigned dirlen,
|
||||
tp_ftw_str * files, unsigned i,
|
||||
const char *restrict const locale);
|
||||
int compare_ftw_str(const void *v1, const void *v2);
|
||||
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, char *restrict const dir,
|
||||
unsigned dirlen, int rsrc, void (*fn) (SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
|
||||
const char *restrict const dir, unsigned dirlen, tp_ftw_str * files,
|
||||
unsigned count, const char *restrict const locale),
|
||||
void tp_ftw(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, char *restrict const dir,
|
||||
unsigned dirlen, int rsrc, void (*fn)(SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const
|
||||
dir, unsigned dirlen,
|
||||
tp_ftw_str * files,
|
||||
unsigned count,
|
||||
const char *restrict const
|
||||
locale),
|
||||
const char *restrict const locale);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
687
src/fill.c
687
src/fill.c
|
|
@ -64,63 +64,73 @@
|
|||
|
||||
#define QUEUE_SIZE_CHUNK 1024
|
||||
|
||||
typedef struct queue_s {
|
||||
typedef struct queue_s
|
||||
{
|
||||
int x, y, y_outside;
|
||||
} queue_t;
|
||||
|
||||
queue_t * queue;
|
||||
queue_t *queue;
|
||||
int queue_size = 0, queue_end = 0;
|
||||
|
||||
/* Local function prototypes: */
|
||||
|
||||
SDL_Surface * global_screen, * global_last, * global_canvas;
|
||||
SDL_Surface *global_screen, *global_last, *global_canvas;
|
||||
Uint32 global_old_colr, global_cur_colr;
|
||||
Uint8 * global_touched;
|
||||
Uint8 *global_touched;
|
||||
int global_extent_x1, global_extent_y1, global_extent_x2, global_extent_y2;
|
||||
int global_prog_anim;
|
||||
|
||||
double colors_close(SDL_Surface * canvas, Uint32 c1, Uint32 c2);
|
||||
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr, double pct);
|
||||
void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, int x, int y, int y_outside);
|
||||
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y, Uint32 draw_color, Uint8 * touched);
|
||||
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr,
|
||||
double pct);
|
||||
void simulate_flood_fill_outside_check(SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, int x, int y,
|
||||
int y_outside);
|
||||
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y,
|
||||
Uint32 draw_color, Uint8 * touched);
|
||||
|
||||
void init_queue(void);
|
||||
void add_to_queue(int x, int y, int y_outside);
|
||||
int remove_from_queue(int * x, int * y, int * y_outside);
|
||||
int remove_from_queue(int *x, int *y, int *y_outside);
|
||||
void cleanup_queue(void);
|
||||
|
||||
void init_queue(void) {
|
||||
void init_queue(void)
|
||||
{
|
||||
queue_size = 0;
|
||||
queue_end = 0;
|
||||
|
||||
queue = (queue_t *) malloc(sizeof(queue_t) * QUEUE_SIZE_CHUNK);
|
||||
if (queue == NULL)
|
||||
{
|
||||
fprintf(stderr, "Fill queue cannot be malloc()'d\n");
|
||||
return;
|
||||
}
|
||||
{
|
||||
fprintf(stderr, "Fill queue cannot be malloc()'d\n");
|
||||
return;
|
||||
}
|
||||
|
||||
queue_size = QUEUE_SIZE_CHUNK;
|
||||
}
|
||||
|
||||
void add_to_queue(int x, int y, int y_outside) {
|
||||
void add_to_queue(int x, int y, int y_outside)
|
||||
{
|
||||
/* Reallocate if we need more space */
|
||||
if (queue_end + 1 > queue_size)
|
||||
{
|
||||
queue_t *tmp;
|
||||
tmp =
|
||||
(queue_t *) realloc(queue,
|
||||
sizeof(queue_t) * (queue_size + QUEUE_SIZE_CHUNK));
|
||||
if (tmp == NULL)
|
||||
{
|
||||
queue_t * tmp;
|
||||
tmp = (queue_t *) realloc(queue, sizeof(queue_t) * (queue_size + QUEUE_SIZE_CHUNK));
|
||||
if (tmp == NULL)
|
||||
{
|
||||
fprintf(stderr, "Fill queue cannot be realloc()'d\n");
|
||||
return;
|
||||
}
|
||||
queue_size += QUEUE_SIZE_CHUNK;
|
||||
#ifdef DEBUG
|
||||
printf("queue_size = %d\n", queue_size);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
queue = tmp;
|
||||
fprintf(stderr, "Fill queue cannot be realloc()'d\n");
|
||||
return;
|
||||
}
|
||||
queue_size += QUEUE_SIZE_CHUNK;
|
||||
#ifdef DEBUG
|
||||
printf("queue_size = %d\n", queue_size);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
queue = tmp;
|
||||
}
|
||||
|
||||
queue[queue_end].x = x;
|
||||
queue[queue_end].y = y;
|
||||
|
|
@ -130,14 +140,15 @@ void add_to_queue(int x, int y, int y_outside) {
|
|||
|
||||
#ifdef DEBUG
|
||||
if (queue_end % 100 == 0)
|
||||
{
|
||||
printf("queue_end = %d\n", queue_end);
|
||||
fflush(stdout);
|
||||
}
|
||||
{
|
||||
printf("queue_end = %d\n", queue_end);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int remove_from_queue(int * x, int * y, int * y_outside) {
|
||||
int remove_from_queue(int *x, int *y, int *y_outside)
|
||||
{
|
||||
if (queue_end == 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -149,16 +160,17 @@ int remove_from_queue(int * x, int * y, int * y_outside) {
|
|||
|
||||
#ifdef DEBUG
|
||||
if (queue_end % 100 == 0)
|
||||
{
|
||||
printf("queue_end = %d\n", queue_end);
|
||||
fflush(stdout);
|
||||
}
|
||||
{
|
||||
printf("queue_end = %d\n", queue_end);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cleanup_queue(void) {
|
||||
void cleanup_queue(void)
|
||||
{
|
||||
if (queue != NULL)
|
||||
free(queue);
|
||||
|
||||
|
|
@ -177,51 +189,60 @@ double colors_close(SDL_Surface * canvas, Uint32 c1, Uint32 c2)
|
|||
Uint8 r1, g1, b1, r2, g2, b2;
|
||||
|
||||
if (c1 == c2)
|
||||
{
|
||||
/* Get it over with quick, if possible! */
|
||||
{
|
||||
/* Get it over with quick, if possible! */
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double r, g, b;
|
||||
{
|
||||
double r, g, b;
|
||||
|
||||
SDL_GetRGB(c1, canvas->format, &r1, &g1, &b1);
|
||||
SDL_GetRGB(c2, canvas->format, &r2, &g2, &b2);
|
||||
SDL_GetRGB(c1, canvas->format, &r1, &g1, &b1);
|
||||
SDL_GetRGB(c2, canvas->format, &r2, &g2, &b2);
|
||||
|
||||
// use distance in linear RGB space
|
||||
r = sRGB_to_linear_table[r1] - sRGB_to_linear_table[r2];
|
||||
r *= r;
|
||||
g = sRGB_to_linear_table[g1] - sRGB_to_linear_table[g2];
|
||||
g *= g;
|
||||
b = sRGB_to_linear_table[b1] - sRGB_to_linear_table[b2];
|
||||
b *= b;
|
||||
// use distance in linear RGB space
|
||||
r = sRGB_to_linear_table[r1] - sRGB_to_linear_table[r2];
|
||||
r *= r;
|
||||
g = sRGB_to_linear_table[g1] - sRGB_to_linear_table[g2];
|
||||
g *= g;
|
||||
b = sRGB_to_linear_table[b1] - sRGB_to_linear_table[b2];
|
||||
b *= b;
|
||||
|
||||
// easy to confuse:
|
||||
// dark grey, brown, purple
|
||||
// light grey, tan
|
||||
// red, orange
|
||||
return (r + g + b);
|
||||
}
|
||||
// easy to confuse:
|
||||
// dark grey, brown, purple
|
||||
// light grey, tan
|
||||
// red, orange
|
||||
return (r + g + b);
|
||||
}
|
||||
}
|
||||
|
||||
int would_flood_fill(SDL_Surface * canvas, Uint32 cur_colr, Uint32 old_colr)
|
||||
{
|
||||
if (colors_close(canvas, cur_colr, old_colr) < COLOR_MATCH_NARROW)
|
||||
{
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * x1, int * y1, int * x2, int * y2, Uint8 * touched)
|
||||
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, SDL_Surface * last,
|
||||
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
|
||||
Uint32 old_colr, int *x1, int *y1, int *x2, int *y2,
|
||||
Uint8 * touched)
|
||||
{
|
||||
simulate_flood_fill(screen, texture, renderer, last, canvas, x, y, cur_colr, old_colr, x1, y1, x2, y2, touched);
|
||||
simulate_flood_fill(screen, texture, renderer, last, canvas, x, y, cur_colr,
|
||||
old_colr, x1, y1, x2, y2, touched);
|
||||
}
|
||||
|
||||
|
||||
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr, double pct) {
|
||||
Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr,
|
||||
double pct)
|
||||
{
|
||||
Uint8 old_r, old_g, old_b, draw_r, draw_g, draw_b, new_r, new_g, new_b;
|
||||
|
||||
SDL_GetRGB(draw_colr, canvas->format, &draw_r, &draw_g, &draw_b);
|
||||
|
|
@ -235,7 +256,12 @@ Uint32 blend(SDL_Surface * canvas, Uint32 draw_colr, Uint32 old_colr, double pct
|
|||
return SDL_MapRGB(canvas->format, new_r, new_g, new_b);
|
||||
}
|
||||
|
||||
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * extent_x1, int * extent_y1, int * extent_x2, int * extent_y2, Uint8 * touched) {
|
||||
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, SDL_Surface * last,
|
||||
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
|
||||
Uint32 old_colr, int *extent_x1, int *extent_y1,
|
||||
int *extent_x2, int *extent_y2, Uint8 * touched)
|
||||
{
|
||||
int y_outside;
|
||||
|
||||
/* Get ready */
|
||||
|
|
@ -257,9 +283,10 @@ void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Render
|
|||
|
||||
/* Do the work (possibly queuing more, as we go) */
|
||||
while (remove_from_queue(&x, &y, &y_outside))
|
||||
{
|
||||
simulate_flood_fill_outside_check(screen, texture, renderer, x, y, y_outside);
|
||||
}
|
||||
{
|
||||
simulate_flood_fill_outside_check(screen, texture, renderer, x, y,
|
||||
y_outside);
|
||||
}
|
||||
cleanup_queue();
|
||||
|
||||
*extent_x1 = global_extent_x1;
|
||||
|
|
@ -268,7 +295,10 @@ void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Render
|
|||
*extent_y2 = global_extent_y2;
|
||||
}
|
||||
|
||||
void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, int x, int y, int y_outside)
|
||||
void simulate_flood_fill_outside_check(SDL_Surface * screen,
|
||||
SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, int x, int y,
|
||||
int y_outside)
|
||||
{
|
||||
int fillL, fillR, narrowFillL, narrowFillR, i, outside, just_queued;
|
||||
double in_line, closeness;
|
||||
|
|
@ -287,13 +317,13 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * textu
|
|||
return;
|
||||
|
||||
if (y < global_extent_y1)
|
||||
{
|
||||
global_extent_y1 = y;
|
||||
}
|
||||
{
|
||||
global_extent_y1 = y;
|
||||
}
|
||||
if (y > global_extent_y2)
|
||||
{
|
||||
global_extent_y2 = y;
|
||||
}
|
||||
{
|
||||
global_extent_y2 = y;
|
||||
}
|
||||
|
||||
|
||||
fillL = x;
|
||||
|
|
@ -303,139 +333,172 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * textu
|
|||
|
||||
global_prog_anim++;
|
||||
if ((global_prog_anim % 8) == 0)
|
||||
{
|
||||
show_progress_bar_(screen, texture, renderer);
|
||||
{
|
||||
show_progress_bar_(screen, texture, renderer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((global_prog_anim % 800) == 1) /* Always lay sound _once_ */
|
||||
if ((global_prog_anim % 800) == 1) /* Always lay sound _once_ */
|
||||
playsound(global_canvas, 1, SND_FILL, 1, x, SNDDIST_NEAR);
|
||||
|
||||
#ifdef DEBUG_WATCH
|
||||
if (global_prog_anim % 100 == 0)
|
||||
{
|
||||
SDL_BlitSurface(global_canvas, NULL, global_screen, NULL);
|
||||
SDL_Flip(global_screen);
|
||||
}
|
||||
{
|
||||
SDL_BlitSurface(global_canvas, NULL, global_screen, NULL);
|
||||
SDL_Flip(global_screen);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find left side, filling along the way */
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL /* - 1 */, y);
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last,
|
||||
fillL /* - 1 */ , y);
|
||||
in_line = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
outside = 0;
|
||||
while (in_line < COLOR_MATCH_WIDE && outside < WIDE_MATCH_THRESHOLD)
|
||||
{
|
||||
if (in_line > COLOR_MATCH_NARROW)
|
||||
{
|
||||
if (in_line > COLOR_MATCH_NARROW) {
|
||||
outside++;
|
||||
} else {
|
||||
narrowFillL = fillL;
|
||||
}
|
||||
|
||||
if (global_touched != NULL) {
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
|
||||
fillL--;
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
|
||||
|
||||
if (fillL >= 0)
|
||||
{
|
||||
in_line = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
}
|
||||
else
|
||||
{
|
||||
in_line = 3.0;
|
||||
}
|
||||
outside++;
|
||||
}
|
||||
else
|
||||
{
|
||||
narrowFillL = fillL;
|
||||
}
|
||||
|
||||
if (global_touched != NULL)
|
||||
{
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y,
|
||||
blend(global_canvas,
|
||||
global_cur_colr,
|
||||
px_colr,
|
||||
(1.0 - in_line)));
|
||||
fillL--;
|
||||
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
|
||||
|
||||
if (fillL >= 0)
|
||||
{
|
||||
in_line = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
}
|
||||
else
|
||||
{
|
||||
in_line = 3.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (fillL >= 0)
|
||||
{
|
||||
if (global_touched != NULL)
|
||||
{
|
||||
if (global_touched != NULL)
|
||||
{
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
|
||||
global_touched[(y * global_canvas->w) + fillL] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, fillL, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillL, y,
|
||||
blend(global_canvas,
|
||||
global_cur_colr,
|
||||
px_colr,
|
||||
(1.0 - in_line)));
|
||||
}
|
||||
|
||||
|
||||
if (fillL < global_extent_x1)
|
||||
{
|
||||
global_extent_x1 = fillL;
|
||||
}
|
||||
{
|
||||
global_extent_x1 = fillL;
|
||||
}
|
||||
|
||||
fillL++;
|
||||
|
||||
|
||||
/* Find right side, filling along the way */
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR + 1, y);
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, fillR + 1, y);
|
||||
in_line = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
outside = 0;
|
||||
while (in_line < COLOR_MATCH_WIDE && outside < WIDE_MATCH_THRESHOLD)
|
||||
{
|
||||
if (in_line > COLOR_MATCH_NARROW)
|
||||
{
|
||||
if (in_line > COLOR_MATCH_NARROW) {
|
||||
outside++;
|
||||
} else {
|
||||
narrowFillR = fillR;
|
||||
}
|
||||
|
||||
if (global_touched != NULL) {
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
|
||||
fillR++;
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
|
||||
|
||||
if (fillR < global_canvas->w)
|
||||
{
|
||||
in_line = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
}
|
||||
else
|
||||
{
|
||||
in_line = 3.0;
|
||||
}
|
||||
outside++;
|
||||
}
|
||||
else
|
||||
{
|
||||
narrowFillR = fillR;
|
||||
}
|
||||
|
||||
if (global_touched != NULL)
|
||||
{
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y,
|
||||
blend(global_canvas,
|
||||
global_cur_colr,
|
||||
px_colr,
|
||||
(1.0 - in_line)));
|
||||
fillR++;
|
||||
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
|
||||
|
||||
if (fillR < global_canvas->w)
|
||||
{
|
||||
in_line = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
}
|
||||
else
|
||||
{
|
||||
in_line = 3.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (fillR < global_canvas->w)
|
||||
{
|
||||
if (global_touched != NULL)
|
||||
{
|
||||
if (global_touched != NULL)
|
||||
{
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y, blend(global_canvas, global_cur_colr, px_colr, (1.0 - in_line)));
|
||||
global_touched[(y * global_canvas->w) + fillR] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, fillR, y);
|
||||
putpixels[global_canvas->format->BytesPerPixel] (global_canvas, fillR, y,
|
||||
blend(global_canvas,
|
||||
global_cur_colr,
|
||||
px_colr,
|
||||
(1.0 - in_line)));
|
||||
}
|
||||
|
||||
if (fillR > global_extent_x2)
|
||||
{
|
||||
global_extent_x2 = fillR;
|
||||
}
|
||||
{
|
||||
global_extent_x2 = fillR;
|
||||
}
|
||||
|
||||
fillR--;
|
||||
|
||||
|
|
@ -444,69 +507,74 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Texture * textu
|
|||
|
||||
just_queued = 0;
|
||||
if (y > 0)
|
||||
{
|
||||
for (i = narrowFillL; i <= narrowFillR; i++)
|
||||
{
|
||||
for (i = narrowFillL; i <= narrowFillR; i++)
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, i, y - 1);
|
||||
closeness = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
if (closeness < COLOR_MATCH_NARROW ||
|
||||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD))
|
||||
{
|
||||
if (!just_queued
|
||||
&& (global_touched == NULL
|
||||
|| !global_touched[((y - 1) * global_canvas->w) + i]))
|
||||
{
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, i, y - 1);
|
||||
closeness = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
if (closeness < COLOR_MATCH_NARROW ||
|
||||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD)
|
||||
)
|
||||
{
|
||||
if (!just_queued && (global_touched == NULL || !global_touched[((y - 1) * global_canvas->w) + i]))
|
||||
{
|
||||
add_to_queue(i, y - 1, y_outside + 1);
|
||||
just_queued = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
add_to_queue(i, y - 1, y_outside + 1);
|
||||
just_queued = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Continue filling downwards from this scanline */
|
||||
|
||||
just_queued = 0;
|
||||
if (y < global_canvas->h - 1)
|
||||
{
|
||||
for (i = narrowFillL; i <= narrowFillR; i++)
|
||||
{
|
||||
for (i = narrowFillL; i <= narrowFillR; i++)
|
||||
px_colr =
|
||||
getpixels[global_last->format->BytesPerPixel] (global_last, i, y + 1);
|
||||
closeness = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
if (closeness < COLOR_MATCH_NARROW ||
|
||||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD))
|
||||
{
|
||||
if (!just_queued
|
||||
&& (global_touched == NULL
|
||||
|| !global_touched[((y + 1) * global_canvas->w) + i]))
|
||||
{
|
||||
px_colr = getpixels[global_last->format->BytesPerPixel] (global_last, i, y + 1);
|
||||
closeness = colors_close(global_canvas, px_colr, global_old_colr);
|
||||
if (closeness < COLOR_MATCH_NARROW ||
|
||||
(closeness < COLOR_MATCH_WIDE && y_outside < WIDE_MATCH_THRESHOLD)
|
||||
)
|
||||
{
|
||||
if (!just_queued && (global_touched == NULL || !global_touched[((y + 1) * global_canvas->w) + i]))
|
||||
{
|
||||
add_to_queue(i, y + 1, y_outside + 1);
|
||||
just_queued = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
add_to_queue(i, y + 1, y_outside + 1);
|
||||
just_queued = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
just_queued = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x_left, int y_top, int x_right, int y_bottom,
|
||||
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched
|
||||
) {
|
||||
int x_left, int y_top, int x_right, int y_bottom,
|
||||
int x1, int y1, int x2, int y2, Uint32 draw_color,
|
||||
Uint8 * touched)
|
||||
{
|
||||
Uint32 old_colr, new_colr;
|
||||
int xx, yy;
|
||||
Uint8 draw_r, draw_g, draw_b, old_r, old_g, old_b, new_r, new_g, new_b;
|
||||
|
|
@ -521,9 +589,12 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
|
|||
C2 = (A * x2) + (B * y2);
|
||||
/* FIXME: C2 should be larger than C1? */
|
||||
|
||||
for (yy = y_top; yy <= y_bottom; yy++) {
|
||||
for (xx = x_left; xx <= x_right; xx++) {
|
||||
if (touched[(yy * canvas->w) + xx]) {
|
||||
for (yy = y_top; yy <= y_bottom; yy++)
|
||||
{
|
||||
for (xx = x_left; xx <= x_right; xx++)
|
||||
{
|
||||
if (touched[(yy * canvas->w) + xx])
|
||||
{
|
||||
/* Get the old color, and blend it (with a distance-based ratio) with the target color */
|
||||
old_colr = getpixels[last->format->BytesPerPixel] (last, xx, yy);
|
||||
SDL_GetRGB(old_colr, last->format, &old_r, &old_g, &old_b);
|
||||
|
|
@ -532,13 +603,18 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
|
|||
https://stackoverflow.com/questions/521493/creating-a-linear-gradient-in-2d-array) */
|
||||
C = (A * xx) + (B * yy);
|
||||
|
||||
if (C < C1) {
|
||||
if (C < C1)
|
||||
{
|
||||
/* At/beyond the click spot (opposite direction of mouse); solid color */
|
||||
ratio = 0.0;
|
||||
} else if (C >= C2) {
|
||||
}
|
||||
else if (C >= C2)
|
||||
{
|
||||
/* At/beyond the mouse; completely faded out */
|
||||
ratio = 1.0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The actual gradient... */
|
||||
ratio = (C - C1) / (C2 - C1);
|
||||
}
|
||||
|
|
@ -546,9 +622,15 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
|
|||
/* Apply fuzziness at any antialiased edges we detected */
|
||||
ratio = (ratio * ((float) touched[yy * canvas->w + xx] / 255.0));
|
||||
|
||||
new_r = (Uint8) (((float) old_r) * ratio + ((float) draw_r * (1.0 - ratio)));
|
||||
new_g = (Uint8) (((float) old_g) * ratio + ((float) draw_g * (1.0 - ratio)));
|
||||
new_b = (Uint8) (((float) old_b) * ratio + ((float) draw_b * (1.0 - ratio)));
|
||||
new_r =
|
||||
(Uint8) (((float) old_r) * ratio +
|
||||
((float) draw_r * (1.0 - ratio)));
|
||||
new_g =
|
||||
(Uint8) (((float) old_g) * ratio +
|
||||
((float) draw_g * (1.0 - ratio)));
|
||||
new_b =
|
||||
(Uint8) (((float) old_b) * ratio +
|
||||
((float) draw_b * (1.0 - ratio)));
|
||||
|
||||
new_colr = SDL_MapRGB(canvas->format, new_r, new_g, new_b);
|
||||
putpixels[canvas->format->BytesPerPixel] (canvas, xx, yy, new_colr);
|
||||
|
|
@ -557,27 +639,32 @@ void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
|
|||
}
|
||||
}
|
||||
|
||||
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y, Uint32 draw_color, Uint8 * touched) {
|
||||
void draw_brush_fill_single(SDL_Surface * canvas, int x, int y,
|
||||
Uint32 draw_color, Uint8 * touched)
|
||||
{
|
||||
int xx, yy;
|
||||
|
||||
for (yy = -16; yy < 16; yy++)
|
||||
{
|
||||
for (xx = -16; xx < 16; xx++)
|
||||
{
|
||||
for (xx = -16; xx < 16; xx++)
|
||||
{
|
||||
if ((xx * xx) + (yy * yy) < (16 * 16) &&
|
||||
touched[((y + yy) * canvas->w) + (x + xx)])
|
||||
{
|
||||
putpixels[canvas->format->BytesPerPixel] (canvas, x + xx, y + yy, draw_color);
|
||||
}
|
||||
}
|
||||
if ((xx * xx) + (yy * yy) < (16 * 16) &&
|
||||
touched[((y + yy) * canvas->w) + (x + xx)])
|
||||
{
|
||||
putpixels[canvas->format->BytesPerPixel] (canvas, x + xx, y + yy,
|
||||
draw_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_brush_fill(SDL_Surface * canvas,
|
||||
int x_left ATTRIBUTE_UNUSED, int y_top ATTRIBUTE_UNUSED, int x_right ATTRIBUTE_UNUSED, int y_bottom ATTRIBUTE_UNUSED,
|
||||
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched,
|
||||
int * up_x1, int * up_y1, int * up_x2, int * up_y2
|
||||
) {
|
||||
int x_left ATTRIBUTE_UNUSED, int y_top ATTRIBUTE_UNUSED,
|
||||
int x_right ATTRIBUTE_UNUSED,
|
||||
int y_bottom ATTRIBUTE_UNUSED, int x1, int y1, int x2,
|
||||
int y2, Uint32 draw_color, Uint8 * touched, int *up_x1,
|
||||
int *up_y1, int *up_x2, int *up_y2)
|
||||
{
|
||||
int dx, dy;
|
||||
int y;
|
||||
int orig_x1, orig_y1, orig_x2, orig_y2, tmp;
|
||||
|
|
@ -593,60 +680,60 @@ void draw_brush_fill(SDL_Surface * canvas,
|
|||
dy = y2 - y1;
|
||||
|
||||
if (dx != 0)
|
||||
{
|
||||
m = ((float) dy) / ((float) dx);
|
||||
b = y1 - m * x1;
|
||||
|
||||
if (x2 >= x1)
|
||||
dx = 1;
|
||||
else
|
||||
dx = -1;
|
||||
|
||||
while (x1 != x2)
|
||||
{
|
||||
m = ((float)dy) / ((float)dx);
|
||||
b = y1 - m * x1;
|
||||
y1 = m * x1 + b;
|
||||
y2 = m * (x1 + dx) + b;
|
||||
|
||||
if (x2 >= x1)
|
||||
dx = 1;
|
||||
else
|
||||
dx = -1;
|
||||
|
||||
while (x1 != x2)
|
||||
{
|
||||
y1 = m * x1 + b;
|
||||
y2 = m * (x1 + dx) + b;
|
||||
|
||||
if (y1 > y2)
|
||||
{
|
||||
for (y = y1; y >= y2; y--)
|
||||
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = y1; y <= y2; y++)
|
||||
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
|
||||
}
|
||||
|
||||
x1 = x1 + dx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y1 > y2)
|
||||
{
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
{
|
||||
for (y = y1; y >= y2; y--)
|
||||
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = y1; y <= y2; y++)
|
||||
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
|
||||
}
|
||||
|
||||
for (y = y1; y <= y2; y++)
|
||||
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
|
||||
x1 = x1 + dx;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y1 > y2)
|
||||
{
|
||||
y = y1;
|
||||
y1 = y2;
|
||||
y2 = y;
|
||||
}
|
||||
|
||||
for (y = y1; y <= y2; y++)
|
||||
draw_brush_fill_single(canvas, x1, y, draw_color, touched);
|
||||
}
|
||||
|
||||
if (orig_x1 > orig_x2)
|
||||
{
|
||||
tmp = orig_x1;
|
||||
orig_x1 = orig_x2;
|
||||
orig_x2 = tmp;
|
||||
}
|
||||
{
|
||||
tmp = orig_x1;
|
||||
orig_x1 = orig_x2;
|
||||
orig_x2 = tmp;
|
||||
}
|
||||
|
||||
if (orig_y1 > orig_y2)
|
||||
{
|
||||
tmp = orig_y1;
|
||||
orig_y1 = orig_y2;
|
||||
orig_y2 = tmp;
|
||||
}
|
||||
{
|
||||
tmp = orig_y1;
|
||||
orig_y1 = orig_y2;
|
||||
orig_y2 = tmp;
|
||||
}
|
||||
|
||||
*up_x1 = orig_x1 - 16;
|
||||
*up_y1 = orig_y1 - 16;
|
||||
|
|
@ -654,9 +741,10 @@ void draw_brush_fill(SDL_Surface * canvas,
|
|||
*up_y2 = orig_y2 + 16;
|
||||
}
|
||||
|
||||
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_right, int y_bottom,
|
||||
int x, int y, Uint32 draw_color, Uint8 * touched
|
||||
) {
|
||||
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top,
|
||||
int x_right, int y_bottom, int x, int y,
|
||||
Uint32 draw_color, Uint8 * touched)
|
||||
{
|
||||
Uint32 old_colr, new_colr;
|
||||
int xx, yy;
|
||||
float xd, yd, dist, rad, ratio;
|
||||
|
|
@ -666,7 +754,8 @@ void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_rig
|
|||
xd = max(abs(x - x_right), abs(x - x_left));
|
||||
yd = max(abs(y - y_bottom), abs(y - y_top));
|
||||
rad = sqrt(xd * xd + yd * yd);
|
||||
if (rad == 0) {
|
||||
if (rad == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -674,27 +763,38 @@ void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_rig
|
|||
SDL_GetRGB(draw_color, canvas->format, &draw_r, &draw_g, &draw_b);
|
||||
|
||||
/* Traverse the flood-filled zone */
|
||||
for (yy = y_top; yy <= y_bottom; yy++) {
|
||||
for (xx = x_left; xx <= x_right; xx++) {
|
||||
for (yy = y_top; yy <= y_bottom; yy++)
|
||||
{
|
||||
for (xx = x_left; xx <= x_right; xx++)
|
||||
{
|
||||
/* Only alter the pixels within the flood itself */
|
||||
if (touched[(yy * canvas->w) + xx]) {
|
||||
if (touched[(yy * canvas->w) + xx])
|
||||
{
|
||||
/* Determine the distance from the click point */
|
||||
xd = fabs((float) (xx - x));
|
||||
yd = fabs((float) (yy - y));
|
||||
dist = sqrt(xd * xd + yd * yd);
|
||||
if (dist < rad) {
|
||||
if (dist < rad)
|
||||
{
|
||||
ratio = (dist / rad);
|
||||
|
||||
/* Get the old color, and blend it (with a distance-based ratio) with the target color */
|
||||
old_colr = getpixels[canvas->format->BytesPerPixel] (canvas, xx, yy);
|
||||
old_colr =
|
||||
getpixels[canvas->format->BytesPerPixel] (canvas, xx, yy);
|
||||
SDL_GetRGB(old_colr, canvas->format, &old_r, &old_g, &old_b);
|
||||
|
||||
/* Apply fuzziness at any antialiased edges we detected */
|
||||
ratio = (ratio * ((float) touched[yy * canvas->w + xx] / 255.0));
|
||||
|
||||
new_r = (Uint8) (((float) old_r) * ratio + ((float) draw_r * (1.00 - ratio)));
|
||||
new_g = (Uint8) (((float) old_g) * ratio + ((float) draw_g * (1.00 - ratio)));
|
||||
new_b = (Uint8) (((float) old_b) * ratio + ((float) draw_b * (1.00 - ratio)));
|
||||
new_r =
|
||||
(Uint8) (((float) old_r) * ratio +
|
||||
((float) draw_r * (1.00 - ratio)));
|
||||
new_g =
|
||||
(Uint8) (((float) old_g) * ratio +
|
||||
((float) draw_g * (1.00 - ratio)));
|
||||
new_b =
|
||||
(Uint8) (((float) old_b) * ratio +
|
||||
((float) draw_b * (1.00 - ratio)));
|
||||
|
||||
new_colr = SDL_MapRGB(canvas->format, new_r, new_g, new_b);
|
||||
putpixels[canvas->format->BytesPerPixel] (canvas, xx, yy, new_colr);
|
||||
|
|
@ -703,4 +803,3 @@ void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_rig
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
31
src/fill.h
31
src/fill.h
|
|
@ -37,17 +37,26 @@
|
|||
#include "SDL.h"
|
||||
|
||||
int would_flood_fill(SDL_Surface * canvas, Uint32 cur_colr, Uint32 old_colr);
|
||||
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * x1, int * y1, int * x2, int * y2, Uint8 * touched);
|
||||
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, SDL_Surface * last, SDL_Surface * canvas, int x, int y, Uint32 cur_colr, Uint32 old_colr, int * x1, int * y1, int * x2, int * y2, Uint8 * touched);
|
||||
void do_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, SDL_Surface * last,
|
||||
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
|
||||
Uint32 old_colr, int *x1, int *y1, int *x2, int *y2,
|
||||
Uint8 * touched);
|
||||
void simulate_flood_fill(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, SDL_Surface * last,
|
||||
SDL_Surface * canvas, int x, int y, Uint32 cur_colr,
|
||||
Uint32 old_colr, int *x1, int *y1, int *x2, int *y2,
|
||||
Uint8 * touched);
|
||||
void draw_linear_gradient(SDL_Surface * canvas, SDL_Surface * last,
|
||||
int x_left, int y_top, int x_right, int y_bottom,
|
||||
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched);
|
||||
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top, int x_right, int y_bottom,
|
||||
int x, int y, Uint32 draw_color, Uint8 * touched);
|
||||
void draw_brush_fill(SDL_Surface * canvas,
|
||||
int x_left, int y_top, int x_right, int y_bottom,
|
||||
int x1, int y1, int x2, int y2, Uint32 draw_color, Uint8 * touched,
|
||||
int * up_x1, int * up_y1, int * up_x2, int * up_y2);
|
||||
int x_left, int y_top, int x_right, int y_bottom,
|
||||
int x1, int y1, int x2, int y2, Uint32 draw_color,
|
||||
Uint8 * touched);
|
||||
void draw_radial_gradient(SDL_Surface * canvas, int x_left, int y_top,
|
||||
int x_right, int y_bottom, int x, int y,
|
||||
Uint32 draw_color, Uint8 * touched);
|
||||
void draw_brush_fill(SDL_Surface * canvas, int x_left, int y_top, int x_right,
|
||||
int y_bottom, int x1, int y1, int x2, int y2,
|
||||
Uint32 draw_color, Uint8 * touched, int *up_x1,
|
||||
int *up_y1, int *up_x2, int *up_y2);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@
|
|||
#define gettext_noop(String) String
|
||||
#endif
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
FILL_FLOOD,
|
||||
FILL_BRUSH,
|
||||
FILL_GRADIENT_LINEAR,
|
||||
|
|
@ -56,8 +57,10 @@ const char *const fill_names[NUM_FILLS] = {
|
|||
const char *const fill_tips[NUM_FILLS] = {
|
||||
gettext_noop("Click to fill an area with a solid color."),
|
||||
gettext_noop("Click and drag to fill an area by hand, using a brush."),
|
||||
gettext_noop("Click and drag to fill an area with a linear gradient (from the chosen color to transparent)."),
|
||||
gettext_noop("Click to fill an area with a radial gradient (from the chosen color to transparent).")
|
||||
gettext_noop
|
||||
("Click and drag to fill an area with a linear gradient (from the chosen color to transparent)."),
|
||||
gettext_noop
|
||||
("Click to fill an area with a radial gradient (from the chosen color to transparent).")
|
||||
};
|
||||
|
||||
const char *const fill_img_fnames[NUM_FILLS] = {
|
||||
|
|
@ -68,4 +71,3 @@ const char *const fill_img_fnames[NUM_FILLS] = {
|
|||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
1665
src/fonts.c
1665
src/fonts.c
File diff suppressed because it is too large
Load diff
15
src/fonts.h
15
src/fonts.h
|
|
@ -121,9 +121,11 @@ int TuxPaint_Font_FontHeight(TuxPaint_Font * tpf);
|
|||
|
||||
#ifdef FORKED_FONTS
|
||||
void reliable_write(int fd, const void *buf, size_t count);
|
||||
void run_font_scanner(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer,
|
||||
void run_font_scanner(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer,
|
||||
const char *restrict const locale);
|
||||
void receive_some_font_info(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer);
|
||||
void receive_some_font_info(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer);
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -191,7 +193,8 @@ TuxPaint_Font *getfonthandle(int desire);
|
|||
|
||||
int charset_works(TuxPaint_Font * font, const char *s);
|
||||
|
||||
TuxPaint_Font *TuxPaint_Font_OpenFont(const char *pangodesc, const char *ttffilename, int size);
|
||||
TuxPaint_Font *TuxPaint_Font_OpenFont(const char *pangodesc,
|
||||
const char *ttffilename, int size);
|
||||
void TuxPaint_Font_CloseFont(TuxPaint_Font * tpf);
|
||||
const char *TuxPaint_Font_FontFaceFamilyName(TuxPaint_Font * tpf);
|
||||
const char *TuxPaint_Font_FontFaceStyleName(TuxPaint_Font * tpf);
|
||||
|
|
@ -199,10 +202,12 @@ const char *TuxPaint_Font_FontFaceStyleName(TuxPaint_Font * tpf);
|
|||
#ifdef NO_SDLPANGO
|
||||
TuxPaint_Font *load_locale_font(TuxPaint_Font * fallback, int size);
|
||||
#else
|
||||
void sdl_color_to_pango_color(SDL_Color sdl_color, SDLPango_Matrix * pango_color);
|
||||
void sdl_color_to_pango_color(SDL_Color sdl_color,
|
||||
SDLPango_Matrix * pango_color);
|
||||
#endif
|
||||
|
||||
int load_user_fonts(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer, void *vp,
|
||||
int load_user_fonts(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer, void *vp,
|
||||
const char *restrict const locale);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -87,35 +87,40 @@ char *get_fname(const char *const name, int kind)
|
|||
{
|
||||
char f[512];
|
||||
// const char *restrict const dir;
|
||||
const char * dir;
|
||||
const char *dir;
|
||||
|
||||
if (kind == DIR_SAVE) {
|
||||
if (kind == DIR_SAVE)
|
||||
{
|
||||
dir = savedir;
|
||||
} else if (kind == DIR_DATA) {
|
||||
}
|
||||
else if (kind == DIR_DATA)
|
||||
{
|
||||
dir = datadir;
|
||||
} else if (kind == DIR_EXPORT || kind == DIR_EXPORT_PARENT) {
|
||||
}
|
||||
else if (kind == DIR_EXPORT || kind == DIR_EXPORT_PARENT)
|
||||
{
|
||||
dir = exportdir;
|
||||
}
|
||||
|
||||
snprintf(f, sizeof(f),
|
||||
"%s%c%s",
|
||||
dir, (*name) ? '/' : '\0', /* Some mkdir()'s don't like trailing slashes */
|
||||
name);
|
||||
snprintf(f, sizeof(f), "%s%c%s", dir, (*name) ? '/' : '\0', /* Some mkdir()'s don't like trailing slashes */
|
||||
name);
|
||||
|
||||
if (kind == DIR_EXPORT_PARENT) {
|
||||
if (kind == DIR_EXPORT_PARENT)
|
||||
{
|
||||
int len, i, stop;
|
||||
|
||||
stop = -1;
|
||||
len = strlen(f);
|
||||
for (i = len - 1; i >= 0 && stop == -1; i--) {
|
||||
for (i = len - 1; i >= 0 && stop == -1; i--)
|
||||
{
|
||||
if (f[i] == '/')
|
||||
stop = i;
|
||||
}
|
||||
if (stop != -1) {
|
||||
if (stop != -1)
|
||||
{
|
||||
f[stop] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return strdup(f);
|
||||
}
|
||||
|
||||
|
|
|
|||
506
src/gifenc.c
506
src/gifenc.c
|
|
@ -16,52 +16,50 @@
|
|||
#define write_num(fd, n) write((fd), (uint8_t []) {(n) & 0xFF, (n) >> 8}, 2)
|
||||
|
||||
static uint8_t vga[0x30] = {
|
||||
0x00, 0x00, 0x00,
|
||||
0xAA, 0x00, 0x00,
|
||||
0x00, 0xAA, 0x00,
|
||||
0xAA, 0x55, 0x00,
|
||||
0x00, 0x00, 0xAA,
|
||||
0xAA, 0x00, 0xAA,
|
||||
0x00, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA,
|
||||
0x55, 0x55, 0x55,
|
||||
0xFF, 0x55, 0x55,
|
||||
0x55, 0xFF, 0x55,
|
||||
0xFF, 0xFF, 0x55,
|
||||
0x55, 0x55, 0xFF,
|
||||
0xFF, 0x55, 0xFF,
|
||||
0x55, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x00, 0x00,
|
||||
0xAA, 0x00, 0x00,
|
||||
0x00, 0xAA, 0x00,
|
||||
0xAA, 0x55, 0x00,
|
||||
0x00, 0x00, 0xAA,
|
||||
0xAA, 0x00, 0xAA,
|
||||
0x00, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA,
|
||||
0x55, 0x55, 0x55,
|
||||
0xFF, 0x55, 0x55,
|
||||
0x55, 0xFF, 0x55,
|
||||
0xFF, 0xFF, 0x55,
|
||||
0x55, 0x55, 0xFF,
|
||||
0xFF, 0x55, 0xFF,
|
||||
0x55, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
|
||||
struct Node {
|
||||
uint16_t key;
|
||||
struct Node *children[];
|
||||
struct Node
|
||||
{
|
||||
uint16_t key;
|
||||
struct Node *children[];
|
||||
};
|
||||
typedef struct Node Node;
|
||||
|
||||
static Node *
|
||||
new_node(uint16_t key, int degree)
|
||||
static Node *new_node(uint16_t key, int degree)
|
||||
{
|
||||
Node *node = calloc(1, sizeof(*node) + degree * sizeof(Node *));
|
||||
if (node)
|
||||
node->key = key;
|
||||
return node;
|
||||
Node *node = calloc(1, sizeof(*node) + degree * sizeof(Node *));
|
||||
if (node)
|
||||
node->key = key;
|
||||
return node;
|
||||
}
|
||||
|
||||
static Node *
|
||||
new_trie(int degree, int *nkeys)
|
||||
static Node *new_trie(int degree, int *nkeys)
|
||||
{
|
||||
Node *root = new_node(0, degree);
|
||||
/* Create nodes for single pixels. */
|
||||
for (*nkeys = 0; *nkeys < degree; (*nkeys)++)
|
||||
root->children[*nkeys] = new_node(*nkeys, degree);
|
||||
*nkeys += 2; /* skip clear code and stop code */
|
||||
return root;
|
||||
Node *root = new_node(0, degree);
|
||||
/* Create nodes for single pixels. */
|
||||
for (*nkeys = 0; *nkeys < degree; (*nkeys)++)
|
||||
root->children[*nkeys] = new_node(*nkeys, degree);
|
||||
*nkeys += 2; /* skip clear code and stop code */
|
||||
return root;
|
||||
}
|
||||
|
||||
static void
|
||||
del_trie(Node *root, int degree)
|
||||
static void del_trie(Node * root, int degree)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -72,191 +70,261 @@ del_trie(Node *root, int degree)
|
|||
free(root);
|
||||
}
|
||||
|
||||
static void put_loop(ge_GIF *gif, uint16_t loop);
|
||||
static void put_loop(ge_GIF * gif, uint16_t loop);
|
||||
|
||||
#define OR_ABORT if (res == -1) { fprintf(stderr, "Cannot write to GIF\n"); return(NULL); }
|
||||
#define OR_ABORT2 if (res == -1) { fprintf(stderr, "Cannot write to GIF\n"); return; }
|
||||
|
||||
ge_GIF *
|
||||
ge_new_gif(
|
||||
const char *fname, uint16_t width, uint16_t height,
|
||||
uint8_t *palette, int depth, int loop
|
||||
)
|
||||
ge_GIF *ge_new_gif(const char *fname, uint16_t width, uint16_t height,
|
||||
uint8_t * palette, int depth, int loop)
|
||||
{
|
||||
int i, r, g, b, v;
|
||||
ssize_t res;
|
||||
ge_GIF *gif = calloc(1, sizeof(*gif) + 2*width*height);
|
||||
if (!gif)
|
||||
goto no_gif;
|
||||
gif->w = width; gif->h = height;
|
||||
gif->depth = depth > 1 ? depth : 2;
|
||||
gif->frame = (uint8_t *) &gif[1];
|
||||
gif->back = &gif->frame[width*height];
|
||||
gif->fd = creat(fname, 0666);
|
||||
if (gif->fd == -1)
|
||||
goto no_fd;
|
||||
int i, r, g, b, v;
|
||||
ssize_t res;
|
||||
ge_GIF *gif = calloc(1, sizeof(*gif) + 2 * width * height);
|
||||
if (!gif)
|
||||
goto no_gif;
|
||||
gif->w = width;
|
||||
gif->h = height;
|
||||
gif->depth = depth > 1 ? depth : 2;
|
||||
gif->frame = (uint8_t *) & gif[1];
|
||||
gif->back = &gif->frame[width * height];
|
||||
gif->fd = creat(fname, 0666);
|
||||
if (gif->fd == -1)
|
||||
goto no_fd;
|
||||
#ifdef _WIN32
|
||||
setmode(gif->fd, O_BINARY);
|
||||
setmode(gif->fd, O_BINARY);
|
||||
#endif
|
||||
res = write(gif->fd, "GIF89a", 6); OR_ABORT;
|
||||
res = write_num(gif->fd, width); OR_ABORT;
|
||||
res = write_num(gif->fd, height); OR_ABORT;
|
||||
res = write(gif->fd, (uint8_t []) {0xF0 | (depth-1), 0x00, 0x00}, 3); OR_ABORT;
|
||||
if (palette) {
|
||||
res = write(gif->fd, palette, 3 << depth); OR_ABORT;
|
||||
} else if (depth <= 4) {
|
||||
res = write(gif->fd, vga, 3 << depth); OR_ABORT;
|
||||
} else {
|
||||
res = write(gif->fd, vga, sizeof(vga)); OR_ABORT;
|
||||
i = 0x10;
|
||||
for (r = 0; r < 6; r++) {
|
||||
for (g = 0; g < 6; g++) {
|
||||
for (b = 0; b < 6; b++) {
|
||||
res = write(gif->fd, (uint8_t []) {r*51, g*51, b*51}, 3); OR_ABORT;
|
||||
if (++i == 1 << depth)
|
||||
goto done_gct;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 1; i <= 24; i++) {
|
||||
v = i * 0xFF / 25;
|
||||
res = write(gif->fd, (uint8_t []) {v, v, v}, 3); OR_ABORT;
|
||||
res = write(gif->fd, "GIF89a", 6);
|
||||
OR_ABORT;
|
||||
res = write_num(gif->fd, width);
|
||||
OR_ABORT;
|
||||
res = write_num(gif->fd, height);
|
||||
OR_ABORT;
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
0xF0 | (depth - 1), 0x00, 0x00}
|
||||
, 3);
|
||||
OR_ABORT;
|
||||
if (palette)
|
||||
{
|
||||
res = write(gif->fd, palette, 3 << depth);
|
||||
OR_ABORT;
|
||||
}
|
||||
else if (depth <= 4)
|
||||
{
|
||||
res = write(gif->fd, vga, 3 << depth);
|
||||
OR_ABORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = write(gif->fd, vga, sizeof(vga));
|
||||
OR_ABORT;
|
||||
i = 0x10;
|
||||
for (r = 0; r < 6; r++)
|
||||
{
|
||||
for (g = 0; g < 6; g++)
|
||||
{
|
||||
for (b = 0; b < 6; b++)
|
||||
{
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
r * 51, g * 51, b * 51}
|
||||
, 3);
|
||||
OR_ABORT;
|
||||
if (++i == 1 << depth)
|
||||
goto done_gct;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 1; i <= 24; i++)
|
||||
{
|
||||
v = i * 0xFF / 25;
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
v, v, v}
|
||||
, 3);
|
||||
OR_ABORT;
|
||||
}
|
||||
}
|
||||
done_gct:
|
||||
if (loop >= 0 && loop <= 0xFFFF)
|
||||
put_loop(gif, (uint16_t) loop);
|
||||
return gif;
|
||||
if (loop >= 0 && loop <= 0xFFFF)
|
||||
put_loop(gif, (uint16_t) loop);
|
||||
return gif;
|
||||
no_fd:
|
||||
free(gif);
|
||||
free(gif);
|
||||
no_gif:
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
put_loop(ge_GIF *gif, uint16_t loop)
|
||||
static void put_loop(ge_GIF * gif, uint16_t loop)
|
||||
{
|
||||
ssize_t res;
|
||||
ssize_t res;
|
||||
|
||||
res = write(gif->fd, (uint8_t []) {'!', 0xFF, 0x0B}, 3); OR_ABORT2;
|
||||
res = write(gif->fd, "NETSCAPE2.0", 11); OR_ABORT2;
|
||||
res = write(gif->fd, (uint8_t []) {0x03, 0x01}, 2); OR_ABORT2;
|
||||
res = write_num(gif->fd, loop); OR_ABORT2;
|
||||
res = write(gif->fd, "\0", 1); OR_ABORT2;
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
'!', 0xFF, 0x0B}, 3);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, "NETSCAPE2.0", 11);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
0x03, 0x01}, 2);
|
||||
OR_ABORT2;
|
||||
res = write_num(gif->fd, loop);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, "\0", 1);
|
||||
OR_ABORT2;
|
||||
}
|
||||
|
||||
/* Add packed key to buffer, updating offset and partial.
|
||||
* gif->offset holds position to put next *bit*
|
||||
* gif->partial holds bits to include in next byte */
|
||||
static void
|
||||
put_key(ge_GIF *gif, uint16_t key, int key_size)
|
||||
static void put_key(ge_GIF * gif, uint16_t key, int key_size)
|
||||
{
|
||||
int byte_offset, bit_offset, bits_to_write;
|
||||
ssize_t res;
|
||||
int byte_offset, bit_offset, bits_to_write;
|
||||
ssize_t res;
|
||||
|
||||
byte_offset = gif->offset / 8;
|
||||
bit_offset = gif->offset % 8;
|
||||
gif->partial |= ((uint32_t) key) << bit_offset;
|
||||
bits_to_write = bit_offset + key_size;
|
||||
while (bits_to_write >= 8) {
|
||||
gif->buffer[byte_offset++] = gif->partial & 0xFF;
|
||||
if (byte_offset == 0xFF) {
|
||||
res = write(gif->fd, "\xFF", 1); OR_ABORT2;
|
||||
res = write(gif->fd, gif->buffer, 0xFF); OR_ABORT2;
|
||||
byte_offset = 0;
|
||||
}
|
||||
gif->partial >>= 8;
|
||||
bits_to_write -= 8;
|
||||
byte_offset = gif->offset / 8;
|
||||
bit_offset = gif->offset % 8;
|
||||
gif->partial |= ((uint32_t) key) << bit_offset;
|
||||
bits_to_write = bit_offset + key_size;
|
||||
while (bits_to_write >= 8)
|
||||
{
|
||||
gif->buffer[byte_offset++] = gif->partial & 0xFF;
|
||||
if (byte_offset == 0xFF)
|
||||
{
|
||||
res = write(gif->fd, "\xFF", 1);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, gif->buffer, 0xFF);
|
||||
OR_ABORT2;
|
||||
byte_offset = 0;
|
||||
}
|
||||
gif->offset = (gif->offset + key_size) % (0xFF * 8);
|
||||
gif->partial >>= 8;
|
||||
bits_to_write -= 8;
|
||||
}
|
||||
gif->offset = (gif->offset + key_size) % (0xFF * 8);
|
||||
}
|
||||
|
||||
static void end_key(ge_GIF * gif)
|
||||
{
|
||||
int byte_offset;
|
||||
ssize_t res;
|
||||
|
||||
byte_offset = gif->offset / 8;
|
||||
if (gif->offset % 8)
|
||||
gif->buffer[byte_offset++] = gif->partial & 0xFF;
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
byte_offset}
|
||||
, 1);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, gif->buffer, byte_offset);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, "\0", 1);
|
||||
OR_ABORT2;
|
||||
gif->offset = gif->partial = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
end_key(ge_GIF *gif)
|
||||
put_image(ge_GIF * gif, uint16_t w, uint16_t h, uint16_t x, uint16_t y)
|
||||
{
|
||||
int byte_offset;
|
||||
ssize_t res;
|
||||
int nkeys, key_size, i, j;
|
||||
Node *node, *child, *root;
|
||||
ssize_t res;
|
||||
int degree = 1 << gif->depth;
|
||||
|
||||
byte_offset = gif->offset / 8;
|
||||
if (gif->offset % 8)
|
||||
gif->buffer[byte_offset++] = gif->partial & 0xFF;
|
||||
res = write(gif->fd, (uint8_t []) {byte_offset}, 1); OR_ABORT2;
|
||||
res = write(gif->fd, gif->buffer, byte_offset); OR_ABORT2;
|
||||
res = write(gif->fd, "\0", 1); OR_ABORT2;
|
||||
gif->offset = gif->partial = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
put_image(ge_GIF *gif, uint16_t w, uint16_t h, uint16_t x, uint16_t y)
|
||||
{
|
||||
int nkeys, key_size, i, j;
|
||||
Node *node, *child, *root;
|
||||
ssize_t res;
|
||||
int degree = 1 << gif->depth;
|
||||
|
||||
res = write(gif->fd, ",", 1); OR_ABORT2;
|
||||
res = write_num(gif->fd, x); OR_ABORT2;
|
||||
res = write_num(gif->fd, y); OR_ABORT2;
|
||||
res = write_num(gif->fd, w); OR_ABORT2;
|
||||
res = write_num(gif->fd, h); OR_ABORT2;
|
||||
res = write(gif->fd, (uint8_t []) {0x00, gif->depth}, 2); OR_ABORT2;
|
||||
root = node = new_trie(degree, &nkeys);
|
||||
key_size = gif->depth + 1;
|
||||
put_key(gif, degree, key_size); /* clear code */
|
||||
for (i = y; i < y+h; i++) {
|
||||
for (j = x; j < x+w; j++) {
|
||||
uint8_t pixel = gif->frame[i*gif->w+j] & (degree - 1);
|
||||
child = node->children[pixel];
|
||||
if (child) {
|
||||
node = child;
|
||||
} else {
|
||||
put_key(gif, node->key, key_size);
|
||||
if (nkeys < 0x1000) {
|
||||
if (nkeys == (1 << key_size))
|
||||
key_size++;
|
||||
node->children[pixel] = new_node(nkeys++, degree);
|
||||
} else {
|
||||
put_key(gif, degree, key_size); /* clear code */
|
||||
del_trie(root, degree);
|
||||
root = node = new_trie(degree, &nkeys);
|
||||
key_size = gif->depth + 1;
|
||||
}
|
||||
node = root->children[pixel];
|
||||
}
|
||||
res = write(gif->fd, ",", 1);
|
||||
OR_ABORT2;
|
||||
res = write_num(gif->fd, x);
|
||||
OR_ABORT2;
|
||||
res = write_num(gif->fd, y);
|
||||
OR_ABORT2;
|
||||
res = write_num(gif->fd, w);
|
||||
OR_ABORT2;
|
||||
res = write_num(gif->fd, h);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
0x00, gif->depth}, 2);
|
||||
OR_ABORT2;
|
||||
root = node = new_trie(degree, &nkeys);
|
||||
key_size = gif->depth + 1;
|
||||
put_key(gif, degree, key_size); /* clear code */
|
||||
for (i = y; i < y + h; i++)
|
||||
{
|
||||
for (j = x; j < x + w; j++)
|
||||
{
|
||||
uint8_t pixel = gif->frame[i * gif->w + j] & (degree - 1);
|
||||
child = node->children[pixel];
|
||||
if (child)
|
||||
{
|
||||
node = child;
|
||||
}
|
||||
else
|
||||
{
|
||||
put_key(gif, node->key, key_size);
|
||||
if (nkeys < 0x1000)
|
||||
{
|
||||
if (nkeys == (1 << key_size))
|
||||
key_size++;
|
||||
node->children[pixel] = new_node(nkeys++, degree);
|
||||
}
|
||||
else
|
||||
{
|
||||
put_key(gif, degree, key_size); /* clear code */
|
||||
del_trie(root, degree);
|
||||
root = node = new_trie(degree, &nkeys);
|
||||
key_size = gif->depth + 1;
|
||||
}
|
||||
node = root->children[pixel];
|
||||
}
|
||||
}
|
||||
put_key(gif, node->key, key_size);
|
||||
put_key(gif, degree + 1, key_size); /* stop code */
|
||||
end_key(gif);
|
||||
del_trie(root, degree);
|
||||
}
|
||||
put_key(gif, node->key, key_size);
|
||||
put_key(gif, degree + 1, key_size); /* stop code */
|
||||
end_key(gif);
|
||||
del_trie(root, degree);
|
||||
}
|
||||
|
||||
static int
|
||||
get_bbox(ge_GIF *gif, uint16_t *w, uint16_t *h, uint16_t *x, uint16_t *y)
|
||||
get_bbox(ge_GIF * gif, uint16_t * w, uint16_t * h, uint16_t * x, uint16_t * y)
|
||||
{
|
||||
int i, j, k;
|
||||
int left, right, top, bottom;
|
||||
left = gif->w; right = 0;
|
||||
top = gif->h; bottom = 0;
|
||||
k = 0;
|
||||
for (i = 0; i < gif->h; i++) {
|
||||
for (j = 0; j < gif->w; j++, k++) {
|
||||
if (gif->frame[k] != gif->back[k]) {
|
||||
if (j < left) left = j;
|
||||
if (j > right) right = j;
|
||||
if (i < top) top = i;
|
||||
if (i > bottom) bottom = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (left != gif->w && top != gif->h) {
|
||||
*x = left; *y = top;
|
||||
*w = right - left + 1;
|
||||
*h = bottom - top + 1;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
int i, j, k;
|
||||
int left, right, top, bottom;
|
||||
left = gif->w;
|
||||
right = 0;
|
||||
top = gif->h;
|
||||
bottom = 0;
|
||||
k = 0;
|
||||
for (i = 0; i < gif->h; i++)
|
||||
{
|
||||
for (j = 0; j < gif->w; j++, k++)
|
||||
{
|
||||
if (gif->frame[k] != gif->back[k])
|
||||
{
|
||||
if (j < left)
|
||||
left = j;
|
||||
if (j > right)
|
||||
right = j;
|
||||
if (i < top)
|
||||
top = i;
|
||||
if (i > bottom)
|
||||
bottom = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (left != gif->w && top != gif->h)
|
||||
{
|
||||
*x = left;
|
||||
*y = top;
|
||||
*w = right - left + 1;
|
||||
*h = bottom - top + 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* (From the docs)
|
||||
|
|
@ -267,46 +335,52 @@ get_bbox(ge_GIF *gif, uint16_t *w, uint16_t *h, uint16_t *x, uint16_t *y)
|
|||
* a minimum of `delay` == 6. If `delay` == 0, no delay information will be stored
|
||||
* for the frame. This can be used when creating still (single-frame) GIF images.
|
||||
*/
|
||||
static void
|
||||
set_delay(ge_GIF *gif, uint16_t d)
|
||||
static void set_delay(ge_GIF * gif, uint16_t d)
|
||||
{
|
||||
ssize_t res;
|
||||
ssize_t res;
|
||||
|
||||
res = write(gif->fd, (uint8_t []) {'!', 0xF9, 0x04, 0x04}, 4); OR_ABORT2;
|
||||
res = write_num(gif->fd, d); OR_ABORT2;
|
||||
res = write(gif->fd, "\0\0", 2); OR_ABORT2;
|
||||
res = write(gif->fd, (uint8_t[])
|
||||
{
|
||||
'!', 0xF9, 0x04, 0x04}, 4);
|
||||
OR_ABORT2;
|
||||
res = write_num(gif->fd, d);
|
||||
OR_ABORT2;
|
||||
res = write(gif->fd, "\0\0", 2);
|
||||
OR_ABORT2;
|
||||
}
|
||||
|
||||
void
|
||||
ge_add_frame(ge_GIF *gif, uint16_t delay)
|
||||
void ge_add_frame(ge_GIF * gif, uint16_t delay)
|
||||
{
|
||||
uint16_t w, h, x, y;
|
||||
uint8_t *tmp;
|
||||
uint16_t w, h, x, y;
|
||||
uint8_t *tmp;
|
||||
|
||||
if (delay)
|
||||
set_delay(gif, delay);
|
||||
if (gif->nframes == 0) {
|
||||
w = gif->w;
|
||||
h = gif->h;
|
||||
x = y = 0;
|
||||
} else if (!get_bbox(gif, &w, &h, &x, &y)) {
|
||||
/* image's not changed; save one pixel just to add delay */
|
||||
w = h = 1;
|
||||
x = y = 0;
|
||||
}
|
||||
put_image(gif, w, h, x, y);
|
||||
gif->nframes++;
|
||||
tmp = gif->back;
|
||||
gif->back = gif->frame;
|
||||
gif->frame = tmp;
|
||||
if (delay)
|
||||
set_delay(gif, delay);
|
||||
if (gif->nframes == 0)
|
||||
{
|
||||
w = gif->w;
|
||||
h = gif->h;
|
||||
x = y = 0;
|
||||
}
|
||||
else if (!get_bbox(gif, &w, &h, &x, &y))
|
||||
{
|
||||
/* image's not changed; save one pixel just to add delay */
|
||||
w = h = 1;
|
||||
x = y = 0;
|
||||
}
|
||||
put_image(gif, w, h, x, y);
|
||||
gif->nframes++;
|
||||
tmp = gif->back;
|
||||
gif->back = gif->frame;
|
||||
gif->frame = tmp;
|
||||
}
|
||||
|
||||
void
|
||||
ge_close_gif(ge_GIF* gif)
|
||||
void ge_close_gif(ge_GIF * gif)
|
||||
{
|
||||
ssize_t res;
|
||||
ssize_t res;
|
||||
|
||||
res = write(gif->fd, ";", 1); OR_ABORT2;
|
||||
close(gif->fd);
|
||||
free(gif);
|
||||
res = write(gif->fd, ";", 1);
|
||||
OR_ABORT2;
|
||||
close(gif->fd);
|
||||
free(gif);
|
||||
}
|
||||
|
|
|
|||
29
src/gifenc.h
29
src/gifenc.h
|
|
@ -3,22 +3,21 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct ge_GIF {
|
||||
uint16_t w, h;
|
||||
int depth;
|
||||
int fd;
|
||||
int offset;
|
||||
int nframes;
|
||||
uint8_t *frame, *back;
|
||||
uint32_t partial;
|
||||
uint8_t buffer[0xFF];
|
||||
typedef struct ge_GIF
|
||||
{
|
||||
uint16_t w, h;
|
||||
int depth;
|
||||
int fd;
|
||||
int offset;
|
||||
int nframes;
|
||||
uint8_t *frame, *back;
|
||||
uint32_t partial;
|
||||
uint8_t buffer[0xFF];
|
||||
} ge_GIF;
|
||||
|
||||
ge_GIF *ge_new_gif(
|
||||
const char *fname, uint16_t width, uint16_t height,
|
||||
uint8_t *palette, int depth, int loop
|
||||
);
|
||||
void ge_add_frame(ge_GIF *gif, uint16_t delay);
|
||||
void ge_close_gif(ge_GIF* gif);
|
||||
ge_GIF *ge_new_gif(const char *fname, uint16_t width, uint16_t height,
|
||||
uint8_t * palette, int depth, int loop);
|
||||
void ge_add_frame(ge_GIF * gif, uint16_t delay);
|
||||
void ge_close_gif(ge_GIF * gif);
|
||||
|
||||
#endif /* GIFENC_H */
|
||||
|
|
|
|||
477
src/i18n.c
477
src/i18n.c
|
|
@ -60,10 +60,16 @@ static char *android_locale()
|
|||
static char android_locale_buf[32];
|
||||
JNIEnv *mEnv = Android_JNI_GetEnv();
|
||||
jclass mLocaleClass = (*mEnv)->FindClass(mEnv, "java/util/Locale");
|
||||
jmethodID mGetDefaultMethod = (*mEnv)->GetStaticMethodID(mEnv, mLocaleClass, "getDefault", "()Ljava/util/Locale;");
|
||||
jobject mLocaleObject = (*mEnv)->CallStaticObjectMethod(mEnv, mLocaleClass, mGetDefaultMethod);
|
||||
jmethodID mToStringMethod = (*mEnv)->GetMethodID(mEnv, mLocaleClass, "toString", "()Ljava/lang/String;");
|
||||
jstring mLocaleString = (*mEnv)->CallObjectMethod(mEnv, mLocaleObject, mToStringMethod);
|
||||
jmethodID mGetDefaultMethod =
|
||||
(*mEnv)->GetStaticMethodID(mEnv, mLocaleClass, "getDefault",
|
||||
"()Ljava/util/Locale;");
|
||||
jobject mLocaleObject =
|
||||
(*mEnv)->CallStaticObjectMethod(mEnv, mLocaleClass, mGetDefaultMethod);
|
||||
jmethodID mToStringMethod =
|
||||
(*mEnv)->GetMethodID(mEnv, mLocaleClass, "toString",
|
||||
"()Ljava/lang/String;");
|
||||
jstring mLocaleString =
|
||||
(*mEnv)->CallObjectMethod(mEnv, mLocaleObject, mToStringMethod);
|
||||
const char *locale = (*mEnv)->GetStringUTFChars(mEnv, mLocaleString, 0);
|
||||
|
||||
strcpy(android_locale_buf, locale);
|
||||
|
|
@ -484,7 +490,9 @@ static void show_lang_usage(int exitcode)
|
|||
const char *const prg = "tuxpaint";
|
||||
|
||||
/* FIXME: All this should REALLY be array-based!!! */
|
||||
fprintf(f, "\n" "Usage: %s [--lang LANGUAGE]\n" "\n" "LANGUAGE may be one of:\n"
|
||||
fprintf(f,
|
||||
"\n" "Usage: %s [--lang LANGUAGE]\n" "\n"
|
||||
"LANGUAGE may be one of:\n"
|
||||
/* C */ " english american-english\n"
|
||||
/* ach */ " acholi acoli\n"
|
||||
/* af */ " afrikaans\n"
|
||||
|
|
@ -505,7 +513,8 @@ static void show_lang_usage(int exitcode)
|
|||
/* brx */ " bodo\n"
|
||||
/* nb */ " bokmal\n"
|
||||
/* bs */ " bosnian\n"
|
||||
/* pt_BR */ " brazilian brazilian-portuguese portugues-brazilian\n"
|
||||
/* pt_BR */
|
||||
" brazilian brazilian-portuguese portugues-brazilian\n"
|
||||
/* br */ " breton brezhoneg\n"
|
||||
/* en_GB */ " british british-english\n"
|
||||
/* bg_BG */ " bulgarian\n"
|
||||
|
|
@ -562,7 +571,8 @@ static void show_lang_usage(int exitcode)
|
|||
/* mni */ " manipuri-bengali\n"
|
||||
/* mni@meiteimayek */ " manipuri-meitei-mayek\n"
|
||||
/* nr */ " marathi\n"
|
||||
/* es_MX */ " mexican mexican-spanish espanol-mejicano\n"
|
||||
/* es_MX */
|
||||
" mexican mexican-spanish espanol-mejicano\n"
|
||||
/* mn */ " mongolian\n"
|
||||
/* nr */ " ndebele\n"
|
||||
/* ne */ " nepali\n"
|
||||
|
|
@ -760,7 +770,8 @@ static void show_locale_usage(FILE * f, const char *const prg)
|
|||
" wa_BE (Walloon)\n"
|
||||
" wo_SN (Wolof)\n"
|
||||
" cy_GB (Welsh Cymraeg)\n"
|
||||
" xh_ZA (Xhosa)\n" " zam (Zapoteco-Miahuatlan)\n" " zu_ZA (Zulu)\n" "\n", prg);
|
||||
" xh_ZA (Xhosa)\n" " zam (Zapoteco-Miahuatlan)\n"
|
||||
" zu_ZA (Zulu)\n" "\n", prg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -785,10 +796,10 @@ static int search_int_array(int l, int *array)
|
|||
int i;
|
||||
|
||||
for (i = 0; array[i] != -1; i++)
|
||||
{
|
||||
if (array[i] == l)
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (array[i] == l)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -804,18 +815,19 @@ static void ctype_utf8(void)
|
|||
#ifndef _WIN32
|
||||
/* FIXME: should this iterate over more locales?
|
||||
A zapotec speaker may have es_MX.UTF-8 available but not have en_US.UTF-8 for example */
|
||||
const char *names[] = { "en_US.UTF8", "en_US.UTF-8", "UTF8", "UTF-8", "C.UTF-8" };
|
||||
const char *names[] =
|
||||
{ "en_US.UTF8", "en_US.UTF-8", "UTF8", "UTF-8", "C.UTF-8" };
|
||||
int i = sizeof(names) / sizeof(names[0]);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (iswprint((wchar_t) 0xf7)) // division symbol -- which is in Latin-1 :-/
|
||||
return;
|
||||
if (--i < 0)
|
||||
break;
|
||||
setlocale(LC_CTYPE, names[i]);
|
||||
setlocale(LC_MESSAGES, names[i]);
|
||||
}
|
||||
{
|
||||
if (iswprint((wchar_t) 0xf7)) // division symbol -- which is in Latin-1 :-/
|
||||
return;
|
||||
if (--i < 0)
|
||||
break;
|
||||
setlocale(LC_CTYPE, names[i]);
|
||||
setlocale(LC_MESSAGES, names[i]);
|
||||
}
|
||||
fprintf(stderr, "Failed to find a locale with iswprint() working!\n");
|
||||
#endif
|
||||
}
|
||||
|
|
@ -828,13 +840,14 @@ static void ctype_utf8(void)
|
|||
*/
|
||||
static const char *language_to_locale(const char *langstr)
|
||||
{
|
||||
int i = sizeof language_to_locale_array / sizeof language_to_locale_array[0];
|
||||
int i =
|
||||
sizeof language_to_locale_array / sizeof language_to_locale_array[0];
|
||||
|
||||
while (i--)
|
||||
{
|
||||
if (!strcmp(langstr, language_to_locale_array[i].language))
|
||||
return language_to_locale_array[i].locale;
|
||||
}
|
||||
{
|
||||
if (!strcmp(langstr, language_to_locale_array[i].language))
|
||||
return language_to_locale_array[i].locale;
|
||||
}
|
||||
if (strcmp(langstr, "help") == 0 || strcmp(langstr, "list") == 0)
|
||||
show_lang_usage(0);
|
||||
fprintf(stderr, "%s is an invalid language\n", langstr);
|
||||
|
|
@ -854,34 +867,37 @@ static const char *language_to_locale(const char *langstr)
|
|||
*/
|
||||
static const char *locale_to_closest_locale(const char *inlocale)
|
||||
{
|
||||
const int numlocale = sizeof(language_to_locale_array) / sizeof(language_to_locale_array[0]);
|
||||
const char* outlocale = NULL;
|
||||
const int numlocale =
|
||||
sizeof(language_to_locale_array) / sizeof(language_to_locale_array[0]);
|
||||
const char *outlocale = NULL;
|
||||
int outlocale_score = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
/* find the locale with the longest string match */
|
||||
for (i = 0; i < numlocale; i++)
|
||||
{
|
||||
const char *candidate = language_to_locale_array[i].locale;
|
||||
|
||||
for (j = 0; j < (int) strlen(inlocale) && j < (int) strlen(candidate);
|
||||
j++)
|
||||
{
|
||||
const char* candidate = language_to_locale_array[i].locale;
|
||||
|
||||
for (j = 0; j < (int) strlen(inlocale) && j < (int) strlen(candidate); j++)
|
||||
{
|
||||
if(inlocale[j] != candidate[j]) break;
|
||||
}
|
||||
|
||||
if (j > outlocale_score)
|
||||
{
|
||||
outlocale = candidate;
|
||||
outlocale_score = j;
|
||||
}
|
||||
if (inlocale[j] != candidate[j])
|
||||
break;
|
||||
}
|
||||
|
||||
if (j > outlocale_score)
|
||||
{
|
||||
outlocale = candidate;
|
||||
outlocale_score = j;
|
||||
}
|
||||
}
|
||||
|
||||
/* locale must match at least two characters */
|
||||
if (outlocale_score < 2)
|
||||
{
|
||||
outlocale = "";
|
||||
}
|
||||
{
|
||||
outlocale = "";
|
||||
}
|
||||
|
||||
return outlocale;
|
||||
}
|
||||
|
|
@ -925,68 +941,70 @@ static void set_langint_from_locale_string(const char *restrict loc)
|
|||
*dot = '\0';
|
||||
|
||||
if (cntrycode)
|
||||
{
|
||||
ccodeaux = strdup(cntrycode);
|
||||
*cntrycode = '\0';
|
||||
}
|
||||
{
|
||||
ccodeaux = strdup(cntrycode);
|
||||
*cntrycode = '\0';
|
||||
}
|
||||
|
||||
if (at)
|
||||
{
|
||||
ataux = strdup(at);
|
||||
*at = '\0';
|
||||
|
||||
if (cntrycode)
|
||||
{
|
||||
ataux = strdup(at);
|
||||
*at = '\0';
|
||||
|
||||
if (cntrycode)
|
||||
{
|
||||
/* ll_CC@variant */
|
||||
//if (found == 0) printf("ll_CC@variant check\n");
|
||||
snprintf(straux, 255, "%s%s%s", baseloc, ccodeaux, ataux);
|
||||
len_baseloc = strlen(straux);
|
||||
for (i = 0; i < NUM_LANGS && found == 0; i++)
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(straux, lang_prefixes[i], len_baseloc))
|
||||
{
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ll@variant */
|
||||
//if (found == 0) printf("ll@variant check\n");
|
||||
snprintf(straux, 255, "%s%s", baseloc, ataux);
|
||||
/* ll_CC@variant */
|
||||
//if (found == 0) printf("ll_CC@variant check\n");
|
||||
snprintf(straux, 255, "%s%s%s", baseloc, ccodeaux, ataux);
|
||||
len_baseloc = strlen(straux);
|
||||
for (i = 0; i < NUM_LANGS && found == 0; i++)
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i])
|
||||
&& !strncasecmp(straux, lang_prefixes[i], len_baseloc))
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(straux, lang_prefixes[i], len_baseloc))
|
||||
{
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ll@variant */
|
||||
//if (found == 0) printf("ll@variant check\n");
|
||||
snprintf(straux, 255, "%s%s", baseloc, ataux);
|
||||
len_baseloc = strlen(straux);
|
||||
for (i = 0; i < NUM_LANGS && found == 0; i++)
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i])
|
||||
&& !strncasecmp(straux, lang_prefixes[i], len_baseloc))
|
||||
{
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cntrycode)
|
||||
{
|
||||
/* ll_CC */
|
||||
//if (found == 0) printf("ll_CC check\n");
|
||||
snprintf(straux, 255, "%s%s", baseloc, ccodeaux);
|
||||
len_baseloc = strlen(straux);
|
||||
|
||||
/* Which, if any, of the locales is it? */
|
||||
|
||||
for (i = 0; i < NUM_LANGS && found == 0; i++)
|
||||
{
|
||||
/* ll_CC */
|
||||
//if (found == 0) printf("ll_CC check\n");
|
||||
snprintf(straux, 255, "%s%s", baseloc, ccodeaux);
|
||||
len_baseloc = strlen(straux);
|
||||
|
||||
/* Which, if any, of the locales is it? */
|
||||
|
||||
for (i = 0; i < NUM_LANGS && found == 0; i++)
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i]) &&
|
||||
!strncasecmp(straux, lang_prefixes[i], strlen(lang_prefixes[i])))
|
||||
{
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i]) &&
|
||||
!strncasecmp(straux, lang_prefixes[i], strlen(lang_prefixes[i])))
|
||||
{
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ll */
|
||||
// if (found == 0) printf("ll check\n");
|
||||
|
|
@ -994,14 +1012,15 @@ static void set_langint_from_locale_string(const char *restrict loc)
|
|||
/* Which, if any, of the locales is it? */
|
||||
|
||||
for (i = 0; i < NUM_LANGS && found == 0; i++)
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i])
|
||||
&& !strncasecmp(baseloc, lang_prefixes[i], strlen(lang_prefixes[i])))
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (len_baseloc == strlen(lang_prefixes[i]) && !strncasecmp(baseloc, lang_prefixes[i], strlen(lang_prefixes[i])))
|
||||
{
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Last resort, we should never arrive here, this check depends
|
||||
on the right order in lang_prefixes[]
|
||||
|
|
@ -1011,14 +1030,14 @@ static void set_langint_from_locale_string(const char *restrict loc)
|
|||
// printf("Language still not found: loc= %s Trying reverse check as last resource...\n", loc);
|
||||
|
||||
for (i = 0; i < NUM_LANGS && found == 0; i++)
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (!strncasecmp(loc, lang_prefixes[i], strlen(lang_prefixes[i])))
|
||||
{
|
||||
// Case-insensitive (both "pt_BR" and "pt_br" work, etc.)
|
||||
if (!strncasecmp(loc, lang_prefixes[i], strlen(lang_prefixes[i])))
|
||||
{
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
langint = i;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
// printf("langint %i, lang_ext %s\n", langint, lang_prefixes[langint]);
|
||||
|
||||
free(baseloc);
|
||||
|
|
@ -1048,7 +1067,8 @@ static void mysetenv(const char *name, const char *value)
|
|||
char *str;
|
||||
#endif
|
||||
|
||||
if (name != NULL && value != NULL) {
|
||||
if (name != NULL && value != NULL)
|
||||
{
|
||||
#ifdef HAVE_SETENV
|
||||
setenv(name, value, 1);
|
||||
#else
|
||||
|
|
@ -1058,11 +1078,12 @@ static void mysetenv(const char *name, const char *value)
|
|||
sprintf(str, "%s=%s", name, value);
|
||||
putenv(str);
|
||||
#endif
|
||||
} else {
|
||||
fprintf(stderr, "WARNING: mysetenv() received a null pointer. name=%s, value=%s\n",
|
||||
(name == NULL ? "NULL" : name),
|
||||
(value == NULL ? "NULL" : value)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,
|
||||
"WARNING: mysetenv() received a null pointer. name=%s, value=%s\n",
|
||||
(name == NULL ? "NULL" : name), (value == NULL ? "NULL" : value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1074,7 +1095,8 @@ static void mysetenv(const char *name, const char *value)
|
|||
* @return The Y-nudge value for font rendering in the language.
|
||||
*/
|
||||
|
||||
static int set_current_language(const char *restrict loc, int * ptr_num_wished_langs)
|
||||
static int set_current_language(const char *restrict loc,
|
||||
int *ptr_num_wished_langs)
|
||||
{
|
||||
int i;
|
||||
int j = 0;
|
||||
|
|
@ -1087,66 +1109,67 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
|
|||
*ptr_num_wished_langs = 0;
|
||||
|
||||
if (strlen(loc) > 0)
|
||||
{
|
||||
/* Got command line or config file language */
|
||||
DEBUG_PRINTF("Language via config: %s\n", loc);
|
||||
mysetenv("LANGUAGE", loc);
|
||||
}
|
||||
{
|
||||
/* Got command line or config file language */
|
||||
DEBUG_PRINTF("Language via config: %s\n", loc);
|
||||
mysetenv("LANGUAGE", loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINTF("Language NOT set via config\n");
|
||||
{
|
||||
DEBUG_PRINTF("Language NOT set via config\n");
|
||||
|
||||
/* Find what language to use from env vars */
|
||||
env = getenv("LANGUAGE");
|
||||
if (env == NULL || env[0] == '\0')
|
||||
{
|
||||
env = getenv("LC_ALL");
|
||||
if (env != NULL && env[0] != '\0')
|
||||
{
|
||||
DEBUG_PRINTF("Language via LC_ALL: %s\n", getenv("LC_ALL"));
|
||||
mysetenv("LANGUAGE", getenv("LC_ALL"));
|
||||
}
|
||||
else
|
||||
{
|
||||
env = getenv("LC_MESSAGES");
|
||||
if (env != NULL && env[0] != '\0')
|
||||
{
|
||||
DEBUG_PRINTF("Language via LC_MESSAGES: %s\n", getenv("LC_MESSAGES"));
|
||||
mysetenv("LANGUAGE", getenv("LC_MESSAGES"));
|
||||
}
|
||||
else
|
||||
{
|
||||
env = getenv("LANG");
|
||||
if (env != NULL && env[0] != '\0')
|
||||
{
|
||||
DEBUG_PRINTF("Language via LANG: %s\n", getenv("LANG"));
|
||||
mysetenv("LANGUAGE", getenv("LANG"));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINTF("No language set!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Find what language to use from env vars */
|
||||
env = getenv("LANGUAGE");
|
||||
if (env == NULL || env[0] == '\0')
|
||||
{
|
||||
env = getenv("LC_ALL");
|
||||
if (env != NULL && env[0] != '\0')
|
||||
{
|
||||
DEBUG_PRINTF("Language via LC_ALL: %s\n", getenv("LC_ALL"));
|
||||
mysetenv("LANGUAGE", getenv("LC_ALL"));
|
||||
}
|
||||
else
|
||||
{
|
||||
env = getenv("LC_MESSAGES");
|
||||
if (env != NULL && env[0] != '\0')
|
||||
{
|
||||
DEBUG_PRINTF("Language was set to '%s'\n", getenv("LANGUAGE"));
|
||||
}
|
||||
DEBUG_PRINTF("Language via LC_MESSAGES: %s\n",
|
||||
getenv("LC_MESSAGES"));
|
||||
mysetenv("LANGUAGE", getenv("LC_MESSAGES"));
|
||||
}
|
||||
else
|
||||
{
|
||||
env = getenv("LANG");
|
||||
if (env != NULL && env[0] != '\0')
|
||||
{
|
||||
DEBUG_PRINTF("Language via LANG: %s\n", getenv("LANG"));
|
||||
mysetenv("LANGUAGE", getenv("LANG"));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINTF("No language set!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINTF("Language was set to '%s'\n", getenv("LANGUAGE"));
|
||||
}
|
||||
}
|
||||
|
||||
oldloc = strdup(loc);
|
||||
|
||||
/* First set the locale according to the environment, then try to overwrite with loc,
|
||||
after that, ctype_utf8() call will test the compatibility with utf8 and try to load
|
||||
a different locale if the resulting one is not compatible. */
|
||||
DEBUG_PRINTF("Locale BEFORE is: %s\n", setlocale(LC_ALL, NULL)); //EP
|
||||
DEBUG_PRINTF("Locale BEFORE is: %s\n", setlocale(LC_ALL, NULL)); //EP
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_ALL, loc);
|
||||
ctype_utf8();
|
||||
|
||||
DEBUG_PRINTF("Locale AFTER is: %s\n", setlocale(LC_ALL, NULL)); //EP
|
||||
DEBUG_PRINTF("Locale AFTER is: %s\n", setlocale(LC_ALL, NULL)); //EP
|
||||
|
||||
#ifdef BDIST_WIN32
|
||||
// FIXME: After the update of MinGW/MSYS2 in January 2022, gettext() no longer find
|
||||
|
|
@ -1177,77 +1200,80 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
|
|||
loc = setlocale(LC_MESSAGES, NULL);
|
||||
|
||||
if (oldloc && loc && strcmp(oldloc, "") != 0 && strcmp(loc, oldloc) != 0)
|
||||
{
|
||||
/* System doesn't recognize that locale! Hack, per Albert C., is to set LC_ALL to a valid UTF-8 locale, then set LANGUAGE to the locale we want to force -bjk 2010.10.05 */
|
||||
{
|
||||
/* System doesn't recognize that locale! Hack, per Albert C., is to set LC_ALL to a valid UTF-8 locale, then set LANGUAGE to the locale we want to force -bjk 2010.10.05 */
|
||||
|
||||
/* Albert's comments from December 2009:
|
||||
gettext() won't even bother to look up messages unless it
|
||||
is totally satisfied that you are using one of the locales that
|
||||
it ships with! Make gettext() unhappy, and it'll switch to the
|
||||
lobotomized 7-bit Linux "C" locale just to spite you.
|
||||
/* Albert's comments from December 2009:
|
||||
gettext() won't even bother to look up messages unless it
|
||||
is totally satisfied that you are using one of the locales that
|
||||
it ships with! Make gettext() unhappy, and it'll switch to the
|
||||
lobotomized 7-bit Linux "C" locale just to spite you.
|
||||
|
||||
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/SUPPORTED?content-type=text/x-cvsweb-markup&cvsroot=glibc
|
||||
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/SUPPORTED?content-type=text/x-cvsweb-markup&cvsroot=glibc
|
||||
|
||||
You can confuse gettext() into mostly behaving. For example, a
|
||||
user could pick a random UTF-8 locale and change the messages.
|
||||
In that case, Tux Paint thinks it's in the other locale but the
|
||||
messages come out right. Like so: LANGUAGE=zam LC_ALL=fr_FR.UTF-8
|
||||
It doesn't work to leave LC_ALL unset, set it to "zam", set it to "C",
|
||||
or set it to random nonsense. Yeah, Tux Paint will think it's in
|
||||
a French locale, but the messages will be Zapotec nonetheless.
|
||||
You can confuse gettext() into mostly behaving. For example, a
|
||||
user could pick a random UTF-8 locale and change the messages.
|
||||
In that case, Tux Paint thinks it's in the other locale but the
|
||||
messages come out right. Like so: LANGUAGE=zam LC_ALL=fr_FR.UTF-8
|
||||
It doesn't work to leave LC_ALL unset, set it to "zam", set it to "C",
|
||||
or set it to random nonsense. Yeah, Tux Paint will think it's in
|
||||
a French locale, but the messages will be Zapotec nonetheless.
|
||||
|
||||
Maybe it's time to give up on gettext().
|
||||
Maybe it's time to give up on gettext().
|
||||
|
||||
[see also: https://sourceforge.net/mailarchive/message.php?msg_name=787b0d920912222352i5ab22834x92686283b565016b%40mail.gmail.com ]
|
||||
*/
|
||||
[see also: https://sourceforge.net/mailarchive/message.php?msg_name=787b0d920912222352i5ab22834x92686283b565016b%40mail.gmail.com ]
|
||||
*/
|
||||
|
||||
/* Unneeded here, this has yet been done as part of ctype_utf8() call before, iterating over a list of locales */
|
||||
// setlocale(LC_ALL, "en_US.UTF-8"); /* Is it dumb to assume "en_US" is pretty close to "C" locale? */
|
||||
/* Unneeded here, this has yet been done as part of ctype_utf8() call before, iterating over a list of locales */
|
||||
// setlocale(LC_ALL, "en_US.UTF-8"); /* Is it dumb to assume "en_US" is pretty close to "C" locale? */
|
||||
|
||||
mysetenv("LANGUAGE", oldloc);
|
||||
set_langint_from_locale_string(oldloc);
|
||||
}
|
||||
mysetenv("LANGUAGE", oldloc);
|
||||
set_langint_from_locale_string(oldloc);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (getenv("LANGUAGE") == NULL)
|
||||
mysetenv("LANGUAGE", loc);
|
||||
if (getenv("LANGUAGE") == NULL)
|
||||
mysetenv("LANGUAGE", loc);
|
||||
#endif
|
||||
|
||||
if (getenv("LANGUAGE") == NULL)
|
||||
mysetenv("LANGUAGE", "C");
|
||||
}
|
||||
if (getenv("LANGUAGE") == NULL)
|
||||
mysetenv("LANGUAGE", "C");
|
||||
}
|
||||
env_language = strdup(getenv("LANGUAGE"));
|
||||
|
||||
if (*env_language)
|
||||
{
|
||||
env_language_lang = strtok(env_language, ":");
|
||||
while (env_language_lang != NULL)
|
||||
{
|
||||
env_language_lang = strtok(env_language, ":");
|
||||
while (env_language_lang != NULL)
|
||||
num_wished_langs++;
|
||||
set_langint_from_locale_string(env_language_lang);
|
||||
wished_langs[j].langint = langint;
|
||||
wished_langs[j].lang_prefix = lang_prefixes[langint];
|
||||
wished_langs[j].need_own_font =
|
||||
search_int_array(langint, lang_use_own_font);
|
||||
wished_langs[j].need_right_to_left =
|
||||
search_int_array(langint, lang_use_right_to_left);
|
||||
wished_langs[j].need_right_to_left_word =
|
||||
search_int_array(langint, lang_use_right_to_left_word);
|
||||
for (i = 0; lang_y_nudge[i][0] != -1; i++)
|
||||
{
|
||||
// printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]);
|
||||
if (lang_y_nudge[i][0] == langint)
|
||||
{
|
||||
num_wished_langs++;
|
||||
set_langint_from_locale_string(env_language_lang);
|
||||
wished_langs[j].langint = langint;
|
||||
wished_langs[j].lang_prefix = lang_prefixes[langint];
|
||||
wished_langs[j].need_own_font = search_int_array(langint, lang_use_own_font);
|
||||
wished_langs[j].need_right_to_left = search_int_array(langint, lang_use_right_to_left);
|
||||
wished_langs[j].need_right_to_left_word = search_int_array(langint, lang_use_right_to_left_word);
|
||||
for (i = 0; lang_y_nudge[i][0] != -1; i++)
|
||||
{
|
||||
// printf("lang_y_nudge[%d][0] = %d\n", i, lang_y_nudge[i][0]);
|
||||
if (lang_y_nudge[i][0] == langint)
|
||||
{
|
||||
wished_langs[j].lang_y_nudge = lang_y_nudge[i][1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
j++;
|
||||
env_language_lang = strtok(NULL, ":");
|
||||
wished_langs[j].lang_y_nudge = lang_y_nudge[i][1];
|
||||
break;
|
||||
}
|
||||
if (*env_language)
|
||||
free(env_language);
|
||||
}
|
||||
|
||||
|
||||
j++;
|
||||
env_language_lang = strtok(NULL, ":");
|
||||
}
|
||||
if (*env_language)
|
||||
free(env_language);
|
||||
}
|
||||
// set_langint_from_locale_string(loc);
|
||||
|
||||
|
||||
|
|
@ -1264,13 +1290,15 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
|
|||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "DEBUG: Language is %s (%d) %s/%s\n",
|
||||
lang_prefix, langint, need_right_to_left ? "(RTL)" : "", need_right_to_left_word ? "(RTL words)" : "");
|
||||
lang_prefix, langint, need_right_to_left ? "(RTL)" : "",
|
||||
need_right_to_left_word ? "(RTL words)" : "");
|
||||
fflush(stderr);
|
||||
#endif
|
||||
|
||||
free(oldloc);
|
||||
|
||||
DEBUG_PRINTF("lang_prefixes[%d] is \"%s\"\n", get_current_language(), lang_prefixes[get_current_language()]);
|
||||
DEBUG_PRINTF("lang_prefixes[%d] is \"%s\"\n", get_current_language(),
|
||||
lang_prefixes[get_current_language()]);
|
||||
|
||||
*ptr_num_wished_langs = num_wished_langs;
|
||||
|
||||
|
|
@ -1289,27 +1317,28 @@ static int set_current_language(const char *restrict loc, int * ptr_num_wished_l
|
|||
* @param int * a place to return the number of languages we want to use, when scanning stamp descriptions
|
||||
* @return Y-nudge
|
||||
*/
|
||||
int setup_i18n(const char *restrict lang, const char *restrict locale, int * num_wished_langs)
|
||||
int setup_i18n(const char *restrict lang, const char *restrict locale,
|
||||
int *num_wished_langs)
|
||||
{
|
||||
DEBUG_PRINTF("lang %p, locale %p\n", lang, locale);
|
||||
DEBUG_PRINTF("lang \"%s\", locale \"%s\"\n", lang, locale);
|
||||
|
||||
if (locale)
|
||||
{
|
||||
if (!strcmp(locale, "help"))
|
||||
{
|
||||
if (!strcmp(locale, "help"))
|
||||
{
|
||||
show_locale_usage(stdout, "tuxpaint");
|
||||
exit(0);
|
||||
}
|
||||
show_locale_usage(stdout, "tuxpaint");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
locale = locale_to_closest_locale(apple_locale());
|
||||
#else
|
||||
locale = "";
|
||||
#endif
|
||||
}
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
locale = locale_to_closest_locale(apple_locale());
|
||||
#else
|
||||
locale = "";
|
||||
#endif
|
||||
}
|
||||
|
||||
if (lang)
|
||||
locale = language_to_locale(lang);
|
||||
|
|
|
|||
|
|
@ -206,7 +206,8 @@ extern w_langs wished_langs[255];
|
|||
/* Function prototypes: */
|
||||
|
||||
int get_current_language(void);
|
||||
int setup_i18n(const char *restrict lang, const char *restrict locale, int * ptr_num_wished_languages) MUST_CHECK;
|
||||
int setup_i18n(const char *restrict lang, const char *restrict locale,
|
||||
int *ptr_num_wished_languages) MUST_CHECK;
|
||||
|
||||
#ifdef NO_SDLPANGO
|
||||
int smash_i18n(void) MUST_CHECK;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@
|
|||
#include "SDL.h"
|
||||
|
||||
|
||||
int DisplayPageSetup(const SDL_Surface* surface);
|
||||
const char* SurfacePrint(const SDL_Surface* surface, int showDialog);
|
||||
int DisplayPageSetup(const SDL_Surface * surface);
|
||||
const char *SurfacePrint(const SDL_Surface * surface, int showDialog);
|
||||
|
||||
|
||||
#endif /* __IOS_PRINT_H__ */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -105,13 +105,13 @@ typedef struct osk_keyboard
|
|||
char *name; /* The name of the keyboard */
|
||||
char *keyboard_list; /* The names of the keyboards allowed from this one */
|
||||
SDL_Surface *surface; /* The surface containing the current layout's keyboard */
|
||||
/* The surfaces containing the current layout's button backgrounds*/
|
||||
/* The surfaces containing the current layout's button backgrounds */
|
||||
SDL_Surface *button_up;
|
||||
SDL_Surface *button_down;
|
||||
SDL_Surface *button_off;
|
||||
SDL_Surface *button_nav;
|
||||
SDL_Surface *button_hold;
|
||||
/* The surfaces containing some symbols for the current layout's buttons */
|
||||
/* The surfaces containing some symbols for the current layout's buttons */
|
||||
SDL_Surface *oskdel; /* delete arrow */
|
||||
SDL_Surface *osktab; /* Tab arrows */
|
||||
SDL_Surface *oskenter; /* Return hook/arrow */
|
||||
|
|
@ -133,7 +133,7 @@ typedef struct osk_keyboard
|
|||
int composed_type; /* 1 if the value stored in composed is yet the unicode value */
|
||||
osk_composenode *composing; /* The node in the middle of a compose sequence */
|
||||
osk_key *last_key_pressed; /* The last key pressed */
|
||||
SDL_Surface * canvas_ptr; /* Canvas drawing surface, for bpp and sizing needs when cycling through keyboard layouts */
|
||||
SDL_Surface *canvas_ptr; /* Canvas drawing surface, for bpp and sizing needs when cycling through keyboard layouts */
|
||||
/* Large and small buttons, to pass back to osk_create() when cycling through keyboard layouts */
|
||||
SDL_Surface *BLANK_button_up;
|
||||
SDL_Surface *BLANK_button_down;
|
||||
|
|
@ -147,17 +147,23 @@ typedef struct osk_keyboard
|
|||
SDL_Surface *BLANK_oskshift;
|
||||
} on_screen_keyboard;
|
||||
|
||||
struct osk_keyboard *osk_create(char * layout_name, SDL_Surface * canvas,
|
||||
SDL_Surface * BLANK_button_up, SDL_Surface * BLANK_button_down,
|
||||
SDL_Surface * BLANK_button_off, SDL_Surface * BLANK_button_nav,
|
||||
struct osk_keyboard *osk_create(char *layout_name, SDL_Surface * canvas,
|
||||
SDL_Surface * BLANK_button_up,
|
||||
SDL_Surface * BLANK_button_down,
|
||||
SDL_Surface * BLANK_button_off,
|
||||
SDL_Surface * BLANK_button_nav,
|
||||
SDL_Surface * BLANK_button_hold,
|
||||
SDL_Surface * BLANK_oskdel, SDL_Surface * BLANK_osktab, SDL_Surface * BLANK_oskenter,
|
||||
SDL_Surface * BLANK_oskcapslock, SDL_Surface * BLANK_oskshift,
|
||||
SDL_Surface * BLANK_oskdel,
|
||||
SDL_Surface * BLANK_osktab,
|
||||
SDL_Surface * BLANK_oskenter,
|
||||
SDL_Surface * BLANK_oskcapslock,
|
||||
SDL_Surface * BLANK_oskshift,
|
||||
int disable_change);
|
||||
|
||||
struct osk_layout *osk_load_layout(char *layout_name);
|
||||
|
||||
void osk_get_layout_data(char *layout_name, int *layout_w, int *layout_h, char *layout_buttons, char *layout_labels,
|
||||
void osk_get_layout_data(char *layout_name, int *layout_w, int *layout_h,
|
||||
char *layout_buttons, char *layout_labels,
|
||||
char *layout_keycodes);
|
||||
void osk_reset(on_screen_keyboard * osk);
|
||||
struct osk_keyboard *osk_clicked(on_screen_keyboard * keyboard, int x, int y);
|
||||
|
|
|
|||
|
|
@ -95,5 +95,5 @@ struct cfginfo
|
|||
|
||||
#define CFGINFO_MAXOFFSET (sizeof(struct cfginfo))
|
||||
|
||||
extern void parse_one_option(struct cfginfo *restrict tmpcfg, const char *str, const char *opt,
|
||||
const char *restrict src);
|
||||
extern void parse_one_option(struct cfginfo *restrict tmpcfg, const char *str,
|
||||
const char *opt, const char *restrict src);
|
||||
|
|
|
|||
142
src/pixels.c
142
src/pixels.c
|
|
@ -37,19 +37,21 @@ static void putpixel8(SDL_Surface * surface, int x, int y, Uint32 pixel)
|
|||
Uint8 *p;
|
||||
|
||||
/* Assuming the X/Y values are within the bounds of this surface... */
|
||||
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
x); /* Go in X pixels */
|
||||
if (likely
|
||||
(likely((unsigned) x < (unsigned) surface->w)
|
||||
&& likely((unsigned) y < (unsigned) surface->h)))
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
x); /* Go in X pixels */
|
||||
|
||||
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
|
||||
*p = pixel;
|
||||
}
|
||||
*p = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw a single pixel into the surface: */
|
||||
|
|
@ -58,19 +60,21 @@ static void putpixel16(SDL_Surface * surface, int x, int y, Uint32 pixel)
|
|||
Uint8 *p;
|
||||
|
||||
/* Assuming the X/Y values are within the bounds of this surface... */
|
||||
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
(x * 2)); /* Go in X pixels */
|
||||
if (likely
|
||||
(likely((unsigned) x < (unsigned) surface->w)
|
||||
&& likely((unsigned) y < (unsigned) surface->h)))
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
(x * 2)); /* Go in X pixels */
|
||||
|
||||
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
|
||||
*(Uint16 *) p = pixel;
|
||||
}
|
||||
*(Uint16 *) p = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw a single pixel into the surface: */
|
||||
|
|
@ -79,31 +83,33 @@ static void putpixel24(SDL_Surface * surface, int x, int y, Uint32 pixel)
|
|||
Uint8 *p;
|
||||
|
||||
/* Assuming the X/Y values are within the bounds of this surface... */
|
||||
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
|
||||
if (likely
|
||||
(likely((unsigned) x < (unsigned) surface->w)
|
||||
&& likely((unsigned) y < (unsigned) surface->h)))
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
(x * 3)); /* Go in X pixels */
|
||||
|
||||
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
(x * 3)); /* Go in X pixels */
|
||||
|
||||
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
{
|
||||
p[0] = (pixel >> 16) & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = pixel & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = pixel & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = (pixel >> 16) & 0xff;
|
||||
}
|
||||
|
||||
p[0] = (pixel >> 16) & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = pixel & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = pixel & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = (pixel >> 16) & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw a single pixel into the surface: */
|
||||
|
|
@ -112,19 +118,21 @@ static void putpixel32(SDL_Surface * surface, int x, int y, Uint32 pixel)
|
|||
Uint8 *p;
|
||||
|
||||
/* Assuming the X/Y values are within the bounds of this surface... */
|
||||
if (likely(likely((unsigned)x < (unsigned)surface->w) && likely((unsigned)y < (unsigned)surface->h)))
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
(x * 4)); /* Go in X pixels */
|
||||
if (likely
|
||||
(likely((unsigned) x < (unsigned) surface->w)
|
||||
&& likely((unsigned) y < (unsigned) surface->h)))
|
||||
{
|
||||
// Set a pointer to the exact location in memory of the pixel
|
||||
p = (Uint8 *) (((Uint8 *) surface->pixels) + /* Start: beginning of RAM */
|
||||
(y * surface->pitch) + /* Go down Y lines */
|
||||
(x * 4)); /* Go in X pixels */
|
||||
|
||||
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
/* Set the (correctly-sized) piece of data in the surface's RAM
|
||||
* to the pixel value sent in: */
|
||||
|
||||
*(Uint32 *) p = pixel; // 32-bit display
|
||||
}
|
||||
*(Uint32 *) p = pixel; // 32-bit display
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a pixel: */
|
||||
|
|
@ -133,9 +141,9 @@ static Uint32 getpixel8(SDL_Surface * surface, int x, int y)
|
|||
Uint8 *p;
|
||||
|
||||
/* get the X/Y values within the bounds of this surface */
|
||||
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
|
||||
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
|
||||
x = (x < 0) ? 0 : surface->w - 1;
|
||||
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
|
||||
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
|
||||
y = (y < 0) ? 0 : surface->h - 1;
|
||||
|
||||
/* Set a pointer to the exact location in memory of the pixel
|
||||
|
|
@ -159,9 +167,9 @@ static Uint32 getpixel16(SDL_Surface * surface, int x, int y)
|
|||
Uint8 *p;
|
||||
|
||||
/* get the X/Y values within the bounds of this surface */
|
||||
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
|
||||
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
|
||||
x = (x < 0) ? 0 : surface->w - 1;
|
||||
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
|
||||
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
|
||||
y = (y < 0) ? 0 : surface->h - 1;
|
||||
|
||||
/* Set a pointer to the exact location in memory of the pixel
|
||||
|
|
@ -186,9 +194,9 @@ static Uint32 getpixel24(SDL_Surface * surface, int x, int y)
|
|||
Uint32 pixel;
|
||||
|
||||
/* get the X/Y values within the bounds of this surface */
|
||||
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
|
||||
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
|
||||
x = (x < 0) ? 0 : surface->w - 1;
|
||||
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
|
||||
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
|
||||
y = (y < 0) ? 0 : surface->h - 1;
|
||||
|
||||
/* Set a pointer to the exact location in memory of the pixel
|
||||
|
|
@ -219,9 +227,9 @@ static Uint32 getpixel32(SDL_Surface * surface, int x, int y)
|
|||
Uint8 *p;
|
||||
|
||||
/* get the X/Y values within the bounds of this surface */
|
||||
if (unlikely((unsigned)x > (unsigned)surface->w - 1u))
|
||||
if (unlikely((unsigned) x > (unsigned) surface->w - 1u))
|
||||
x = (x < 0) ? 0 : surface->w - 1;
|
||||
if (unlikely((unsigned)y > (unsigned)surface->h - 1u))
|
||||
if (unlikely((unsigned) y > (unsigned) surface->h - 1u))
|
||||
y = (y < 0) ? 0 : surface->h - 1;
|
||||
|
||||
/* Set a pointer to the exact location in memory of the pixel
|
||||
|
|
@ -239,11 +247,11 @@ static Uint32 getpixel32(SDL_Surface * surface, int x, int y)
|
|||
return *(Uint32 *) p; // 32-bit display
|
||||
}
|
||||
|
||||
void (*putpixels[]) (SDL_Surface *, int, int, Uint32) =
|
||||
{
|
||||
putpixel8, putpixel8, putpixel16, putpixel24, putpixel32};
|
||||
void (*putpixels[])(SDL_Surface *, int, int, Uint32) = {
|
||||
putpixel8, putpixel8, putpixel16, putpixel24, putpixel32
|
||||
};
|
||||
|
||||
|
||||
Uint32(*getpixels[])(SDL_Surface *, int, int) =
|
||||
{
|
||||
getpixel8, getpixel8, getpixel16, getpixel24, getpixel32};
|
||||
Uint32(*getpixels[])(SDL_Surface *, int, int) = {
|
||||
getpixel8, getpixel8, getpixel16, getpixel24, getpixel32
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "SDL.h"
|
||||
|
||||
extern void (*putpixels[]) (SDL_Surface *, int, int, Uint32);
|
||||
extern void (*putpixels[])(SDL_Surface *, int, int, Uint32);
|
||||
extern Uint32(*getpixels[]) (SDL_Surface *, int, int);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,21 +24,21 @@
|
|||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
/*
|
||||
* MAC test must be last because it tests true even on iOS / tvOS / watchOS.
|
||||
*/
|
||||
* MAC test must be last because it tests true even on iOS / tvOS / watchOS.
|
||||
*/
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_IPHONE || TARGET_OS_SIMULATOR || TARGET_IPHONE_SIMULATOR || TARGET_OS_EMBEDDED
|
||||
#define __IOS__ 1
|
||||
#elif TARGET_OS_OSX || TARGET_OS_MAC
|
||||
#define __MACOS__ 1
|
||||
#else
|
||||
#define __OTHER_APPLE__ 1
|
||||
#if TARGET_OS_IOS || TARGET_OS_IPHONE || TARGET_OS_SIMULATOR || TARGET_IPHONE_SIMULATOR || TARGET_OS_EMBEDDED
|
||||
#define __IOS__ 1
|
||||
#elif TARGET_OS_OSX || TARGET_OS_MAC
|
||||
#define __MACOS__ 1
|
||||
#else
|
||||
#define __OTHER_APPLE__ 1
|
||||
|
||||
#warning "Unsupported Apple platform, will build on a best-effort basis"
|
||||
#endif
|
||||
#warning "Unsupported Apple platform, will build on a best-effort basis"
|
||||
#endif
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
||||
|
|
|
|||
114
src/playsound.c
114
src/playsound.c
|
|
@ -48,70 +48,72 @@ static int old_sound[4] = { -1, -1, -1, -1 };
|
|||
* (low values, near the top of the window, are quieter), or
|
||||
* SNDDIST_NEAR for full volume
|
||||
*/
|
||||
void playsound(SDL_Surface * screen, int chan, int s, int override, int x, int y)
|
||||
void playsound(SDL_Surface * screen, int chan, int s, int override, int x,
|
||||
int y)
|
||||
{
|
||||
#ifndef NOSOUND
|
||||
int left, dist;
|
||||
|
||||
if (!mute && use_sound && s != SND_NONE)
|
||||
{
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("playsound #%d in channel %d, pos (%d,%d), %soverride, ptr=%p\n", s, chan, x, y, override ? "" : "no ",
|
||||
sounds[s]);
|
||||
printf("playsound #%d in channel %d, pos (%d,%d), %soverride, ptr=%p\n",
|
||||
s, chan, x, y, override ? "" : "no ", sounds[s]);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
if (override || !Mix_Playing(chan))
|
||||
{
|
||||
Mix_PlayChannel(chan, sounds[s], 0);
|
||||
|
||||
old_sound[chan] = s;
|
||||
}
|
||||
|
||||
if (old_sound[chan] == s)
|
||||
{
|
||||
if (y == SNDDIST_NEAR)
|
||||
dist = 0;
|
||||
else
|
||||
{
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
else if (y >= screen->h - 1)
|
||||
y = screen->h - 1;
|
||||
|
||||
dist = (255 * ((screen->h - 1) - y)) / (screen->h - 1);
|
||||
}
|
||||
|
||||
|
||||
if (use_stereo)
|
||||
{
|
||||
if (x == SNDPOS_LEFT)
|
||||
left = 255 - dist;
|
||||
else if (x == SNDPOS_CENTER)
|
||||
left = (255 - dist) / 2;
|
||||
else if (x == SNDPOS_RIGHT)
|
||||
left = 0;
|
||||
else
|
||||
{
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
else if (x >= screen->w)
|
||||
x = screen->w - 1;
|
||||
|
||||
left = ((255 - dist) * ((screen->w - 1) - x)) / (screen->w - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stereo disabled; treat everything like a SNDPOS_CENTER
|
||||
(equal amount in each of the left/right channels) */
|
||||
left = (255 - dist) / 2;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("Panning of sound #%d in channel %d, left=%d, right=%d\n", s,
|
||||
chan, left, (255 - dist) - left);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
if (override || !Mix_Playing(chan))
|
||||
{
|
||||
Mix_PlayChannel(chan, sounds[s], 0);
|
||||
|
||||
old_sound[chan] = s;
|
||||
}
|
||||
|
||||
if (old_sound[chan] == s)
|
||||
{
|
||||
if (y == SNDDIST_NEAR)
|
||||
dist = 0;
|
||||
else
|
||||
{
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
else if (y >= screen->h - 1)
|
||||
y = screen->h - 1;
|
||||
|
||||
dist = (255 * ((screen->h - 1) - y)) / (screen->h - 1);
|
||||
}
|
||||
|
||||
|
||||
if (use_stereo)
|
||||
{
|
||||
if (x == SNDPOS_LEFT)
|
||||
left = 255 - dist;
|
||||
else if (x == SNDPOS_CENTER)
|
||||
left = (255 - dist) / 2;
|
||||
else if (x == SNDPOS_RIGHT)
|
||||
left = 0;
|
||||
else
|
||||
{
|
||||
if (x < 0)
|
||||
x = 0;
|
||||
else if (x >= screen->w)
|
||||
x = screen->w - 1;
|
||||
|
||||
left = ((255 - dist) * ((screen->w - 1) - x)) / (screen->w - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stereo disabled; treat everything like a SNDPOS_CENTER
|
||||
(equal amount in each of the left/right channels) */
|
||||
left = (255 - dist) / 2;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("Panning of sound #%d in channel %d, left=%d, right=%d\n", s, chan, left, (255 - dist) - left);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
Mix_SetPanning(chan, left, (255 - dist) - left);
|
||||
}
|
||||
Mix_SetPanning(chan, left, (255 - dist) - left);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
extern Mix_Chunk *sounds[NUM_SOUNDS];
|
||||
extern int mute, use_sound, use_stereo;
|
||||
|
||||
void playsound(SDL_Surface * screen, int chan, int s, int override, int x, int y);
|
||||
void playsound(SDL_Surface * screen, int chan, int s, int override, int x,
|
||||
int y);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -69,17 +69,18 @@
|
|||
|
||||
static int f2int(float f)
|
||||
{
|
||||
return ((int)f);
|
||||
return ((int) f);
|
||||
}
|
||||
|
||||
static int f2dec(float f)
|
||||
{
|
||||
return (int)((f - f2int(f)) * 100);
|
||||
return (int) ((f - f2int(f)) * 100);
|
||||
}
|
||||
|
||||
/* Actually save the PostScript data to the file stream: */
|
||||
int do_ps_save(FILE * fi,
|
||||
const char *restrict const fname, SDL_Surface * surf, const char *restrict pprsize, int is_pipe)
|
||||
const char *restrict const fname, SDL_Surface * surf,
|
||||
const char *restrict pprsize, int is_pipe)
|
||||
{
|
||||
const struct paper *ppr;
|
||||
int img_w = surf->w;
|
||||
|
|
@ -93,7 +94,8 @@ int do_ps_save(FILE * fi,
|
|||
Uint8 r, g, b;
|
||||
char buf[256];
|
||||
|
||||
Uint32(*getpixel) (SDL_Surface *, int, int) = getpixels[surf->format->BytesPerPixel];
|
||||
Uint32(*getpixel) (SDL_Surface *, int, int) =
|
||||
getpixels[surf->format->BytesPerPixel];
|
||||
int printed_img_w, printed_img_h;
|
||||
time_t t = time(NULL);
|
||||
int rotate;
|
||||
|
|
@ -103,35 +105,35 @@ int do_ps_save(FILE * fi,
|
|||
/* Determine paper size: */
|
||||
|
||||
if (pprsize == NULL)
|
||||
{
|
||||
/* User did not request a specific paper size (on command-line or
|
||||
in config file), ask the system. It will return either their
|
||||
$PAPER env. var., the value from /etc/papersize, or NULL: */
|
||||
|
||||
pprsize = systempapername();
|
||||
|
||||
if (pprsize == NULL)
|
||||
{
|
||||
/* User did not request a specific paper size (on command-line or
|
||||
in config file), ask the system. It will return either their
|
||||
$PAPER env. var., the value from /etc/papersize, or NULL: */
|
||||
/* No setting, env. var. or /etc/ file; use the default! */
|
||||
|
||||
pprsize = systempapername();
|
||||
|
||||
if (pprsize == NULL)
|
||||
{
|
||||
/* No setting, env. var. or /etc/ file; use the default! */
|
||||
|
||||
pprsize = defaultpapername();
|
||||
pprsize = defaultpapername();
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Using default paper\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
{
|
||||
printf("Using system paper\n");
|
||||
}
|
||||
printf("Using default paper\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
{
|
||||
printf("Using system paper\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
{
|
||||
printf("Using user paper\n");
|
||||
}
|
||||
{
|
||||
printf("Using user paper\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
@ -147,7 +149,8 @@ int do_ps_save(FILE * fi,
|
|||
ppr_h = paperpsheight(ppr);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h, (float)ppr_w / 72.0, (float)ppr_h / 72.0);
|
||||
printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h,
|
||||
(float) ppr_w / 72.0, (float) ppr_h / 72.0);
|
||||
#endif
|
||||
|
||||
paperdone(); // FIXME: Should we do this at quit? -bjk 2007.06.25
|
||||
|
|
@ -155,18 +158,19 @@ int do_ps_save(FILE * fi,
|
|||
|
||||
/* Determine whether it's best to rotate the image: */
|
||||
|
||||
if ((ppr_w >= ppr_h && img_w >= img_h) || (ppr_w <= ppr_h && img_w <= img_h))
|
||||
{
|
||||
rotate = 0;
|
||||
r_img_w = img_w;
|
||||
r_img_h = img_h;
|
||||
}
|
||||
if ((ppr_w >= ppr_h && img_w >= img_h)
|
||||
|| (ppr_w <= ppr_h && img_w <= img_h))
|
||||
{
|
||||
rotate = 0;
|
||||
r_img_w = img_w;
|
||||
r_img_h = img_h;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotate = 1;
|
||||
r_img_w = img_h;
|
||||
r_img_h = img_w;
|
||||
}
|
||||
{
|
||||
rotate = 1;
|
||||
r_img_w = img_h;
|
||||
r_img_h = img_w;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Image is %d x %d\n", img_w, img_h);
|
||||
|
|
@ -177,13 +181,16 @@ int do_ps_save(FILE * fi,
|
|||
|
||||
/* Determine scale: */
|
||||
|
||||
scale = my_min(((float)(ppr_w - (MARGIN * 2)) / (float)r_img_w), ((float)(ppr_h - (MARGIN * 2)) / (float)r_img_h));
|
||||
scale =
|
||||
my_min(((float) (ppr_w - (MARGIN * 2)) / (float) r_img_w),
|
||||
((float) (ppr_h - (MARGIN * 2)) / (float) r_img_h));
|
||||
|
||||
printed_img_w = r_img_w * scale;
|
||||
printed_img_h = r_img_h * scale;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Scaling image by %.2f (to %d x %d)\n", scale, printed_img_w, printed_img_h);
|
||||
printf("Scaling image by %.2f (to %d x %d)\n", scale, printed_img_w,
|
||||
printed_img_h);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -209,7 +216,8 @@ int do_ps_save(FILE * fi,
|
|||
|
||||
fprintf(fi, "%%%%Pages: 1\n");
|
||||
|
||||
fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int)(ppr_w + 0.5), (int)(ppr_h + 0.5));
|
||||
fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int) (ppr_w + 0.5),
|
||||
(int) (ppr_h + 0.5));
|
||||
|
||||
fprintf(fi, "%%%%EndComments\n");
|
||||
|
||||
|
|
@ -228,20 +236,23 @@ int do_ps_save(FILE * fi,
|
|||
|
||||
fprintf(fi, "%%%%Page: 1 1\n");
|
||||
|
||||
fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n", ppr_w, ppr_h);
|
||||
fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n",
|
||||
ppr_w, ppr_h);
|
||||
|
||||
fprintf(fi, "gsave\n");
|
||||
|
||||
/* 'translate' moves the user space origin to a new position with
|
||||
respect to the current page, leaving the orientation of the axes and
|
||||
the unit lengths unchanged. */
|
||||
fprintf(fi, "%d.%02d %d.%02d translate\n", f2int(tlate_x), f2dec(tlate_x), f2int(tlate_y), f2dec(tlate_y));
|
||||
fprintf(fi, "%d.%02d %d.%02d translate\n", f2int(tlate_x), f2dec(tlate_x),
|
||||
f2int(tlate_y), f2dec(tlate_y));
|
||||
|
||||
/* 'scale' modifies the unit lengths independently along the current
|
||||
x and y axes, leaving the origin location and the orientation of the
|
||||
axes unchanged. */
|
||||
fprintf(fi, "%d.%02d %d.%02d scale\n",
|
||||
f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_h), f2dec(printed_img_h));
|
||||
f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_h),
|
||||
f2dec(printed_img_h));
|
||||
|
||||
/* Rotate the image */
|
||||
if (rotate)
|
||||
|
|
@ -261,23 +272,23 @@ int do_ps_save(FILE * fi,
|
|||
cur_line_len = 0;
|
||||
|
||||
for (y = 0; y < img_h; y++)
|
||||
{
|
||||
for (plane = 0; plane < 3; plane++)
|
||||
{
|
||||
for (plane = 0; plane < 3; plane++)
|
||||
{
|
||||
for (x = 0; x < img_w; x++)
|
||||
{
|
||||
SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b);
|
||||
fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b)));
|
||||
for (x = 0; x < img_w; x++)
|
||||
{
|
||||
SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b);
|
||||
fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b)));
|
||||
|
||||
cur_line_len++;
|
||||
if (cur_line_len >= 30)
|
||||
{
|
||||
fprintf(fi, "\n");
|
||||
cur_line_len = 0;
|
||||
}
|
||||
}
|
||||
cur_line_len++;
|
||||
if (cur_line_len >= 30)
|
||||
{
|
||||
fprintf(fi, "\n");
|
||||
cur_line_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fi, "\n");
|
||||
fprintf(fi, "grestore\n");
|
||||
|
|
@ -286,74 +297,74 @@ int do_ps_save(FILE * fi,
|
|||
fprintf(fi, "%%%%EOF\n");
|
||||
|
||||
if (!is_pipe)
|
||||
{
|
||||
fclose(fi);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
fclose(fi);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pid_t child_pid, w;
|
||||
int status;
|
||||
{
|
||||
pid_t child_pid, w;
|
||||
int status;
|
||||
|
||||
#ifdef __APPLE__
|
||||
/* macOS does not always reset errno so Tux Paint thinks print never
|
||||
* succeeds - let's reset before calling pclose() on macOS */
|
||||
errno = 0;
|
||||
/* macOS does not always reset errno so Tux Paint thinks print never
|
||||
* succeeds - let's reset before calling pclose() on macOS */
|
||||
errno = 0;
|
||||
#endif
|
||||
|
||||
child_pid = pclose(fi);
|
||||
child_pid = pclose(fi);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("pclose returned %d\n", child_pid);
|
||||
fflush(stdout);
|
||||
printf("errno = %d\n", errno);
|
||||
fflush(stdout);
|
||||
printf("pclose returned %d\n", child_pid);
|
||||
fflush(stdout);
|
||||
printf("errno = %d\n", errno);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
if (child_pid < 0 || (errno != 0 && errno != EAGAIN))
|
||||
{ /* FIXME: This right? */
|
||||
return 0;
|
||||
}
|
||||
else if (child_pid == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
w = waitpid(child_pid, &status, 0);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (w == -1)
|
||||
{
|
||||
perror("waitpid");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
printf("exited, status=%d\n", WEXITSTATUS(status));
|
||||
}
|
||||
else if (WIFSIGNALED(status))
|
||||
{
|
||||
printf("killed by signal %d\n", WTERMSIG(status));
|
||||
}
|
||||
else if (WIFSTOPPED(status))
|
||||
{
|
||||
printf("stopped by signal %d\n", WSTOPSIG(status));
|
||||
}
|
||||
else if (WIFCONTINUED(status))
|
||||
{
|
||||
printf("continued\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status));
|
||||
|
||||
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */
|
||||
return 0;
|
||||
|
||||
if (child_pid < 0 || (errno != 0 && errno != EAGAIN))
|
||||
{ /* FIXME: This right? */
|
||||
return 0;
|
||||
}
|
||||
else if (child_pid == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
w = waitpid(child_pid, &status, 0);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (w == -1)
|
||||
{
|
||||
perror("waitpid");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
printf("exited, status=%d\n", WEXITSTATUS(status));
|
||||
}
|
||||
else if (WIFSIGNALED(status))
|
||||
{
|
||||
printf("killed by signal %d\n", WTERMSIG(status));
|
||||
}
|
||||
else if (WIFSTOPPED(status))
|
||||
{
|
||||
printf("stopped by signal %d\n", WSTOPSIG(status));
|
||||
}
|
||||
else if (WIFCONTINUED(status))
|
||||
{
|
||||
printf("continued\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status));
|
||||
|
||||
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@
|
|||
#ifdef PRINTMETHOD_PS
|
||||
|
||||
int do_ps_save(FILE * fi,
|
||||
const char *restrict const fname, SDL_Surface * surf, const char *restrict pprsize, int is_pipe);
|
||||
const char *restrict const fname, SDL_Surface * surf,
|
||||
const char *restrict pprsize, int is_pipe);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ int progress_bar_disabled, prog_bar_ctr;
|
|||
*
|
||||
* @param screen Screen surface
|
||||
*/
|
||||
void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture, SDL_Renderer * renderer)
|
||||
void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer)
|
||||
{
|
||||
SDL_Rect dest, src, r;
|
||||
int x;
|
||||
|
|
@ -51,34 +52,36 @@ void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture, SDL_Rendere
|
|||
|
||||
newtime = SDL_GetTicks();
|
||||
if (newtime > oldtime + 15) /* trying not to eat some serious CPU time! */
|
||||
{
|
||||
for (x = 0; x < screen->w; x = x + 65)
|
||||
{
|
||||
for (x = 0; x < screen->w; x = x + 65)
|
||||
{
|
||||
src.x = 65 - (prog_bar_ctr % 65);
|
||||
src.y = 0;
|
||||
src.w = 65;
|
||||
src.h = 24;
|
||||
src.x = 65 - (prog_bar_ctr % 65);
|
||||
src.y = 0;
|
||||
src.w = 65;
|
||||
src.h = 24;
|
||||
|
||||
dest.x = x;
|
||||
dest.y = screen->h - 24;
|
||||
dest.x = x;
|
||||
dest.y = screen->h - 24;
|
||||
|
||||
SDL_BlitSurface(img_progress, &src, screen, &dest);
|
||||
}
|
||||
|
||||
prog_bar_ctr++;
|
||||
|
||||
r.x = 0;
|
||||
r.y = screen->h - 24;
|
||||
r.w = screen->w;
|
||||
r.h = 24;
|
||||
|
||||
SDL_UpdateTexture(texture, &r, screen->pixels + ((screen->h - 24) * screen->pitch), screen->pitch);
|
||||
|
||||
/* Docs says one should clear the renderer, even if this means a refresh of the whole thing. */
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
SDL_BlitSurface(img_progress, &src, screen, &dest);
|
||||
}
|
||||
|
||||
prog_bar_ctr++;
|
||||
|
||||
r.x = 0;
|
||||
r.y = screen->h - 24;
|
||||
r.w = screen->w;
|
||||
r.h = 24;
|
||||
|
||||
SDL_UpdateTexture(texture, &r,
|
||||
screen->pixels + ((screen->h - 24) * screen->pitch),
|
||||
screen->pitch);
|
||||
|
||||
/* Docs says one should clear the renderer, even if this means a refresh of the whole thing. */
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
oldtime = newtime;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
extern SDL_Surface *img_progress;
|
||||
extern int progress_bar_disabled, prog_bar_ctr;
|
||||
|
||||
void show_progress_bar_(SDL_Surface * screen, SDL_Texture *texture, SDL_Renderer *renderer);
|
||||
void show_progress_bar_(SDL_Surface * screen, SDL_Texture * texture,
|
||||
SDL_Renderer * renderer);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ unsigned char linear_to_sRGB(float linear)
|
|||
|
||||
slot = linear * 4096.0 + 0.5;
|
||||
if (slot > 4095)
|
||||
{
|
||||
if (linear > 0.5)
|
||||
slot = 4095;
|
||||
else
|
||||
slot = 0;
|
||||
}
|
||||
{
|
||||
if (linear > 0.5)
|
||||
slot = 4095;
|
||||
else
|
||||
slot = 0;
|
||||
}
|
||||
return linear_to_sRGB_table[slot];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -305,7 +305,8 @@ static const unsigned char linear_to_sRGB_table[4096] =
|
|||
"\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd"
|
||||
"\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfd\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
|
||||
"\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe"
|
||||
"\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
|
||||
"\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
|
||||
|
||||
unsigned char linear_to_sRGB(float linear) FUNCTION;
|
||||
|
||||
|
|
|
|||
25
src/shapes.h
25
src/shapes.h
|
|
@ -118,8 +118,8 @@ const int shape_locked[NUM_SHAPES] = {
|
|||
0, /* Hexagon */
|
||||
0, /* Heptagon */
|
||||
0, /* Heptagon */
|
||||
1, /* Octagon */ /* FIXME: Consider unlocking? -bjk 2022.01.21 */
|
||||
1, /* Octagon */ /* FIXME: Consider unlocking? -bjk 2022.01.21 */
|
||||
1, /* Octagon *//* FIXME: Consider unlocking? -bjk 2022.01.21 */
|
||||
1, /* Octagon *//* FIXME: Consider unlocking? -bjk 2022.01.21 */
|
||||
0, /* Rhombus */
|
||||
0, /* Rhombus */
|
||||
0, /* 3 points star */
|
||||
|
|
@ -334,8 +334,10 @@ const char *const shape_tips[NUM_SHAPES] = {
|
|||
gettext_noop("A rectangle has four sides and four right angles."),
|
||||
|
||||
// Description of a circle
|
||||
gettext_noop("A circle is a curve where all points have the same distance from the center."),
|
||||
gettext_noop("A circle is a curve where all points have the same distance from the center."),
|
||||
gettext_noop
|
||||
("A circle is a curve where all points have the same distance from the center."),
|
||||
gettext_noop
|
||||
("A circle is a curve where all points have the same distance from the center."),
|
||||
|
||||
// Description of an ellipse
|
||||
gettext_noop("An ellipse is a stretched circle."),
|
||||
|
|
@ -362,8 +364,10 @@ const char *const shape_tips[NUM_SHAPES] = {
|
|||
gettext_noop("An octagon has eight equal sides."),
|
||||
|
||||
// Description of a rhombus
|
||||
gettext_noop("A rhombus has four equal sides, and opposite sides are parallel."),
|
||||
gettext_noop("A rhombus has four equal sides, and opposite sides are parallel."),
|
||||
gettext_noop
|
||||
("A rhombus has four equal sides, and opposite sides are parallel."),
|
||||
gettext_noop
|
||||
("A rhombus has four equal sides, and opposite sides are parallel."),
|
||||
|
||||
gettext_noop("A star with 3 points."),
|
||||
gettext_noop("A star with 3 points."),
|
||||
|
|
@ -423,15 +427,18 @@ const char *const shapemode_img_fnames[NUM_SHAPEMODES] = {
|
|||
/* String shown when Shapes tool is selected;
|
||||
one version for normal ("complex shapes"),
|
||||
the other for simplified mode ("simple shapes") */
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
SHAPE_COMPLEXITY_NORMAL,
|
||||
SHAPE_COMPLEXITY_SIMPLE,
|
||||
NUM_SHAPE_COMPLEXITIES
|
||||
};
|
||||
|
||||
const char *const shape_tool_tips[NUM_SHAPE_COMPLEXITIES] = {
|
||||
gettext_noop("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want. Move around to rotate it, and click again to draw it."),
|
||||
gettext_noop("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want.")
|
||||
gettext_noop
|
||||
("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want. Move around to rotate it, and click again to draw it."),
|
||||
gettext_noop
|
||||
("Pick a shape. Click to start drawing, drag, and let go when it is the size and shape you want.")
|
||||
};
|
||||
|
||||
/* Strings shown when switching between "from center"
|
||||
|
|
|
|||
|
|
@ -29,17 +29,19 @@
|
|||
#include <unistd.h>
|
||||
#include <png.h>
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, w, h, y;
|
||||
FILE * fi;
|
||||
FILE *fi;
|
||||
png_structp png;
|
||||
png_infop info;
|
||||
png_byte ctype, depth;
|
||||
png_bytep * rows;
|
||||
png_bytep *rows;
|
||||
|
||||
|
||||
/* Usage output */
|
||||
if (argc == 1 || strcmp(argv[1], "--help") == 0) {
|
||||
if (argc == 1 || strcmp(argv[1], "--help") == 0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s file.png [file.png ...]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -53,30 +55,39 @@ int main(int argc, char * argv[]) {
|
|||
|
||||
|
||||
/* Open each PNG image!... */
|
||||
for (i = 1; i < argc; i++) {
|
||||
printf("%5d ------------------------------------------------------------------\n", i);
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
printf
|
||||
("%5d ------------------------------------------------------------------\n",
|
||||
i);
|
||||
printf("%s\n", argv[i]);
|
||||
fflush(stdout);
|
||||
|
||||
/* Open the file */
|
||||
fi = fopen(argv[i], "rb");
|
||||
if (fi == NULL) {
|
||||
if (fi == NULL)
|
||||
{
|
||||
printf("Cannot open\n");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prepare PNG library stuff... */
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!png) {
|
||||
if (!png)
|
||||
{
|
||||
fprintf(stderr, "Cannot png_create_read_struct()!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
info = png_create_info_struct(png);
|
||||
if (!info) {
|
||||
if (!info)
|
||||
{
|
||||
fprintf(stderr, "Cannot png_create_info_struct()!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png))) {
|
||||
if (setjmp(png_jmpbuf(png)))
|
||||
{
|
||||
fprintf(stderr, "Cannot setjmp(png_jmpbuf(png)))!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -95,39 +106,43 @@ int main(int argc, char * argv[]) {
|
|||
depth = png_get_bit_depth(png, info);
|
||||
|
||||
/* If 16-bit, strip to 8-bit */
|
||||
if (depth == 16) {
|
||||
if (depth == 16)
|
||||
{
|
||||
printf("test-png warning: 16-bit\n");
|
||||
png_set_strip_16(png);
|
||||
}
|
||||
|
||||
/* Switch palette to RGB */
|
||||
if (ctype == PNG_COLOR_TYPE_PALETTE) {
|
||||
if (ctype == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
printf("test-png warning: paletted\n");
|
||||
png_set_palette_to_rgb(png);
|
||||
}
|
||||
|
||||
/* Expand low-depth greyscale up to 8-bit */
|
||||
if (ctype == PNG_COLOR_TYPE_GRAY && depth < 8) {
|
||||
if (ctype == PNG_COLOR_TYPE_GRAY && depth < 8)
|
||||
{
|
||||
printf("test-png warning: greyscale with only %d-bit depth\n", depth);
|
||||
png_set_expand_gray_1_2_4_to_8(png);
|
||||
}
|
||||
|
||||
/* Expand tRNS chunks into alpha */
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS)) {
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS))
|
||||
{
|
||||
printf("test-png warning: contains tRNS chunk\n");
|
||||
png_set_tRNS_to_alpha(png);
|
||||
}
|
||||
|
||||
/* Fill alpha channel if there is none */
|
||||
if (ctype == PNG_COLOR_TYPE_RGB ||
|
||||
ctype == PNG_COLOR_TYPE_GRAY ||
|
||||
ctype == PNG_COLOR_TYPE_PALETTE) {
|
||||
ctype == PNG_COLOR_TYPE_GRAY || ctype == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
|
||||
}
|
||||
|
||||
/* Expand grey to color */
|
||||
if (ctype == PNG_COLOR_TYPE_GRAY ||
|
||||
ctype == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||
if (ctype == PNG_COLOR_TYPE_GRAY || ctype == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
printf("test-png warning: greyscale\n");
|
||||
png_set_gray_to_rgb(png);
|
||||
}
|
||||
|
|
@ -137,15 +152,19 @@ int main(int argc, char * argv[]) {
|
|||
|
||||
/* Allocate space */
|
||||
rows = (png_bytep *) malloc(sizeof(png_bytep) * h);
|
||||
if (!rows) {
|
||||
if (!rows)
|
||||
{
|
||||
fprintf(stderr, "Failed to malloc() space for image data rows!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
for (y = 0; y < h; y++)
|
||||
{
|
||||
rows[y] = (png_byte *) malloc(png_get_rowbytes(png, info));
|
||||
if (!rows[y]) {
|
||||
fprintf(stderr, "Failed to malloc() space for image data row #%d!\n", y);
|
||||
if (!rows[y])
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Failed to malloc() space for image data row #%d!\n", y);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -170,5 +189,5 @@ int main(int argc, char * argv[]) {
|
|||
fflush(stdout);
|
||||
}
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
36155
src/tuxpaint.c
36155
src/tuxpaint.c
File diff suppressed because it is too large
Load diff
|
|
@ -54,10 +54,10 @@ DIR *opendir(const char *pSpec)
|
|||
strcat(pathname, "/*");
|
||||
pDir->hFind = FindFirstFile(pathname, &pDir->wfd);
|
||||
if (pDir->hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
free(pDir);
|
||||
pDir = NULL;
|
||||
}
|
||||
{
|
||||
free(pDir);
|
||||
pDir = NULL;
|
||||
}
|
||||
return pDir;
|
||||
}
|
||||
|
||||
|
|
@ -83,16 +83,16 @@ struct dirent *readdir(struct DIR *pDir)
|
|||
assert(pDir != NULL);
|
||||
if (pDir->hFind)
|
||||
|
||||
{
|
||||
strcpy(pDir->de.d_name, (const char *)pDir->wfd.cFileName);
|
||||
if (!FindNextFile(pDir->hFind, &pDir->wfd))
|
||||
{
|
||||
strcpy(pDir->de.d_name, (const char *) pDir->wfd.cFileName);
|
||||
if (!FindNextFile(pDir->hFind, &pDir->wfd))
|
||||
|
||||
{
|
||||
FindClose(pDir->hFind);
|
||||
pDir->hFind = NULL;
|
||||
}
|
||||
return &pDir->de;
|
||||
{
|
||||
FindClose(pDir->hFind);
|
||||
pDir->hFind = NULL;
|
||||
}
|
||||
return &pDir->de;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +107,9 @@ struct dirent *readdir(struct DIR *pDir)
|
|||
*/
|
||||
int alphasort(const void *a, const void *b)
|
||||
{
|
||||
return (strcmp((*(const struct dirent **)a)->d_name, (*(const struct dirent **)b)->d_name));
|
||||
return (strcmp
|
||||
((*(const struct dirent **) a)->d_name,
|
||||
(*(const struct dirent **) b)->d_name));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -124,11 +126,15 @@ static int addToList(int i, struct dirent ***namelist, struct dirent *entry)
|
|||
int size;
|
||||
struct dirent *block;
|
||||
|
||||
*namelist = (struct dirent **)realloc((void *)(*namelist), (size_t) ((i + 1) * sizeof(struct dirent *)));
|
||||
*namelist =
|
||||
(struct dirent **) realloc((void *) (*namelist),
|
||||
(size_t) ((i + 1) * sizeof(struct dirent *)));
|
||||
if (*namelist == NULL)
|
||||
return -1;
|
||||
size = (((char *)&entry->d_name) - ((char *)entry)) + strlen(entry->d_name) + 1;
|
||||
block = (struct dirent *)malloc(size);
|
||||
size =
|
||||
(((char *) &entry->d_name) - ((char *) entry)) + strlen(entry->d_name) +
|
||||
1;
|
||||
block = (struct dirent *) malloc(size);
|
||||
if (block == NULL)
|
||||
return -1;
|
||||
(*namelist)[i] = block;
|
||||
|
|
@ -145,7 +151,8 @@ static int addToList(int i, struct dirent ***namelist, struct dirent *entry)
|
|||
* @param compar Callback for sorting items in the list (via qsort()).
|
||||
* @return Count of items, or -1 on error.
|
||||
*/
|
||||
int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparCB compar)
|
||||
int scandir(const char *dir, struct dirent ***namelist, selectCB select,
|
||||
comparCB compar)
|
||||
{
|
||||
DIR *pDir;
|
||||
int count;
|
||||
|
|
@ -157,15 +164,16 @@ int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparC
|
|||
return -1;
|
||||
count = 0;
|
||||
while ((entry = readdir(pDir)) != NULL)
|
||||
{
|
||||
if (select == NULL || (select != NULL && select(entry)))
|
||||
if ((count = addToList(count, namelist, entry)) < 0)
|
||||
break;
|
||||
}
|
||||
{
|
||||
if (select == NULL || (select != NULL && select(entry)))
|
||||
if ((count = addToList(count, namelist, entry)) < 0)
|
||||
break;
|
||||
}
|
||||
closedir(pDir);
|
||||
if (count <= 0)
|
||||
return -1;
|
||||
if (compar != NULL)
|
||||
qsort((void *)(*namelist), (size_t) count, sizeof(struct dirent *), compar);
|
||||
qsort((void *) (*namelist), (size_t) count, sizeof(struct dirent *),
|
||||
compar);
|
||||
return count;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ typedef struct
|
|||
extern DIR *opendir(const char *pSpec);
|
||||
extern void closedir(DIR * pDir);
|
||||
extern struct dirent *readdir(struct DIR *pDir);
|
||||
typedef int (*selectCB) (const struct dirent *);
|
||||
typedef int (*comparCB) (const void *, const void *);
|
||||
typedef int (*selectCB)(const struct dirent *);
|
||||
typedef int (*comparCB)(const void *, const void *);
|
||||
extern int alphasort(const void *a, const void *b);
|
||||
extern int scandir(const char *dir, struct dirent ***namelist, selectCB select, comparCB compar);
|
||||
extern int scandir(const char *dir, struct dirent ***namelist,
|
||||
selectCB select, comparCB compar);
|
||||
|
|
|
|||
|
|
@ -68,17 +68,18 @@ static SDL_Surface *make24bitDIB(SDL_Surface * surf)
|
|||
|
||||
surf24 = SDL_ConvertSurface(surf, &pixfmt, SDL_SWSURFACE);
|
||||
surfDIB = SDL_CreateRGBSurface(SDL_SWSURFACE, surf24->w, surf24->h, 24,
|
||||
pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask, pixfmt.Amask);
|
||||
pixfmt.Rmask, pixfmt.Gmask, pixfmt.Bmask,
|
||||
pixfmt.Amask);
|
||||
|
||||
linesize = surf24->w * 3; // Flip top2bottom
|
||||
dst = surfDIB->pixels;
|
||||
src = ((Uint8 *) surf24->pixels) + ((surf24->h - 1) * surf24->pitch);
|
||||
for (i = 0; i < surf24->h; ++i)
|
||||
{
|
||||
memcpy(dst, src, linesize);
|
||||
src -= surf24->pitch;
|
||||
dst += surfDIB->pitch;
|
||||
}
|
||||
{
|
||||
memcpy(dst, src, linesize);
|
||||
src -= surf24->pitch;
|
||||
dst += surfDIB->pitch;
|
||||
}
|
||||
|
||||
SDL_FreeSurface(surf24); // Free temp surface
|
||||
|
||||
|
|
@ -104,16 +105,17 @@ static int GetDefaultPrinterStrings(char *device, char *driver, char *output)
|
|||
return 0;
|
||||
|
||||
if (((dev = strtok(buff, ",")) != NULL) &&
|
||||
((drv = strtok(NULL, ", ")) != NULL) && ((out = strtok(NULL, ", ")) != NULL))
|
||||
{
|
||||
if (device)
|
||||
strcpy(device, dev);
|
||||
if (driver)
|
||||
strcpy(driver, drv);
|
||||
if (output)
|
||||
strcpy(output, out);
|
||||
return 1;
|
||||
}
|
||||
((drv = strtok(NULL, ", ")) != NULL)
|
||||
&& ((out = strtok(NULL, ", ")) != NULL))
|
||||
{
|
||||
if (device)
|
||||
strcpy(device, dev);
|
||||
if (driver)
|
||||
strcpy(driver, drv);
|
||||
if (output)
|
||||
strcpy(output, out);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +145,8 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
|
|||
if (!OpenPrinter(device, &hPrinter, NULL))
|
||||
goto err_exit;
|
||||
|
||||
sizeof_devmode = (int)DocumentProperties(hWnd, hPrinter, device, NULL, NULL, 0);
|
||||
sizeof_devmode =
|
||||
(int) DocumentProperties(hWnd, hPrinter, device, NULL, NULL, 0);
|
||||
|
||||
if (!sizeof_devmode)
|
||||
goto err_exit;
|
||||
|
|
@ -156,7 +159,8 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
|
|||
if (!devmode)
|
||||
goto err_exit;
|
||||
|
||||
res = DocumentProperties(hWnd, hPrinter, device, devmode, NULL, DM_OUT_BUFFER);
|
||||
res =
|
||||
DocumentProperties(hWnd, hPrinter, device, devmode, NULL, DM_OUT_BUFFER);
|
||||
if (res != IDOK)
|
||||
goto err_exit;
|
||||
|
||||
|
|
@ -166,7 +170,9 @@ static HANDLE LoadCustomPrinterHDEVMODE(HWND hWnd, const char *filepath)
|
|||
goto err_exit;
|
||||
fclose(fp);
|
||||
|
||||
res = DocumentProperties(hWnd, hPrinter, device, devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER);
|
||||
res =
|
||||
DocumentProperties(hWnd, hPrinter, device, devmode, devmode,
|
||||
DM_IN_BUFFER | DM_OUT_BUFFER);
|
||||
if (res != IDOK)
|
||||
goto err_exit;
|
||||
|
||||
|
|
@ -189,25 +195,26 @@ err_exit:
|
|||
/**
|
||||
* FIXME
|
||||
*/
|
||||
static int SaveCustomPrinterHDEVMODE(HWND hWnd, const char *filepath, HANDLE hDevMode)
|
||||
static int SaveCustomPrinterHDEVMODE(HWND hWnd, const char *filepath,
|
||||
HANDLE hDevMode)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
|
||||
NOREF(hWnd);
|
||||
if ((fp = fopen(filepath, "wb")) != NULL)
|
||||
{
|
||||
DEVMODE *devmode = (DEVMODE *) GlobalLock(hDevMode);
|
||||
int block_size = devmode->dmSize + devmode->dmDriverExtra;
|
||||
int block_written;
|
||||
char devname[dmDeviceNameSize];
|
||||
{
|
||||
DEVMODE *devmode = (DEVMODE *) GlobalLock(hDevMode);
|
||||
int block_size = devmode->dmSize + devmode->dmDriverExtra;
|
||||
int block_written;
|
||||
char devname[dmDeviceNameSize];
|
||||
|
||||
strcpy(devname, (const char *)devmode->dmDeviceName);
|
||||
fwrite(devname, 1, sizeof(devname), fp);
|
||||
block_written = fwrite(devmode, 1, block_size, fp);
|
||||
GlobalUnlock(hDevMode);
|
||||
fclose(fp);
|
||||
return block_size == block_written;
|
||||
}
|
||||
strcpy(devname, (const char *) devmode->dmDeviceName);
|
||||
fwrite(devname, 1, sizeof(devname), fp);
|
||||
block_written = fwrite(devmode, 1, block_size, fp);
|
||||
GlobalUnlock(hDevMode);
|
||||
fclose(fp);
|
||||
return block_size == block_written;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -222,10 +229,10 @@ static int FileExists(const char *filepath)
|
|||
FILE *fp;
|
||||
|
||||
if ((fp = fopen(filepath, "rb")) != NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -250,22 +257,23 @@ static int GetCustomPrinterDC(HWND hWnd, const char *printcfg, int show)
|
|||
pd.hDevMode = LoadCustomPrinterHDEVMODE(hWnd, printcfg);
|
||||
|
||||
if (show || !FileExists(printcfg))
|
||||
{
|
||||
if (PrintDlg(&pd))
|
||||
{
|
||||
if (PrintDlg(&pd))
|
||||
{
|
||||
hDCprinter = pd.hDC;
|
||||
SaveCustomPrinterHDEVMODE(hWnd, printcfg, pd.hDevMode);
|
||||
GlobalFree(pd.hDevMode);
|
||||
return 1;
|
||||
}
|
||||
hDCprinter = pd.hDC;
|
||||
SaveCustomPrinterHDEVMODE(hWnd, printcfg, pd.hDevMode);
|
||||
GlobalFree(pd.hDevMode);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
GlobalFree(pd.hDevMode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
DEVMODE *devmode = (DEVMODE *) GlobalLock(pd.hDevMode);
|
||||
|
||||
hDCprinter = CreateDC(NULL, (const char *)devmode->dmDeviceName, NULL, devmode);
|
||||
hDCprinter =
|
||||
CreateDC(NULL, (const char *) devmode->dmDeviceName, NULL, devmode);
|
||||
GlobalUnlock(pd.hDevMode);
|
||||
GlobalFree(pd.hDevMode);
|
||||
}
|
||||
|
|
@ -295,9 +303,9 @@ static int GetPrinterDC(HWND hWnd, const char *printcfg, int show)
|
|||
hDCprinter = NULL;
|
||||
|
||||
if (printcfg)
|
||||
{
|
||||
return GetCustomPrinterDC(hWnd, printcfg, show);
|
||||
}
|
||||
{
|
||||
return GetCustomPrinterDC(hWnd, printcfg, show);
|
||||
}
|
||||
hDCprinter = GetDefaultPrinterDC();
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -318,7 +326,8 @@ int IsPrinterAvailable(void)
|
|||
/**
|
||||
* FIXME
|
||||
*/
|
||||
const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *printcfg, int showdialog)
|
||||
const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf,
|
||||
const char *printcfg, int showdialog)
|
||||
{
|
||||
const char *res = NULL;
|
||||
HWND hWnd;
|
||||
|
|
@ -342,10 +351,10 @@ const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *pr
|
|||
|
||||
hWnd = wminfo.info.win.window;
|
||||
if (!GetPrinterDC(hWnd, printcfg, showdialog))
|
||||
{
|
||||
ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!hDCprinter)
|
||||
return "win32_print: GetPrinterDC() failed.";
|
||||
|
|
@ -360,26 +369,26 @@ const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *pr
|
|||
|
||||
nError = StartDoc(hDCprinter, &di);
|
||||
if (nError == SP_ERROR)
|
||||
{
|
||||
res = "win32_print: StartDoc() failed.";
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
res = "win32_print: StartDoc() failed.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
nError = StartPage(hDCprinter);
|
||||
if (nError <= 0)
|
||||
{
|
||||
res = "win32_print: StartPage() failed.";
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
res = "win32_print: StartPage() failed.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
surf24 = make24bitDIB(surf);
|
||||
if (!surf24)
|
||||
{
|
||||
res = "win32_print: make24bitDIB() failed.";
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
res = "win32_print: make24bitDIB() failed.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(&bmih, 0, sizeof(bmih));
|
||||
bmih.biSize = sizeof(bmih);
|
||||
|
|
@ -395,100 +404,100 @@ const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *pr
|
|||
sY = GetDeviceCaps(hDCprinter, LOGPIXELSY);
|
||||
|
||||
switch (scaling)
|
||||
{
|
||||
case STRETCH_TO_FIT:
|
||||
{
|
||||
case STRETCH_TO_FIT:
|
||||
{
|
||||
/* stretches x and y dimensions independently to fit the page */
|
||||
/* doesn't preserve image aspect-ratio */
|
||||
rcDst.top = 0;
|
||||
rcDst.left = 0;
|
||||
rcDst.bottom = pageHeight;
|
||||
rcDst.right = pageWidth;
|
||||
break;
|
||||
}
|
||||
case SCALE_TO_FIT:
|
||||
{
|
||||
/* maximises image size on the page */
|
||||
/* preserves aspect-ratio, alignment is top and center */
|
||||
int width = bmih.biWidth;
|
||||
int height = bmih.biHeight;
|
||||
|
||||
if (width < pageWidth && height < pageHeight)
|
||||
{
|
||||
float dW = (float)pageWidth / width;
|
||||
float dH = (float)pageHeight / height;
|
||||
|
||||
if (dW < dH)
|
||||
{
|
||||
width = pageWidth;
|
||||
height = (int)((height * dW * (sY / sX)) + 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = (int)((width * dH * (sX / sY)) + 0.5f);
|
||||
height = pageHeight;
|
||||
}
|
||||
}
|
||||
if (width > pageWidth)
|
||||
{
|
||||
height = height * width / pageWidth;
|
||||
width = pageWidth;
|
||||
}
|
||||
if (height > pageHeight)
|
||||
{
|
||||
width = width * height / pageHeight;
|
||||
height = pageHeight;
|
||||
}
|
||||
|
||||
rcDst.top = 0;
|
||||
rcDst.left = (pageWidth - width) / 2;
|
||||
rcDst.bottom = rcDst.top + height;
|
||||
rcDst.right = rcDst.left + width;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = "win32_print: invalid scaling option.";
|
||||
goto error;
|
||||
/* stretches x and y dimensions independently to fit the page */
|
||||
/* doesn't preserve image aspect-ratio */
|
||||
rcDst.top = 0;
|
||||
rcDst.left = 0;
|
||||
rcDst.bottom = pageHeight;
|
||||
rcDst.right = pageWidth;
|
||||
break;
|
||||
}
|
||||
case SCALE_TO_FIT:
|
||||
{
|
||||
/* maximises image size on the page */
|
||||
/* preserves aspect-ratio, alignment is top and center */
|
||||
int width = bmih.biWidth;
|
||||
int height = bmih.biHeight;
|
||||
|
||||
if (width < pageWidth && height < pageHeight)
|
||||
{
|
||||
float dW = (float) pageWidth / width;
|
||||
float dH = (float) pageHeight / height;
|
||||
|
||||
if (dW < dH)
|
||||
{
|
||||
width = pageWidth;
|
||||
height = (int) ((height * dW * (sY / sX)) + 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = (int) ((width * dH * (sX / sY)) + 0.5f);
|
||||
height = pageHeight;
|
||||
}
|
||||
}
|
||||
if (width > pageWidth)
|
||||
{
|
||||
height = height * width / pageWidth;
|
||||
width = pageWidth;
|
||||
}
|
||||
if (height > pageHeight)
|
||||
{
|
||||
width = width * height / pageHeight;
|
||||
height = pageHeight;
|
||||
}
|
||||
|
||||
rcDst.top = 0;
|
||||
rcDst.left = (pageWidth - width) / 2;
|
||||
rcDst.bottom = rcDst.top + height;
|
||||
rcDst.right = rcDst.left + width;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
res = "win32_print: invalid scaling option.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
hDCCaps = GetDeviceCaps(hDCprinter, RASTERCAPS);
|
||||
|
||||
if (hDCCaps & RC_PALETTE)
|
||||
{
|
||||
res = "win32_print: printer context requires palette.";
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
res = "win32_print: printer context requires palette.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (hDCCaps & RC_STRETCHDIB)
|
||||
{
|
||||
SetStretchBltMode(hDCprinter, COLORONCOLOR);
|
||||
{
|
||||
SetStretchBltMode(hDCprinter, COLORONCOLOR);
|
||||
|
||||
bmi.bmiHeader = bmih;
|
||||
nError = StretchDIBits(hDCprinter, rcDst.left, rcDst.top,
|
||||
rcDst.right - rcDst.left,
|
||||
rcDst.bottom - rcDst.top,
|
||||
0, 0, bmih.biWidth, bmih.biHeight,
|
||||
surf24->pixels, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
if (nError == (int) GDI_ERROR)
|
||||
{
|
||||
res = "win32_print: StretchDIBits() failed.";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
bmi.bmiHeader = bmih;
|
||||
nError = StretchDIBits(hDCprinter, rcDst.left, rcDst.top,
|
||||
rcDst.right - rcDst.left,
|
||||
rcDst.bottom - rcDst.top,
|
||||
0, 0, bmih.biWidth, bmih.biHeight,
|
||||
surf24->pixels, &bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
if (nError == (int) GDI_ERROR)
|
||||
{
|
||||
res = "win32_print: StretchDIBits() not available.";
|
||||
res = "win32_print: StretchDIBits() failed.";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = "win32_print: StretchDIBits() not available.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nError = EndPage(hDCprinter);
|
||||
if (nError <= 0)
|
||||
{
|
||||
res = "win32_print: EndPage() failed.";
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
res = "win32_print: EndPage() failed.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
EndDoc(hDCprinter);
|
||||
|
||||
|
|
@ -514,7 +523,8 @@ error:
|
|||
/*
|
||||
Read access to Windows Registry
|
||||
*/
|
||||
static HRESULT ReadRegistry(const char *key, const char *option, char *value, int size)
|
||||
static HRESULT ReadRegistry(const char *key, const char *option, char *value,
|
||||
int size)
|
||||
{
|
||||
LONG res;
|
||||
HKEY hKey = NULL;
|
||||
|
|
@ -563,17 +573,18 @@ char *GetDefaultSaveDir(const char *suffix)
|
|||
{
|
||||
char prefix[MAX_PATH];
|
||||
char path[2 * MAX_PATH];
|
||||
const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
|
||||
const char *key =
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
|
||||
const char *option = "AppData";
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (SUCCEEDED(hr = ReadRegistry(key, option, prefix, sizeof(prefix))))
|
||||
{
|
||||
remove_slash(prefix);
|
||||
snprintf(path, sizeof(path), "%s/%s", prefix, suffix);
|
||||
_mkdir(path);
|
||||
return strdup(path);
|
||||
}
|
||||
{
|
||||
remove_slash(prefix);
|
||||
snprintf(path, sizeof(path), "%s/%s", prefix, suffix);
|
||||
_mkdir(path);
|
||||
return strdup(path);
|
||||
}
|
||||
return strdup("userdata");
|
||||
}
|
||||
|
||||
|
|
@ -587,15 +598,16 @@ char *GetDefaultSaveDir(const char *suffix)
|
|||
char *GetSystemFontDir(void)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
|
||||
const char *key =
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
|
||||
const char *option = "Fonts";
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (SUCCEEDED(hr = ReadRegistry(key, option, path, sizeof(path))))
|
||||
{
|
||||
remove_slash(path);
|
||||
return strdup(path);
|
||||
}
|
||||
{
|
||||
remove_slash(path);
|
||||
return strdup(path);
|
||||
}
|
||||
return strdup("C:\\WINDOWS\\FONTS");
|
||||
}
|
||||
|
||||
|
|
@ -609,15 +621,16 @@ char *GetUserImageDir(void);
|
|||
char *GetUserImageDir(void)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
const char *key = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
|
||||
const char *key =
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
|
||||
const char *option = "My Pictures";
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
|
||||
if (SUCCEEDED(hr = ReadRegistry(key, option, path, sizeof(path))))
|
||||
{
|
||||
remove_slash(path);
|
||||
return strdup(path);
|
||||
}
|
||||
{
|
||||
remove_slash(path);
|
||||
return strdup(path);
|
||||
}
|
||||
return strdup("C:\\Pictures");
|
||||
}
|
||||
|
||||
|
|
@ -630,9 +643,9 @@ static char *GetUserTempDir(void)
|
|||
const char *temp = getenv("TEMP");
|
||||
|
||||
if (!temp)
|
||||
{
|
||||
temp = "userdata";
|
||||
}
|
||||
{
|
||||
temp = "userdata";
|
||||
}
|
||||
return strdup(temp);
|
||||
}
|
||||
|
||||
|
|
@ -662,7 +675,8 @@ static int g_bWindowActive = 0;
|
|||
/**
|
||||
* FIXME
|
||||
*/
|
||||
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
int bEatKeystroke = 0;
|
||||
|
|
@ -672,14 +686,15 @@ LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
|
|||
return CallNextHookEx(g_hKeyboardHook, nCode, wParam, lParam);
|
||||
|
||||
switch (wParam)
|
||||
{
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
{
|
||||
bEatKeystroke = g_bWindowActive && ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN));
|
||||
break;
|
||||
}
|
||||
bEatKeystroke = g_bWindowActive && ((p->vkCode == VK_LWIN)
|
||||
|| (p->vkCode == VK_RWIN));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bEatKeystroke)
|
||||
return 1;
|
||||
|
|
@ -693,7 +708,9 @@ int InstallKeyboardHook(void)
|
|||
{
|
||||
if (g_hKeyboardHook)
|
||||
return -1;
|
||||
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
|
||||
g_hKeyboardHook =
|
||||
SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc,
|
||||
GetModuleHandle(NULL), 0);
|
||||
return g_hKeyboardHook ? 0 : -2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@
|
|||
#endif
|
||||
|
||||
/* if printcfg is NULL, uses the default printer */
|
||||
extern const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf, const char *printcfg, int showdialog);
|
||||
extern const char *SurfacePrint(SDL_Window * window, SDL_Surface * surf,
|
||||
const char *printcfg, int showdialog);
|
||||
extern int IsPrinterAvailable(void);
|
||||
|
||||
/* additional windows functions requiring <windows.h> */
|
||||
|
|
|
|||
|
|
@ -1,23 +1,26 @@
|
|||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
int MoveFileToRecycleBin(const TCHAR *fullPathName);
|
||||
int MoveFileToRecycleBin(const TCHAR * fullPathName);
|
||||
int win32_trash(const char *path);
|
||||
|
||||
int MoveFileToRecycleBin(const TCHAR *fullPathName)
|
||||
int MoveFileToRecycleBin(const TCHAR * fullPathName)
|
||||
{
|
||||
SHFILEOPSTRUCT fileOp;
|
||||
const TCHAR *src = fullPathName;
|
||||
TCHAR *dest;
|
||||
|
||||
fileOp.pFrom = dest = alloca(sizeof(*dest) * (_tcslen(fullPathName) + 2));
|
||||
while((*dest++ = *src++) != _T('\0')) {}
|
||||
while ((*dest++ = *src++) != _T('\0'))
|
||||
{
|
||||
}
|
||||
*dest = _T('\0');
|
||||
|
||||
fileOp.hwnd = NULL;
|
||||
fileOp.wFunc = FO_DELETE;
|
||||
fileOp.pTo = NULL;
|
||||
fileOp.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO;
|
||||
fileOp.fFlags =
|
||||
FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT | FOF_ALLOWUNDO;
|
||||
return SHFileOperation(&fileOp);
|
||||
}
|
||||
|
||||
|
|
@ -26,8 +29,10 @@ int win32_trash(const char *path)
|
|||
char *p, *src;
|
||||
|
||||
src = p = strdup(path);
|
||||
while(*p != '\0'){
|
||||
if (*p == '/') *p = '\\';
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (*p == '/')
|
||||
*p = '\\';
|
||||
p++;
|
||||
}
|
||||
return MoveFileToRecycleBin(src);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue