improved gcfin handling a bit
attempted to use XLoadFontSet in the x11 plugin experimentally
This commit is contained in:
parent
a46113abad
commit
e65912ae72
@ -172,6 +172,7 @@ class X11.GC(Object)
|
|||||||
fontName := nil.
|
fontName := nil.
|
||||||
|
|
||||||
var fontPtr := nil.
|
var fontPtr := nil.
|
||||||
|
var fontSet := nil.
|
||||||
|
|
||||||
method(#class) new
|
method(#class) new
|
||||||
{
|
{
|
||||||
|
@ -1945,7 +1945,9 @@ retry:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOO_DEBUG3 (moo, "TOKEN: [%.*js] %d\n", (moo_ooi_t)moo->c->tok.name.len, moo->c->tok.name.ptr, (int)moo->c->tok.type);
|
#if defined(MOO_DEBUG_LEXER)
|
||||||
|
MOO_DEBUG3 (moo, "TOKEN: [%.*js] %d\n", (moo_ooi_t)moo->c->tok.name.len, moo->c->tok.name.ptr, (int)moo->c->tok.type);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4537,11 +4537,12 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
* having the following line causes to skip firing the
|
* having the following line causes to skip firing the
|
||||||
* timed semaphore that would expire between now and the
|
* timed semaphore that would expire between now and the
|
||||||
* moment the next inspection occurs. */
|
* moment the next inspection occurs. */
|
||||||
if (moo->processor->active != moo->nil_process) goto finalization;
|
if (moo->processor->active != moo->nil_process) goto switch_to_next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no running process, no io semaphore */
|
/* no running process, no io semaphore */
|
||||||
|
if (moo->sem_gcfin != moo->_nil && moo->sem_gcfin_sigreq) goto signal_sem_gcfin;
|
||||||
vm_sleep (moo, &ft);
|
vm_sleep (moo, &ft);
|
||||||
}
|
}
|
||||||
vm_gettime (moo, &now);
|
vm_gettime (moo, &now);
|
||||||
@ -4576,11 +4577,14 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moo->sem_gcfin_sigreq)
|
|
||||||
|
if ((moo_oop_t)moo->sem_gcfin != moo->_nil)
|
||||||
{
|
{
|
||||||
if ((moo_oop_t)moo->sem_gcfin != moo->_nil)
|
moo_oop_process_t proc;
|
||||||
|
|
||||||
|
if (moo->sem_gcfin_sigreq)
|
||||||
{
|
{
|
||||||
moo_oop_process_t proc;
|
signal_sem_gcfin:
|
||||||
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signalled GCFIN semaphore\n");
|
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signalled GCFIN semaphore\n");
|
||||||
proc = signal_semaphore (moo, moo->sem_gcfin);
|
proc = signal_semaphore (moo, moo->sem_gcfin);
|
||||||
|
|
||||||
@ -4590,24 +4594,47 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
||||||
switch_to_process_from_nil (moo, proc);
|
switch_to_process_from_nil (moo, proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moo->sem_gcfin_sigreq = 0;
|
||||||
}
|
}
|
||||||
moo->sem_gcfin_sigreq = 0;
|
else
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((moo_oop_t)moo->sem_gcfin != moo->_nil && moo->processor->active == moo->nil_process)
|
|
||||||
{
|
{
|
||||||
moo_oop_process_t proc;
|
/* the gcfin semaphore signalling is not requested and there are
|
||||||
proc = signal_semaphore (moo, moo->sem_gcfin);
|
* no runnable processes nor no waiting semaphores. if there is
|
||||||
if ((moo_oop_t)proc != moo->_nil)
|
* process waiting on the gcfin semaphore, i will just schedule
|
||||||
|
* it to run */
|
||||||
|
/* TODO: check if this is the best implementation practice */
|
||||||
|
if (moo->processor->active == moo->nil_process)
|
||||||
{
|
{
|
||||||
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
MOO_LOG0 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Signalled GCFIN semaphore without gcfin signal request\n");
|
||||||
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
proc = signal_semaphore (moo, moo->sem_gcfin);
|
||||||
switch_to_process_from_nil (moo, proc);
|
if ((moo_oop_t)proc != moo->_nil)
|
||||||
|
{
|
||||||
|
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE));
|
||||||
|
MOO_ASSERT (moo, proc == moo->processor->runnable.first);
|
||||||
|
switch_to_process_from_nil (moo, proc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
while (moo->sem_list_count > 0)
|
||||||
|
{
|
||||||
|
/* handle async signals */
|
||||||
|
--moo->sem_list_count;
|
||||||
|
signal_semaphore (moo, moo->sem_list[moo->sem_list_count]);
|
||||||
|
if (moo->processor->active == moo->nil_process)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (semaphore heap has pending request)
|
||||||
|
{
|
||||||
|
signal them...
|
||||||
|
}*/
|
||||||
|
#endif
|
||||||
|
|
||||||
if (moo->processor->active == moo->nil_process)
|
if (moo->processor->active == moo->nil_process)
|
||||||
{
|
{
|
||||||
/* no more waiting semaphore and no more process */
|
/* no more waiting semaphore and no more process */
|
||||||
@ -4616,21 +4643,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
finalization:
|
switch_to_next:
|
||||||
#if 0
|
|
||||||
while (moo->sem_list_count > 0)
|
|
||||||
{
|
|
||||||
/* handle async signals */
|
|
||||||
--moo->sem_list_count;
|
|
||||||
signal_semaphore (moo, moo->sem_list[moo->sem_list_count]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
if (semaphore heap has pending request)
|
|
||||||
{
|
|
||||||
signal them...
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/* TODO: implement different process switching scheme - time-slice or clock based??? */
|
/* TODO: implement different process switching scheme - time-slice or clock based??? */
|
||||||
#if defined(MOO_EXTERNAL_PROCESS_SWITCH)
|
#if defined(MOO_EXTERNAL_PROCESS_SWITCH)
|
||||||
if (!moo->proc_switched && moo->switch_proc) { switch_to_next_runnable_process (moo); }
|
if (!moo->proc_switched && moo->switch_proc) { switch_to_next_runnable_process (moo); }
|
||||||
|
21
moo/lib/gc.c
21
moo/lib/gc.c
@ -118,7 +118,7 @@ static kernel_class_info_t kernel_classes[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void move_finalizable_objects (moo_t* moo);
|
static moo_oow_t move_finalizable_objects (moo_t* moo);
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
* BOOTSTRAPPER
|
* BOOTSTRAPPER
|
||||||
@ -630,6 +630,7 @@ void moo_gc (moo_t* moo)
|
|||||||
moo_oop_t old_nil;
|
moo_oop_t old_nil;
|
||||||
moo_oow_t i;
|
moo_oow_t i;
|
||||||
moo_cb_t* cb;
|
moo_cb_t* cb;
|
||||||
|
moo_oow_t gcfin_count;
|
||||||
|
|
||||||
if (moo->active_context)
|
if (moo->active_context)
|
||||||
{
|
{
|
||||||
@ -712,10 +713,11 @@ void moo_gc (moo_t* moo)
|
|||||||
/* scan the new heap to move referenced objects */
|
/* scan the new heap to move referenced objects */
|
||||||
scan_ptr = scan_new_heap (moo, scan_ptr);
|
scan_ptr = scan_new_heap (moo, scan_ptr);
|
||||||
|
|
||||||
/* FINALIZATION */
|
/* check finalizable objects registered and scan the heap again.
|
||||||
move_finalizable_objects (moo);
|
* symbol table compation is placed after this phase assuming that
|
||||||
|
* no symbol is added to be finalized. */
|
||||||
|
gcfin_count = move_finalizable_objects (moo);
|
||||||
scan_ptr = scan_new_heap (moo, scan_ptr);
|
scan_ptr = scan_new_heap (moo, scan_ptr);
|
||||||
/* END FINALIZATION */
|
|
||||||
|
|
||||||
/* traverse the symbol table for unreferenced symbols.
|
/* traverse the symbol table for unreferenced symbols.
|
||||||
* if the symbol has not moved to the new heap, the symbol
|
* if the symbol has not moved to the new heap, the symbol
|
||||||
@ -760,8 +762,7 @@ void moo_gc (moo_t* moo)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (moo->active_method) SET_ACTIVE_METHOD_CODE (moo); /* update moo->active_code */
|
if (moo->active_method) SET_ACTIVE_METHOD_CODE (moo); /* update moo->active_code */
|
||||||
/*if (moo->sem_gcfin_count > 0) signal_semaphore (moo, moo->sem_gcfin);*/
|
if (gcfin_count > 0) moo->sem_gcfin_sigreq = 1;
|
||||||
if (moo->sem_gcfin_count > 0) moo->sem_gcfin_sigreq = 1;
|
|
||||||
|
|
||||||
/* TODO: include some gc statstics like number of live objects, gc performance, etc */
|
/* TODO: include some gc statstics like number of live objects, gc performance, etc */
|
||||||
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
MOO_LOG4 (moo, MOO_LOG_GC | MOO_LOG_INFO,
|
||||||
@ -878,11 +879,11 @@ int moo_deregfinalizable (moo_t* moo, moo_oop_t oop)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void move_finalizable_objects (moo_t* moo)
|
static moo_oow_t move_finalizable_objects (moo_t* moo)
|
||||||
{
|
{
|
||||||
moo_finalizable_t* x, * y;
|
moo_finalizable_t* x, * y;
|
||||||
|
moo_oow_t count = 0;
|
||||||
|
|
||||||
moo->sem_gcfin_count = 0;
|
|
||||||
for (x = moo->collectable.first; x; x = x->next)
|
for (x = moo->collectable.first; x; x = x->next)
|
||||||
{
|
{
|
||||||
MOO_ASSERT (moo, (MOO_OBJ_GET_FLAGS_GCFIN(x->oop) & (MOO_GCFIN_FINALIZABLE | MOO_GCFIN_FINALIZED)) == MOO_GCFIN_FINALIZABLE);
|
MOO_ASSERT (moo, (MOO_OBJ_GET_FLAGS_GCFIN(x->oop) & (MOO_GCFIN_FINALIZABLE | MOO_GCFIN_FINALIZED)) == MOO_GCFIN_FINALIZABLE);
|
||||||
@ -914,7 +915,7 @@ static void move_finalizable_objects (moo_t* moo)
|
|||||||
/* add it to the collectable list */
|
/* add it to the collectable list */
|
||||||
MOO_APPEND_TO_LIST (&moo->collectable, x);
|
MOO_APPEND_TO_LIST (&moo->collectable, x);
|
||||||
|
|
||||||
moo->sem_gcfin_count++;
|
count++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -923,4 +924,6 @@ static void move_finalizable_objects (moo_t* moo)
|
|||||||
|
|
||||||
x = y;
|
x = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#if !defined(__DOS__)
|
#if !defined(__DOS__)
|
||||||
# define USE_THREAD
|
# define USE_THREAD
|
||||||
@ -1758,6 +1759,8 @@ int main (int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
setlocale (LC_ALL, "");
|
||||||
|
|
||||||
memset (&vmprim, 0, MOO_SIZEOF(vmprim));
|
memset (&vmprim, 0, MOO_SIZEOF(vmprim));
|
||||||
vmprim.dl_open = dl_open;
|
vmprim.dl_open = dl_open;
|
||||||
vmprim.dl_close = dl_close;
|
vmprim.dl_close = dl_close;
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
/* this is for gc debugging */
|
/* this is for gc debugging */
|
||||||
#define MOO_DEBUG_GC
|
#define MOO_DEBUG_GC
|
||||||
|
/*#define MOO_DEBUG_LEXER*/
|
||||||
#define MOO_DEBUG_COMPILER
|
#define MOO_DEBUG_COMPILER
|
||||||
/*#define MOO_DEBUG_VM_PROCESSOR*/
|
/*#define MOO_DEBUG_VM_PROCESSOR*/
|
||||||
/*#define MOO_DEBUG_VM_EXEC*/
|
/*#define MOO_DEBUG_VM_EXEC*/
|
||||||
|
@ -386,9 +386,13 @@ void moo_freemem (moo_t* moo, void* ptr)
|
|||||||
#if defined(MOO_ENABLE_STATIC_MODULE)
|
#if defined(MOO_ENABLE_STATIC_MODULE)
|
||||||
|
|
||||||
#include "../mod/console.h"
|
#include "../mod/console.h"
|
||||||
#include "../mod/_ffi.h"
|
#if defined(MOO_ENABLE_MOD_FFI)
|
||||||
|
# include "../mod/_ffi.h"
|
||||||
|
#endif
|
||||||
#include "../mod/_stdio.h"
|
#include "../mod/_stdio.h"
|
||||||
#include "../mod/_x11.h"
|
#if defined(MOO_ENABLE_MOD_X11)
|
||||||
|
# include "../mod/_x11.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
|
@ -1175,7 +1175,6 @@ struct moo_t
|
|||||||
/* semaphore to notify finalizable objects */
|
/* semaphore to notify finalizable objects */
|
||||||
moo_oop_semaphore_t sem_gcfin;
|
moo_oop_semaphore_t sem_gcfin;
|
||||||
int sem_gcfin_sigreq;
|
int sem_gcfin_sigreq;
|
||||||
moo_oow_t sem_gcfin_count;
|
|
||||||
|
|
||||||
moo_oop_t* tmp_stack[256]; /* stack for temporaries */
|
moo_oop_t* tmp_stack[256]; /* stack for temporaries */
|
||||||
moo_oow_t tmp_count;
|
moo_oow_t tmp_count;
|
||||||
|
@ -63,6 +63,7 @@ struct x11_gc_t
|
|||||||
moo_oop_t font_name;
|
moo_oop_t font_name;
|
||||||
|
|
||||||
moo_oop_t font_ptr;
|
moo_oop_t font_ptr;
|
||||||
|
moo_oop_t font_set; /* XFontSet */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct x11_widget_t* oop_x11_widget_t;
|
typedef struct x11_widget_t* oop_x11_widget_t;
|
||||||
|
159
moo/mod/x11.c
159
moo/mod/x11.c
@ -466,7 +466,6 @@ static moo_pfrc_t pf_destroy_gc (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
Display* disp;
|
Display* disp;
|
||||||
|
|
||||||
|
|
||||||
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
gc = (oop_x11_gc_t)MOO_STACK_GETARG(moo, nargs, 0); /* GC object */
|
gc = (oop_x11_gc_t)MOO_STACK_GETARG(moo, nargs, 0); /* GC object */
|
||||||
|
|
||||||
@ -477,6 +476,13 @@ static moo_pfrc_t pf_destroy_gc (moo_t* moo, moo_ooi_t nargs)
|
|||||||
gc->font_ptr = moo->_nil;
|
gc->font_ptr = moo->_nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MOO_OOP_IS_SMPTR(gc->font_set))
|
||||||
|
{
|
||||||
|
XFreeFontSet (disp, MOO_OOP_TO_SMPTR(gc->font_set));
|
||||||
|
gc->font_set = moo->_nil;
|
||||||
|
MOO_DEBUG0 (moo, "Freed Font Set\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (MOO_OOP_IS_SMPTR(gc->gc_handle))
|
if (MOO_OOP_IS_SMPTR(gc->gc_handle))
|
||||||
{
|
{
|
||||||
XFreeGC (disp, MOO_OOP_TO_SMPTR(gc->gc_handle));
|
XFreeGC (disp, MOO_OOP_TO_SMPTR(gc->gc_handle));
|
||||||
@ -496,7 +502,6 @@ static moo_pfrc_t pf_apply_gc (moo_t* moo, moo_ooi_t nargs)
|
|||||||
unsigned long int mask = 0;
|
unsigned long int mask = 0;
|
||||||
XGCValues v;
|
XGCValues v;
|
||||||
|
|
||||||
|
|
||||||
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
a0 = (oop_x11_gc_t)MOO_STACK_GETARG(moo, nargs, 0);
|
a0 = (oop_x11_gc_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||||
/* TODO check if a0 is an instance of X11.GC */
|
/* TODO check if a0 is an instance of X11.GC */
|
||||||
@ -513,30 +518,66 @@ static moo_pfrc_t pf_apply_gc (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
if (MOO_OBJ_IS_CHAR_POINTER(a0->font_name) && MOO_OBJ_GET_SIZE(a0->font_name) > 0)
|
if (MOO_OBJ_IS_CHAR_POINTER(a0->font_name) && MOO_OBJ_GET_SIZE(a0->font_name) > 0)
|
||||||
{
|
{
|
||||||
XFontStruct* font;
|
XFontSet fs;
|
||||||
/* TODO: .... use font_name */
|
char **missing_charsets;
|
||||||
font = XLoadQueryFont (disp, "-misc-fixed-medium-r-normal-ko-18-120-100-100-c-180-iso10646-1");
|
int num_missing_charsets = 0;
|
||||||
if (font)
|
char *default_string;
|
||||||
|
|
||||||
|
/* TODO: don't create this again and again */
|
||||||
|
/* TODO: use font name */
|
||||||
|
fs = XCreateFontSet (disp, "-adobe-*-medium-r-normal-*-14-*-*-*-*-*-*-*,-baekmuk-*-medium-r-normal-*-14-*-*-*-*-*-*-*,-*-*-medium-r-normal-*-*-*-*-*-*-*-*-*",
|
||||||
|
&missing_charsets, &num_missing_charsets, &default_string);
|
||||||
|
if (num_missing_charsets)
|
||||||
{
|
{
|
||||||
if (!MOO_IN_SMPTR_RANGE(font))
|
int i;
|
||||||
|
|
||||||
|
MOO_DEBUG0 (moo, "The following charsets are missing:\n");
|
||||||
|
for(i = 0; i < num_missing_charsets; i++)
|
||||||
|
MOO_DEBUG1 (moo, "\t%s\n", missing_charsets[i]);
|
||||||
|
MOO_DEBUG1 (moo, "The string %s will be used in place of any characters from those set\n", default_string);
|
||||||
|
XFreeStringList(missing_charsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs)
|
||||||
|
{
|
||||||
|
/* TODO: error handling. rollback upon failure... etc */
|
||||||
|
MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(fs));
|
||||||
|
if (MOO_OOP_IS_SMPTR(a0->font_set))
|
||||||
{
|
{
|
||||||
MOO_DEBUG0 (moo, "<x11.apply_gc> Font pointer not in small pointer range\n");
|
MOO_DEBUG0 (moo, "Freed Font Set ..\n");
|
||||||
XFreeFont (disp, font);
|
XFreeFontSet (disp, MOO_OOP_TO_SMPTR(a0->font_set));
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE);
|
|
||||||
return MOO_PF_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
XSetFont (disp, gc, font->fid);
|
|
||||||
if (MOO_OOP_IS_SMPTR(a0->font_ptr)) XFreeFont (disp, MOO_OOP_TO_SMPTR(a0->font_ptr));
|
|
||||||
a0->font_ptr = MOO_SMPTR_TO_OOP(font);
|
|
||||||
}
|
}
|
||||||
|
a0->font_set = MOO_SMPTR_TO_OOP (fs);
|
||||||
|
MOO_DEBUG0 (moo, "XCreateFontSet ok....\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOO_DEBUG2 (moo, "<x11.apply_gc> Cannot load font - %.*js\n", MOO_OBJ_GET_SIZE(a0->font_name), MOO_OBJ_GET_CHAR_SLOT(a0->font_name));
|
XFontStruct* font;
|
||||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ESYSERR);
|
|
||||||
return MOO_PF_SUCCESS;
|
/* TODO: .... use font_name */
|
||||||
|
font = XLoadQueryFont (disp, "-misc-fixed-medium-r-normal-ko-18-120-100-100-c-180-iso10646-1");
|
||||||
|
if (font)
|
||||||
|
{
|
||||||
|
if (!MOO_IN_SMPTR_RANGE(font))
|
||||||
|
{
|
||||||
|
MOO_DEBUG0 (moo, "<x11.apply_gc> Font pointer not in small pointer range\n");
|
||||||
|
XFreeFont (disp, font);
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ERANGE);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XSetFont (disp, gc, font->fid);
|
||||||
|
if (MOO_OOP_IS_SMPTR(a0->font_ptr)) XFreeFont (disp, MOO_OOP_TO_SMPTR(a0->font_ptr));
|
||||||
|
a0->font_ptr = MOO_SMPTR_TO_OOP(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MOO_DEBUG2 (moo, "<x11.apply_gc> Cannot load font - %.*js\n", MOO_OBJ_GET_SIZE(a0->font_name), MOO_OBJ_GET_CHAR_SLOT(a0->font_name));
|
||||||
|
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_ESYSERR);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,15 +679,11 @@ static moo_pfrc_t pf_fill_rectangle (moo_t* moo, moo_ooi_t nargs)
|
|||||||
|
|
||||||
static moo_pfrc_t pf_draw_string (moo_t* moo, moo_ooi_t nargs)
|
static moo_pfrc_t pf_draw_string (moo_t* moo, moo_ooi_t nargs)
|
||||||
{
|
{
|
||||||
|
|
||||||
oop_x11_t x11;
|
oop_x11_t x11;
|
||||||
oop_x11_gc_t gc;
|
oop_x11_gc_t gc;
|
||||||
moo_oop_t a1, a2, a3;
|
moo_oop_t a1, a2, a3;
|
||||||
|
|
||||||
Display* disp;
|
Display* disp;
|
||||||
XChar2b* stptr;
|
|
||||||
moo_oow_t stlen;
|
|
||||||
int ascent = 0;
|
|
||||||
|
|
||||||
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
x11 = (oop_x11_t)MOO_STACK_GETRCV(moo, nargs);
|
||||||
disp = MOO_OOP_TO_SMPTR(x11->display);
|
disp = MOO_OOP_TO_SMPTR(x11->display);
|
||||||
@ -666,26 +703,66 @@ static moo_pfrc_t pf_draw_string (moo_t* moo, moo_ooi_t nargs)
|
|||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: draw string chunk by chunk to avoid memory allocation in uchars_to_xchars2bstr */
|
if (MOO_OOP_IS_SMPTR(gc->font_set))
|
||||||
stptr = uchars_to_xchar2bstr (moo, MOO_OBJ_GET_CHAR_SLOT(a3), MOO_OBJ_GET_SIZE(a3), &stlen);
|
|
||||||
if (!stptr)
|
|
||||||
{
|
{
|
||||||
MOO_DEBUG0 (moo, "<x11.draw_string> Error in converting a string\n");
|
moo_oow_t ucslen, bcslen;
|
||||||
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
moo_bch_t* bb;
|
||||||
return MOO_PF_SUCCESS;
|
int ascent = 10;
|
||||||
|
XRectangle r;
|
||||||
|
|
||||||
|
ucslen = MOO_OBJ_GET_SIZE(a3);
|
||||||
|
if (moo_convootobchars (moo, MOO_OBJ_GET_CHAR_SLOT(a3), &ucslen, MOO_NULL, &bcslen) <= -1 ||
|
||||||
|
!(bb = moo_allocmem (moo, MOO_SIZEOF(moo_bch_t) * bcslen)))
|
||||||
|
{
|
||||||
|
MOO_DEBUG0 (moo, "<x11.draw_string> Error in converting a string\n");
|
||||||
|
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if defined(MOO_OOCH_IS_UCH)
|
||||||
|
moo_convootobchars (moo, MOO_OBJ_GET_CHAR_SLOT(a3), &ucslen, bb, &bcslen);
|
||||||
|
//#else
|
||||||
|
// moo_copybcstr (&bb->fn[parlen], bcslen + 1, arg->name);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
XmbTextExtents(MOO_OOP_TO_SMPTR(gc->font_set), bb, bcslen, MOO_NULL, &r);
|
||||||
|
ascent = r.height;
|
||||||
|
|
||||||
|
XmbDrawString (disp, (Window)MOO_OOP_TO_SMOOI(((oop_x11_widget_t)gc->widget)->window_handle),
|
||||||
|
MOO_OOP_TO_SMPTR(gc->font_set), MOO_OOP_TO_SMPTR(gc->gc_handle),
|
||||||
|
MOO_OOP_TO_SMOOI(a1), MOO_OOP_TO_SMOOI(a2) + ascent, bb, bcslen);
|
||||||
|
|
||||||
|
moo_freemem (moo, bb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XChar2b* stptr;
|
||||||
|
moo_oow_t stlen;
|
||||||
|
int ascent = 0;
|
||||||
|
|
||||||
|
/* TODO: draw string chunk by chunk to avoid memory allocation in uchars_to_xchars2bstr */
|
||||||
|
stptr = uchars_to_xchar2bstr (moo, MOO_OBJ_GET_CHAR_SLOT(a3), MOO_OBJ_GET_SIZE(a3), &stlen);
|
||||||
|
if (!stptr)
|
||||||
|
{
|
||||||
|
MOO_DEBUG0 (moo, "<x11.draw_string> Error in converting a string\n");
|
||||||
|
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||||
|
return MOO_PF_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MOO_OOP_IS_SMPTR(gc->font_ptr))
|
||||||
|
{
|
||||||
|
int direction, descent;
|
||||||
|
XCharStruct overall;
|
||||||
|
XTextExtents16 (MOO_OOP_TO_SMPTR(gc->font_ptr), stptr, stlen, &direction, &ascent, &descent, &overall);
|
||||||
|
}
|
||||||
|
|
||||||
|
XDrawString16 (disp, (Window)MOO_OOP_TO_SMOOI(((oop_x11_widget_t)gc->widget)->window_handle), MOO_OOP_TO_SMPTR(gc->gc_handle),
|
||||||
|
MOO_OOP_TO_SMOOI(a1), MOO_OOP_TO_SMOOI(a2) + ascent, stptr, stlen);
|
||||||
|
|
||||||
|
moo_freemem (moo, stptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MOO_OOP_IS_SMPTR(gc->font_ptr))
|
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||||
{
|
|
||||||
int direction, descent;
|
|
||||||
XCharStruct overall;
|
|
||||||
XTextExtents16 (MOO_OOP_TO_SMPTR(gc->font_ptr), stptr, stlen, &direction, &ascent, &descent, &overall);
|
|
||||||
}
|
|
||||||
|
|
||||||
XDrawString16 (disp, (Window)MOO_OOP_TO_SMOOI(((oop_x11_widget_t)gc->widget)->window_handle), MOO_OOP_TO_SMPTR(gc->gc_handle),
|
|
||||||
MOO_OOP_TO_SMOOI(a1), MOO_OOP_TO_SMOOI(a2) + ascent, stptr, stlen);
|
|
||||||
|
|
||||||
moo_freemem (moo, stptr);
|
|
||||||
return MOO_PF_SUCCESS;
|
return MOO_PF_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user