src/bin/evas_cserve_tool
src/bin/evas_cserve2
src/bin/evas_cserve2_slave
-src/bin/evas_cserve2_debug
src/bin/evas_cserve2_client
-src/bin/evas_cserve2_usage
src/bin/dummy_slave
*.gcno
*.gcov
2012-04-26 Carsten Haitzler (The Rasterman)
* Fix GL engine bitmap font handling
-
-2012-06-19 Vincent Torri
-
- * Remove uselesss software DirectDraw 16 bits engine
-
-2012-06-27 Sung W. Park (sung_)
-
- * Added (w, h) <= 0 check in EvasGL surface that was never handled before.
- * Handled evas_gl_make_current to return error when either surface
- or context is NULL. Before, when that was the case, it just did
- make_current(NULL, NULL) internally.
-
-2012-04-28 Carsten Haitzler (The Rasterman)
-
- * Fix font instance refcounting for textprops that hang around.
-
-2012-07-19 Jiyoun Park(jypark)
-
- * Fix jpeg save bug related with error handler
evas-software-8-x11.pc.in \
evas-software-gdi.pc.in \
evas-software-ddraw.pc.in \
+evas-software-16-ddraw.pc.in \
evas-direct3d.pc.in \
evas-software-16-wince.pc.in \
evas-psl1ght.pc.in \
pkgconfig_DATA += evas-software-ddraw.pc
endif
+if BUILD_ENGINE_SOFTWARE_16_DDRAW
+pkgconfig_DATA += evas-software-16-ddraw.pc
+endif
+
if BUILD_ENGINE_DIRECT3D
pkgconfig_DATA += evas-direct3d.pc
endif
Removal:
* Remove EVAS_FRAME_QUEUING, EVAS_SLI, METRIC_CACHE and WORD_CACHE.
* Remove librsvg svg loader (If you want to use it, use the evas_generic_loader variant).
- * Remove software DirectDraw 16 bits engine
Evas 1.2.0
want_evas_engine_software_ddraw="no"
want_evas_engine_software_8_x11="no"
want_evas_engine_software_16_x11="no"
+want_evas_engine_software_16_ddraw="no"
want_evas_engine_software_16_wince="no"
want_evas_engine_software_16_sdl="no"
want_evas_engine_gl_xlib="no"
want_evas_engine_software_gdi="yes"
want_evas_engine_software_ddraw="yes"
want_evas_engine_direct3d="yes"
+ want_evas_engine_software_16_ddraw="yes"
want_evas_image_loader_edb="no"
want_evas_image_loader_svg="no"
;;
if test "x${want_harfbuzz}" = "xyes" -o "x${want_harfbuzz}" = "xauto" ; then
PKG_CHECK_MODULES([HARFBUZZ],
- [harfbuzz >= 0.9.0],
+ [harfbuzz >= 0.6.0],
[
have_harfbuzz="yes"
requirement_evas="harfbuzz ${requirement_evas}"
EVAS_CHECK_ENGINE([software-16-x11], [${want_evas_engine_software_16_x11}], [no], [Software X11 16 bits])
+EVAS_CHECK_ENGINE([software-16-ddraw], [${want_evas_engine_software_16_ddraw}], [no], [Software DirectDraw 16 bits])
+
EVAS_CHECK_ENGINE([software-16-wince], [${want_evas_engine_software_16_wince}], [no], [Software Windows CE 16 bits])
EVAS_CHECK_ENGINE([software-16-sdl], [${want_evas_engine_software_16_sdl}], [no], [Software SDL 16 bits])
if test "x$have_evas_engine_software_16_sdl" = "xyes" -o "x$have_evas_engine_software_16_sdl" = "xstatic"; then
have_evas_engine_software_16="yes"
fi
+if test "x$have_evas_engine_software_16_ddraw" = "xyes" -o "x$have_evas_engine_software_16_ddraw" = "xstatic"; then
+ have_evas_engine_software_16="yes"
+fi
if test "x$have_evas_engine_software_16_wince" = "xyes" -o "x$have_evas_engine_software_16_wince" = "xstatic"; then
have_evas_engine_software_16="yes"
fi
evas-software-16-x11.pc
evas-software-gdi.pc
evas-software-ddraw.pc
+evas-software-16-ddraw.pc
evas-direct3d.pc
evas-software-16-wince.pc
evas-software-sdl.pc
src/modules/engines/software_8_x11/Makefile
src/modules/engines/software_16/Makefile
src/modules/engines/software_16_x11/Makefile
+src/modules/engines/software_16_ddraw/Makefile
src/modules/engines/software_16_sdl/Makefile
src/modules/engines/wayland_shm/Makefile
src/modules/engines/wayland_egl/Makefile
# FIXME: kill software 16bit
echo " Software 16bit ............: $have_evas_engine_software_16"
echo " Software 16bit X11.........: $have_evas_engine_software_16_x11"
+echo " Software 16bit Directdraw..: $have_evas_engine_software_16_ddraw"
echo " Software 16bit WinCE.......: $have_evas_engine_software_16_wince"
echo " Software 16bit SDL.........: $have_evas_engine_software_16_sdl (primitive: $sdl_primitive)"
echo " Wayland Shm................: $have_evas_engine_wayland_shm"
--- /dev/null
+Name: evas-software-16-ddraw
+Description: Evas 16bit software DirectDaw engine
+Version: @VERSION@
])
+dnl use: EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_DDRAW(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
+
+AC_DEFUN([EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_DDRAW],
+[
+
+have_dep="no"
+evas_engine_[]$1[]_cflags=""
+evas_engine_[]$1[]_libs=""
+
+AC_CHECK_HEADER([ddraw.h],
+ [
+ have_dep="yes"
+ evas_engine_[]$1[]_libs="-lddraw -lgdi32"
+ ]
+)
+
+AC_SUBST([evas_engine_$1_cflags])
+AC_SUBST([evas_engine_$1_libs])
+
+if test "x${have_dep}" = "xyes" ; then
+ m4_default([$4], [:])
+else
+ m4_default([$5], [:])
+fi
+
+])
+
dnl use: EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_WINCE(engine, simple, want_static[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
AC_DEFUN([EVAS_CHECK_ENGINE_DEP_SOFTWARE_16_WINCE],
#sbs-git:slp/pkgs/e/evas evas 1.1.0+svn.69113slp2+build01 828d8bb285397266eb8985fd081fa2692fa3a7d6
Name: evas
Summary: Multi-platform Canvas Library
-Version: 1.2.0+svn.73001slp2+build01
+Version: 1.2.0+svn.72376slp2+build01
Release: 1
Group: System/Libraries
License: BSD
%{_libdir}/evas/modules/savers/*/*/module.so
%{_libdir}/evas/cserve2/loaders/*/*/module.so
%{_bindir}/evas_cserve2_client
-%{_bindir}/evas_cserve2_usage
-%{_bindir}/evas_cserve2_debug
%{_libexecdir}/evas_cserve2
%{_libexecdir}/evas_cserve2_slave
%{_libexecdir}/dummy_slave
SUBDIRS = loaders
libexec_PROGRAMS = evas_cserve2 evas_cserve2_slave dummy_slave
-bin_PROGRAMS = evas_cserve2_client evas_cserve2_usage evas_cserve2_debug
+bin_PROGRAMS = evas_cserve2_client
AM_CPPFLAGS = \
-I. \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_LIBEXEC_DIR=\"$(libexecdir)\" \
@FREETYPE_CFLAGS@ \
-@EINA_CFLAGS@ \
-@EET_CFLAGS@
+@EINA_CFLAGS@
evas_cserve2_SOURCES = \
evas_cserve2.h \
evas_cserve2_fonts.c \
evas_cserve2_main_loop_linux.c
-libevas_cserve2_utils_la = $(top_builddir)/src/lib/cserve2/libevas_cserve2_utils.la
-
evas_cserve2_LDADD = \
@FREETYPE_LIBS@ \
@EINA_LIBS@ \
-@EFL_SHM_OPEN_LIBS@ \
-@EET_LIBS@ \
-$(libevas_cserve2_utils_la)
+@EFL_SHM_OPEN_LIBS@
evas_cserve2_client_SOURCES = \
evas_cserve2_client.c
-evas_cserve2_usage_SOURCES = \
-evas_cserve2_usage.c
-
-evas_cserve2_debug_SOURCES = \
-evas_cserve2_debug.c
-
-evas_cserve2_usage_LDADD = \
-@EINA_LIBS@
-
-evas_cserve2_debug_LDADD = \
-@EINA_LIBS@
-
evas_cserve2_slave_SOURCES = \
evas_cserve2_slave.c \
evas_cserve2_utils.c
return response_send(fd, ERROR, &err, sizeof(Error_Type));
}
-static void *
-_cserve2_shm_map(const char *name, size_t length, off_t offset)
+void *
+cserve2_shm_map(const char *name, size_t length, off_t offset)
{
void *map;
int fd;
return map;
}
-/*
-static void
-_cserve2_shm_unmap(void *map, size_t length)
+void
+cserve2_shm_unmap(void *map, size_t length)
{
munmap(map, length);
}
-*/
static Error_Type
image_open(const char *file __UNUSED__, const char *key __UNUSED__, Slave_Msg_Image_Opened *result)
static Error_Type
image_load(const char *shmfile, Slave_Msg_Image_Load *params)
{
- char *map = _cserve2_shm_map(shmfile, params->shm.mmap_size,
- params->shm.mmap_offset);
+ char *map = cserve2_shm_map(shmfile, params->shm.mmap_size,
+ params->shm.mmap_offset);
if (map == MAP_FAILED)
return CSERVE2_RESOURCE_ALLOCATION_FAILED;
#endif
#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_bin_log_dom, __VA_ARGS__)
-#define DEBUG_LOAD_TIME 1
-
extern int _evas_cserve2_bin_log_dom;
typedef struct _Slave Slave;
void *ftdata1; // Freetype file source info comes here
void *ftdata2; // Freetype font info comes here
unsigned int rend_flags;
+ unsigned int hint;
unsigned int size;
unsigned int dpi;
const char *name;
const char *file;
- void *data;
- int datasize;
};
struct _Slave_Msg_Font_Loaded {
void *ftdata2;
};
-struct _Slave_Msg_Font_Glyphs_Load {
- struct {
- void *ftdata1;
- void *ftdata2;
- unsigned int rend_flags;
- unsigned int hint;
- } font;
- struct {
- unsigned int nglyphs;
- unsigned int *glyphs;
- } glyphs;
- struct {
- Shm_Handle *shm;
- unsigned int usage;
- unsigned int nglyphs;
- } cache;
-};
-
-struct _Slave_Msg_Glyph {
- unsigned int index;
- unsigned int offset;
- unsigned int size;
- unsigned int rows;
- unsigned int width;
- unsigned int pitch;
- unsigned int num_grays;
- unsigned int pixel_mode;
-};
-
-typedef struct _Slave_Msg_Glyph Slave_Msg_Glyph;
-
-struct _Slave_Msg_Font_Cache {
- unsigned int nglyphs;
- Slave_Msg_Glyph *glyphs;
- Shm_Handle *shm;
- unsigned int usage;
-};
-
-typedef struct _Slave_Msg_Font_Cache Slave_Msg_Font_Cache;
-
-struct _Slave_Msg_Font_Glyphs_Loaded {
- unsigned int ncaches;
- Slave_Msg_Font_Cache **caches;
-};
-
typedef struct _Slave_Msg_Font_Load Slave_Msg_Font_Load;
typedef struct _Slave_Msg_Font_Loaded Slave_Msg_Font_Loaded;
-typedef struct _Slave_Msg_Font_Glyphs_Load Slave_Msg_Font_Glyphs_Load;
-typedef struct _Slave_Msg_Font_Glyphs_Loaded Slave_Msg_Font_Glyphs_Loaded;
typedef void *(*Font_Request_Msg_Create)(void *data, int *size);
-typedef void (*Font_Request_Msg_Free)(void *msg, void *data);
+typedef void (*Font_Request_Msg_Free)(void *data);
typedef void (*Font_Request_Response)(Client *c, void *data, void *resp, unsigned int rid);
typedef void (*Font_Request_Error)(Client *c, void *data, Error_Type error, unsigned int rid);
CSERVE2_REQ_LAST
} Font_Request_Type;
-typedef struct _Glyph_Entry Glyph_Entry;
-
typedef void (*Fd_Watch_Cb)(int fd, Fd_Flags flags, void *data);
typedef void (*Timeout_Cb)(void); /* void* for compat? */
typedef void (*Main_Loop_Child_Dead_Cb)(int pid, int status); /* void* for compat? */
off_t cserve2_shm_offset_get(const Shm_Handle *shm);
size_t cserve2_shm_map_size_get(const Shm_Handle *shm);
size_t cserve2_shm_size_get(const Shm_Handle *shm);
-void *cserve2_shm_map(Shm_Handle *shm);
-void cserve2_shm_unmap(Shm_Handle *shm);
-size_t cserve2_shm_size_normalize(size_t size);
void cserve2_command_run(Client *client, Message_Type type);
void cserve2_cache_image_preload(Client *client, unsigned int client_image_id, unsigned int rid);
void cserve2_cache_image_unload(Client *client, unsigned int client_image_id);
-int cserve2_cache_font_load(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int rid);
-int cserve2_cache_font_unload(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int rid);
-int cserve2_cache_font_glyphs_load(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int hint, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs, unsigned int rid);
-int cserve2_cache_font_glyphs_used(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int hint, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs, unsigned int rid);
-void cserve2_cache_stats_get(Client *client, unsigned int rid);
-void cserve2_cache_font_debug(Client *client, unsigned int rid);
+int cserve2_cache_font_load(Client *client, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int hint, unsigned int size, unsigned int dpi, unsigned int rid);
Font_Request *cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request_Funcs *funcs, void *data);
-void cserve2_request_waiter_add(Font_Request *req, unsigned int rid, Client *client);
void cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err);
void cserve2_request_cancel_all(Font_Request *req, Error_Type err);
void cserve2_requests_init(void);
void cserve2_font_init(void);
void cserve2_font_shutdown(void);
void *cserve2_font_slave_cb(Slave_Thread_Data *sd, Slave_Command *cmd, const void *cmddata, void *data);
-void cserve2_font_source_ft_free(void *fontsource);
-void cserve2_font_ft_free(void *fontinfo);
#endif /* _EVAS_CSERVE2_H */
#include <string.h>
-#ifdef DEBUG_LOAD_TIME
- #include <sys/time.h>
-#endif
-
#include "evas_cserve2.h"
-#include "evas_cs2_utils.h"
typedef struct _Request_Funcs Request_Funcs;
typedef struct _Request Request;
typedef struct _Font_Source Font_Source;
typedef struct _Font_Entry Font_Entry;
typedef struct _Font_Cache Font_Cache;
+typedef struct _Glyph_Entry Glyph_Entry;
typedef void *(*Request_Msg_Create)(Entry *e, int *size);
typedef void (*Request_Response)(Entry *e, void *resp);
Eina_List *references;
Request *request;
Entry_Type type;
-#ifdef DEBUG_LOAD_TIME
- struct timeval load_start;
- struct timeval load_finish;
- int load_time;
- int saved_time;
-#endif
};
struct _File_Data {
};
struct _Font_Source {
- const char *key;
const char *name;
const char *file;
int references;
Entry base;
Font_Request *request;
unsigned int rend_flags;
+ unsigned int hint;
unsigned int size;
unsigned int dpi;
Font_Source *src;
void *ft;
- Fash_Glyph2 *glyphs;
- unsigned int nglyphs;
- Eina_Inlist *caches;
- Font_Cache *last_cache;
- Eina_Bool unused : 1;
-#ifdef DEBUG_LOAD_TIME
- struct timeval load_start;
- struct timeval load_finish;
- int gl_load_time;
- int gl_saved_time;
-#endif
};
struct _Font_Cache {
- EINA_INLIST;
Font_Entry *fe;
- Shm_Handle *shm;
- unsigned int usage;
- int inuse;
+ struct {
+ const char *name;
+ void *data;
+ unsigned int size;
+ unsigned int usage;
+ } shm;
Eina_Inlist *glyphs;
- unsigned int nglyphs;
};
struct _Glyph_Entry {
EINA_INLIST;
Font_Entry *fe;
- Font_Cache *fc;
+ Font_Cache *fi;
unsigned int index;
unsigned int offset;
- unsigned int size;
- unsigned int rows;
- unsigned int width;
- unsigned int pitch;
- unsigned int num_grays;
- unsigned int pixel_mode;
-};
-
-struct _Glyphs_Request {
- Client *client;
- Font_Entry *fe;
- unsigned int current;
- unsigned int nglyphs;
- unsigned int *glyphs;
- unsigned int nrender;
- unsigned int *render;
- unsigned int nanswer;
- Glyph_Entry **answer;
- unsigned int hint;
};
-typedef struct _Glyphs_Request Glyphs_Request;
-
-struct _Glyphs_Group {
- Font_Cache *fc;
- Eina_List *glyphs;
-};
-
-typedef struct _Glyphs_Group Glyphs_Group;
-
struct _Reference {
Client *client;
Entry *entry;
static Eina_List *image_entries_lru = NULL;
-static Eina_List *font_shm_lru = NULL;
-
static int max_unused_mem_usage = 5 * 1024; /* in kbytes */
static int unused_mem_usage = 0;
-static int max_font_usage = 10 * 4 * 1024; /* in kbytes */
-static int font_mem_usage = 0;
-
-#ifdef DEBUG_LOAD_TIME
-static int
-_timeval_sub(const struct timeval *tv2, const struct timeval *tv1)
-{
- int t1, t2;
-
- t1 = tv1->tv_usec + tv1->tv_sec * 1000000;
- t2 = tv2->tv_usec + tv2->tv_sec * 1000000;
-
- // Make sure that we don't add negative values. Some images may have
- // been not loaded yet, so it would mess with the stats.
- if (t2 > t1)
- return t2 - t1;
-
- return 0;
-}
-#endif
-
-static inline void
-_entry_load_start(Entry *e)
-{
-#ifdef DEBUG_LOAD_TIME
- gettimeofday(&e->load_start, NULL);
-#endif
-}
-
-static inline void
-_entry_load_finish(Entry *e)
-{
-#ifdef DEBUG_LOAD_TIME
- gettimeofday(&e->load_finish, NULL);
- e->load_time = _timeval_sub(&e->load_finish, &e->load_start);
-#endif
-}
-
-static inline void
-_entry_load_reused(Entry *e)
-{
-#ifdef DEBUG_LOAD_TIME
- e->saved_time += e->load_time;
-#endif
-}
static void
_image_opened_send(Client *client, File_Data *entry, unsigned int rid)
}
static void
-_font_loaded_send(Client *client, unsigned int rid)
+_font_loaded_send(Client *client, Font_Entry *fe __UNUSED__, unsigned int rid)
{
int size;
Msg_Font_Loaded msg;
DBG("Sending FONT_LOADED reply for RID: %d.", rid);
-
- size = sizeof(msg);
- memset(&msg, 0, size);
+ memset(&msg, 0, sizeof(msg));
msg.base.rid = rid;
msg.base.type = CSERVE2_FONT_LOADED;
memcpy(buf + sizeof(msg) + pathlen, f->key, keylen);
*bufsize = size;
-
- _entry_load_start(&f->base);
-
return buf;
}
{
Waiter *w;
- _entry_load_finish(&e->base);
e->w = resp->w;
e->h = resp->h;
e->frame_count = resp->frame_count;
memcpy(ptr, i->file->loader_data, loaderlen);
*bufsize = size;
-
- _entry_load_start(&i->base);
-
return buf;
}
{
Waiter *w;
- _entry_load_finish(&e->base);
-
e->alpha_sparse = resp->alpha_sparse;
if (!e->doload)
DBG("Entry %d loaded by speculative preload.", e->base.id);
}
if (fentry)
- {
- fentry->images = eina_list_remove(fentry->images, entry);
- if (!fentry->images && !fentry->base.references)
- eina_hash_del_by_key(file_entries, &fentry->base.id);
- }
+ fentry->images = eina_list_remove(fentry->images, entry);
if (entry->shm)
cserve2_shm_unref(entry->shm);
free(entry);
static int
_font_entry_cmp(const Font_Entry *k1, int k1_length __UNUSED__, const Font_Entry *k2, int k2_length __UNUSED__)
{
- if (k1->src->key == k2->src->key)
+ if (k1->src->name == k2->src->name)
{
if (k1->size == k2->size)
{
if (k1->rend_flags == k2->rend_flags)
- return k1->dpi - k2->dpi;
+ {
+ if (k1->hint == k2->hint)
+ return k1->dpi - k2->dpi;
+ return k1->hint - k2->hint;
+ }
return k1->rend_flags - k2->rend_flags;
}
return k1->size - k2->size;
}
- return strcmp(k1->src->key, k2->src->key);
+ return strcmp(k1->src->name, k2->src->name);
}
static int
_font_entry_key_hash(const Font_Entry *key, int key_length __UNUSED__)
{
int hash;
- hash = eina_hash_djb2(key->src->key, eina_stringshare_strlen(key->src->key) + 1);
+ hash = eina_hash_djb2(key->src->name, eina_stringshare_strlen(key->src->name) + 1);
hash ^= eina_hash_int32(&key->rend_flags, sizeof(int));
hash ^= eina_hash_int32(&key->size, sizeof(int));
hash ^= eina_hash_int32(&key->dpi, sizeof(int));
static void
_font_entry_free(Font_Entry *fe)
{
- fash_gl_free(fe->glyphs);
- fe->src->references--;
- if (fe->ft) cserve2_font_ft_free(fe->ft);
- if (fe->src->references <= 0)
- eina_hash_del_by_key(font_sources, fe->src->key);
free(fe);
}
static void
-_glyph_free_cb(void *data)
-{
- Glyph_Entry *gl = data;
- free(gl);
-}
-
-static void
_font_source_free(Font_Source *fs)
{
- eina_stringshare_del(fs->key);
- eina_stringshare_del(fs->name);
- eina_stringshare_del(fs->file);
- if (fs->ft) cserve2_font_source_ft_free(fs->ft);
+ if (fs->name) eina_stringshare_del(fs->name);
+ if (fs->file) eina_stringshare_del(fs->file);
free(fs);
}
-static void
-_font_shm_promote(Font_Cache *fc)
-{
- Eina_List *l;
- l = eina_list_data_find_list(font_shm_lru, fc);
- font_shm_lru = eina_list_demote_list(font_shm_lru, l);
-}
-
-static int
-_font_shm_size_get(Font_Cache *fc)
-{
- int size;
-
- size = sizeof(*fc) + cserve2_shm_size_get(fc->shm);
-
- return size;
-}
-
-static void
-_font_shm_free(Font_Cache *fc)
-{
- Font_Entry *fe = fc->fe;
- fe->caches = eina_inlist_remove(fe->caches, EINA_INLIST_GET(fc));
- if (fc == fe->last_cache)
- fe->last_cache = NULL;
-
- while (fc->glyphs)
- {
- Glyph_Entry *gl = EINA_INLIST_CONTAINER_GET(fc->glyphs, Glyph_Entry);
- fc->glyphs = eina_inlist_remove(fc->glyphs, fc->glyphs);
- fash_gl_del(fe->glyphs, gl->index);
- }
-
- cserve2_shm_unref(fc->shm);
- free(fc);
-
- if (!fe->caches)
- eina_hash_del_by_key(font_entries, fe);
-}
-
-static void
-_font_shm_lru_flush(void)
-{
- Eina_List *l, *l_next;
-
- l = font_shm_lru;
- l_next = eina_list_next(l);
-
- while (l && font_mem_usage > max_font_usage)
- {
- int size;
- Font_Cache *fc;
-
- fc = eina_list_data_get(l);
- if (fc->fe->unused && fc->inuse == 0)
- {
- font_shm_lru = eina_list_remove_list(font_shm_lru, l);
- size = _font_shm_size_get(fc);
- size += fc->nglyphs * sizeof(Glyph_Entry);
- _font_shm_free(fc);
- font_mem_usage -= size;
- }
-
- l = l_next;
- l_next = eina_list_next(l);
- }
-}
-
void
cserve2_cache_init(void)
{
void
cserve2_cache_shutdown(void)
{
- Font_Cache *fc;
-
- EINA_LIST_FREE(font_shm_lru, fc)
- _font_shm_free(fc);
-
eina_hash_free(image_entries);
eina_hash_free(image_ids);
eina_hash_free(file_entries);
if (fentry->invalid)
_file_entry_free(fentry);
- else if (!fentry->images)
- eina_hash_del_by_key(file_entries, &entry->id);
- /* don't free file entries that have images attached to it, they will
- * be freed when the last unused image is freed */
+ else
+ {
+ Image_Data *ie;
+ EINA_LIST_FREE(fentry->images, ie)
+ ie->file = NULL;
+ eina_hash_del_by_key(file_entries, &entry->id);
+ }
}
else if (entry->type == CSERVE2_IMAGE_DATA)
{
else if (entry->type == CSERVE2_FONT_ENTRY)
{
Font_Entry *fe = (Font_Entry *)entry;
- fe->unused = EINA_TRUE;
- if (!fe->caches)
- eina_hash_del_by_key(font_entries, fe);
+ eina_hash_del_by_key(font_entries, fe);
}
else
ERR("Wrong type of entry.");
}
static void
-_font_entry_reference_del(Client *client, Font_Entry *fe)
+_font_entry_reference_del(Client *client, Reference *ref)
{
- Eina_List *l;
- Reference *ref;
+ Entry *entry = ref->entry;
- EINA_LIST_FOREACH(client->fonts.referencing, l, ref)
- {
- if (ref->entry == (Entry *)fe)
- {
- ref->count--;
- if (ref->count > 0)
- break;
-
- client->fonts.referencing = eina_list_remove_list(
- client->fonts.referencing, l);
- _entry_reference_del(&fe->base, ref);
- return;
- }
- }
+ _entry_reference_del(entry, ref);
}
void
EINA_LIST_FREE(client->fonts.referencing, ref)
{
- _entry_reference_del(ref->entry, ref);
+ _font_entry_reference_del(client, ref);
}
}
}
static Font_Entry *
-_cserve2_font_entry_find(const char *name, unsigned int namelen, unsigned int size, unsigned int rend_flags, unsigned int dpi)
+_cserve2_font_entry_find(const char *name, unsigned int namelen, unsigned int size, unsigned int rend_flags, unsigned int hint, unsigned int dpi)
{
Font_Entry tmp_fe;
Font_Source tmp_fs;
Font_Entry *fe;
- tmp_fs.key = eina_stringshare_add_length(name, namelen);
+ tmp_fs.name = eina_stringshare_add_length(name, namelen);
tmp_fe.src = &tmp_fs;
tmp_fe.size = size;
tmp_fe.rend_flags = rend_flags;
+ tmp_fe.hint = hint;
tmp_fe.dpi = dpi;
fe = eina_hash_find(font_entries, &tmp_fe);
- eina_stringshare_del(tmp_fs.key);
+ eina_stringshare_del(tmp_fs.name);
return fe;
}
msg->ftdata1 = fe->src->ft;
msg->ftdata2 = fe->ft;
msg->rend_flags = fe->rend_flags;
+ msg->hint = fe->hint;
msg->size = fe->size;
msg->dpi = fe->dpi;
msg->name = fe->src->name;
*size = 0;
- _entry_load_start(&fe->base);
-
return msg;
}
static void
-_font_load_request_free(void *msg, void *data __UNUSED__)
+_font_load_request_free(void *data)
{
- free(msg);
+ free(data);
}
static void
-_font_load_request_response(Client *client __UNUSED__, void *data, void *resp, unsigned int rid __UNUSED__)
+_font_load_request_response(Client *client, void *data, void *resp, unsigned int rid)
{
Slave_Msg_Font_Loaded *msg = resp;
Font_Entry *fe = data;
- DBG("request %d answered.", rid);
-
if (!fe->src->ft)
fe->src->ft = msg->ftdata1;
if (!fe->ft)
- {
- fe->ft = msg->ftdata2;
- _entry_load_finish(&fe->base);
- }
+ fe->ft = msg->ftdata2;
if (fe->request) fe->request = NULL;
-
- _font_loaded_send(client, rid);
}
static void
-_font_load_request_failed(Client *client __UNUSED__, void *data __UNUSED__, Error_Type error __UNUSED__, unsigned int rid __UNUSED__)
+_font_load_request_failed(Client *client, void *data, Error_Type error, unsigned int rid)
{
- Font_Entry *fe = data;
- DBG("request %d error answered.", rid);
-
- cserve2_client_error_send(client, rid, error);
-
- if (fe->request) fe->request = NULL;
-
- _font_entry_reference_del(client, fe);
}
static Font_Request_Funcs _font_load_funcs = {
.error = (Font_Request_Error)_font_load_request_failed
};
-static Eina_Bool
-_glyphs_request_check(Glyphs_Request *req, Eina_Bool report_load)
-{
- unsigned int i;
- Font_Entry *fe = req->fe;
-
- req->answer = malloc(sizeof(*req->answer) * req->nglyphs);
- req->nanswer = 0;
-
- for (i = req->current; i < req->nglyphs; i++)
- {
- Glyph_Entry *ge;
- ge = fash_gl_find(fe->glyphs, req->glyphs[i]);
- if (ge)
- {
- req->answer[req->nanswer++] = ge;
-#ifdef DEBUG_LOAD_TIME
- // calculate average time saved when loading glyphs
- if (report_load)
- fe->gl_saved_time +=
- (fe->gl_load_time / fe->nglyphs);
-#endif
- ge->fc->inuse++;
- }
- else
- break;
- }
-
- req->current = i;
-
- // No glyphs need to be rendered.
- return (req->nanswer == req->nglyphs);
-}
-
-/* organize answer (cache1{gl1, gl2,}, cache2{gl3,gl4,gl5}, cache3{gl6})
- */
-static Eina_List *
-_glyphs_group_create(Glyphs_Request *req)
-{
- Eina_List *groups = NULL;
- unsigned int i;
-
- for (i = 0; i < req->nanswer; i++)
- {
- Eina_List *l;
- Glyphs_Group *iter, *gg = NULL;
- Font_Cache *fc = req->answer[i]->fc;
-
- EINA_LIST_FOREACH(groups, l, iter)
- {
- if (iter->fc == fc)
- {
- gg = iter;
- break;
- }
- }
-
- if (!gg)
- {
- gg = calloc(1, sizeof(*gg));
- gg->fc = fc;
- groups = eina_list_append(groups, gg);
- }
- gg->glyphs = eina_list_append(gg->glyphs, req->answer[i]);
- }
-
- return groups;
-}
-
-static void
-_glyphs_loaded_send(Glyphs_Request *req, unsigned int rid)
-{
- Msg_Font_Glyphs_Loaded msg;
- unsigned int size;
- Eina_List *ll, *answers = NULL;
- const char *shmname;
- unsigned int shmsize;
- unsigned int intsize;
- char *resp, *buf;
- Glyphs_Group *iter;
-
- memset(&msg, 0, sizeof(msg));
- msg.base.rid = rid;
- msg.base.type = CSERVE2_FONT_GLYPHS_LOADED;
-
- answers = _glyphs_group_create(req);
- msg.ncaches = eina_list_count(answers);
- size = sizeof(msg);
-
- // calculate size of message
- // ncaches * sizeof(cache) + nglyphs1 * sizeof(glyph) +
- // nglyphs2 * sizeof(glyph)...
-
- intsize = sizeof(unsigned int);
-
- EINA_LIST_FOREACH(answers, ll, iter)
- {
- shmname = cserve2_shm_name_get(iter->fc->shm);
- shmsize = eina_stringshare_strlen(shmname) + 1;
- // shm namelen + name
- size += intsize + shmsize;
-
- // nglyphs
- size += intsize;
- // nglyphs * (index + offset + size + rows + width + pitch +
- // num_grays + pixel_mode)
- size += eina_list_count(iter->glyphs) * 8 * intsize;
- }
-
- resp = malloc(size);
- memcpy(resp, &msg, sizeof(msg));
- buf = resp + sizeof(msg);
-
- EINA_LIST_FREE(answers, iter)
- {
- Glyph_Entry *gl;
- unsigned int nglyphs;
-
- shmname = cserve2_shm_name_get(iter->fc->shm);
- shmsize = eina_stringshare_strlen(shmname) + 1;
- memcpy(buf, &shmsize, intsize);
- buf += intsize;
- memcpy(buf, shmname, shmsize);
- buf += shmsize;
-
- nglyphs = eina_list_count(iter->glyphs);
- memcpy(buf, &nglyphs, intsize);
- buf += intsize;
-
- iter->fc->inuse -= eina_list_count(iter->glyphs);
-
- EINA_LIST_FREE(iter->glyphs, gl)
- {
- memcpy(buf, &gl->index, intsize);
- buf += intsize;
- memcpy(buf, &gl->offset, intsize);
- buf += intsize;
- memcpy(buf, &gl->size, intsize);
- buf += intsize;
- memcpy(buf, &gl->rows, intsize);
- buf += intsize;
- memcpy(buf, &gl->width, intsize);
- buf += intsize;
- memcpy(buf, &gl->pitch, intsize);
- buf += intsize;
- memcpy(buf, &gl->num_grays, intsize);
- buf += intsize;
- memcpy(buf, &gl->pixel_mode, intsize);
- buf += intsize;
- }
-
- /* We are removing SHMs from the beginning of the list, so this
- * gives a higher priority to them */
- _font_shm_promote(iter->fc);
- eina_list_free(iter->glyphs);
- free(iter);
- }
-
- cserve2_client_send(req->client, &size, sizeof(size));
- cserve2_client_send(req->client, resp, size);
-
- free(resp);
-}
-
-/*
- * taken from evas_path.c. It would be good to clean up those utils to
- * have cserve link against them easily without dragging unneeded dependencies
- */
-#ifdef _WIN32
-# define EVAS_PATH_SEPARATOR "\\"
-#else
-# define EVAS_PATH_SEPARATOR "/"
-#endif
-
-static char *
-_file_path_join(const char *path, const char *end)
-{
- char *res = NULL;
- size_t len;
-
- if ((!path) && (!end)) return NULL;
- if (!path) return strdup(end);
- if (!end) return strdup(path);
- len = strlen(path);
- len += strlen(end);
- len += strlen(EVAS_PATH_SEPARATOR);
- res = malloc(len + 1);
- if (!res) return NULL;
- strcpy(res, path);
- strcat(res, EVAS_PATH_SEPARATOR);
- strcat(res, end);
- return res;
-}
-
-static Glyphs_Request *
-_glyphs_request_create(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int hint, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs)
-{
- char *fullname;
- Glyphs_Request *req = calloc(1, sizeof(*req));
-
- if (sourcelen == 0)
- source = NULL;
- if (namelen == 0)
- name = NULL;
-
- fullname = _file_path_join(source, name);
- req->fe = _cserve2_font_entry_find(fullname, strlen(fullname) + 1, size,
- rend_flags, dpi);
- free(fullname);
- if (!req->fe)
- {
- ERR("No font entry found: source %s, name %s, rendflags: %d, hint: %d,"
- " size: %d, dpi: %d", source, name, rend_flags, hint, size, dpi);
- free(req);
- return NULL;
- }
-
- req->client = client;
-
- req->nglyphs = nglyphs;
- req->current = 0;
- req->glyphs = glyphs;
- req->hint = hint;
-
- return req;
-}
-
-static void
-_glyphs_request_free(Glyphs_Request *req)
-{
- free(req->glyphs);
- free(req->render);
- free(req->answer);
- free(req);
-}
-
-/* add glyphs that are already in cache to the "answers" array, and the ones
- * that are not cached to the "render" array.
- */
-static void
-_glyphs_load_request_prepare(Glyphs_Request *req)
-{
- unsigned int i, max;
- req->nrender = 0;
- Font_Entry *fe = req->fe;
-
- if (!fe)
- {
- ERR("No font entry for this request.");
- return;
- }
-
- // Won't render more than this number of glyphs
- max = req->nglyphs - req->nanswer;
- req->render = malloc(sizeof(*req->render) * max);
-
- for (i = req->current; i < req->nglyphs; i++)
- {
- Glyph_Entry *ge;
- ge = fash_gl_find(fe->glyphs, req->glyphs[i]);
- if (ge)
- {
- req->answer[req->nanswer++] = ge;
-
-#ifdef DEBUG_LOAD_TIME
- // calculate average time saved when loading glyphs
- fe->gl_saved_time +=
- (fe->gl_load_time / fe->nglyphs);
-#endif
- ge->fc->inuse++;
- }
- else
- req->render[req->nrender++] = req->glyphs[i];
- }
-}
-
-static void *
-_glyphs_load_request_build(void *data, int *size __UNUSED__)
-{
- Glyphs_Request *req = data;
- Slave_Msg_Font_Glyphs_Load *msg = NULL;
- Font_Entry *fe = req->fe;
- Font_Cache *fc;
-
- _glyphs_load_request_prepare(req);
-
- msg = calloc(1, sizeof(*msg));
-
- msg->font.ftdata1 = fe->src->ft;
- msg->font.ftdata2 = fe->ft;
- msg->font.hint = req->hint;
- msg->font.rend_flags = fe->rend_flags;
- msg->glyphs.nglyphs = req->nrender;
- msg->glyphs.glyphs = req->render;
-
- // Trying to reuse last filled cache.
- fc = fe->last_cache;
- if (fc)
- {
- msg->cache.shm = fc->shm;
- msg->cache.usage = fc->usage;
- msg->cache.nglyphs = fc->nglyphs;
- }
-
-#ifdef DEBUG_LOAD_TIME
- gettimeofday(&fe->load_start, NULL);
-#endif
-
- return msg;
-}
-
-static void
-_glyphs_load_request_free(void *msg, void *data)
-{
- _glyphs_request_free(data);
- free(msg);
-}
-
-static void
-_glyphs_load_request_response(Client *client __UNUSED__, void *data, void *resp, unsigned int rid)
-{
- Glyphs_Request *req = data;
- Slave_Msg_Font_Glyphs_Loaded *msg = resp;
- Font_Entry *fe = req->fe;
- Font_Cache *fc = NULL;
- unsigned int i = 0;
-
- if (fe->last_cache && fe->last_cache->shm == msg->caches[0]->shm)
- fc = fe->last_cache;
-
- while (i < msg->ncaches)
- {
- unsigned int j;
- Slave_Msg_Font_Cache *c = msg->caches[i++];
-
- if (!fc)
- {
- fc = malloc(sizeof(*fc));
- fe->caches = eina_inlist_append(fe->caches, EINA_INLIST_GET(fc));
- fe->last_cache = fc;
- fc->fe = fe;
- fc->shm = c->shm;
- fc->glyphs = NULL;
- fc->nglyphs = 0;
- fc->inuse = 0;
- font_shm_lru = eina_list_append(font_shm_lru, fc);
- font_mem_usage += _font_shm_size_get(fc);
- }
- fc->usage = c->usage;
- for (j = 0; j < c->nglyphs; j++)
- {
- Glyph_Entry *gl = malloc(sizeof(*gl));
- gl->fe = fe;
- gl->fc = fc;
- gl->index = c->glyphs[j].index;
- gl->offset = c->glyphs[j].offset;
- gl->size = c->glyphs[j].size;
- gl->rows = c->glyphs[j].rows;
- gl->width = c->glyphs[j].width;
- gl->pitch = c->glyphs[j].pitch;
- gl->num_grays = c->glyphs[j].num_grays;
- gl->pixel_mode = c->glyphs[j].pixel_mode;
- font_mem_usage += sizeof(*gl);
- fc->glyphs = eina_inlist_append(fc->glyphs, EINA_INLIST_GET(gl));
- fc->nglyphs++;
- fe->nglyphs++;
- fash_gl_add(fe->glyphs, gl->index, gl);
- req->answer[req->nanswer++] = gl;
- gl->fc->inuse++;
- }
-
- free(c); // FIXME: We are freeing this here because we only do a
- // simple free on the response message. Later we need to
- // setup a free callback for the slave response.
- fc = NULL;
- }
-
-#ifdef DEBUG_LOAD_TIME
- int load_time;
- gettimeofday(&fe->load_finish, NULL);
- load_time = _timeval_sub(&fe->load_finish, &fe->load_start);
- fe->gl_load_time += load_time;
-#endif
-
- _glyphs_loaded_send(req, rid);
- _font_shm_lru_flush();
-}
-
-static void
-_glyphs_load_request_failed(Client *client __UNUSED__, void *data __UNUSED__, Error_Type error __UNUSED__, unsigned int rid __UNUSED__)
-{
-}
-
-static Font_Request_Funcs _glyphs_load_funcs = {
- .msg_create = (Font_Request_Msg_Create)_glyphs_load_request_build,
- .msg_free = (Font_Request_Msg_Free)_glyphs_load_request_free,
- .response = (Font_Request_Response)_glyphs_load_request_response,
- .error = (Font_Request_Error)_glyphs_load_request_failed
-};
-
-static Eina_Bool
-_font_entry_stats_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
-{
- Font_Entry *fe = data;
- Msg_Stats *msg = fdata;
- Font_Cache *fc;
- int nrefs = eina_list_count(fe->base.references);
-
- msg->fonts.fonts_loaded++;
- if (fe->unused) msg->fonts.fonts_unused++;
-
- // accounting size
- EINA_INLIST_FOREACH(fe->caches, fc)
- {
- unsigned int fc_usage, shmsize;
- /* This is not real requested usage, but an approximation. We don't
- * know how many times each glyph would be used by each client, but
- * assume that a similar set of glyphs from a given font would be used
- * by each client, thus counting them one time per client referencing
- * them.
- */
- fc_usage = fc->usage * nrefs;
- shmsize = cserve2_shm_size_get(fc->shm);
-
- msg->fonts.requested_size += fc_usage;
- msg->fonts.real_size += shmsize;
- if (fe->unused) msg->fonts.unused_size += shmsize;
- }
-
-#ifdef DEBUG_LOAD_TIME
- // accounting fonts load time
- msg->fonts.fonts_load_time += fe->base.load_time;
- if (fe->caches)
- {
- msg->fonts.fonts_used_load_time += fe->base.load_time;
- msg->fonts.fonts_used_saved_time += fe->base.saved_time;
- }
-
- // accounting glyphs load time
- msg->fonts.glyphs_load_time += fe->gl_load_time;
- msg->fonts.glyphs_saved_time += fe->gl_saved_time;
-#endif
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_image_file_entry_stats_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
-{
- Msg_Stats *msg = fdata;
- File_Data *fd = data;
-
- // accounting numbers
- msg->images.files_loaded++;
-
- // accounting size
- msg->images.files_size += sizeof(File_Data) +
- eina_list_count(fd->images) * sizeof(Eina_List *) +
- eina_list_count(fd->base.references) *
- (sizeof(Request) + sizeof(Eina_List *));
-
-#ifdef DEBUG_LOAD_TIME
- // accounting file entries load time
- msg->images.files_load_time += fd->base.load_time;
- msg->images.files_saved_time += fd->base.saved_time;
-#endif
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_image_data_entry_stats_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
-{
- Msg_Stats *msg = fdata;
- Image_Data *id = data;
- unsigned int image_size;
-
- // accounting numbers
- msg->images.images_loaded++;
- if (id->unused) msg->images.images_unused++;
-
- // accounting size
- msg->images.images_size += _image_entry_size_get(id) * 1024;
- if (id->unused) msg->images.unused_size += _image_entry_size_get(id) * 1024;
-
- image_size = id->file->w * id->file->h * 4;
- msg->images.requested_size +=
- (image_size * eina_list_count(id->base.references));
-
-#ifdef DEBUG_LOAD_TIME
- // accounting image entries load time
- msg->images.images_load_time += id->base.load_time;
- msg->images.images_saved_time += id->base.saved_time;
-#endif
-
- return EINA_TRUE;
-}
-
-static void
-_cserve2_cache_image_stats_get(Msg_Stats *msg)
-{
- eina_hash_foreach(file_entries, _image_file_entry_stats_cb, msg);
- eina_hash_foreach(image_entries, _image_data_entry_stats_cb, msg);
-}
-
-static void
-_cserve2_cache_font_stats_get(Msg_Stats *msg)
-{
- eina_hash_foreach(font_entries, _font_entry_stats_cb, msg);
-}
-
-struct _debug_info
-{
- unsigned int size;
- unsigned int nfonts;
-};
-
-static Eina_Bool
-_font_entry_debug_size_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
-{
- struct _debug_info *di = fdata;
- unsigned int size = di->size;
- Font_Entry *fe = data;
- Font_Cache *fc;
- unsigned int intsize = sizeof(unsigned int);
-
- // filelen
- size += intsize;
-
- // file
- if (fe->src->file)
- size += strlen(fe->src->file) + 1;
-
- // namelen
- size += intsize;
-
- // name
- if (fe->src->name)
- size += strlen(fe->src->name) + 1;
-
- // rend_flags, size, dpi
- size += 3 * intsize;
-
- // unused
- size += intsize;
-
- // ncaches
- size += intsize;
-
- EINA_INLIST_FOREACH(fe->caches, fc)
- {
- Glyph_Entry *gl;
-
- // shmnamelen + shmname
- size += intsize;
- size += strlen(cserve2_shm_name_get(fc->shm)) + 1;
-
- // size + usage
- size += 2 * intsize;
-
- // nglyphs
- size += intsize;
-
- EINA_INLIST_FOREACH(fc->glyphs, gl)
- {
- // index, offset, size
- size += 3 * intsize;
-
- // rows, width, pitch
- size += 3 * intsize;
-
- // num_grays, pixel_mode
- size += 2 * intsize;
- }
- }
-
- di->size = size;
- di->nfonts++;
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_font_entry_debug_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
-{
- char **pos = fdata;
- char *buf = *pos;
- Font_Entry *fe = data;
- Font_Cache *fc;
- unsigned int len;
- unsigned int unused;
- unsigned int ncaches;
- unsigned int intsize = sizeof(unsigned int);
-
- // filelen + file
- len = 0;
- if (fe->src->file)
- len = strlen(fe->src->file) + 1;
- memcpy(buf, &len, intsize);
- buf += intsize;
- memcpy(buf, fe->src->file, len);
- buf += len;
-
- // namelen + name
- len = 0;
- if (fe->src->name)
- len = strlen(fe->src->name) + 1;
- memcpy(buf, &len, intsize);
- buf += intsize;
- memcpy(buf, fe->src->name, len);
- buf += len;
-
- // rend_flags, size, dpi
- memcpy(buf, &fe->rend_flags, intsize);
- buf += intsize;
- memcpy(buf, &fe->size, intsize);
- buf += intsize;
- memcpy(buf, &fe->dpi, intsize);
- buf += intsize;
-
- // unused
- unused = fe->unused;
- memcpy(buf, &unused, intsize);
- buf += intsize;
-
- // ncaches
- ncaches = eina_inlist_count(fe->caches);
- memcpy(buf, &ncaches, intsize);
- buf += intsize;
-
- EINA_INLIST_FOREACH(fe->caches, fc)
- {
- Glyph_Entry *gl;
- const char *shmname;
- unsigned int shmsize;
-
- // shmnamelen + shmname
- shmname = cserve2_shm_name_get(fc->shm);
- len = strlen(shmname) + 1;
- memcpy(buf, &len, intsize);
- buf += intsize;
- memcpy(buf, shmname, len);
- buf += len;
-
- // size, usage, nglyphs
- shmsize = cserve2_shm_size_get(fc->shm);
- memcpy(buf, &shmsize, intsize);
- buf += intsize;
- memcpy(buf, &fc->usage, intsize);
- buf += intsize;
- memcpy(buf, &fc->nglyphs, intsize);
- buf += intsize;
-
- EINA_INLIST_FOREACH(fc->glyphs, gl)
- {
- // index, offset, size
- memcpy(buf, &gl->index, intsize);
- buf += intsize;
- memcpy(buf, &gl->offset, intsize);
- buf += intsize;
- memcpy(buf, &gl->size, intsize);
- buf += intsize;
-
- // rows, width, pitch
- memcpy(buf, &gl->rows, intsize);
- buf += intsize;
- memcpy(buf, &gl->width, intsize);
- buf += intsize;
- memcpy(buf, &gl->pitch, intsize);
- buf += intsize;
-
- // num_grays, pixel_mode
- memcpy(buf, &gl->num_grays, intsize);
- buf += intsize;
- memcpy(buf, &gl->pixel_mode, intsize);
- buf += intsize;
- }
- }
-
- *pos = buf;
- return EINA_TRUE;
-}
-
-static void *
-_cserve2_cache_font_debug(unsigned int rid, unsigned int *size)
-{
- Msg_Font_Debug msg;
- char *buf, *pos;
- struct _debug_info di;
- di.size = sizeof(msg);
- di.nfonts = 0;
-
- memset(&msg, 0, sizeof(msg));
-
- msg.base.type = CSERVE2_FONT_DEBUG;
- msg.base.rid = rid;
-
- // First calculate how much size is needed for this message:
-
- // nfonts
- di.size += sizeof(unsigned int);
-
- // size needed for each font entry
- eina_hash_foreach(font_entries, _font_entry_debug_size_cb, &di);
-
- // Now really create the message
- buf = malloc(di.size);
- pos = buf;
-
- // msg base
- memcpy(buf, &msg, sizeof(msg));
- pos += sizeof(msg);
-
- // nfonts
- memcpy(pos, &di.nfonts, sizeof(unsigned int));
- pos += sizeof(unsigned int);
-
- eina_hash_foreach(font_entries, _font_entry_debug_cb, &pos);
-
- *size = di.size;
- return buf;
-}
-
int
cserve2_cache_file_open(Client *client, unsigned int client_file_id, const char *path, const char *key, unsigned int rid)
{
if (ref)
{
entry = (File_Data *)ref->entry;
- _entry_load_reused(ref->entry);
if (entry->invalid)
{
// search whether the file is already opened by another client
snprintf(buf, sizeof(buf), "%s:%s", path, key);
- file_id = (unsigned int)(uintptr_t)eina_hash_find(file_ids, buf);
+ file_id = (unsigned int)eina_hash_find(file_ids, buf);
if (file_id)
{
DBG("found file_id %u for client file id %d",
return -1;
}
ref = _entry_reference_add((Entry *)entry, client, client_file_id);
- _entry_load_reused(ref->entry);
eina_hash_add(client->files.referencing, &client_file_id, ref);
if (entry->base.request)
_request_answer_add(entry->base.request, ref, rid, CSERVE2_OPEN);
entry->key = strdup(key);
entry->base.id = file_id;
eina_hash_add(file_entries, &file_id, entry);
- eina_hash_add(file_ids, buf, (intptr_t*)(int64_t)file_id);
+ eina_hash_add(file_ids, buf, (void *)file_id);
ref = _entry_reference_add((Entry *)entry, client, client_file_id);
eina_hash_add(client->files.referencing, &client_file_id, ref);
image_entries_lru = eina_list_remove(image_entries_lru, entry);
unused_mem_usage -= _image_entry_size_get(entry);
}
- _entry_load_reused(&entry->base);
if (oldref && (oldref->entry->id == image_id))
return 0;
entry->base.id = image_id;
eina_hash_add(image_entries, &image_id, entry);
- eina_hash_add(image_ids, buf, (intptr_t *)(int64_t)image_id);
+ eina_hash_add(image_ids, buf, (void *)image_id);
ref = _entry_reference_add((Entry *)entry, client, msg->image_id);
if (oldref)
}
int
-cserve2_cache_font_load(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int rid)
+cserve2_cache_font_load(Client *client, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int hint, unsigned int size, unsigned int dpi, unsigned int rid)
{
Reference *ref;
Font_Source *fs;
- Font_Entry *fe;
- char *fullname;
-
- if (sourcelen == 0)
- source = NULL;
- if (namelen == 0)
- name = NULL;
+ Font_Entry *fe = _cserve2_font_entry_find(name, namelen, size,
+ rend_flags, hint, dpi);
- fullname = _file_path_join(source, name);
- fe = _cserve2_font_entry_find(fullname, strlen(fullname) + 1, size,
- rend_flags, dpi);
if (fe)
{
- DBG("found font entry %s, rendflags: %d, size: %d, dpi: %d",
- name, rend_flags, size, dpi);
+ DBG("found font entry %s, rendflags: %d, hint: %d, size: %d, dpi: %d",
+ name, rend_flags, hint, size, dpi);
ref = _entry_reference_add((Entry *)fe, client, 0);
client->fonts.referencing = eina_list_append(
client->fonts.referencing, ref);
- _entry_load_reused(&fe->base);
- fe->unused = EINA_FALSE;
-
- if (fe->request)
- cserve2_request_waiter_add(fe->request, rid, client);
- else
- _font_loaded_send(client, rid);
- free(fullname);
+ _font_loaded_send(client, fe, rid);
return 0;
}
fe = calloc(1, sizeof(*fe));
fe->rend_flags = rend_flags;
+ fe->hint = hint;
fe->size = size;
fe->dpi = dpi;
fe->base.type = CSERVE2_FONT_ENTRY;
- fe->glyphs = fash_gl_new(_glyph_free_cb);
- ref = _entry_reference_add((Entry *)fe, client, 0);
- client->fonts.referencing = eina_list_append(
- client->fonts.referencing, ref);
- fe->unused = EINA_FALSE;
- fs = _cserve2_font_source_find(fullname);
+ fs = _cserve2_font_source_find(name);
if (!fs)
{
fs = calloc(1, sizeof(*fs));
- if (source)
- {
- fs->key = eina_stringshare_add(fullname);
- fs->name = eina_stringshare_add_length(name, namelen);
- fs->file = eina_stringshare_add_length(source, sourcelen);
- }
- else
- {
- fs->file = eina_stringshare_add_length(name, namelen);
- fs->key = eina_stringshare_ref(fs->file);
- }
- eina_hash_direct_add(font_sources, fs->key, fs);
+ fs->name = eina_stringshare_add_length(name, namelen);
+ fs->file = eina_stringshare_ref(fs->name);
+ eina_hash_direct_add(font_sources, fs->name, fs);
}
+
fe->src = fs;
fs->references++;
- DBG("adding FONT_LOAD '%s' request.", fs->name);
fe->request = cserve2_request_add(CSERVE2_REQ_FONT_LOAD, rid,
client, &_font_load_funcs, fe);
eina_hash_direct_add(font_entries, fe, fe);
- free(fullname);
-
- return 0;
-}
-
-int
-cserve2_cache_font_unload(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int rid __UNUSED__)
-{
- Font_Entry *fe;
- char *fullname;
-
- if (sourcelen == 0)
- source = NULL;
- if (namelen == 0)
- name = NULL;
-
- fullname = _file_path_join(source, name);
- fe = _cserve2_font_entry_find(fullname, strlen(fullname) + 1, size,
- rend_flags, dpi);
- free(fullname);
-
- if (!fe)
- {
- ERR("Unreferencing font not found: '%s:%s'.", source, name);
- return -1;
- }
-
- _font_entry_reference_del(client, fe);
-
- return 0;
-}
-
-int
-cserve2_cache_font_glyphs_load(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int hint, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs, unsigned int rid)
-{
- Glyphs_Request *req;
-
- req = _glyphs_request_create(client, source, sourcelen, name, namelen,
- hint, rend_flags, size, dpi, glyphs, nglyphs);
- if (!req)
- {
- free(glyphs);
- return -1;
- }
-
- if (_glyphs_request_check(req, EINA_TRUE))
- {
- INF("Glyphs already loaded. Sending answer.");
- _glyphs_loaded_send(req, rid);
- _glyphs_request_free(req);
- }
- else
- {
- cserve2_request_add(CSERVE2_REQ_FONT_GLYPHS_LOAD, rid,
- client, &_glyphs_load_funcs, req);
- }
- return 0;
-}
-
-int
-cserve2_cache_font_glyphs_used(Client *client, const char *source, unsigned int sourcelen, const char *name, unsigned int namelen, unsigned int hint, unsigned int rend_flags, unsigned int size, unsigned int dpi, unsigned int *glyphs, unsigned int nglyphs, unsigned int rid __UNUSED__)
-{
- Glyphs_Group *gg;
- Eina_List *groups;
- Glyphs_Request *req;
-
- DBG("Received report of used glyphs from client %d", client->id);
- req = _glyphs_request_create(client, source, sourcelen, name, namelen,
- hint, rend_flags, size, dpi, glyphs, nglyphs);
- if (!req)
- {
- free(glyphs);
- return 0;
- }
-
- _glyphs_request_check(req, EINA_FALSE);
- groups = _glyphs_group_create(req);
-
- // Promote SHMs which are still cached and in use
- // TODO: We can use later the information from request_prepare to preload
- // glyphs which are not cached anymore, but are in use on the client.
- EINA_LIST_FREE(groups, gg)
- {
- _font_shm_promote(gg->fc);
- eina_list_free(gg->glyphs);
- free(gg);
- }
-
- _glyphs_request_free(req);
return 0;
}
req->entry->request = NULL;
free(req);
}
-
-void
-cserve2_cache_stats_get(Client *client, unsigned int rid)
-{
- Msg_Stats msg;
- int size;
-
- memset(&msg, 0, sizeof(msg));
-
- msg.base.type = CSERVE2_STATS;
- msg.base.rid = rid;
-
- _cserve2_cache_image_stats_get(&msg);
- _cserve2_cache_font_stats_get(&msg);
-
- size = sizeof(msg);
- cserve2_client_send(client, &size, sizeof(size));
- cserve2_client_send(client, &msg, size);
-}
-
-void
-cserve2_cache_font_debug(Client *client, unsigned int rid)
-{
- void *msg;
- unsigned int size;
-
- msg = _cserve2_cache_font_debug(rid, &size);
-
- cserve2_client_send(client, &size, sizeof(size));
- cserve2_client_send(client, msg, size);
-
- free(msg);
-}
#include "evas_cserve2.h"
+static const char *SOCK_PATH = "/tmp/cserve2.socket";
static unsigned int _rid_count = 0;
static struct sockaddr_un socket_local;
+++ /dev/null
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <Eina.h>
-
-#include "evas_cs2.h"
-
-static int socketfd = -1;
-static unsigned int _rid_count = 1;
-static int _evas_cserve2_debug_log_dom = -1;
-
-static struct sockaddr_un socksize;
-#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX sizeof(socksize.sun_path)
-#endif
-
-#ifdef ERR
-#undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_debug_log_dom, __VA_ARGS__)
-#ifdef DBG
-#undef DBG
-#endif
-#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_debug_log_dom, __VA_ARGS__)
-#ifdef WRN
-#undef WRN
-#endif
-#define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_debug_log_dom, __VA_ARGS__)
-#ifdef INF
-#undef INF
-#endif
-#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_debug_log_dom, __VA_ARGS__)
-
-static void
-_socket_path_set(char *path)
-{
- char *env;
- char buf[UNIX_PATH_MAX];
-
- env = getenv("EVAS_CSERVE2_SOCKET");
- if (env && env[0])
- {
- strncpy(path, env, UNIX_PATH_MAX - 1);
- return;
- }
-
- snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket", (int)getuid());
- /* FIXME: check we can actually create this socket */
- strcpy(path, buf);
-}
-
-static Eina_Bool
-_server_connect(void)
-{
- int s, len;
- struct sockaddr_un remote;
-
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- {
- ERR("socket");
- return EINA_FALSE;
- }
-
- remote.sun_family = AF_UNIX;
- _socket_path_set(remote.sun_path);
- len = strlen(remote.sun_path) + sizeof(remote.sun_family);
- if (connect(s, (struct sockaddr *)&remote, len) == -1)
- {
- ERR("connect");
- return EINA_FALSE;
- }
-
- fcntl(s, F_SETFL, O_NONBLOCK);
-
- socketfd = s;
-
- DBG("connected to cserve2 server.");
- return EINA_TRUE;
-}
-
-static void
-_server_disconnect(void)
-{
- close(socketfd);
- socketfd = -1;
-}
-
-static Eina_Bool
-_server_send(const void *data, int size)
-{
- int sent = 0;
- ssize_t ret;
- const char *msg = data;
-
- while (sent < size)
- {
- ret = send(socketfd, msg + sent, size - sent, MSG_NOSIGNAL);
- if (ret < 0)
- {
- if ((errno == EAGAIN) || (errno == EINTR))
- continue;
- return EINA_FALSE;
- }
- sent += ret;
- }
-
- return EINA_TRUE;
-}
-
-static int sr_size = 0;
-static int sr_got = 0;
-static char *sr_buf = NULL;
-
-static void *
-_server_read(int *size)
-{
- int n;
- void *ret;
-
- if (sr_size)
- goto get_data;
-
- n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
- if (n < 0)
- return NULL;
-
- sr_buf = malloc(sr_size);
-
-get_data:
- n = recv(socketfd, sr_buf + sr_got, sr_size - sr_got, 0);
- if (n < 0)
- return NULL;
-
- sr_got += n;
- if (sr_got < sr_size)
- return NULL;
-
- *size = sr_size;
- sr_size = 0;
- sr_got = 0;
- ret = sr_buf;
- sr_buf = NULL;
-
- return ret;
-}
-
-static void
-_debug_msg_send(void)
-{
- Msg_Base msg;
- int size;
-
- memset(&msg, 0, sizeof(msg));
- msg.type = CSERVE2_FONT_DEBUG;
- msg.rid = _rid_count++;
-
- size = sizeof(msg);
-
- if (!_server_send(&size, sizeof(size)))
- {
- ERR("Could not send usage msg size to server.");
- return;
- }
- if (!_server_send(&msg, size))
- {
- ERR("Could not send usage msg body to server.");
- return;
- }
-}
-
-typedef struct _Font_Entry Font_Entry;
-typedef struct _Cache_Entry Cache_Entry;
-typedef struct _Glyph_Entry Glyph_Entry;
-
-struct _Font_Entry
-{
- const char *file;
- const char *name;
- unsigned int rend_flags;
- unsigned int size;
- unsigned int dpi;
- unsigned int unused;
- Eina_List *caches;
-};
-
-struct _Cache_Entry
-{
- const char *shmname;
- unsigned int size;
- unsigned int usage;
- Eina_List *glyphs;
-};
-
-struct _Glyph_Entry
-{
- unsigned int index;
- unsigned int offset;
- unsigned int size;
- unsigned int rows;
- unsigned int width;
- unsigned int pitch;
- unsigned int num_grays;
- unsigned int pixel_mode;
-};
-
-#define READIT(_dst, _src) \
- do { \
- memcpy(&_dst, _src, sizeof(_dst)); \
- _src += sizeof(_dst); \
- } while(0)
-
-static Glyph_Entry *
-_parse_glyph_entry(char **msg)
-{
- Glyph_Entry *ge;
- char *buf = *msg;
-
- ge = calloc(1, sizeof(*ge));
-
- READIT(ge->index, buf);
- READIT(ge->offset, buf);
- READIT(ge->size, buf);
- READIT(ge->rows, buf);
- READIT(ge->width, buf);
- READIT(ge->pitch, buf);
- READIT(ge->num_grays, buf);
- READIT(ge->pixel_mode, buf);
-
- *msg = buf;
-
- return ge;
-}
-
-static Cache_Entry *
-_parse_cache_entry(char **msg)
-{
- Cache_Entry *ce;
- char *buf = *msg;
- unsigned int n;
-
- ce = calloc(1, sizeof(*ce));
-
- READIT(n, buf);
- ce->shmname = eina_stringshare_add_length(buf, n);
- buf += n;
-
- READIT(ce->size, buf);
- READIT(ce->usage, buf);
-
- READIT(n, buf);
- while (n--)
- {
- Glyph_Entry *ge;
- ge = _parse_glyph_entry(&buf);
- ce->glyphs = eina_list_append(ce->glyphs, ge);
- }
-
- *msg = buf;
-
- return ce;
-}
-
-static Font_Entry *
-_parse_font_entry(char **msg)
-{
- Font_Entry *fe;
- char *buf = *msg;
- unsigned int n;
-
- fe = calloc(1, sizeof(*fe));
-
- READIT(n, buf);
- if (n)
- fe->file = eina_stringshare_add_length(buf, n);
- buf += n;
- READIT(n, buf);
- if (n)
- fe->name = eina_stringshare_add_length(buf, n);
- buf += n;
-
- READIT(fe->rend_flags, buf);
- READIT(fe->size, buf);
- READIT(fe->dpi, buf);
- READIT(fe->unused, buf);
-
- READIT(n, buf);
- while (n--)
- {
- Cache_Entry *ce;
- ce = _parse_cache_entry(&buf);
- fe->caches = eina_list_append(fe->caches, ce);
- }
-
- *msg = buf;
-
- return fe;
-}
-
-static Eina_List *
-_debug_msg_read(void)
-{
- Msg_Base *msg = NULL;
- char *buf;
- int size;
- unsigned int nfonts;
- Eina_List *fonts = NULL;
-
- printf("Requesting server debug info.\n\n");
- while (!msg)
- msg = _server_read(&size);
-
- if (msg->type != CSERVE2_FONT_DEBUG)
- {
- ERR("Invalid message received from server."
- "Something went badly wrong.");
- return NULL;
- }
-
- buf = (char *)msg + sizeof(*msg);
-
- READIT(nfonts, buf);
- while (nfonts--)
- {
- Font_Entry *fe;
- fe = _parse_font_entry(&buf);
- fonts = eina_list_append(fonts, fe);
- }
-
- return fonts;
-}
-
-static void
-_glyph_entry_free(Glyph_Entry *ge)
-{
- free(ge);
-}
-
-static void
-_cache_entry_free(Cache_Entry *ce)
-{
- Glyph_Entry *ge;
-
- EINA_LIST_FREE(ce->glyphs, ge)
- _glyph_entry_free(ge);
-
- eina_stringshare_del(ce->shmname);
- free(ce);
-}
-
-static void
-_font_entry_free(Font_Entry *fe)
-{
- Cache_Entry *ce;
-
- EINA_LIST_FREE(fe->caches, ce)
- _cache_entry_free(ce);
-
- eina_stringshare_del(fe->name);
- eina_stringshare_del(fe->file);
- free(fe);
-}
-
-static void
-_glyph_entry_print(Glyph_Entry *ge)
-{
- const char *pxmode[] = {
- "FT_PIXEL_MODE_NONE",
- "FT_PIXEL_MODE_MONO",
- "FT_PIXEL_MODE_GRAY",
- "FT_PIXEL_MODE_GRAY2",
- "FT_PIXEL_MODE_GRAY4",
- "FT_PIXEL_MODE_LCD",
- "FT_PIXEL_MODE_LCD_V"
- };
- printf("\t\tGLYPH %u offset: %u size: %u %ux%u pitch: %u grays: %u "
- "pixel mode: %s\n",
- ge->index, ge->offset, ge->size, ge->width, ge->rows, ge->pitch,
- ge->num_grays, pxmode[ge->pixel_mode]);
-}
-
-static void
-_cache_entry_print(Cache_Entry *ce)
-{
- Eina_List *l;
- Glyph_Entry *ge;
-
- printf("\tSHM %s used %u/%u\n", ce->shmname, ce->usage, ce->size);
-
- EINA_LIST_FOREACH(ce->glyphs, l, ge)
- _glyph_entry_print(ge);
-}
-
-static void
-_font_entry_print(Font_Entry *fe)
-{
- Eina_List *l;
- Cache_Entry *ce;
-
- printf("FONT %s:%s size: %u dpi: %u %s%s%s %s\n",
- fe->file, fe->name, fe->size, fe->dpi,
- fe->rend_flags == 0 ? "REGULAR " : "",
- fe->rend_flags & 1 ? "SLANT " : "",
- fe->rend_flags & 2 ? "WEIGHT" : "",
- fe->unused ? "(unused)" : "");
-
- EINA_LIST_FOREACH(fe->caches, l, ce)
- _cache_entry_print(ce);
-
- putchar('\n');
-}
-
-int
-main(void)
-{
- Eina_List *fonts;
- Font_Entry *fe;
-
- eina_init();
-
- _evas_cserve2_debug_log_dom = eina_log_domain_register
- ("evas_cserve2_debug", EINA_COLOR_BLUE);
-
- if (!_server_connect())
- {
- ERR("Could not connect to server.");
- return -1;
- }
-
- _debug_msg_send();
-
- fonts = _debug_msg_read();
-
- EINA_LIST_FREE(fonts, fe)
- {
- _font_entry_print(fe);
- _font_entry_free(fe);
- }
-
- _server_disconnect();
-
- eina_shutdown();
-}
# include "config.h"
#endif
-#ifdef BUILD_FONT_LOADER_EET
-#include <Eet.h>
-#endif
-
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_SIZES_H
-#include FT_TYPES_H
#include FT_MODULE_H
-#include FT_OUTLINE_H
#include "evas_cserve2.h"
-#define CACHESIZE 4 * 1024
-
-/* The tangent of the slant angle we do on runtime. This value was
- * retrieved from engines/common/evas_font.h */
-#define _EVAS_FONT_SLANT_TAN 0.221694663
-
-#define CHECK_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
-#define MIN_GLYPHS 50
-#define MAX_CACHE_SIZE 1 * 1024 * 1024 // 1MB
-
-#define EVAS_FONT_ROUND_26_6_TO_INT(x) \
- (((x + 0x20) & -0x40) >> 6)
-
static FT_Library cserve2_ft_lib = 0;
static int initialised = 0;
-typedef struct _Font_Info Font_Info;
-typedef struct _Font_Source_Info Font_Source_Info;
-
struct _Font_Info
{
- Font_Source_Info *fsi;
FT_Size size;
- int real_size; // this is probably useless, not used even on client
- int fsize;
- int dpi;
+ int real_size;
int max_h;
unsigned int runtime_rend;
- int shmsize;
};
struct _Font_Source_Info
FT_Face face;
int orig_upem;
int current_size;
- int current_dpi;
- void *data;
- int datasize;
};
+typedef struct _Font_Info Font_Info;
+typedef struct _Font_Source_Info Font_Source_Info;
+
static void *
_font_slave_error_send(Error_Type error)
{
return e;
}
-static void
-_font_slave_size_use(Font_Info *fi)
-{
- Font_Source_Info *fsi = fi->fsi;
-// if ((fsi->current_size != fi->fsize)
-// || (fsi->current_dpi != fi->dpi))
- {
- FT_Activate_Size(fi->size);
- fsi->current_size = fi->fsize;
- fsi->current_dpi = fi->dpi;
- }
-}
-
static Font_Source_Info *
-_font_slave_source_load(const char *file, const char *name)
+_font_slave_source_load(const char *file)
{
int error;
- Font_Source_Info *fsi = calloc(1, sizeof(*fsi));
+ Font_Source_Info *fsi = malloc(sizeof(*fsi));
- if (!name)
- {
- error = FT_New_Face(cserve2_ft_lib, file, 0, &(fsi->face));
- if (error)
- {
- free(fsi);
- return NULL;
- }
- }
-#ifdef BUILD_FONT_LOADER_EET
- else
+ error = FT_New_Face(cserve2_ft_lib, file, 0, &(fsi->face));
+ if (error)
{
- Eet_File *ef;
- void *fdata;
- int fsize = 0;
-
- ef = eet_open(file, EET_FILE_MODE_READ);
- if (!ef)
- {
- free(fsi);
- return NULL;
- }
- fdata = eet_read(ef, name, &fsize);
- eet_close(ef);
- if (!fdata)
- {
- free(fsi);
- return NULL;
- }
- fsi->data = fdata;
- fsi->datasize = fsize;
-
- error = FT_New_Memory_Face(cserve2_ft_lib, fsi->data, fsi->datasize,
- 0, &(fsi->face));
- if (error)
- {
- free(fsi->data);
- free(fsi);
- return NULL;
- }
+ free(fsi);
+ return NULL;
}
-#endif
error = FT_Select_Charmap(fsi->face, ft_encoding_unicode);
if (error)
{
FT_Done_Face(fsi->face);
- free(fsi->data);
free(fsi);
return NULL;
}
fsi->orig_upem = fsi->face->units_per_EM;
fsi->current_size = 0;
- fsi->current_dpi = 0;
return fsi;
}
if (!error)
FT_Activate_Size(fi->size);
- fi->fsize = msg->size;
- fi->dpi = msg->dpi;
fi->real_size = msg->size * 64;
- fi->fsi = fsi;
error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, msg->dpi, msg->dpi);
if (error)
- error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);
+ {
+ fi->real_size = msg->size;
+ error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);
+ }
if (error)
{
- int i, maxd = 0x7fffffff;
+ int i;
int chosen_size = 0;
- int chosen_size2 = 0;
+ int chosen_width = 0;
for (i = 0; i < fsi->face->num_fixed_sizes; i++)
{
- int s, cd;
+ int s;
+ int d, cd;
- s = fsi->face->available_sizes[i].size;
- cd = chosen_size - fi->real_size;
+ s = fsi->face->available_sizes[i].height;
+ cd = chosen_size - msg->size;
if (cd < 0) cd = -cd;
- if (cd < maxd)
+ d = s - msg->size;
+ if (d < 0) d = -d;
+ if (d < cd)
{
- maxd = cd;
+ chosen_width = fsi->face->available_sizes[i].width;
chosen_size = s;
- chosen_size2 = fsi->face->available_sizes[i].y_ppem;
- if (maxd == 0) break;
}
+ if (d == 0) break;
}
fi->real_size = chosen_size;
- error = FT_Set_Pixel_Sizes(fsi->face, 0, fi->real_size);
+ error = FT_Set_Pixel_Sizes(fsi->face, chosen_width, fi->real_size);
if (error)
{
- error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi);
- if (error)
- {
- /* hack around broken fonts */
- fi->real_size = (chosen_size2 / 64) * 60;
- error = FT_Set_Char_Size(fsi->face, 0, fi->real_size, fi->dpi, fi->dpi);
- if (error)
- {
- ERR("Could not choose the font size for font: '%s:%s'.",
- msg->file, msg->name);
- FT_Done_Size(fi->size);
- free(fi);
- return NULL;
- }
- }
+ ERR("Could not choose the font size for font: '%s'.", msg->name);
+ FT_Done_Size(fi->size);
+ free(fi);
+ return NULL;
}
}
Font_Source_Info *fsi;
Font_Info *fi;
- DBG("slave received FONT_LOAD: '%s'", msg->name);
fsi = msg->ftdata1;
/* Loading Font Source */
if (!fsi)
- fsi = _font_slave_source_load(msg->file, msg->name);
+ fsi = _font_slave_source_load(msg->file);
// FIXME: Return correct error message
if (!fsi)
fi = _font_slave_int_load(msg, fsi);
if (!fi)
{
- if (!msg->ftdata1)
- cserve2_font_source_ft_free(fsi);
+ FT_Done_Face(fsi->face);
+ free(fsi);
return NULL;
}
return response;
}
-static Shm_Handle *
-_font_slave_memory_alloc(Font_Info *fi)
-{
- Shm_Handle *shm = cserve2_shm_request(fi->shmsize);
-
- return shm;
-}
-
-/* This function will load the "index" glyph to the glyph slot of the font.
- * In order to use or render it, one should access it from the glyph slot,
- * or get the glyph using FT_Get_Glyph().
- */
-static Eina_Bool
-_font_slave_glyph_load(Font_Info *fi, unsigned int idx, unsigned int hint)
-{
- Font_Source_Info *fsi = fi->fsi;
- FT_Error error;
- const FT_Int32 hintflags[3] =
- { FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT };
- static FT_Matrix transform = {0x10000, _EVAS_FONT_SLANT_TAN * 0x10000,
- 0x00000, 0x10000};
-
- error = FT_Load_Glyph(fsi->face, idx,
- FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP |
- hintflags[hint]);
- if (error)
- {
- ERR("Could not load glyph %d", idx);
- return EINA_FALSE;
- }
-
- /* Transform the outline of Glyph according to runtime_rend. */
- if (fi->runtime_rend & FONT_REND_SLANT)
- FT_Outline_Transform(&fsi->face->glyph->outline, &transform);
- /* Embolden the outline of Glyph according to rundtime_rend. */
- if (fi->runtime_rend & FONT_REND_WEIGHT)
- FT_Outline_Embolden(&fsi->face->glyph->outline,
- (fsi->face->size->metrics.x_ppem * 5 * 64) /
- 100);
-
- return EINA_TRUE;
-}
-
-/* This function will render the glyph currently in the glyph slot into the
- * given Font Cache.
- */
-static Eina_Bool
-_font_slave_glyph_render(Font_Info *fi, Slave_Msg_Font_Cache *c, unsigned int idx)
-{
- Font_Source_Info *fsi = fi->fsi;
- unsigned int glyphsize;
- char *cachedata = cserve2_shm_map(c->shm);
- FT_Glyph glyph;
- FT_BitmapGlyph bglyph;
-
- FT_Get_Glyph(fsi->face->glyph, &glyph);
- FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
- bglyph = (FT_BitmapGlyph)glyph;
-
- glyphsize = bglyph->bitmap.pitch * bglyph->bitmap.rows;
-
- if (c->usage + glyphsize > cserve2_shm_size_get(c->shm))
- {
- FT_Done_Glyph(glyph);
- return EINA_FALSE;
- }
-
- memcpy(cachedata + c->usage, bglyph->bitmap.buffer, glyphsize);
-
- // TODO: Check if we have problems with alignment
- c->glyphs[c->nglyphs].index = idx;
- c->glyphs[c->nglyphs].offset = c->usage;
- c->glyphs[c->nglyphs].size = glyphsize;
- c->glyphs[c->nglyphs].rows = bglyph->bitmap.rows;
- c->glyphs[c->nglyphs].width = bglyph->bitmap.width;
- c->glyphs[c->nglyphs].pitch = bglyph->bitmap.pitch;
- c->glyphs[c->nglyphs].num_grays = bglyph->bitmap.num_grays;
- c->glyphs[c->nglyphs].pixel_mode = bglyph->bitmap.pixel_mode;
- c->usage += glyphsize;
- c->nglyphs++;
-
- FT_Done_Glyph(glyph);
-
- return EINA_TRUE;
-}
-
-static void
-_font_slave_int_metrics_get(Font_Info *fi, unsigned int hint, unsigned int c, int *width, int *height, int *depth)
-{
- unsigned int idx;
- Font_Source_Info *fsi = fi->fsi;
- FT_BBox outbox;
- FT_Glyph glyph;
-
- idx = FT_Get_Char_Index(fsi->face, c);
- if (!idx)
- goto end;
-
- if (!_font_slave_glyph_load(fi, idx, hint))
- goto end;
-
- FT_Get_Glyph(fsi->face->glyph, &glyph);
- FT_Glyph_Get_CBox(glyph,
- ((hint == 0) ? FT_GLYPH_BBOX_UNSCALED :
- FT_GLYPH_BBOX_GRIDFIT),
- &outbox);
- if (width) *width = EVAS_FONT_ROUND_26_6_TO_INT(outbox.xMax - outbox.xMin);
- if (height)
- *height = EVAS_FONT_ROUND_26_6_TO_INT(outbox.yMax - outbox.xMin);
- if (depth) *depth = 1; // FIXME: Do we need to check this?
- FT_Done_Glyph(glyph);
- return;
-
-end:
- if (width) *width = 0;
- if (height) *height = 0;
- if (depth) *depth = 0;
-}
-
-static unsigned int
-_font_slave_int_shm_prev_calculate(unsigned int size, unsigned int nglyphs)
-{
- unsigned int average = size / nglyphs;
- unsigned int newsize;
-
- newsize = MIN_GLYPHS * average;
- newsize = cserve2_shm_size_normalize(newsize);
-
- if (newsize > MAX_CACHE_SIZE)
- return MAX_CACHE_SIZE;
-
- return newsize;
-}
-
-static unsigned int
-_font_slave_int_shm_calculate(Font_Info *fi, unsigned int hint)
-{
- const char *c;
- int i;
- int size = 0;
- int average;
-
- for (c = CHECK_CHARS, i = 0; *c != '\0'; c++, i++)
- {
- int w, h, depth;
- _font_slave_int_metrics_get(fi, hint, *c, &w, &h, &depth);
- size += w * h * depth;
- }
-
- average = size / i; // average glyph size
- size = MIN_GLYPHS * average;
-
- size = cserve2_shm_size_normalize(size);
-
- if (size > MAX_CACHE_SIZE)
- return MAX_CACHE_SIZE; // Assumes no glyph will be bigger than this
-
- return size;
-}
-
-static Slave_Msg_Font_Glyphs_Loaded *
-_font_slave_glyphs_load(const void *cmddata, void *data __UNUSED__)
-{
- const Slave_Msg_Font_Glyphs_Load *msg = cmddata;
- Slave_Msg_Font_Glyphs_Loaded *response;
- Font_Info *fi;
- unsigned int i;
- unsigned int total_glyphs;
- Eina_List *caches = NULL;
- Slave_Msg_Font_Cache *c = NULL;
-
- fi = msg->font.ftdata2;
-
- _font_slave_size_use(fi);
-
- if (msg->cache.shm)
- {
- c = malloc(sizeof(*c) + sizeof(Slave_Msg_Glyph) *
- (msg->glyphs.nglyphs));
- c->nglyphs = 0;
- c->glyphs = (void *)(c + 1);
- c->shm = msg->cache.shm;
- c->usage = msg->cache.usage;
- caches = eina_list_append(caches, c);
- total_glyphs = msg->cache.nglyphs;
- }
-
- if (!fi->shmsize)
- fi->shmsize = _font_slave_int_shm_calculate(fi, msg->font.hint);
-
- i = 0;
-
- while (i < msg->glyphs.nglyphs)
- {
- Eina_Bool r = EINA_TRUE;
-
- if (!c)
- {
- Shm_Handle *shm;
- shm = _font_slave_memory_alloc(fi);
- c = malloc(sizeof(*c) + sizeof(Slave_Msg_Glyph) *
- (msg->glyphs.nglyphs - i));
- c->nglyphs = 0;
- c->glyphs = (void *)(c + 1);
- c->shm = shm;
- c->usage = 0;
- caches = eina_list_append(caches, c);
- total_glyphs = 0;
- }
-
- if (_font_slave_glyph_load(fi, msg->glyphs.glyphs[i], msg->font.hint))
- r = _font_slave_glyph_render(fi, c, msg->glyphs.glyphs[i]);
- if (!r) // SHM is full
- {
- fi->shmsize = _font_slave_int_shm_prev_calculate
- (c->usage, total_glyphs);
- c = NULL;
- continue;
- }
- i++;
- total_glyphs++;
- }
-
- response = malloc(sizeof(*response) +
- sizeof(c) * eina_list_count(caches));
- response->ncaches = eina_list_count(caches);
- response->caches = (void *)(response + 1);
-
- i = 0;
- EINA_LIST_FREE(caches, c)
- response->caches[i++] = c;
-
- return response;
-}
-
void *
cserve2_font_slave_cb(Slave_Thread_Data *sd __UNUSED__, Slave_Command *cmd, const void *cmddata, void *data)
{
response = _font_slave_load(cmddata, data);
break;
case FONT_GLYPHS_LOAD:
- response = _font_slave_glyphs_load(cmddata, data);
+ // command for FONT_GLYPHS_LOAD
break;
default:
ERR("Invalid command for font slave: %d", *cmd);
error = FT_Init_FreeType(&cserve2_ft_lib);
if (error) return;
-
-#ifdef BUILD_FONT_LOADER_EET
- eet_init();
-#endif
}
void
FT_Done_FreeType(cserve2_ft_lib);
cserve2_ft_lib = 0;
-
-#ifdef BUILD_FONT_LOADER_EET
- eet_shutdown();
-#endif
-}
-
-void
-cserve2_font_source_ft_free(void *fontsource)
-{
- Font_Source_Info *fsi = fontsource;
-
- FT_Done_Face(fsi->face);
- free(fsi->data);
- free(fsi);
-}
-
-void
-cserve2_font_ft_free(void *fontinfo)
-{
- Font_Info *fi = fontinfo;
-
- FT_Done_Size(fi->size);
- free(fi);
}
static Eina_Inlist *slaves_idle = NULL;
static Eina_Inlist *slaves_working = NULL;
+struct _Glyph_Request {
+ unsigned int index;
+ unsigned int offset;
+};
+
+typedef struct _Glyph_Request Glyph_Request;
+
void
cserve2_client_error_send(Client *client, unsigned int rid, int error_code)
{
EINA_INLIST_GET(sw));
sw->data = data;
- sw->done = EINA_FALSE;
DBG("Dispatching command '%d' to slave '%p'", cmd, sw->slave);
cserve2_slave_send(sw->slave, cmd, msg, size);
return EINA_TRUE;
_cserve2_client_font_load(Client *client)
{
Msg_Font_Load *msg = (Msg_Font_Load *)client->msg.buf;
- char name[PATH_MAX], source[PATH_MAX], *buf;
+ char name[PATH_MAX];
- buf = ((char *)msg) + sizeof(*msg);
- memcpy(source, buf, msg->sourcelen);
- buf += msg->sourcelen;
- memcpy(name, buf, msg->pathlen);
+ memcpy(name, msg + 1, msg->pathlen);
INF("Received %s command: RID=%d",
(msg->base.type == CSERVE2_FONT_LOAD) ? "FONT_LOAD" : "FONT_UNLOAD",
msg->base.rid);
- INF("Font: %s, rend_flags: %d, size: %d, dpi: %d",
- name, msg->rend_flags, msg->size, msg->dpi);
+ INF("Font: %s, rend_flags: %d, hint: %d, size: %d, dpi: %d",
+ name, msg->rend_flags, msg->hint, msg->size, msg->dpi);
- if (msg->base.type == CSERVE2_FONT_LOAD)
- cserve2_cache_font_load(client, source, msg->sourcelen, name,
- msg->pathlen, msg->rend_flags, msg->size,
- msg->dpi, msg->base.rid);
- else
- cserve2_cache_font_unload(client, source, msg->sourcelen, name,
- msg->pathlen, msg->rend_flags, msg->size,
- msg->dpi, msg->base.rid);
+ cserve2_cache_font_load(client, name, msg->pathlen, msg->rend_flags,
+ msg->hint, msg->size, msg->dpi, msg->base.rid);
}
static void
_cserve2_client_font_glyphs_request(Client *client)
{
Msg_Font_Glyphs_Request *msg = (Msg_Font_Glyphs_Request *)client->msg.buf;
- char source[PATH_MAX], fontpath[PATH_MAX], *buf;
- unsigned int *glyphs;
+ char fontpath[PATH_MAX];
+ Glyph_Request *glyphs;
+ unsigned int i;
+ const char *bufpos = client->msg.buf;
- buf = ((char *)msg) + sizeof(*msg);
- memcpy(source, buf, msg->sourcelen);
- buf += msg->sourcelen;
- memcpy(fontpath, buf, msg->pathlen);
- buf += msg->pathlen;
+ memcpy(fontpath, msg + 1, msg->pathlen);
+ bufpos = bufpos + sizeof(msg) + msg->pathlen;
glyphs = malloc(sizeof(*glyphs) * msg->nglyphs);
- memcpy(glyphs, buf, sizeof(*glyphs) * msg->nglyphs);
+
+ for (i = 0; i < msg->nglyphs; i++)
+ {
+ memcpy(&glyphs[i], bufpos, sizeof(*glyphs));
+ bufpos += sizeof(*glyphs);
+ }
if (msg->base.type == CSERVE2_FONT_GLYPHS_LOAD)
{
INF("Received CSERVE2_FONT_GLYPHS_LOAD command: RID=%d",
msg->base.rid);
- cserve2_cache_font_glyphs_load(client, source, msg->sourcelen,
- fontpath, msg->pathlen,
- msg->hint, msg->rend_flags, msg->size,
- msg->dpi, glyphs, msg->nglyphs,
- msg->base.rid);
}
else
{
INF("Received CSERVE2_FONT_GLYPHS_USED command: RID=%d",
msg->base.rid);
- cserve2_cache_font_glyphs_used(client, source, msg->sourcelen,
- fontpath, msg->pathlen,
- msg->hint, msg->rend_flags, msg->size,
- msg->dpi, glyphs, msg->nglyphs,
- msg->base.rid);
}
}
-static void
-_cserve2_client_stats_request(Client *client)
-{
- Msg_Base *msg = (Msg_Base *)client->msg.buf;
- cserve2_cache_stats_get(client, msg->rid);
-}
-
-static void
-_cserve2_client_font_debug_request(Client *client)
-{
- Msg_Base *msg = (Msg_Base *)client->msg.buf;
- cserve2_cache_font_debug(client, msg->rid);
-}
-
void
cserve2_command_run(Client *client, Message_Type type)
{
case CSERVE2_FONT_GLYPHS_USED:
_cserve2_client_font_glyphs_request(client);
break;
- case CSERVE2_STATS:
- _cserve2_client_stats_request(client);
- break;
- case CSERVE2_FONT_DEBUG:
- _cserve2_client_font_debug_request(client);
- break;
default:
WRN("Unhandled message");
}
Fd_Flags flags;
Fd_Watch_Cb callback;
const void *user_data;
- Eina_Bool deleted : 1;
};
typedef struct _Watch_Data Watch_Data;
static int inotify_fd = -1;
static struct sockaddr_un socket_local;
static Eina_Hash *watch_list;
-static Eina_List *deleted_watch_list;
static Eina_Hash *inotify_path_hash;
static Eina_Hash *inotify_id_hash;
static Eina_Bool running;
static void
_watch_data_free_cb(void *data)
{
- Watch_Data *wd = data;
- wd->deleted = EINA_TRUE;
- deleted_watch_list = eina_list_append(deleted_watch_list, wd);
+ free(data);
}
Eina_Bool
void
cserve2_main_loop_finish(void)
{
- Watch_Data *wd;
-
_socketfd_finish();
_signalfd_finish();
_inotifyfd_finish();
eina_hash_free(watch_list);
- EINA_LIST_FREE(deleted_watch_list, wd)
- free(wd);
close(epoll_fd);
}
{
struct epoll_event events[MAX_EPOLL_EVENTS];
int n, nfds;
- Watch_Data *data;
if (terminate)
break;
for (n = 0; n < nfds; n++)
{
- data = events[n].data.ptr;
+ Watch_Data *data = events[n].data.ptr;
Fd_Flags flags = 0;
if (!data)
continue;
- if (data->deleted)
- continue;
-
if (!data->callback)
continue;
data->callback(data->fd, flags, (void *)data->user_data);
}
- EINA_LIST_FREE(deleted_watch_list, data)
- free(data);
-
_update_timeout();
}
{
{ CSERVE2_REQ_FONT_LOAD, SLAVE_FONT, FONT_LOAD },
{ CSERVE2_REQ_FONT_GLYPHS_LOAD, SLAVE_FONT, FONT_GLYPHS_LOAD },
- { CSERVE2_REQ_LAST, 0, 0 }
+ { CSERVE2_REQ_LAST, 0 }
};
static Slave *_create_image_slave(void *data);
struct _Request_Queue
{
Eina_Inlist *waiting;
- Eina_Inlist *processing; // TODO: Check if is there any use for this list.
+ Eina_Inlist *processing;
};
typedef struct _Request_Queue Request_Queue;
static Request_Queue *requests = NULL;
// static Eina_List *processing = NULL;
-static void _cserve2_requests_process(void);
-
static void
_request_waiter_add(Font_Request *req, Client *client, unsigned int rid)
{
}
Font_Request *
-cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request_Funcs *funcs __UNUSED__, void *data)
+cserve2_request_add(Font_Request_Type type, unsigned int rid, Client *client, Font_Request_Funcs *funcs, void *data)
{
Font_Request *req, *r;
req = NULL;
- /* Check if this request was already being processed. */
EINA_INLIST_FOREACH(requests[type].processing, r)
{
- if (r->data != data)
+ if (r->data == data)
continue;
req = r;
break;
}
- /* Check if this request was already waiting to be processed. */
if (!req)
{
EINA_INLIST_FOREACH(requests[type].waiting, r)
}
}
- /* create new request */
if (!req)
{
DBG("Add request for rid: %d", rid);
req = malloc(sizeof(*req));
- req->type = type;
req->data = data;
req->waiters = NULL;
req->processing = EINA_FALSE;
- req->funcs = funcs;
requests[type].waiting = eina_inlist_append(requests[type].waiting,
EINA_INLIST_GET(req));
}
_request_waiter_add(req, client, rid);
- _cserve2_requests_process();
-
return req;
}
void
-cserve2_request_waiter_add(Font_Request *req, unsigned int rid, Client *client)
-{
- _request_waiter_add(req, client, rid);
-}
-
-void
cserve2_request_cancel(Font_Request *req, Client *client, Error_Type err)
{
Eina_List *l, *l_next;
// TODO: When we have speculative preload, there may be no waiters,
// so we need a flag or something else to make things still load.
- if ((!req->waiters) && (!req->processing))
+ if (!req->waiters)
{
Eina_Inlist **reqlist = &requests[req->type].waiting;
*reqlist = eina_inlist_remove(*reqlist, EINA_INLIST_GET(req));
// TODO: If the request is being processed, it can't be deleted. Must
// be marked as delete_me instead.
- req->funcs->msg_free(req->msg, req->data);
+ req->funcs->msg_free(req->msg);
free(req);
}
free(w);
}
- if (req->processing)
- return;
-
requests[req->type].waiting = eina_inlist_remove(
requests[req->type].waiting, EINA_INLIST_GET(req));
- req->funcs->msg_free(req->msg, req->data);
+ req->funcs->msg_free(req->msg);
free(req);
}
free(w);
}
- req->funcs->msg_free(req->msg, req->data);
+ req->funcs->msg_free(req->msg);
requests[req->type].processing = eina_inlist_remove(
requests[req->type].processing, EINA_INLIST_GET(req));
free(req);
free(w);
}
- req->funcs->msg_free(req->msg, req->data);
+ req->funcs->msg_free(req->msg);
// FIXME: We shouldn't free this message directly, it must be freed by a
// callback.
free(msg);
idle = &_workers[sw->type].idle;
*working = eina_list_remove(*working, sw);
*idle = eina_list_append(*idle, sw);
-
- _cserve2_requests_process();
}
static void
int size;
char *slave_msg = req->funcs->msg_create(req->data, &size);
-
- DBG("dispatching message of type %d to slave.", req->type);
if (!slave_msg)
{
ERR("Could not create slave message for request type %d.", req->type);
return EINA_TRUE;
}
-static void
-_cserve2_requests_process(void)
+void
+cserve2_requests_process(void)
{
- unsigned int rtype, j;
+ int rtype, j;
for (rtype = 0; rtype < CSERVE2_REQ_LAST; rtype++)
{
for (j = 0; _request_match[j].rtype != CSERVE2_REQ_LAST; j++)
{
- if (_request_match[j].rtype == rtype)
+ if (_request_match[j].rtype == j)
{
type = _request_match[j].stype;
ctype = _request_match[j].ctype;
idle = &_workers[type].idle;
working = &_workers[type].working;
- while (requests[rtype].waiting &&
+ while (requests[j].waiting &&
(eina_list_count(*working) < max_workers))
{
Slave_Worker *sw;
off_t image_offset;
size_t map_size;
size_t image_size;
- int refcount;
- void *data;
};
static int id = 0;
-size_t
-cserve2_shm_size_normalize(size_t size)
-{
- long pagesize;
- size_t normalized;
-
- pagesize = sysconf(_SC_PAGESIZE);
- if (pagesize < 1)
- {
- ERR("sysconf() reported weird value for PAGESIZE, assuming 4096.");
- pagesize = 4096;
- }
-
- normalized = ((size + pagesize - 1) / pagesize) * pagesize;
-
- return normalized;
-}
-
Shm_Handle *
cserve2_shm_request(size_t size)
{
Shm_Handle *shm;
char shmname[NAME_MAX];
size_t map_size;
+ long pagesize;
int fd;
map = calloc(1, sizeof(Shm_Mapping));
}
} while (fd == -1);
- map_size = cserve2_shm_size_normalize(size);
+ pagesize = sysconf(_SC_PAGESIZE);
+ if (pagesize < 1)
+ {
+ ERR("sysconf() reported weird value for PAGESIZE, assuming 4096.");
+ pagesize = 4096;
+ }
+
+ map_size = ((size + pagesize - 1) / pagesize) * pagesize;
if (ftruncate(fd, map_size) == -1)
{
Shm_Mapping *map = shm->mapping;
map->segments = eina_inlist_remove(map->segments, EINA_INLIST_GET(shm));
-
- if (shm->data)
- munmap(shm->data, shm->image_size);
free(shm);
if (map->segments)
{
return shm->image_size;
}
-
-void *
-cserve2_shm_map(Shm_Handle *shm)
-{
- int fd;
- const char *name;
-
- if (shm->refcount++)
- return shm->data;
-
- name = cserve2_shm_name_get(shm);
-
- fd = shm_open(name, O_RDWR, S_IWUSR);
- if (fd == -1)
- return MAP_FAILED;
-
- shm->data = mmap(NULL, shm->image_size, PROT_WRITE, MAP_SHARED,
- fd, shm->image_offset);
-
- close(fd);
-
- return shm->data;
-}
-
-void
-cserve2_shm_unmap(Shm_Handle *shm)
-{
- if (--shm->refcount)
- return;
-
- munmap(shm->data, shm->image_size);
- shm->data = NULL;
-}
return response_send(fd, ERROR, &err, sizeof(Error_Type));
}
-static void *
-_cserve2_shm_map(const char *name, size_t length, off_t offset)
+void *
+cserve2_shm_map(const char *name, size_t length, off_t offset)
{
void *map;
int fd;
return map;
}
-static void
-_cserve2_shm_unmap(void *map, size_t length)
+void
+cserve2_shm_unmap(void *map, size_t length)
{
munmap(map, length);
}
Evas_Loader_Module_Api *api;
int err;
Error_Type ret = CSERVE2_NONE;
- char *map = _cserve2_shm_map(shmfile, params->shm.mmap_size,
- params->shm.mmap_offset);
+ char *map = cserve2_shm_map(shmfile, params->shm.mmap_size,
+ params->shm.mmap_offset);
if (map == MAP_FAILED)
return CSERVE2_RESOURCE_ALLOCATION_FAILED;
result->alpha_sparse = ilp.alpha_sparse;
done:
- _cserve2_shm_unmap(map, params->shm.mmap_size);
+ cserve2_shm_unmap(map, params->shm.mmap_size);
return ret;
}
if (n != sizeof(cmd))
{
- ERR("Slave thread read invalid size of command from server: %zu",
+ ERR("Slave thread read invalid size of command from server: %d",
n);
continue;
}
+++ /dev/null
-#include "config.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <Eina.h>
-
-#include "evas_cs2.h"
-
-static int socketfd = -1;
-static unsigned int _rid_count = 1;
-static int _evas_cserve2_usage_log_dom = -1;
-
-static struct sockaddr_un socksize;
-#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX sizeof(socksize.sun_path)
-#endif
-
-#ifdef ERR
-#undef ERR
-#endif
-#define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_usage_log_dom, __VA_ARGS__)
-#ifdef DBG
-#undef DBG
-#endif
-#define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_usage_log_dom, __VA_ARGS__)
-#ifdef WRN
-#undef WRN
-#endif
-#define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_usage_log_dom, __VA_ARGS__)
-#ifdef INF
-#undef INF
-#endif
-#define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_usage_log_dom, __VA_ARGS__)
-
-static void
-_socket_path_set(char *path)
-{
- char *env;
- char buf[UNIX_PATH_MAX];
-
- env = getenv("EVAS_CSERVE2_SOCKET");
- if (env && env[0])
- {
- strncpy(path, env, UNIX_PATH_MAX - 1);
- return;
- }
-
- snprintf(buf, sizeof(buf), "/tmp/.evas-cserve2-%x.socket", (int)getuid());
- /* FIXME: check we can actually create this socket */
- strcpy(path, buf);
-}
-
-static Eina_Bool
-_server_connect(void)
-{
- int s, len;
- struct sockaddr_un remote;
-
- if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- {
- ERR("socket");
- return EINA_FALSE;
- }
-
- remote.sun_family = AF_UNIX;
- _socket_path_set(remote.sun_path);
- len = strlen(remote.sun_path) + sizeof(remote.sun_family);
- if (connect(s, (struct sockaddr *)&remote, len) == -1)
- {
- ERR("connect");
- return EINA_FALSE;
- }
-
- fcntl(s, F_SETFL, O_NONBLOCK);
-
- socketfd = s;
-
- DBG("connected to cserve2 server.");
- return EINA_TRUE;
-}
-
-static void
-_server_disconnect(void)
-{
- close(socketfd);
- socketfd = -1;
-}
-
-static Eina_Bool
-_server_send(const void *data, int size)
-{
- int sent = 0;
- ssize_t ret;
- const char *msg = data;
-
- while (sent < size)
- {
- ret = send(socketfd, msg + sent, size - sent, MSG_NOSIGNAL);
- if (ret < 0)
- {
- if ((errno == EAGAIN) || (errno == EINTR))
- continue;
- return EINA_FALSE;
- }
- sent += ret;
- }
-
- return EINA_TRUE;
-}
-
-static int sr_size = 0;
-static int sr_got = 0;
-static char *sr_buf = NULL;
-
-static void *
-_server_read(int *size)
-{
- int n;
- void *ret;
-
- if (sr_size)
- goto get_data;
-
- n = recv(socketfd, &sr_size, sizeof(sr_size), 0);
- if (n < 0)
- return NULL;
-
- sr_buf = malloc(sr_size);
-
-get_data:
- n = recv(socketfd, sr_buf + sr_got, sr_size - sr_got, 0);
- if (n < 0)
- return NULL;
-
- sr_got += n;
- if (sr_got < sr_size)
- return NULL;
-
- *size = sr_size;
- sr_size = 0;
- sr_got = 0;
- ret = sr_buf;
- sr_buf = NULL;
-
- return ret;
-}
-
-static void
-_usage_msg_send(void)
-{
- Msg_Base msg;
- int size;
-
- memset(&msg, 0, sizeof(msg));
- msg.type = CSERVE2_STATS;
- msg.rid = _rid_count++;
-
- size = sizeof(msg);
-
- if (!_server_send(&size, sizeof(size)))
- {
- ERR("Could not send usage msg size to server.");
- return;
- }
- if (!_server_send(&msg, size))
- {
- ERR("Could not send usage msg body to server.");
- return;
- }
-}
-
-static void
-_usage_msg_read(void)
-{
- Msg_Stats *msg = NULL;
- int size;
-
- printf("Requesting server statistics.\n\n");
- while (!msg)
- msg = _server_read(&size);
-
- if (msg->base.type != CSERVE2_STATS)
- {
- ERR("Invalid message received from server."
- "Something went badly wrong.");
- return;
- }
-
- printf("Printing server usage.\n");
- printf("======================\n\n");
- printf("\nImage Usage Statistics:\n");
- printf("----------------------\n\n");
- printf("Image headers usage: %d bytes\n", msg->images.files_size);
- printf("Image data requested: %d kbytes\n", msg->images.requested_size / 1024);
- printf("Image data usage: %d kbytes\n", msg->images.images_size / 1024);
- printf("Image data unused: %d kbytes\n", msg->images.unused_size / 1024);
- printf("Image headers load time: %dus\n", msg->images.files_load_time);
- printf("Image headers saved time: %dus\n", msg->images.files_saved_time);
- printf("Image data load time: %dus\n", msg->images.images_load_time);
- printf("Image data saved time: %dus\n", msg->images.images_saved_time);
- printf("\nFont Usage Statistics:\n");
- printf("----------------------\n\n");
- printf("Requested usage: %d bytes\n", msg->fonts.requested_size);
- printf("Real usage: %d bytes\n", msg->fonts.real_size);
- printf("Unused size: %d bytes\n", msg->fonts.unused_size);
- printf("Fonts load time: %dus\n", msg->fonts.fonts_load_time);
- printf("Fonts used load time: %dus\n", msg->fonts.fonts_used_load_time);
- printf("Fonts used saved time: %dus\n", msg->fonts.fonts_used_saved_time);
- printf("Glyphs load time: %dus\n", msg->fonts.glyphs_load_time);
- printf("Glyphs saved time: %dus\n", msg->fonts.glyphs_saved_time);
-
- printf("\n");
-}
-
-int
-main(void)
-{
- eina_init();
-
- _evas_cserve2_usage_log_dom = eina_log_domain_register
- ("evas_cserve2_usage", EINA_COLOR_BLUE);
-
- if (!_server_connect())
- {
- ERR("Could not connect to server.");
- return -1;
- }
-
- _usage_msg_send();
-
- _usage_msg_read();
-
- _server_disconnect();
-
- eina_shutdown();
-}
unsigned short strikethrough : 1; /**< whether the character is strikethrough'ed */
unsigned short fg_extended : 1; /**< whether the extended palette is used for the foreground color */
unsigned short bg_extended : 1; /**< whether the extended palette is used for the background color */
- unsigned short double_width : 1; /**< if the codepoint is merged with the following cell to the right visually (cells must be in pairs with 2nd cell being a duplicate in all ways except codepoint is 0) */
};
/**
SUBDIRS += ../modules/engines/software_16/
EVAS_STATIC_MODULE += ../modules/engines/software_16/libevas_engine_software_16.la
endif
+if EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
+SUBDIRS += ../modules/engines/software_16_ddraw/
+EVAS_STATIC_MODULE += ../modules/engines/software_16_ddraw/libevas_engine_software_16_ddraw.la
+EVAS_STATIC_LIBADD += @evas_engine_software_16_ddraw_libs@
+endif
if EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
SUBDIRS += ../modules/engines/software_16_wince/
EVAS_STATIC_MODULE += ../modules/engines/software_16_wince/libevas_engine_software_16_wince.la
fdata = eet_read(ef, nm, &fsize);
if ((fdata) && (fsize > 0))
{
- font = evas->engine.func->font_memory_load(evas->engine.data.output, source, nm, size, fdata, fsize, wanted_rend);
+ font = evas->engine.func->font_memory_load(evas->engine.data.output, fake_name, size, fdata, fsize, wanted_rend);
free(fdata);
}
eet_close(ef);
fdata = eet_read(ef, nm, &fsize);
if ((fdata) && (fsize > 0))
{
- ok = evas->engine.func->font_memory_add(evas->engine.data.output, font, source, nm, size, fdata, fsize, wanted_rend);
+ ok = evas->engine.func->font_memory_add(evas->engine.data.output, font, fake_name, size, fdata, fsize, wanted_rend);
free(fdata);
}
eet_close(ef);
if (n1 == n2)
{
+ Evas_Object_Textblock_Node_Format *remove_format = NULL;
+ Evas_Object_Textblock_Node_Text *merge_node = NULL;
if ((cur1->pos == 0) &&
(cur2->pos == eina_ustrbuf_length_get(n1->unicode)))
{
else
{
n = _NODE_TEXT(EINA_INLIST_GET(n1)->prev);
- /* Short path */
- if (!n)
+ if (n)
+ {
+ merge_node = n;
+ remove_format = merge_node->format_node;
+ }
+ else
{
/* Clear the whole textblock - do it nicer. */
evas_object_textblock_text_markup_set(cur1->obj, "");
}
eina_ustrbuf_remove(n1->unicode, cur1->pos, cur2->pos);
_evas_textblock_cursors_update_offset(cur1, cur1->node, cur1->pos, - (cur2->pos - cur1->pos));
+ if (merge_node)
+ {
+ _evas_textblock_node_text_adjust_offsets_to_start(o, n1,
+ 0, -1);
+ _evas_textblock_nodes_merge(o, merge_node);
+ evas_textblock_cursor_set_at_format(cur1, remove_format);
+ }
}
else
{
cur->pos = 0;
}
-
- /* Force recreation of everything for textblock.
- * FIXME: We have the same thing in other places, merge it... */
- evas_textblock_cursor_paragraph_first(o->cursor);
- evas_textblock_cursor_text_append(o->cursor, "");
-
_evas_textblock_changed(o, obj);
}
typedef struct _Evas_Object_Textgrid_Rect Evas_Object_Textgrid_Rect;
typedef struct _Evas_Object_Textgrid_Text Evas_Object_Textgrid_Text;
typedef struct _Evas_Object_Textgrid_Line Evas_Object_Textgrid_Line;
-typedef struct _Evas_Textgrid_Hash_Master Evas_Textgrid_Hash_Master;
-typedef struct _Evas_Textgrid_Hash_Glyphs Evas_Textgrid_Hash_Glyphs;
-
-struct _Evas_Textgrid_Hash_Master
-{
- int next[16];
-};
-
-struct _Evas_Textgrid_Hash_Glyphs
-{
- Evas_Text_Props props[256];
-};
struct _Evas_Object_Textgrid
{
Evas_Font_Size font_size;
Evas_Font_Description *font_description;
- Eina_Array palette_standard;
- Eina_Array palette_extended;
+ Eina_Array *palette_standard;
+ Eina_Array *palette_extended;
} cur, prev;
int max_ascent;
Evas_Font_Set *font;
- Evas_Textgrid_Hash_Master *master;
- Evas_Textgrid_Hash_Glyphs *glyphs;
- unsigned char *master_used;
- unsigned char *glyphs_used;
- unsigned int master_length;
- unsigned int glyphs_length;
-
- unsigned int last_mask;
- Evas_Textgrid_Hash_Glyphs *last_glyphs;
-
- Eina_Array glyphs_cleanup;
-
unsigned int changed : 1;
unsigned int core_change : 1;
unsigned int row_change : 1;
{
unsigned char r, g, b, a;
int x;
- unsigned int text_props;
+ Evas_Text_Props text_props;
};
struct _Evas_Object_Textgrid_Line
EVAS_MEMPOOL(_mp_obj);
-/* almost generic private array data type */
-static int
-evas_object_textgrid_textprop_get(Evas_Object *obj, Evas_Object_Textgrid *o, Eina_Unicode codepoint,
- unsigned int glyphs_index, unsigned char *used)
-{
- Evas_Textgrid_Hash_Glyphs *glyph;
- unsigned char idx = codepoint & 0xFF;
-
- glyph = &(o->glyphs[glyphs_index]);
-
- if (!glyph->props[idx].info)
- {
- Evas_Font_Instance *script_fi = NULL;
- Evas_Font_Instance *cur_fi = NULL;
- Evas_Script_Type script;
-
- script = evas_common_language_script_type_get(&codepoint, 1);
- ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi, script, &codepoint, 1);
- memset(&(glyph->props[idx]), 0, sizeof(Evas_Text_Props));
- evas_common_text_props_script_set(&(glyph->props[idx]), script);
- ENFN->font_text_props_info_create(ENDT, script_fi, &codepoint,
- &(glyph->props[idx]), NULL, 0, 1,
- EVAS_TEXT_PROPS_MODE_NONE);
- (*used)++;
- }
- else
- {
- evas_common_text_props_content_ref(&(glyph->props[idx]));
- }
-
- return glyphs_index << 8 | (unsigned int) idx;
-}
-
-static int
-evas_object_textgrid_textprop_ref(Evas_Object *obj, Evas_Object_Textgrid *o, Eina_Unicode codepoint)
-{
- unsigned int mask = 0xF0000000;
- unsigned int shift = 28;
- unsigned int offset = 0;
- unsigned int glyphs_index;
-
- if (o->last_glyphs)
- {
- if (o->last_mask && (o->last_mask & codepoint) == o->last_mask)
- goto end;
- }
-
- if (!o->master)
- {
- o->master = calloc(6, sizeof (Evas_Textgrid_Hash_Master));
- o->master_used = calloc(6, sizeof (unsigned char));
- o->glyphs = calloc(1, sizeof (Evas_Textgrid_Hash_Glyphs));
- o->glyphs_used = calloc(1, sizeof (unsigned char));
- if (!o->master_used)
- {
- free(o->master);
- o->master = NULL;
- free(o->master_used);
- o->master_used = NULL;
- free(o->glyphs);
- o->glyphs = NULL;
- free(o->glyphs_used);
- o->glyphs_used = NULL;
- return 0xFFFFFFFF;
- }
-
- while (shift > 8)
- {
- o->master[offset].next[(mask & codepoint) >> shift] = offset + 1;
- o->master_used[offset] = 1;
- offset++;
- shift -= 4;
- mask >>= 4;
- }
-
- o->glyphs_length = 1;
- o->master_length = 6;
- o->master[5].next[(codepoint & 0xF00) >> 8] = 0xFF000000;
- o->last_glyphs = o->glyphs;
- o->last_mask = codepoint & 0xFFFFFF00;
-
- goto end;
- }
-
- while (shift > 8
- && o->master[offset].next[(codepoint & mask) >> shift] != 0)
- {
- offset = o->master[offset].next[(codepoint & mask) >> shift];
- mask >>= 4;
- shift -= 4;
- }
-
- if (shift > 8)
- {
- Evas_Textgrid_Hash_Master *tmp;
- unsigned char *tmp_used;
- int master_count;
- int count;
- int end;
-
- count = (shift - 8) / 4;
- master_count = o->master_length + count;
-
- /* FIXME: find empty entry */
- tmp = realloc(o->master, master_count * sizeof (Evas_Textgrid_Hash_Master));
- if (!tmp) return 0xFFFFFFFF;
- o->master = tmp;
- tmp_used = realloc(o->master_used, master_count);
- if (!tmp_used) return 0xFFFFFFFF;
- o->master_used = tmp_used;
-
- memset(o->master + o->master_length, 0, count * sizeof (Evas_Textgrid_Hash_Master));
- memset(o->master_used + o->master_length, 1, count);
- end = o->master_length;
- o->master_length = master_count;
-
- while (shift > 8)
- {
- o->master[offset].next[(mask & codepoint) >> shift] = end;
- o->master_used[offset] = 1;
- end++;
- offset = end;
- shift -= 4;
- mask >>= 4;
- }
- offset--;
- }
- if (o->master[offset].next[(codepoint & mask) >> shift] == 0)
- {
- Evas_Textgrid_Hash_Glyphs *tmp;
- unsigned char *tmp_used;
- int count;
-
- /* FIXME: find empty entry */
- count = o->glyphs_length + 1;
- tmp = realloc(o->glyphs, count * sizeof (Evas_Textgrid_Hash_Glyphs));
- if (!tmp) return 0xFFFFFFFF;
- o->glyphs = tmp;
- tmp_used = realloc(o->glyphs_used, count * sizeof (unsigned char));
- if (!tmp_used) return 0xFFFFFFFF;
- o->glyphs_used = tmp_used;
-
- o->master[offset].next[(codepoint & mask) >> shift] = o->glyphs_length + 0xFF000000;
-
- memset(o->glyphs + o->glyphs_length, 0, sizeof (Evas_Textgrid_Hash_Glyphs));
- o->glyphs_used[o->glyphs_length] = 0;
- o->glyphs_length = count;
- }
-
- o->last_glyphs = o->glyphs + (o->master[offset].next[(codepoint & mask) >> shift] & 0xFFFFFF);
- o->last_mask = codepoint & 0xFFFFFF00;
-
- end:
- glyphs_index = o->last_glyphs - o->glyphs;
- return evas_object_textgrid_textprop_get(obj, o, codepoint, glyphs_index,
- &(o->glyphs_used[glyphs_index]));
-}
-
-static void
-evas_object_textgrid_textprop_unref(Evas_Object_Textgrid *o, unsigned int props_index)
-{
- Evas_Text_Props *props;
-
- props = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
-
- if (props->info)
- {
- if (props->info->refcount == 1)
- eina_array_push(&o->glyphs_cleanup, (intptr_t*)(int64_t) props_index);
- else
- evas_common_text_props_content_unref(props);
- }
-}
-
-static Evas_Text_Props *
-evas_object_textgrid_textprop_int_to(Evas_Object_Textgrid *o, int props)
-{
- return &(o->glyphs[props >> 8].props[props & 0xFF]);
-}
-
/* all nice and private */
static void
evas_object_textgrid_init(Evas_Object *obj)
EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Textgrid);
o->magic = MAGIC_OBJ_TEXTGRID;
o->prev = o->cur;
- eina_array_step_set(&o->cur.palette_standard, sizeof (Eina_Array), 16);
- eina_array_step_set(&o->cur.palette_extended, sizeof (Eina_Array), 16);
- eina_array_step_set(&o->glyphs_cleanup, sizeof (Eina_Array), 16);
+ o->cur.palette_standard = eina_array_new(16);
+ o->cur.palette_extended = eina_array_new(16);
return o;
}
static void
-evas_object_textgrid_row_clear(Evas_Object_Textgrid *o, Evas_Object_Textgrid_Row *r)
+evas_object_textgrid_row_clear(Evas_Object_Textgrid_Row *r)
{
int i;
if (r->texts)
{
for (i = 0; i < r->texts_num; i++)
- if (r->texts[i].text_props != 0xFFFFFFFF)
- {
- evas_object_textgrid_textprop_unref(o, r->texts[i].text_props);
- r->texts[i].text_props = 0xFFFFFFFF;
- }
+ evas_common_text_props_content_unref(&(r->texts[i].text_props));
free(r->texts);
r->texts = NULL;
r->texts_num = 0;
if (!o->cur.rows) return;
for (i = 0; i < o->cur.h; i++)
{
- evas_object_textgrid_row_clear(o, &(o->cur.rows[i]));
+ evas_object_textgrid_row_clear(&(o->cur.rows[i]));
o->cur.rows[i].ch1 = 0;
o->cur.rows[i].ch2 = o->cur.w - 1;
}
static void
evas_object_textgrid_free(Evas_Object *obj)
{
- Evas_Object_Textgrid_Color *c;
Evas_Object_Textgrid *o;
+ unsigned int i;
/* frees private object data. very simple here */
o = (Evas_Object_Textgrid *)(obj->object_data);
if (o->cur.font_description) evas_font_desc_unref(o->cur.font_description);
if (o->font) evas_font_free(obj->layer->evas, o->font);
if (o->cur.cells) free(o->cur.cells);
- while ((c = eina_array_pop(&o->cur.palette_standard)))
- free(c);
- eina_array_flush(&o->cur.palette_standard);
- while ((c = eina_array_pop(&o->cur.palette_extended)))
- free(c);
- eina_array_flush(&o->cur.palette_extended);
-
- while (eina_array_count(&o->glyphs_cleanup) > 0)
- {
- Evas_Text_Props *prop;
- unsigned int props_index;
-
- props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
- prop = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
-
- evas_common_text_props_content_unref(prop);
- if (!prop->info)
- {
- o->glyphs_used[props_index >> 8]--;
-
- if (!o->glyphs_used[props_index >> 8])
- {
- /* FIXME: cleanup the master tree */
- }
- }
- }
- eina_array_flush(&o->glyphs_cleanup);
-
- free(o->master);
- free(o->glyphs);
- free(o->master_used);
- free(o->glyphs_used);
-
+ for (i = 0; i < eina_array_count(o->cur.palette_standard); i++)
+ free(eina_array_data_get(o->cur.palette_standard, i));
+ eina_array_free(o->cur.palette_standard);
+ for (i = 0; i < eina_array_count(o->cur.palette_extended); i++)
+ free(eina_array_data_get(o->cur.palette_extended, i));
+ eina_array_free(o->cur.palette_extended);
o->magic = 0;
/* FIXME: using evas mempool like text ? */
EVAS_MEMPOOL_FREE(_mp_obj, o);
static void
evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object *obj, Evas_Object_Textgrid *o, int x, Eina_Unicode codepoint, int r, int g, int b, int a)
{
+ Evas_Script_Type script;
+ Evas_Font_Instance *script_fi = NULL;
+ Evas_Font_Instance *cur_fi = NULL;
+
row->texts_num++;
if (row->texts_num > row->texts_alloc)
{
}
row->texts = t;
}
-
- row->texts[row->texts_num - 1].text_props = evas_object_textgrid_textprop_ref(obj, o, codepoint);
+
+ script = evas_common_language_script_type_get(&codepoint, 1);
+ ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
+ script, &codepoint, 1);
+ memset(&(row->texts[row->texts_num - 1].text_props), 0,
+ sizeof(Evas_Text_Props));
+ evas_common_text_props_script_set
+ (&(row->texts[row->texts_num - 1].text_props), script);
+ ENFN->font_text_props_info_create
+ (ENDT, script_fi, &codepoint,
+ &(row->texts[row->texts_num - 1].text_props), NULL, 0, 1,
+ EVAS_TEXT_PROPS_MODE_NONE);
row->texts[row->texts_num - 1].x = x;
row->texts[row->texts_num - 1].r = r;
row->texts[row->texts_num - 1].g = g;
row->ch1 = -1;
row->ch2 = 0;
run = 0;
- xp = 0;
+ xp = obj->cur.geometry.x;
for (xx = 0; xx < o->cur.w; xx++, cells++)
{
- if (cells->bg_extended) palette = &(o->cur.palette_extended);
- else palette = &(o->cur.palette_standard);
- if (cells->bg >= eina_array_count(palette)) c = NULL;
- else c = eina_array_data_get(palette, cells->bg);
+ if (cells->bg_extended) palette = o->cur.palette_extended;
+ else palette = o->cur.palette_standard;
+ c = eina_array_data_get(palette, cells->bg);
if ((c) && (c->a > 0))
{
if (!run)
}
if (cells->codepoint > 0)
{
- if (cells->fg_extended) palette = &(o->cur.palette_extended);
- else palette = &(o->cur.palette_standard);
- if (cells->fg >= eina_array_count(palette)) c = NULL;
- else c = eina_array_data_get(palette, cells->fg);
+ if (cells->fg_extended) palette = o->cur.palette_extended;
+ else palette = o->cur.palette_standard;
+ c = eina_array_data_get(palette, cells->fg);
if ((c) && (c->a > 0))
{
evas_object_textgrid_row_text_append(row, obj, o, xp,
// XXX: underlines and strikethroughs dont get
// merghed into horizontal runs like bg rects above
if (cells->underline)
- evas_object_textgrid_row_line_append(row, xp, w,
+ evas_object_textgrid_row_line_append(row, rx, rw,
o->max_ascent + 1,
- c->r, c->g, c->b, c->a);
+ rr, rg, rb, ra);
if (cells->strikethrough)
- evas_object_textgrid_row_line_append(row, xp, w,
+ evas_object_textgrid_row_line_append(row, rx, rw,
((3 * o->max_ascent) / 4),
- c->r, c->g, c->b, c->a);
+ rr, rg, rb, ra);
}
}
xp += w;
row->texts[xx].b, row->texts[xx].a);
ENFN->font_draw(output, context, surface, o->font,
xp + row->texts[xx].x, yp + o->max_ascent,
- ww, hh, ww, hh,
- evas_object_textgrid_textprop_int_to(o, row->texts[xx].text_props));
+ ww, hh, ww, hh, &(row->texts[xx].text_props));
}
for (xx = 0; xx < row->lines_num; xx++)
{
row->lines[xx].b, row->lines[xx].a);
ENFN->rectangle_draw(output, context, surface,
xp + row->lines[xx].x, yp + row->lines[xx].y,
- row->lines[xx].w, 1);
+ row->lines[xx].w, h);
}
yp += h;
}
}
if (o->pal_change)
{
- evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
- goto done;
+ unsigned int i;
+
+ if (eina_array_count(o->cur.palette_standard) != eina_array_count(o->prev.palette_standard))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ for (i = 0; i < eina_array_count(o->cur.palette_standard); i++)
+ {
+ Evas_Object_Textgrid_Color *c_cur;
+ Evas_Object_Textgrid_Color *c_prev;
+
+ c_cur = eina_array_data_get(o->cur.palette_standard, i);
+ c_prev = eina_array_data_get(o->prev.palette_standard, i);
+ if ((c_cur->a != c_prev->a) ||
+ (c_cur->r != c_prev->r) ||
+ (c_cur->g != c_prev->g) ||
+ (c_cur->b != c_prev->b))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ }
+ if (eina_array_count(o->cur.palette_extended) != eina_array_count(o->prev.palette_extended))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ for (i = 0; i < eina_array_count(o->cur.palette_extended); i++)
+ {
+ Evas_Object_Textgrid_Color *c_cur;
+ Evas_Object_Textgrid_Color *c_prev;
+
+ c_cur = eina_array_data_get(o->cur.palette_extended, i);
+ c_prev = eina_array_data_get(o->prev.palette_extended, i);
+ if ((c_cur->a != c_prev->a) ||
+ (c_cur->r != c_prev->r) ||
+ (c_cur->g != c_prev->g) ||
+ (c_cur->b != c_prev->b))
+ {
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, obj);
+ goto done;
+ }
+ }
}
if (o->row_change)
{
obj->prev = obj->cur;
o->prev = o->cur;
o->changed = 0;
-
- while (eina_array_count(&o->glyphs_cleanup) > 0)
- {
- Evas_Text_Props *prop;
- unsigned int props_index;
-
- props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
- prop = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
-
- evas_common_text_props_content_unref(prop);
- if (!prop->info)
- {
- o->glyphs_used[props_index >> 8]--;
-
- if (!o->glyphs_used[props_index >> 8])
- {
- /* FIXME: cleanup the master tree */
- }
- }
- }
}
static unsigned int
Evas_Font_Instance *cur_fi = NULL;
Evas_Text_Props text_props;
Evas_Script_Type script;
- int advance, vadvance;
script = evas_common_language_script_type_get(W, 1);
ENFN->font_run_end_get(ENDT, o->font, &script_fi, &cur_fi,
ENFN->font_string_size_get(ENDT, o->font, &text_props,
&o->cur.char_width, &o->cur.char_height);
o->max_ascent = ENFN->font_max_ascent_get(ENDT, o->font);
-// inset = ENFN->font_inset_get(ENDT, o->font, &text_props);
- advance = ENFN->font_h_advance_get(ENDT, o->font, &text_props);
- vadvance = ENFN->font_v_advance_get(ENDT, o->font, &text_props);
- if (advance > o->cur.char_width) o->cur.char_width = advance;
- if (vadvance > o->cur.char_height) o->cur.char_height = vadvance;
evas_common_text_props_content_unref(&text_props);
}
else
o->core_change = 1;
evas_object_textgrid_rows_clear(obj);
evas_object_change(obj);
-
- /* Force destroy of all cached Evas_Text_Props */
- while (eina_array_count(&o->glyphs_cleanup) > 0)
- {
- Evas_Text_Props *prop;
- unsigned int props_index;
-
- props_index = (unsigned int) (intptr_t) eina_array_pop(&o->glyphs_cleanup);
- prop = &(o->glyphs[props_index >> 8].props[props_index & 0xFF]);
-
- evas_common_text_props_content_unref(prop);
- if (!prop->info)
- {
- o->glyphs_used[props_index >> 8]--;
-
- if (!o->glyphs_used[props_index >> 8])
- {
- /* FIXME: cleanup the master tree */
- }
- }
- }
}
EAPI void
switch (pal)
{
case EVAS_TEXTGRID_PALETTE_STANDARD:
- palette = &(o->cur.palette_standard);
+ palette = o->cur.palette_standard;
break;
case EVAS_TEXTGRID_PALETTE_EXTENDED:
- palette = &(o->cur.palette_extended);
+ palette = o->cur.palette_extended;
break;
default:
return;
}
- count = eina_array_count(palette);
- if (idx < count)
- {
- color = eina_array_data_get(palette, idx);
- if (color->a == a &&
- color->r == r &&
- color->g == g &&
- color->b == b)
- return ;
- }
- else
- {
- color = malloc(sizeof(Evas_Object_Textgrid_Color));
- if (!color) return;
- }
+ color = malloc(sizeof(Evas_Object_Textgrid_Color));
+ if (!color) return;
color->a = a;
color->r = r;
color->g = g;
color->b = b;
+ count = eina_array_count(palette);
if (idx < count) eina_array_data_set(palette, idx, color);
else if (idx == count) eina_array_push(palette, color);
else
switch (pal)
{
case EVAS_TEXTGRID_PALETTE_STANDARD:
- palette = &(o->cur.palette_standard);
+ palette = o->cur.palette_standard;
break;
case EVAS_TEXTGRID_PALETTE_EXTENDED:
- palette = &(o->cur.palette_extended);
+ palette = o->cur.palette_extended;
break;
default:
return;
if (r->ch1 < 0)
{
- evas_object_textgrid_row_clear(o, r);
+ evas_object_textgrid_row_clear(r);
r->ch1 = x;
r->ch2 = x2;
}
if EVAS_CSERVE2
-noinst_LTLIBRARIES = libevas_cserve2.la libevas_cserve2_utils.la
+noinst_LTLIBRARIES = libevas_cserve2.la
libevas_cserve2_la_SOURCES = \
evas_cs2.h \
evas_cs2_image_data.c \
evas_cs2_client.c
-libevas_cserve2_utils_la_SOURCES = \
-evas_cs2_utils.h \
-evas_cs2_utils.c
-
-libevas_cserve2_la_LIBADD = @EINA_LIBS@ libevas_cserve2_utils.la
+libevas_cserve2_la_LIBADD = @EINA_LIBS@
endif
CSERVE2_FONT_GLYPHS_LOAD,
CSERVE2_FONT_GLYPHS_LOADED,
CSERVE2_FONT_GLYPHS_USED,
- CSERVE2_STATS,
- CSERVE2_FONT_DEBUG,
CSERVE2_ERROR
} Message_Type;
*/
struct _Msg_Font_Load {
Msg_Base base;
- unsigned int sourcelen; // font id
unsigned int pathlen; // font id
unsigned int rend_flags; // font id
+ unsigned int hint; // font id
unsigned int size; // font id
unsigned int dpi; // font id
};
/**
* @struct _Msg_Font_Glyphs_Request
*
- * Message from client to request load of glyphs, or inform usage of them.
+ * Message from client to request load of glyphs, of inform usage of them.
*
* The path strings follow the struct inside the message, as well as
* the list of glyphs to be loaded.
*/
struct _Msg_Font_Glyphs_Request {
Msg_Base base;
- unsigned int sourcelen; // font id
unsigned int pathlen; // font id
unsigned int rend_flags; // font id
+ unsigned int hint; // font id
unsigned int size; // font id
unsigned int dpi; // font id
- unsigned int hint;
unsigned int nglyphs;
};
* - struct {
* unsigned int index;
* unsigned int offset;
- * unsigned int size;
- * unsigned int rows;
- * unsigned int width;
- * unsigned int pitch;
- * unsigned int num_grays;
- * unsigned int pixel_mode;
* } glarray[];
*/
struct _Msg_Font_Glyphs_Loaded {
unsigned int ncaches;
};
-struct _Msg_Stats {
- Msg_Base base;
- struct {
- unsigned int requested_size;
- unsigned int real_size;
- unsigned int unused_size;
- unsigned int fonts_loaded; /* number of loaded fonts */
- unsigned int fonts_unused; /* number of loaded fonts without reference
- * from any clients */
- int fonts_load_time; /* total time spent loading fonts */
- int fonts_used_load_time; /* total time spent loading fonts that are
- * really used, i.e. fonts that have glyphs
- * rendered */
- int fonts_used_saved_time;
- int glyphs_load_time; /* total time spent loading glyphs */
- int glyphs_saved_time; /* total time spent loading glyphs */
- } fonts;
- struct {
- unsigned int files_loaded; /* number of file headers loaded */
- unsigned int images_loaded; /* number of image data loaded */
- unsigned int images_unused; /* number of image data loaded and unused */
-
- unsigned int requested_size; /* memory usage originally requested by
- * the client */
- unsigned int files_size; /* memory usage from image headers */
- unsigned int images_size; /* memory usage from image data */
- unsigned int unused_size; /* memory usage from image data */
-
- int files_load_time;
- int files_saved_time;
- int images_load_time;
- int images_saved_time;
- } images;
-};
-
-/*
- * @struct _Msg_Font_Debug
- *
- * Message from server containing all font cache info.
- *
- * Content of the message follows:
- *
- * * number of font entries;
- * * each font entry:
- * - unsigned int filelen
- * - const char file
- * - unsigned int namelen
- * - const char name
- * - unsigned int rend_flags;
- * - unsigned int size;
- * - unsigned int dpi;
- * - unsigned int unused;
- * - ncaches:
- * - each cache:
- * * usigned int shmnamelen;
- * * const char shmname;
- * * unsigned int size;
- * * unsigned int usage;
- * * unsigned int nglyphs;
- * * each glyph:
- * - unsigned int index;
- * - unsigned int offset;
- * - unsigned int size;
- * - unsigned int rows;
- * - unsigned int width;
- * - unsigned int pitch;
- * - unsigned int num_grays;
- * - unsigned int pixel_mode;
- */
-struct _Msg_Font_Debug {
- Msg_Base base;
-};
-
struct _Msg_Error {
Msg_Base base;
int error;
typedef struct _Msg_Font_Loaded Msg_Font_Loaded;
typedef struct _Msg_Font_Glyphs_Request Msg_Font_Glyphs_Request;
typedef struct _Msg_Font_Glyphs_Loaded Msg_Font_Glyphs_Loaded;
-typedef struct _Msg_Stats Msg_Stats;
-typedef struct _Msg_Font_Debug Msg_Font_Debug;
typedef struct _Msg_Error Msg_Error;
#endif
#include "evas_cs2.h"
#include "evas_cs2_private.h"
-#include "evas_cs2_utils.h"
#ifdef EVAS_CSERVE2
}
static Eina_Bool
-_server_safe_send(int fd, const void *data, int size)
-{
- int sent = 0;
- ssize_t ret;
- const char *msg = data;
-
- while (sent < size)
- {
- ret = send(fd, msg + sent, size - sent, MSG_NOSIGNAL);
- if (ret < 0)
- {
- if ((errno == EAGAIN) || (errno == EINTR))
- continue;
- return EINA_FALSE;
- }
- sent += ret;
- }
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
_server_send(const void *buf, int size, Op_Callback cb, void *data)
{
const Msg_Base *msg;
- if (!_server_safe_send(socketfd, &size, sizeof(size)))
+ if (send(socketfd, &size, sizeof(size), MSG_NOSIGNAL) == -1)
{
ERR("Couldn't send message size to server.");
return EINA_FALSE;
}
- if (!_server_safe_send(socketfd, buf, size))
+ if (send(socketfd, buf, size, MSG_NOSIGNAL) == -1)
{
ERR("Couldn't send message body to server.");
return EINA_FALSE;
case CSERVE2_SETOPTS:
case CSERVE2_LOAD:
case CSERVE2_PRELOAD:
- case CSERVE2_FONT_LOAD:
- case CSERVE2_FONT_GLYPHS_LOAD:
_request_answer_add(msg->type, msg->rid, cb, data);
break;
default:
{
_server_dispatch_until(0);
}
-
-typedef struct _Glyph_Map Glyph_Map;
-typedef struct _CS_Glyph_Out CS_Glyph_Out;
-
-struct _Font_Entry
-{
- const char *source;
- const char *name;
- unsigned int size;
- unsigned int dpi;
- Font_Rend_Flags wanted_rend;
-
- unsigned int rid; // open
-
- Eina_Hash *glyphs_maps;
- Fash_Glyph2 *fash[3]; // one per hinting value
-
- Eina_Clist glyphs_queue;
- int glyphs_queue_count;
- Eina_Clist glyphs_used;
- int glyphs_used_count;
-
- Eina_Bool failed : 1;
-};
-
-struct _Glyph_Map
-{
- Font_Entry *fe;
- const char *name;
- unsigned int size;
- Eina_File *map;
- unsigned char *data;
- Eina_Clist glyphs;
-};
-
-struct _CS_Glyph_Out
-{
- RGBA_Font_Glyph_Out base;
- Eina_Clist map_entry;
- Eina_Clist used_list;
- unsigned int idx;
- unsigned int rid;
- Glyph_Map *map;
- unsigned int offset;
- unsigned int size;
- Eina_Bool used;
-};
-
-static void
-_font_entry_free(Font_Entry *fe)
-{
- int i;
-
- for (i = 0; i < 3; i++)
- if (fe->fash[i])
- fash_gl_free(fe->fash[i]);
-
- eina_stringshare_del(fe->source);
- eina_stringshare_del(fe->name);
- eina_hash_free(fe->glyphs_maps);
- free(fe);
-}
-
-static void
-_glyphs_map_free(Glyph_Map *m)
-{
- eina_file_map_free(m->map, m->data);
- eina_file_close(m->map);
- eina_stringshare_del(m->name);
- free(m);
-}
-
-static void
-_glyph_out_free(void *gl)
-{
- CS_Glyph_Out *glout = gl;
-
- if (glout->map)
- {
- eina_clist_remove(&glout->map_entry);
- if (eina_clist_empty(&glout->map->glyphs))
- {
- eina_hash_del(glout->map->fe->glyphs_maps, &glout->map->name,
- NULL);
- _glyphs_map_free(glout->map);
- }
- }
-
- free(glout);
-}
-
-static void
-_font_loaded_cb(void *data, const void *msg)
-{
- const Msg_Base *m = msg;
- Font_Entry *fe = data;
-
- fe->rid = 0;
-
- if (m->type == CSERVE2_ERROR)
- fe->failed = EINA_TRUE;
-}
-
-static unsigned int
-_font_load_server_send(Font_Entry *fe, Message_Type type)
-{
- Msg_Font_Load *msg;
- int source_len, path_len, size;
- char *buf;
- unsigned int ret = 0;
- void (*cb)(void *data, const void *msg) = NULL;
-
- if (!cserve2_init)
- return 0;
-
- source_len = fe->source ? eina_stringshare_strlen(fe->source) + 1 : 0;
- path_len = eina_stringshare_strlen(fe->name) + 1;
-
- size = sizeof(*msg) + path_len + source_len;
- msg = calloc(1, size);
-
- msg->base.rid = _next_rid();
- msg->base.type = type;
-
- msg->sourcelen = source_len;
- msg->pathlen = path_len;
- msg->rend_flags = fe->wanted_rend;
- msg->size = fe->size;
- msg->dpi = fe->dpi;
-
- buf = ((char *)msg) + sizeof(*msg);
- memcpy(buf, fe->source, source_len);
- buf += source_len;
- memcpy(buf, fe->name, path_len);
-
- if (type == CSERVE2_FONT_LOAD)
- cb = _font_loaded_cb;
-
- if (_server_send(msg, size, cb, fe))
- ret = msg->base.rid;
-
- free(msg);
-
- return ret;
-}
-
-Font_Entry *
-evas_cserve2_font_load(const char *source, const char *name, int size, int dpi, Font_Rend_Flags wanted_rend)
-{
- Font_Entry *fe;
-
- fe = calloc(1, sizeof(Font_Entry));
- if (!fe) return NULL;
-
- fe->source = source ? eina_stringshare_add(source) : NULL;
- fe->name = eina_stringshare_add(name);
- fe->size = size;
- fe->dpi = dpi;
- fe->wanted_rend = wanted_rend;
-
- if (!(fe->rid = _font_load_server_send(fe, CSERVE2_FONT_LOAD)))
- {
- eina_stringshare_del(fe->source);
- eina_stringshare_del(fe->name);
- free(fe);
- return NULL;
- }
-
- fe->glyphs_maps = eina_hash_stringshared_new(NULL);
- eina_clist_init(&fe->glyphs_queue);
- eina_clist_init(&fe->glyphs_used);
-
- return fe;
-}
-
-void
-evas_cserve2_font_free(Font_Entry *fe)
-{
- if (!fe) return;
-
- if (fe->failed)
- return;
-
- _font_load_server_send(fe, CSERVE2_FONT_UNLOAD);
-
- _font_entry_free(fe);
-}
-
-typedef struct
-{
- Font_Entry *fe;
- Font_Hint_Flags hints;
- unsigned int rid;
-} Glyph_Request_Data;
-
-static void
-_glyph_request_cb(void *data, const void *msg)
-{
- const Msg_Font_Glyphs_Loaded *resp = msg;
- Glyph_Request_Data *grd = data;
- Font_Entry *fe = grd->fe;
- unsigned int ncaches = 0;
- const char *buf;
-
- if (resp->base.type == CSERVE2_ERROR)
- {
- free(grd);
- return;
- }
-
- buf = (const char *)resp + sizeof(*resp);
- while (ncaches < resp->ncaches)
- {
- int i = 0, nglyphs;
- int namelen;
- const char *name;
- Glyph_Map *map;
-
- memcpy(&namelen, buf, sizeof(int));
- buf += sizeof(int);
-
- name = eina_stringshare_add_length(buf, namelen);
- buf += namelen;
-
- memcpy(&nglyphs, buf, sizeof(int));
- buf += sizeof(int);
-
- map = eina_hash_find(fe->glyphs_maps, name);
- if (!map)
- {
- map = calloc(1, sizeof(*map));
- map->fe = fe;
- map->name = name;
- map->map = eina_file_open(name, EINA_TRUE);
- map->data = eina_file_map_all(map->map, EINA_FILE_WILLNEED);
- eina_clist_init(&map->glyphs);
- eina_hash_direct_add(fe->glyphs_maps, &map->name, map);
- }
- else
- eina_stringshare_del(name);
-
- while (i < nglyphs)
- {
- unsigned int idx, offset, glsize;
- int rows, width, pitch, num_grays, pixel_mode;
- CS_Glyph_Out *gl;
-
- memcpy(&idx, buf, sizeof(int));
- buf += sizeof(int);
- memcpy(&offset, buf, sizeof(int));
- buf += sizeof(int);
- memcpy(&glsize, buf, sizeof(int));
- buf += sizeof(int);
- memcpy(&rows, buf, sizeof(int));
- buf += sizeof(int);
- memcpy(&width, buf, sizeof(int));
- buf += sizeof(int);
- memcpy(&pitch, buf, sizeof(int));
- buf += sizeof(int);
- memcpy(&num_grays, buf, sizeof(int));
- buf += sizeof(int);
- memcpy(&pixel_mode, buf, sizeof(int));
- buf += sizeof(int);
-
- gl = fash_gl_find(fe->fash[grd->hints], idx);
- gl->map = map;
- gl->offset = offset;
- gl->size = glsize;
- gl->base.bitmap.rows = rows;
- gl->base.bitmap.width = width;
- gl->base.bitmap.pitch = pitch;
- gl->base.bitmap.buffer = map->data + gl->offset;
- gl->base.bitmap.num_grays = num_grays;
- gl->base.bitmap.pixel_mode = pixel_mode;
-
- gl->rid = 0;
-
- eina_clist_add_head(&map->glyphs, &gl->map_entry);
-
- i++;
- }
-
- ncaches++;
- }
-
- free(grd);
-}
-
-static unsigned int
-_glyph_request_server_send(Font_Entry *fe, Font_Hint_Flags hints, Eina_Bool used)
-{
- Msg_Font_Glyphs_Request *msg;
- Glyph_Request_Data *grd = NULL;
- int source_len, name_len, size, nglyphs;
- char *buf;
- unsigned int *glyphs;
- unsigned int ret = 0;
- Op_Callback cb;
- Eina_Clist *queue, *itr, *itr_next;
-
-
- source_len = fe->source ? eina_stringshare_strlen(fe->source) + 1 : 0;
- name_len = eina_stringshare_strlen(fe->name) + 1;
-
- if (!used)
- {
- nglyphs = fe->glyphs_queue_count;
- queue = &fe->glyphs_queue;
- }
- else
- {
- nglyphs = fe->glyphs_used_count;
- queue = &fe->glyphs_used;
- }
-
- size = sizeof(*msg) + source_len + name_len + (nglyphs * sizeof(int));
- msg = calloc(1, size);
-
- msg->base.rid = _next_rid();
- if (!used)
- msg->base.type = CSERVE2_FONT_GLYPHS_LOAD;
- else
- msg->base.type = CSERVE2_FONT_GLYPHS_USED;
-
- msg->sourcelen = source_len;
- msg->pathlen = name_len;
- msg->rend_flags = fe->wanted_rend;
- msg->size = fe->size;
- msg->dpi = fe->dpi;
- msg->hint = hints;
- msg->nglyphs = nglyphs;
-
- buf = ((char *)msg) + sizeof(*msg);
- memcpy(buf, fe->source, source_len);
- buf += source_len;
- memcpy(buf, fe->name, name_len);
- buf += name_len;
- glyphs = (unsigned int *)buf;
- nglyphs = 0;
- EINA_CLIST_FOR_EACH_SAFE(itr, itr_next, queue)
- {
- CS_Glyph_Out *gl;
-
- if (!used)
- {
- gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, map_entry);
- gl->rid = msg->base.rid;
- eina_clist_remove(&gl->map_entry);
- }
- else
- {
- gl = EINA_CLIST_ENTRY(itr, CS_Glyph_Out, used_list);
- gl->used = EINA_FALSE;
- eina_clist_remove(&gl->used_list);
- }
- glyphs[nglyphs++] = gl->idx;
- }
- if (!used)
- fe->glyphs_queue_count = 0;
- else
- fe->glyphs_used_count = 0;
-
- if (!used)
- {
- cb = _glyph_request_cb;
- grd = malloc(sizeof(*grd));
- grd->fe = fe;
- grd->rid = msg->base.rid;
- grd->hints = hints;
- }
- else
- cb = NULL;
-
- if (_server_send(msg, size, cb, grd))
- ret = msg->base.rid;
- else
- free(grd);
-
- free(msg);
-
- return ret;
-}
-
-Eina_Bool
-evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints)
-{
- Fash_Glyph2 *fash;
- CS_Glyph_Out *glyph;
-
- if (fe->rid)
- _server_dispatch_until(fe->rid);
-
- if (fe->failed)
- return EINA_FALSE;
-
- fash = fe->fash[hints];
- if (!fash)
- {
- fash = fash_gl_new(_glyph_out_free);
- fe->fash[hints] = fash;
- }
-
- glyph = fash_gl_find(fash, idx);
- if (!glyph)
- {
- glyph = calloc(1, sizeof(*glyph));
-
- glyph->idx = idx;
-
- fash_gl_add(fash, idx, glyph);
-
- eina_clist_add_head(&fe->glyphs_queue, &glyph->map_entry);
- fe->glyphs_queue_count++;
- }
- else if (!glyph->used)
- {
- eina_clist_add_head(&fe->glyphs_used, &glyph->used_list);
- fe->glyphs_used_count++;
- glyph->used = EINA_TRUE;
- }
-
- /* crude way to manage a queue, but it will work for now */
- if (fe->glyphs_queue_count == 50)
- _glyph_request_server_send(fe, hints, EINA_FALSE);
-
- return EINA_TRUE;
-}
-
-Eina_Bool
-evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints)
-{
- Fash_Glyph2 *fash;
- CS_Glyph_Out *glyph;
-
- if (fe->rid)
- _server_dispatch_until(fe->rid);
-
- if (fe->failed)
- return EINA_FALSE;
-
- fash = fe->fash[hints];
- if (!fash)
- return EINA_FALSE;
-
- glyph = fash_gl_find(fash, idx);
- /* If we found the glyph on client cache, we should also have at least
- * its request done.
- */
- if (!glyph)
- return EINA_FALSE;
-
- if (!glyph->map)
- return EINA_TRUE;
-
- if (glyph->used)
- return EINA_TRUE;
-
- eina_clist_add_head(&fe->glyphs_used, &glyph->used_list);
- fe->glyphs_used_count++;
- glyph->used = EINA_TRUE;
-
- return EINA_TRUE;
-}
-
-RGBA_Font_Glyph_Out *
-evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints)
-{
- Fash_Glyph2 *fash;
- CS_Glyph_Out *out;
-
- if (fe->failed)
- return NULL;
-
- /* quick hack, flush pending queue when we are asked for a bitmap */
- if (fe->glyphs_queue_count)
- _glyph_request_server_send(fe, hints, EINA_FALSE);
-
- if (fe->glyphs_used_count)
- _glyph_request_server_send(fe, hints, EINA_TRUE);
-
- fash = fe->fash[hints];
- if (!fash)
- {
- // this should not happen really, so let the user know he fucked up
- system("format c:");
- return NULL;
- }
-
- out = fash_gl_find(fash, idx);
- if (!out)
- {
- // again, if we are asking for a bitmap we were supposed to already
- // have requested the glyph, it must be there
- return NULL;
- }
- if (out->rid)
- _server_dispatch_until(out->rid);
-
- // promote shm and font entry in lru or something
-
- return &(out->base);
-}
-
#endif
};
typedef struct _Data_Entry Data_Entry;
-typedef struct _Font_Entry Font_Entry;
int evas_cserve2_init(void);
int evas_cserve2_shutdown(void);
void evas_cserve2_dispatch(void);
void *evas_cserve2_image_data_get(Image_Entry *ie);
-
-Font_Entry *evas_cserve2_font_load(const char *source, const char *name, int size, int dpi, Font_Rend_Flags wanted_rend);
-void evas_cserve2_font_free(Font_Entry *fe);
-Eina_Bool evas_cserve2_font_glyph_request(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
-Eina_Bool evas_cserve2_font_glyph_used(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
-RGBA_Font_Glyph_Out *evas_cserve2_font_glyph_bitmap_get(Font_Entry *fe, unsigned int idx, Font_Hint_Flags hints);
#endif
+++ /dev/null
-/* THIS FILE TO BE SHARED WITH THE BIN PART. KEEP IT CLEAN. THERE BE DRAGONS */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <Eina.h>
-
-#include "evas_cs2_utils.h"
-
-/* fash */
-typedef struct _Fash_Glyph_Map Fash_Glyph_Map;
-typedef struct _Fash_Glyph_Map2 Fash_Glyph_Map2;
-
-struct _Fash_Glyph_Map
-{
- void *item[256];
-};
-
-struct _Fash_Glyph_Map2
-{
- Fash_Glyph_Map *bucket[256];
-};
-
-struct _Fash_Glyph2
-{
- Fash_Glyph_Map2 *bucket[256];
- void (*free_cb)(void *glyph);
-};
-
-static void
-_fash_item_free(Fash_Glyph2 *fash, Fash_Glyph_Map *map)
-{
- int i;
-
- if (fash->free_cb)
- for (i = 0; i < 256; i++)
- if (map->item[i])
- fash->free_cb(map->item[i]);
- free(map);
-}
-
-static void
-_fash_gl2_free(Fash_Glyph2 *fash, Fash_Glyph_Map2 *fash2)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- if (fash2->bucket[i]) _fash_item_free(fash, fash2->bucket[i]);
- free(fash2);
-}
-
-void
-fash_gl_free(Fash_Glyph2 *fash)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- if (fash->bucket[i]) _fash_gl2_free(fash, fash->bucket[i]);
- free(fash);
-}
-
-Fash_Glyph2 *
-fash_gl_new(void (*free_cb)(void *glyph))
-{
- Fash_Glyph2 *fash = calloc(1, sizeof(Fash_Glyph2));
- fash->free_cb = free_cb;
- return fash;
-}
-
-void *
-fash_gl_find(Fash_Glyph2 *fash, int item)
-{
- int grp, maj, min;
-
- // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
- grp = (item >> 16) & 0xff;
- maj = (item >> 8) & 0xff;
- min = item & 0xff;
- if (!fash->bucket[grp]) return NULL;
- if (!fash->bucket[grp]->bucket[maj]) return NULL;
- return fash->bucket[grp]->bucket[maj]->item[min];
-}
-
-void
-fash_gl_add(Fash_Glyph2 *fash, int item, void *glyph)
-{
- int grp, maj, min;
-
- // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
- grp = (item >> 16) & 0xff;
- maj = (item >> 8) & 0xff;
- min = item & 0xff;
- if (!fash->bucket[grp])
- fash->bucket[grp] = calloc(1, sizeof(Fash_Glyph_Map2));
- EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]);
- if (!fash->bucket[grp]->bucket[maj])
- fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Glyph_Map));
- EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]);
- fash->bucket[grp]->bucket[maj]->item[min] = glyph;
-}
-
-void
-fash_gl_del(Fash_Glyph2 *fash, int item)
-{
- int grp, maj, min;
- void *data;
-
- // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
- grp = (item >> 16) & 0xff;
- maj = (item >> 8) & 0xff;
- min = item & 0xff;
- if (!fash->bucket[grp]) return;
- if (!fash->bucket[grp]->bucket[maj]) return;
- if (!fash->bucket[grp]->bucket[maj]->item[min]) return;
-
- data = fash->bucket[grp]->bucket[maj]->item[min];
- fash->free_cb(data);
- fash->bucket[grp]->bucket[maj]->item[min] = NULL;
-}
+++ /dev/null
-/* THIS FILE TO BE SHARED WITH THE BIN PART. KEEP IT CLEAN. THERE BE DRAGONS */
-#ifndef _EVAS_CSERVE2_UTILS_H_
-#define _EVAS_CSERVE2_UTILS_H_
-
-typedef struct _Fash_Glyph2 Fash_Glyph2;
-
-Fash_Glyph2 *fash_gl_new(void (*free_cb)(void *glyph));
-void fash_gl_free(Fash_Glyph2 *fash);
-void *fash_gl_find(Fash_Glyph2 *fash, int item);
-void fash_gl_add(Fash_Glyph2 *fash, int item, void *glyph);
-void fash_gl_del(Fash_Glyph2 *fash, int item);
-
-#endif /* EVAS_CSERVE2_UTILS_H_ */
EAPI RGBA_Font_Int *evas_common_font_int_load (const char *name, int size, Font_Rend_Flags wanted_rend);
EAPI RGBA_Font_Int *evas_common_font_int_load_init (RGBA_Font_Int *fn);
EAPI RGBA_Font_Int *evas_common_font_int_load_complete (RGBA_Font_Int *fi);
-EAPI RGBA_Font *evas_common_font_memory_load (const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend);
+EAPI RGBA_Font *evas_common_font_memory_load (const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend);
EAPI RGBA_Font *evas_common_font_load (const char *name, int size, Font_Rend_Flags wanted_rend);
EAPI RGBA_Font *evas_common_font_add (RGBA_Font *fn, const char *name, int size, Font_Rend_Flags wanted_rend);
-EAPI RGBA_Font *evas_common_font_memory_add (RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend);
+EAPI RGBA_Font *evas_common_font_memory_add (RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend);
EAPI void evas_common_font_free (RGBA_Font *fn);
-EAPI void evas_common_font_int_unref (RGBA_Font_Int *fi);
EAPI void evas_common_font_hinting_set (RGBA_Font *fn, Font_Hint_Flags hinting);
EAPI Eina_Bool evas_common_hinting_available (Font_Hint_Flags hinting);
-EAPI RGBA_Font *evas_common_font_memory_hinting_load (const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend);
+EAPI RGBA_Font *evas_common_font_memory_hinting_load (const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend);
EAPI RGBA_Font *evas_common_font_hinting_load (const char *name, int size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend);
EAPI RGBA_Font *evas_common_font_hinting_add (RGBA_Font *fn, const char *name, int size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend);
-EAPI RGBA_Font *evas_common_font_memory_hinting_add (RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend);
+EAPI RGBA_Font *evas_common_font_memory_hinting_add (RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend);
EAPI void evas_common_font_int_modify_cache_by (RGBA_Font_Int *fi, int dir);
EAPI int evas_common_font_cache_get (void);
EAPI void evas_common_font_cache_set (int size);
#define EVAS_FONT_WALK_IS_VISIBLE (_glyph_itr->index != 0)
#define EVAS_FONT_WALK_X_BEAR (_glyph_itr->x_bear)
-#define EVAS_FONT_WALK_Y_BEAR (_glyph_itr->y_bear)
+#define EVAS_FONT_WALK_Y_BEAR (fg->glyph_out->top)
#define EVAS_FONT_WALK_X_ADV ((_glyph_itr > text_props->info->glyph) ? \
_glyph_itr->pen_after - (_glyph_itr - 1)->pen_after : \
_glyph_itr->pen_after)
#include "evas_font_ot.h"
+struct prword
+{
+ EINA_INLIST;
+ struct cinfo *cinfo;
+ Evas_Text_Props text_props;
+ DATA8 *im;
+ int roww;
+ int width;
+ int height;
+ int baseline;
+};
+
+struct cinfo
+{
+ FT_UInt index;
+ struct
+ {
+ int x, y;
+ } pos;
+ int posx;
+ RGBA_Font_Glyph *fg;
+ struct
+ {
+ int w,h;
+ int rows;
+ unsigned char *data;
+ } bm;
+};
+
typedef struct _Evas_Glyph Evas_Glyph;
struct _Evas_Glyph
{
length = eina_binbuf_length_get(text_props->bin) / sizeof (Evas_Glyph);
for (it = 0; it < length; ++it)
{
+ FT_UInt idx;
RGBA_Font_Glyph *fg;
int chr_x, chr_y;
fg = glyphs[it].fg;
-
- glyphs[it].coord.w = fg->glyph_out->bitmap.width;
- glyphs[it].coord.h = fg->glyph_out->bitmap.rows;
- glyphs[it].j = fg->glyph_out->bitmap.pitch;
- glyphs[it].data = fg->glyph_out->bitmap.buffer;
+ idx = glyphs[it].idx;
if (dc->font_ext.func.gl_new)
{
w = glyphs[it].coord.w;
if (j < w) j = w;
h = glyphs[it].coord.h;
+ /*
+ if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
+ && (fg->glyph_out->bitmap.num_grays == 256)
+ )
+ */
#ifdef HAVE_PIXMAN
# ifdef PIXMAN_FONT
evas_common_font_draw_prepare(Evas_Text_Props *text_props)
{
RGBA_Font_Int *fi;
- RGBA_Font_Glyph *fg;
EVAS_FONT_WALK_TEXT_INIT();
fi = text_props->font_instance;
EVAS_FONT_WALK_TEXT_START()
{
Evas_Glyph glyph;
+ RGBA_Font_Glyph *fg;
FT_UInt idx;
if (!EVAS_FONT_WALK_IS_VISIBLE) continue;
glyph.fg = fg;
glyph.coord.x = EVAS_FONT_WALK_PEN_X + EVAS_FONT_WALK_X_OFF + EVAS_FONT_WALK_X_BEAR;
glyph.coord.y = EVAS_FONT_WALK_PEN_Y + EVAS_FONT_WALK_Y_OFF + EVAS_FONT_WALK_Y_BEAR;
+ glyph.coord.w = fg->glyph_out->bitmap.width;
+ glyph.coord.h = fg->glyph_out->bitmap.rows;
+ glyph.j = fg->glyph_out->bitmap.pitch;
glyph.idx = idx;
+ glyph.data = fg->glyph_out->bitmap.buffer;
eina_binbuf_append_length(text_props->bin, (void*) &glyph, sizeof (Evas_Glyph));
}
EVAS_FONT_WALK_TEXT_END();
- /* check if there's a request queue in fi, if so ask cserve2 to render
- * those glyphs
- */
-
text_props->generation = fi->generation;
}
#include "evas_font_private.h" /* for Frame-Queuing support */
#include "evas_font_ot.h"
-#ifdef EVAS_CSERVE2
-# include "../../cserve2/evas_cs2_private.h"
-#endif
-
#ifdef USE_HARFBUZZ
# include <hb.h>
# include <hb-ft.h>
hb_font_destroy(fi->ft.hb_font);
#endif
evas_common_font_source_free(fi->src);
- if (fi->references <= 0) fonts_lru = eina_list_remove(fonts_lru, fi);
+ if (fi->references == 0) fonts_lru = eina_list_remove(fonts_lru, fi);
if (fi->fash) fi->fash->freeme(fi->fash);
if (fi->inuse)
{
fonts_use_usage -= fi->usage;
fi->usage = 0;
}
-#ifdef EVAS_CSERVE2
- evas_cserve2_font_free(fi->cs2_handler);
-#endif
free(fi);
}
}
EAPI RGBA_Font_Int *
-evas_common_font_int_memory_load(const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend)
+evas_common_font_int_memory_load(const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend)
{
RGBA_Font_Int *fi;
- char *fake_name;
- fake_name = evas_file_path_join(source, name);
- fi = evas_common_font_int_find(fake_name, size, wanted_rend);
- if (fi)
- {
- free(fake_name);
- return fi;
- }
+ fi = evas_common_font_int_find(name, size, wanted_rend);
+ if (fi) return fi;
fi = calloc(1, sizeof(RGBA_Font_Int));
- if (!fi)
- {
- free(fake_name);
- return NULL;
- }
- fi->src = evas_common_font_source_find(fake_name);
+ if (!fi) return NULL;
+ fi->src = evas_common_font_source_find(name);
if (!fi->src)
- fi->src = evas_common_font_source_memory_load(fake_name, data, data_size);
+ fi->src = evas_common_font_source_memory_load(name, data, data_size);
if (!fi->src)
{
free(fi);
- free(fake_name);
return NULL;
}
fi->size = size;
_evas_common_font_int_cache_init(fi);
fi = evas_common_font_int_load_init(fi);
evas_common_font_int_load_complete(fi);
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- fi->cs2_handler = evas_cserve2_font_load(source, name, size, font_dpi,
- wanted_rend);
-#endif
- free(fake_name);
return fi;
}
fi->wanted_rend = wanted_rend;
_evas_common_font_int_cache_init(fi);
fi = evas_common_font_int_load_init(fi);
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- fi->cs2_handler = evas_cserve2_font_load(NULL, name, size, font_dpi,
- wanted_rend);
-#endif
// evas_common_font_int_load_complete(fi);
return fi;
}
}
EAPI RGBA_Font *
-evas_common_font_memory_load(const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend)
+evas_common_font_memory_load(const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend)
{
RGBA_Font *fn;
RGBA_Font_Int *fi;
- fi = evas_common_font_int_memory_load(source, name, size, data, data_size,
+ fi = evas_common_font_int_memory_load(name, size, data, data_size,
wanted_rend);
if (!fi) return NULL;
fn = calloc(1, sizeof(RGBA_Font));
if (!fn)
{
- evas_common_font_int_unref(fi);
+ fi->references--;
+ if (fi->references == 0)
+ {
+ fonts_lru = eina_list_prepend(fonts_lru, fi);
+ evas_common_font_int_modify_cache_by(fi, 1);
+ evas_common_font_flush();
+ }
return NULL;
}
fn->fonts = eina_list_append(fn->fonts, fi);
{
if (evas_common_font_source_load_complete(fi->src))
{
- evas_common_font_int_unref(fi);
+ fi->references--;
+ if (fi->references == 0)
+ {
+ fonts_lru = eina_list_prepend(fonts_lru, fi);
+ evas_common_font_int_modify_cache_by(fi, 1);
+ evas_common_font_flush();
+ }
return NULL;
}
}
fn = calloc(1, sizeof(RGBA_Font));
if (!fn)
{
- evas_common_font_int_unref(fi);
+ fi->references--;
+ if (fi->references == 0)
+ {
+ fonts_lru = eina_list_prepend(fonts_lru, fi);
+ evas_common_font_int_modify_cache_by(fi, 1);
+ evas_common_font_flush();
+ }
return NULL;
}
}
EAPI RGBA_Font *
-evas_common_font_memory_add(RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend)
+evas_common_font_memory_add(RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Rend_Flags wanted_rend)
{
RGBA_Font_Int *fi;
if (!fn)
return NULL;
- fi = evas_common_font_int_memory_load(source, name, size, data, data_size, wanted_rend);
+ fi = evas_common_font_int_memory_load(name, size, data, data_size, wanted_rend);
if (fi)
{
fn->fonts = eina_list_append(fn->fonts, fi);
}
EAPI void
-evas_common_font_int_unref(RGBA_Font_Int *fi)
-{
- fi->references--;
- if (fi->references == 0)
- {
- fonts_lru = eina_list_append(fonts_lru, fi);
- evas_common_font_int_modify_cache_by(fi, 1);
- evas_common_font_flush();
- }
-}
-
-EAPI void
evas_common_font_free(RGBA_Font *fn)
{
Eina_List *l;
fn->references--;
if (fn->references > 0) return;
EINA_LIST_FOREACH(fn->fonts, l, fi)
- evas_common_font_int_unref(fi);
+ {
+ fi->references--;
+ if (fi->references == 0)
+ {
+ fonts_lru = eina_list_append(fonts_lru, fi);
+ evas_common_font_int_modify_cache_by(fi, 1);
+ }
+ }
evas_common_font_flush();
eina_list_free(fn->fonts);
if (fn->fash) fn->fash->freeme(fn->fash);
}
EAPI RGBA_Font *
-evas_common_font_memory_hinting_load(const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend)
+evas_common_font_memory_hinting_load(const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend)
{
RGBA_Font *fn;
- fn = evas_common_font_memory_load(source, name, size, data, data_size, wanted_rend);
+ fn = evas_common_font_memory_load(name, size, data, data_size, wanted_rend);
if (fn) evas_common_font_hinting_set(fn, hinting);
return fn;
}
}
EAPI RGBA_Font *
-evas_common_font_memory_hinting_add(RGBA_Font *fn, const char *source, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend)
+evas_common_font_memory_hinting_add(RGBA_Font *fn, const char *name, int size, const void *data, int data_size, Font_Hint_Flags hinting, Font_Rend_Flags wanted_rend)
{
- fn = evas_common_font_memory_add(fn, source, name, size, data, data_size,
+ fn = evas_common_font_memory_add(fn, name, size, data, data_size,
wanted_rend);
if (fn) evas_common_font_hinting_set(fn, hinting);
return fn;
return;
}
evas_common_font_int_modify_cache_by(fi, -1);
- if (fi->references <= 1)
- {
- if (fi->fash)
- {
- for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
- {
- Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k];
- if (fmap2)
+ if (fi->fash)
+ {
+ for (k = 0; k <= 0xff; k++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
+ {
+ Fash_Glyph_Map2 *fmap2 = fi->fash->bucket[k];
+ if (fmap2)
+ {
+ for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
+ {
+ Fash_Glyph_Map *fmap = fmap2->bucket[j];
+ if (fmap)
{
- for (j = 0; j <= 0xff; j++) // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
- {
- Fash_Glyph_Map *fmap = fmap2->bucket[j];
- if (fmap)
- {
- for (i = 0; i <= 0xff; i++)
- {
- RGBA_Font_Glyph *fg = fmap->item[i];
- if ((fg) && (fg != (void *)(-1)))
- {
- FT_Done_Glyph(fg->glyph);
- /* extension calls */
- if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat);
- if (fg->glyph_out_free) fg->glyph_out_free(fg->glyph_out);
- free(fg);
- fmap->item[i] = NULL;
- }
- }
- }
- }
+ for (i = 0; i <= 0xff; i++)
+ {
+ RGBA_Font_Glyph *fg = fmap->item[i];
+ if ((fg) && (fg != (void *)(-1)))
+ {
+ FT_Done_Glyph(fg->glyph);
+ /* extension calls */
+ if (fg->ext_dat_free) fg->ext_dat_free(fg->ext_dat);
+ free(fg);
+ fmap->item[i] = NULL;
+ }
+ }
}
- }
- fi->fash->freeme(fi->fash);
- fi->fash = NULL;
- }
+ }
+ }
+ }
+ fi->fash->freeme(fi->fash);
+ fi->fash = NULL;
}
if (fi->inuse) fonts_use_usage -= fi->usage;
fi->usage = 0;
#include "evas_font_private.h"
-#ifdef EVAS_CSERVE2
-# include "../../cserve2/evas_cs2_private.h"
-#endif
-
#include <assert.h>
#include FT_OUTLINE_H
fi->src->current_size = fi->size;
}
val = (int)fi->src->ft.face->size->metrics.height;
- if ((fi->src->ft.face->bbox.yMax == 0) &&
- (fi->src->ft.face->bbox.yMin == 0) &&
- (fi->src->ft.face->units_per_EM == 0))
- return val >> 6;
- else if (fi->src->ft.face->units_per_EM == 0)
+ if (fi->src->ft.face->units_per_EM == 0)
return val;
return val >> 6;
// dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
{
fg = _fash_gl_find(fi->fash, idx);
if (fg == (void *)(-1)) return NULL;
- else if (fg)
- {
-#ifdef EVAS_CSERVE2
- if (fi->cs2_handler)
- evas_cserve2_font_glyph_used(fi->cs2_handler, idx,
- fi->hinting);
-#endif
- return fg;
- }
+ else if (fg) return fg;
}
+
// fg = eina_hash_find(fi->glyphs, &hindex);
// if (fg) return fg;
{
FT_BBox outbox;
- FT_Glyph_Get_CBox(fg->glyph,
- ((fi->hinting == 0) ? FT_GLYPH_BBOX_UNSCALED :
- FT_GLYPH_BBOX_GRIDFIT),
+ FT_Glyph_Get_CBox(fg->glyph, FT_GLYPH_BBOX_UNSCALED,
&outbox);
fg->width = EVAS_FONT_ROUND_26_6_TO_INT(outbox.xMax - outbox.xMin);
fg->x_bear = EVAS_FONT_ROUND_26_6_TO_INT(outbox.xMin);
- fg->y_bear = EVAS_FONT_ROUND_26_6_TO_INT(outbox.yMax);
}
fg->index = idx;
if (!fi->fash) fi->fash = _fash_gl_new();
if (fi->fash) _fash_gl_add(fi->fash, idx, fg);
-#ifdef EVAS_CSERVE2
- if (fi->cs2_handler)
- evas_cserve2_font_glyph_request(fi->cs2_handler, idx, fi->hinting);
-#endif
-
// eina_hash_direct_add(fi->glyphs, &fg->index, fg);
return fg;
}
int size;
FT_Error error;
RGBA_Font_Int *fi = fg->fi;
- FT_BitmapGlyph fbg;
-
-#ifdef EVAS_CSERVE2
- if (fi->cs2_handler)
- {
- fg->glyph_out = evas_cserve2_font_glyph_bitmap_get(fi->cs2_handler,
- fg->index,
- fg->fi->hinting);
- if (fg->glyph_out)
- return EINA_TRUE;
- }
-#endif
-
- /* no cserve2 case */
FTLOCK();
error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
if (error)
}
FTUNLOCK();
- fbg = (FT_BitmapGlyph)fg->glyph;
-
- fg->glyph_out = malloc(sizeof(RGBA_Font_Glyph_Out));
- fg->glyph_out->bitmap.rows = fbg->bitmap.rows;
- fg->glyph_out->bitmap.width = fbg->bitmap.width;
- fg->glyph_out->bitmap.pitch = fbg->bitmap.pitch;
- fg->glyph_out->bitmap.buffer = fbg->bitmap.buffer;
- fg->glyph_out->bitmap.num_grays = fbg->bitmap.num_grays;
- fg->glyph_out->bitmap.pixel_mode = fbg->bitmap.pixel_mode;
-
- fg->glyph_out_free = free;
+ fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
/* This '+ 200' is just an estimation of how much memory freetype will use
* on it's size. This value is not really used anywhere in code - it's
* only for statistics. */
EAPI FT_UInt
evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl)
{
- static const unsigned short mapfix[] =
- {
- 0x00b0, 0x7,
- 0x00b1, 0x8,
- 0x00b7, 0x1f,
- 0x03c0, 0x1c,
- 0x20a4, 0xa3,
- 0x2260, 0x1d,
- 0x2264, 0x1a,
- 0x2265, 0x1b,
- 0x23ba, 0x10,
- 0x23bb, 0x11,
- 0x23bc, 0x13,
- 0x23bd, 0x14,
- 0x2409, 0x3,
- 0x240a, 0x6,
- 0x240b, 0xa,
- 0x240c, 0x4,
- 0x240d, 0x5,
- 0x2424, 0x9,
- 0x2500, 0x12,
- 0x2502, 0x19,
- 0x250c, 0xd,
- 0x2510, 0xc,
- 0x2514, 0xe,
- 0x2518, 0xb,
- 0x251c, 0x15,
- 0x2524, 0x16,
- 0x252c, 0x18,
- 0x2534, 0x17,
- 0x253c, 0xf,
- 0x2592, 0x2,
- 0x25c6, 0x1,
- };
Font_Char_Index result;
//FT_UInt ret;
#ifdef HAVE_PTHREAD
// pthread_mutex_unlock(&fi->ft_mutex);
#endif
- // this is a workaround freetype bugs where for a bitmap old style font
- // even if it has unicode information and mappings, they are not used
- // to find terminal line/drawing chars, so do this by hand with a table
- if ((result.index <= 0) && (fi->src->ft.face->num_fixed_sizes == 1) &&
- (fi->src->ft.face->num_glyphs < 512))
- {
- int i, min = 0, max;
-
- // binary search through sorted table of codepoints to new
- // codepoints with a guess that bitmap font is playing the old
- // game of putting line drawing chars in specific ranges
- max = sizeof(mapfix) / (sizeof(mapfix[0]) * 2);
- i = (min + max) / 2;
- for (;;)
- {
- unsigned short v;
-
- v = mapfix[i << 1];
- if (gl == v)
- {
- gl = mapfix[(i << 1) + 1];
- FTLOCK();
- result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
- FTUNLOCK();
- break;
- }
- // failure to find at all
- if ((max - min) <= 2) break;
- // if glyph above out position...
- if (gl > v)
- {
- min = i;
- if ((max - min) == 2) i = max;
- else i = (min + max) / 2;
- }
- // if glyph below out position
- else if (gl < v)
- {
- max = i;
- if ((max - min) == 2) i = min;
- else i = (min + max) / 2;
- }
- }
- }
return result.index;
}
Evas_Coord ret_adv = 0;
if (text_props->len > 0)
{
-// RGBA_Font_Int *fi = text_props->font_instance;
+ RGBA_Font_Int *fi = text_props->font_instance;
const Evas_Font_Glyph_Info *glyph = text_props->info->glyph +
text_props->start;
const Evas_Font_Glyph_Info *last_glyph = glyph + text_props->len - 1;
return;
props->info->refcount++;
- if (props->font_instance)
- ((RGBA_Font_Int *)props->font_instance)->references++;
}
void
if (!props->info)
return;
- if (props->font_instance)
- {
- evas_common_font_int_unref(props->font_instance);
- props->font_instance = NULL;
- }
-
if (--(props->info->refcount) == 0)
{
if (props->bin)
LKU(fi->ft_mutex);
gl_itr->x_bear = fg->x_bear;
- gl_itr->y_bear = fg->y_bear;
gl_itr->width = fg->width;
/* text_props->info->glyph[char_index].advance =
* text_props->info->glyph[char_index].index =
gl_itr->index = idx;
gl_itr->x_bear = fg->x_bear;
- gl_itr->y_bear = fg->y_bear;
adv = fg->glyph->advance.x >> 10;
gl_itr->width = fg->width;
}
text_props->info = calloc(1, sizeof(Evas_Text_Props_Info));
- if (text_props->font_instance != fi)
- {
- if (text_props->font_instance)
- evas_common_font_int_unref(text_props->font_instance);
- text_props->font_instance = fi;
- fi->references++;
- }
-
+ text_props->font_instance = fi;
+
evas_common_font_int_reload(fi);
if (fi->src->current_size != fi->size)
{
{
unsigned int index; /* Should conform to FT */
Evas_Coord x_bear;
+#if 0
/* This one is rarely used, only in draw, in which we already get the glyph
* so it doesn't really save time. Leaving it here just so no one will
* add it thinking it was accidentally skipped */
Evas_Coord y_bear;
+#endif
Evas_Coord width;
Evas_Coord pen_after;
};
EVAS_EINA_STATIC_MODULE_DEFINE(engine, gl_sdl);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, psl1ght);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16);
+EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_ddraw);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_sdl);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_wince);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_16_x11);
#ifdef EVAS_STATIC_BUILD_SOFTWARE_16
EVAS_EINA_STATIC_MODULE_USE(engine, software_16),
#endif
+#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
+ EVAS_EINA_STATIC_MODULE_USE(engine, software_16_ddraw),
+#endif
#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_SDL
EVAS_EINA_STATIC_MODULE_USE(engine, software_16_sdl),
#endif
#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_X11
EVAS_EINA_STATIC_MODULE_USE(engine, software_16_x11),
#endif
+#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
+ EVAS_EINA_STATIC_MODULE_USE(engine, software_ddraw),
+#endif
+#ifdef EVAS_STATIC_BUILD_SOFTWARE_16_GDI
+ EVAS_EINA_STATIC_MODULE_USE(engine, software_gdi),
+#endif
#ifdef EVAS_STATIC_BUILD_SOFTWARE_8
EVAS_EINA_STATIC_MODULE_USE(engine, software_8),
#endif
#ifdef EVAS_STATIC_BUILD_SOFTWARE_8_X11
EVAS_EINA_STATIC_MODULE_USE(engine, software_8_x11),
#endif
-#ifdef EVAS_STATIC_BUILD_SOFTWARE_DDRAW
- EVAS_EINA_STATIC_MODULE_USE(engine, software_ddraw),
-#endif
-#ifdef EVAS_STATIC_BUILD_SOFTWARE_GDI
- EVAS_EINA_STATIC_MODULE_USE(engine, software_gdi),
-#endif
#ifdef EVAS_STATIC_BUILD_SOFTWARE_GENERIC
EVAS_EINA_STATIC_MODULE_USE(engine, software_generic),
#endif
typedef struct _RGBA_Font_Int RGBA_Font_Int;
typedef struct _RGBA_Font_Source RGBA_Font_Source;
typedef struct _RGBA_Font_Glyph RGBA_Font_Glyph;
-typedef struct _RGBA_Font_Glyph_Out RGBA_Font_Glyph_Out;
typedef struct _RGBA_Gfx_Compositor RGBA_Gfx_Compositor;
typedef struct _Cutout_Rect Cutout_Rect;
in order to comply with the wanted_rend. */
Eina_List *task;
-#ifdef EVAS_CSERVE2
- void *cs2_handler;
-#endif
int generation;
} ft;
};
-/*
- * laziness wins for now. The parts used from the freetpye struct are
- * kept intact to avoid changing the code using it until we know exactly
- * what needs to be changed
- */
-struct _RGBA_Font_Glyph_Out
-{
- struct {
- int rows;
- int width;
- int pitch;
- unsigned char *buffer;
- short num_grays;
- char pixel_mode;
- } bitmap;
-};
-
struct _RGBA_Font_Glyph
{
FT_UInt index;
Evas_Coord width;
Evas_Coord x_bear;
- Evas_Coord y_bear;
FT_Glyph glyph;
- RGBA_Font_Glyph_Out *glyph_out;
- void (*glyph_out_free)(void *);
+ FT_BitmapGlyph glyph_out;
/* this is a problem - only 1 engine at a time can extend such a font... grrr */
void *ext_dat;
void (*ext_dat_free) (void *ext_dat);
int (*image_cache_get) (void *data);
Evas_Font_Set *(*font_load) (void *data, const char *name, int size, Font_Rend_Flags wanted_rend);
- Evas_Font_Set *(*font_memory_load) (void *data, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend);
+ Evas_Font_Set *(*font_memory_load) (void *data, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend);
Evas_Font_Set *(*font_add) (void *data, Evas_Font_Set *font, const char *name, int size, Font_Rend_Flags wanted_rend);
- Evas_Font_Set *(*font_memory_add) (void *data, Evas_Font_Set *font, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend);
+ Evas_Font_Set *(*font_memory_add) (void *data, Evas_Font_Set *font, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend);
void (*font_free) (void *data, Evas_Font_Set *font);
int (*font_ascent_get) (void *data, Evas_Font_Set *font);
int (*font_descent_get) (void *data, Evas_Font_Set *font);
if !EVAS_STATIC_BUILD_SOFTWARE_16
SUBDIRS += software_16
endif
+if !EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
+SUBDIRS += software_16_ddraw
+endif
if !EVAS_STATIC_BUILD_SOFTWARE_16_WINCE
SUBDIRS += software_16_wince
endif
#endif
XVisualInfo *vi_use;
const GLubyte *vendor, *renderer, *version;
- int blacklist = 0;
if (!_evas_gl_x11_vi) return NULL;
fprintf(stderr, "renderer: %s\n", renderer);
fprintf(stderr, "version: %s\n", version);
}
-
- if (strstr((const char *)vendor, "Mesa Project"))
- {
- if (strstr((const char *)renderer, "Software Rasterizer"))
- blacklist = 1;
- }
- if (strstr((const char *)renderer, "softpipe"))
- blacklist = 1;
- if (blacklist)
- {
- ERR("OpenGL Driver blacklisted:");
- ERR("Vendor: %s", (const char *)vendor);
- ERR("Renderer: %s", (const char *)renderer);
- ERR("Version: %s", (const char *)version);
- eng_window_free(gw);
- return NULL;
- }
// GLX
#else
if (!context)
{
int i, j, num;
GLXFBConfig *fbc;
+ int blacklist = 0;
if (gw->glxwin)
{
--- /dev/null
+#ifndef __EVAS_ENGINE_SOFTWARE_16_DDRAW_H__
+#define __EVAS_ENGINE_SOFTWARE_16_DDRAW_H__
+
+
+#include <windows.h>
+#include <ddraw.h>
+
+typedef struct _Evas_Engine_Info_Software_16_DDraw Evas_Engine_Info_Software_16_DDraw;
+
+struct _Evas_Engine_Info_Software_16_DDraw
+{
+ /* PRIVATE - don't mess with this baby or evas will poke its tongue out */
+ /* at you and make nasty noises */
+ Evas_Engine_Info magic;
+
+ struct {
+ HWND window;
+ LPDIRECTDRAW object; /* DirectDraw object */
+ LPDIRECTDRAWSURFACE surface_primary; /* DirectDraw primary surface */
+ LPDIRECTDRAWSURFACE surface_back; /* DirectDraw back surface */
+ LPDIRECTDRAWSURFACE surface_source; /* DirectDraw source surface */
+ int depth;
+
+ int rotation;
+ } info;
+
+ /* non-blocking or blocking mode */
+ Evas_Engine_Render_Mode render_mode;
+};
+
+
+#endif /* __EVAS_ENGINE_SOFTWARE_16_DDRAW_H__ */
--- /dev/null
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/src/lib \
+-I$(top_srcdir)/src/lib/include \
+-I$(top_srcdir)/src/modules/engines \
+-I$(top_srcdir)/src/modules/engines/software_16 \
+@EINA_CFLAGS@ \
+@FREETYPE_CFLAGS@ \
+@PIXMAN_CFLAGS@ \
+@FRIBIDI_CFLAGS@ \
+@evas_engine_software_16_ddraw_cflags@
+
+if BUILD_ENGINE_SOFTWARE_16_DDRAW
+
+SOFTWARE_16_DDRAW_SOURCES = \
+evas_engine.c \
+evas_ddraw_buffer.cpp \
+evas_ddraw_main.cpp
+
+SOFTWARE_16_DDRAW_LIBADD = @evas_engine_software_16_ddraw_libs@
+
+
+includes_HEADERS = Evas_Engine_Software_16_DDraw.h
+includesdir = $(includedir)/evas-@VMAJ@
+
+if !EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
+
+pkgdir = $(libdir)/evas/modules/engines/software_16_ddraw/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+
+module_la_SOURCES = $(SOFTWARE_16_DDRAW_SOURCES)
+module_la_CXXFLAGS = -fno-rtti -fno-exceptions
+module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @EINA_LIBS@ $(SOFTWARE_16_DDRAW_LIBADD)
+module_la_LDFLAGS = @lt_enable_auto_import@ -no-undefined -module -avoid-version
+module_la_LIBTOOLFLAGS = --tag=disable-static
+
+else
+
+noinst_LTLIBRARIES = libevas_engine_software_16_ddraw.la
+
+libevas_engine_software_16_ddraw_la_SOURCES = $(SOFTWARE_16_DDRAW_SOURCES)
+libevas_engine_software_16_ddraw_la_LIBADD = $(SOFTWARE_16_DDRAW_LIBADD)
+
+endif
+endif
+
+EXTRA_DIST = evas_engine.h
--- /dev/null
+#include "evas_common.h"
+#include "evas_engine.h"
+
+
+DDraw_Output_Buffer *
+evas_software_ddraw_output_buffer_new(HWND window,
+ LPDIRECTDRAW object,
+ LPDIRECTDRAWSURFACE surface_primary,
+ LPDIRECTDRAWSURFACE surface_back,
+ LPDIRECTDRAWSURFACE surface_source,
+ int width,
+ int height)
+{
+ DDSURFACEDESC surface_desc;
+ DDraw_Output_Buffer *ddob;
+
+ ddob = (DDraw_Output_Buffer *)calloc(1, sizeof(DDraw_Output_Buffer));
+ if (!ddob) return NULL;
+
+ ddob->dd.window = window;
+ ddob->dd.object = object;
+ ddob->dd.surface_primary = surface_primary;
+ ddob->dd.surface_back = surface_back;
+ ddob->dd.surface_source = surface_source;
+ ddob->width = width;
+ ddob->height = height;
+ ddob->pitch = width * 2;
+
+ ZeroMemory(&surface_desc, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+
+ if (FAILED(ddob->dd.surface_source->Lock(NULL,
+ &surface_desc,
+ DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
+ NULL)))
+ {
+ free(ddob);
+ return NULL;
+ }
+
+ ddob->data = (DATA16 *)surface_desc.lpSurface;
+
+ if (FAILED(ddob->dd.surface_source->Unlock(NULL)))
+ {
+ free(ddob);
+ return NULL;
+ }
+ if (ddob->im)
+ evas_cache_image_drop(&ddob->im->cache_entry);
+
+ ddob->im = (Soft16_Image *) evas_cache_image_data(evas_common_soft16_image_cache_get(), width, height, (DATA32 *) ddob->data, 0, EVAS_COLORSPACE_RGB565_A5P);
+ if (ddob->im)
+ ddob->im->stride = ddob->pitch;
+
+ return ddob;
+}
+
+void
+evas_software_ddraw_output_buffer_free(DDraw_Output_Buffer *ddob, int sync)
+{
+ free(ddob);
+}
+
+void
+evas_software_ddraw_output_buffer_paste(DDraw_Output_Buffer *ddob)
+{
+ RECT dst_rect;
+ RECT src_rect;
+ POINT p;
+
+ SetRect(&src_rect, 0, 0, ddob->width, ddob->height);
+
+ if (FAILED(ddob->dd.surface_back->BltFast(0, 0,
+ ddob->dd.surface_source,
+ &src_rect,
+ DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT)))
+ return;
+
+ p.x = 0;
+ p.y = 0;
+ ClientToScreen(ddob->dd.window, &p);
+ GetClientRect(ddob->dd.window, &dst_rect);
+ OffsetRect(&dst_rect, p.x, p.y);
+ ddob->dd.surface_primary->Blt(&dst_rect,
+ ddob->dd.surface_back, &src_rect,
+ DDBLT_WAIT, NULL);
+}
--- /dev/null
+#include "evas_engine.h"
+
+
+void *
+evas_software_ddraw_lock(DDraw_Output_Buffer *ddob, int *ddraw_width, int *ddraw_height, int *ddraw_pitch, int *ddraw_depth)
+{
+ DDSURFACEDESC surface_desc;
+
+ ZeroMemory(&surface_desc, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+
+ if (FAILED(ddob->dd.surface_back->Lock(NULL,
+ &surface_desc,
+ DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY,
+ NULL)))
+ return NULL;
+
+ *ddraw_width = surface_desc.dwWidth;
+ *ddraw_height = surface_desc.dwHeight;
+ *ddraw_pitch = surface_desc.lPitch;
+ *ddraw_depth = surface_desc.ddpfPixelFormat.dwRGBBitCount >> 3;
+
+ return surface_desc.lpSurface;
+}
+
+void
+evas_software_ddraw_unlock_and_flip(DDraw_Output_Buffer *ddob)
+{
+ RECT dst_rect;
+ RECT src_rect;
+ POINT p;
+
+ if (FAILED(ddob->dd.surface_back->Unlock(NULL)))
+ return;
+
+ /* we figure out where on the primary surface our window lives */
+ p.x = 0;
+ p.y = 0;
+ ClientToScreen(ddob->dd.window, &p);
+ GetClientRect(ddob->dd.window, &dst_rect);
+ OffsetRect(&dst_rect, p.x, p.y);
+ SetRect(&src_rect, 0, 0, ddob->width, ddob->height);
+
+ /* nothing to do if the function fails, so we don't check the result */
+ ddob->dd.surface_primary->BltFast(0, 0,
+ ddob->dd.surface_back, &dst_rect,
+ DDBLTFAST_WAIT || DDBLTFAST_NOCOLORKEY);
+}
+
+void
+evas_software_ddraw_surface_resize(DDraw_Output_Buffer *ddob)
+{
+ DDSURFACEDESC surface_desc;
+
+ ddob->dd.surface_back->Release();
+ memset (&surface_desc, 0, sizeof (surface_desc));
+ surface_desc.dwSize = sizeof (surface_desc);
+ /* FIXME: that code does not compile. Must know why */
+#if 0
+ surface_desc.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
+ surface_desc.dwWidth = width;
+ surface_desc.dwHeight = height;
+ IDirectDrawSurface7_SetSurfaceDesc(ddob->dd.surface_back, &surface_desc, NULL);
+#else
+ surface_desc.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
+ surface_desc.dwWidth = ddob->width;
+ surface_desc.dwHeight = ddob->height;
+ ddob->dd.object->CreateSurface(&surface_desc, &ddob->dd.surface_back, NULL);
+#endif
+}
--- /dev/null
+#include "evas_common.h"
+#include "evas_private.h"
+#include "evas_engine.h"
+#include "Evas_Engine_Software_16_DDraw.h"
+#include "evas_common_soft16.h"
+
+int _evas_engine_soft16_ddraw_log_dom = -1;
+/* function tables - filled in later (func and parent func) */
+static Evas_Func func, pfunc;
+
+/* engine struct data */
+typedef struct _Render_Engine Render_Engine;
+
+struct _Render_Engine
+{
+ HWND window;
+ LPDIRECTDRAW object;
+ LPDIRECTDRAWSURFACE surface_primary;
+ LPDIRECTDRAWSURFACE surface_back;
+ LPDIRECTDRAWSURFACE surface_source;
+ int width;
+ int height;
+ int rotation;
+ Tilebuf *tb;
+ Tilebuf_Rect *rects;
+ Tilebuf_Rect *cur_rect;
+ DDraw_Output_Buffer *ddob;
+ Soft16_Image *tmp_out; /* used by indirect render, like rotation */
+ HRGN clip_rects;
+ unsigned char end : 1;
+};
+
+/* prototypes we will use here */
+
+static void *eng_info(Evas *e);
+static void eng_info_free(Evas *e, void *info);
+static int eng_setup(Evas *e, void *info);
+static void eng_output_free(void *data);
+static void eng_output_resize(void *data, int w, int h);
+static void eng_output_tile_size_set(void *data, int w, int h);
+static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
+static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
+static void eng_output_redraws_clear(void *data);
+static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch);
+static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
+static void eng_output_flush(void *data);
+static void eng_output_idle_flush(void *data);
+
+/* engine api this module provides */
+static void *
+eng_info(Evas *e)
+{
+ Evas_Engine_Info_Software_16_DDraw *info;
+ info = calloc(1, sizeof(Evas_Engine_Info_Software_16_DDraw));
+ if (!info) return NULL;
+ info->magic.magic = rand();
+ info->render_mode = EVAS_RENDER_MODE_BLOCKING;
+ return info;
+ e = NULL;
+}
+
+static void
+eng_info_free(Evas *e, void *info)
+{
+ Evas_Engine_Info_Software_16_DDraw *in;
+ in = (Evas_Engine_Info_Software_16_DDraw *)info;
+ free(in);
+}
+
+static void
+_tmp_out_alloc(Render_Engine *re)
+{
+ Tilebuf_Rect *r;
+ int w = 0, h = 0;
+
+ EINA_INLIST_FOREACH(re->rects, r)
+ {
+ if (r->w > w) w = r->w;
+ if (r->h > h) h = r->h;
+ }
+
+ if (re->tmp_out)
+ {
+ if ((re->tmp_out->cache_entry.w < w) || (re->tmp_out->cache_entry.h < h))
+ {
+ evas_cache_image_drop(&re->tmp_out->cache_entry);
+ re->tmp_out = NULL;
+ }
+ }
+
+ if (!re->tmp_out)
+ {
+ Soft16_Image *im;
+
+ im = (Soft16_Image *) evas_cache_image_empty(evas_common_soft16_image_cache_get());
+ im->cache_entry.flags.alpha = 0;
+ evas_cache_image_surface_alloc(&im->cache_entry, w, h);
+
+ re->tmp_out = im;
+ }
+}
+
+
+static int
+eng_setup(Evas *e, void *in)
+{
+ Render_Engine *re;
+ Evas_Engine_Info_Software_16_DDraw *info;
+
+ info = (Evas_Engine_Info_Software_16_DDraw *)in;
+ if (!e->engine.data.output)
+ {
+ /* the only check - simplistic, i know, but enough for this
+ * "special purpose" engine. Remember it is meant to be used
+ * for limited power devices that have a 16bit display mode
+ * and no real other acceleration, and high resolution so we
+ * can pre-dither into 16bpp. */
+ if (info->info.depth != 16)
+ return 0;
+ /* do common routine init - we wil at least use it for core
+ * image loading and font loading/glyph rendering & placement */
+ evas_common_cpu_init();
+
+ evas_common_blend_init();
+ evas_common_image_init();
+ evas_common_convert_init();
+ evas_common_scale_init();
+ evas_common_rectangle_init();
+ evas_common_polygon_init();
+ evas_common_line_init();
+ evas_common_font_init();
+ evas_common_draw_init();
+ evas_common_tilebuf_init();
+ evas_common_soft16_image_init();
+
+ /* render engine specific data */
+ re = calloc(1, sizeof(Render_Engine));
+ if (!re)
+ return 0;
+ e->engine.data.output = re;
+ re->window = info->info.window;
+ re->object = info->info.object;
+ re->surface_primary = info->info.surface_primary;
+ re->surface_back = info->info.surface_back;
+ re->surface_source = info->info.surface_source;
+ re->width = e->output.w;
+ re->height = e->output.h;
+ re->rotation = info->info.rotation;
+ re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
+ if (re->tb)
+ evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+ }
+ else
+ {
+ /* we changed the info after first init - do a re-eval where
+ * appropriate */
+ if (info->info.depth != 16)
+ return 0;
+ re = e->engine.data.output;
+ if (re->tb) evas_common_tilebuf_free(re->tb);
+ re->window = info->info.window;
+ re->object = info->info.object;
+ re->surface_primary = info->info.surface_primary;
+ re->surface_back = info->info.surface_back;
+ re->surface_source = info->info.surface_source;
+ re->width = e->output.w;
+ re->height = e->output.h;
+ re->rotation = info->info.rotation;
+ re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
+ if (re->tb)
+ evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+ if (re->tmp_out)
+ {
+ evas_cache_image_drop(&re->tmp_out->cache_entry);
+ re->tmp_out = NULL;
+ }
+ }
+ if (!e->engine.data.output) return 0;
+ /* add a draw context if we dont have one */
+ if (!e->engine.data.context)
+ e->engine.data.context =
+ e->engine.func->context_new(e->engine.data.output);
+
+ return 1;
+}
+
+static void
+eng_output_free(void *data)
+{
+ Render_Engine *re;
+
+ re = (Render_Engine *)data;
+ if (re->ddob) evas_software_ddraw_output_buffer_free(re->ddob, 0);
+ if (re->clip_rects) DeleteObject(re->clip_rects);
+ if (re->tb) evas_common_tilebuf_free(re->tb);
+ if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
+ if (re->tmp_out) evas_cache_image_drop(&re->tmp_out->cache_entry);
+ free(re);
+
+ evas_common_font_shutdown();
+ evas_common_image_shutdown();
+ evas_common_soft16_image_shutdown();
+}
+
+static void
+eng_output_resize(void *data, int w, int h)
+{
+ Render_Engine *re;
+
+ re = (Render_Engine *)data;
+
+ if ((re->width == w) && (re->height == h)) return;
+
+ if (re->ddob)
+ evas_software_ddraw_surface_resize(re->ddob);
+
+ evas_common_tilebuf_free(re->tb);
+ re->width = w;
+ re->height = h;
+ re->tb = evas_common_tilebuf_new(w, h);
+ if (re->tb)
+ evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
+ if (re->ddob)
+ {
+ evas_software_ddraw_output_buffer_free(re->ddob, 0);
+ re->ddob = NULL;
+ }
+ if (re->clip_rects)
+ {
+ DeleteObject(re->clip_rects);
+ re->clip_rects = NULL;
+ }
+ if (re->tmp_out)
+ {
+ evas_cache_image_drop(&re->tmp_out->cache_entry);
+ re->tmp_out = NULL;
+ }
+}
+
+static void
+eng_output_tile_size_set(void *data, int w, int h)
+{
+ Render_Engine *re;
+
+ re = (Render_Engine *)data;
+ evas_common_tilebuf_set_tile_size(re->tb, w, h);
+}
+
+static void
+eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
+{
+ Render_Engine *re;
+
+ re = (Render_Engine *)data;
+ evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
+}
+
+static void
+eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
+{
+ Render_Engine *re;
+
+ re = (Render_Engine *)data;
+ evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
+}
+
+static void
+eng_output_redraws_clear(void *data)
+{
+ Render_Engine *re;
+
+ re = (Render_Engine *)data;
+ evas_common_tilebuf_clear(re->tb);
+}
+
+static inline void
+_output_buffer_alloc(Render_Engine *re)
+{
+ int width;
+ int height;
+
+ if (re->ddob) return;
+
+ if ((re->rotation == 0) || (re->rotation == 180))
+ {
+ width = re->width;
+ height = re->height;
+ }
+ else
+ {
+ width = re->height;
+ height = re->width;
+ }
+
+ re->ddob = evas_software_ddraw_output_buffer_new(re->window,
+ re->object,
+ re->surface_primary,
+ re->surface_back,
+ re->surface_source,
+ width,
+ height);
+}
+
+static void *
+eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
+{
+ Render_Engine *re;
+ Tilebuf_Rect *rect;
+ int ux, uy, uw, uh;
+
+ re = (Render_Engine *)data;
+ if (re->end)
+ {
+ re->end = 0;
+ return NULL;
+ }
+ if (!re->rects)
+ {
+ re->rects = evas_common_tilebuf_get_render_rects(re->tb);
+ if (!re->rects) return NULL;
+
+ re->cur_rect = re->rects;
+ _output_buffer_alloc(re);
+ if (re->rotation != 0) _tmp_out_alloc(re); /* grows if required */
+ }
+ if (!re->cur_rect)
+ {
+ if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
+ re->rects = NULL;
+ return NULL;
+ }
+ rect = re->cur_rect;
+ ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
+ re->cur_rect = (Tilebuf_Rect *)((EINA_INLIST_GET(re->cur_rect))->next);
+ if (!re->cur_rect)
+ {
+ evas_common_tilebuf_free_render_rects(re->rects);
+ re->rects = NULL;
+ re->end = 1;
+ }
+
+ *x = ux; *y = uy; *w = uw; *h = uh;
+ if (re->rotation == 0)
+ {
+ *cx = ux; *cy = uy; *cw = uw; *ch = uh;
+ return &re->ddob->im;
+ }
+ else
+ {
+ *cx = 0; *cy = 0; *cw = uw; *ch = uh;
+ return re->tmp_out;
+ }
+}
+
+static void
+_blit_rot_90(Soft16_Image *dst, const Soft16_Image *src,
+ int out_x, int out_y, int w, int h)
+{
+ DATA16 *dp, *sp;
+ int x, y;
+
+ sp = src->pixels;
+ dp = dst->pixels + (out_x +
+ (w + out_y - 1) * dst->stride);
+
+ for (y = 0; y < h; y++)
+ {
+ DATA16 *dp_itr, *sp_itr;
+
+ sp_itr = sp;
+ dp_itr = dp;
+
+ for (x = 0; x < w; x++)
+ {
+ *dp_itr = *sp_itr;
+
+ sp_itr++;
+ dp_itr -= dst->stride;
+ }
+ sp += src->stride;
+ dp++;
+ }
+}
+
+static void
+_blit_rot_180(Soft16_Image *dst, const Soft16_Image *src,
+ int out_x, int out_y, int w, int h)
+{
+ DATA16 *dp, *sp;
+ int x, y;
+
+ sp = src->pixels;
+ dp = dst->pixels + ((w + out_x - 1) +
+ (h + out_y - 1) * dst->stride);
+
+ for (y = 0; y < h; y++)
+ {
+ DATA16 *dp_itr, *sp_itr;
+
+ sp_itr = sp;
+ dp_itr = dp;
+
+ for (x = 0; x < w; x++)
+ {
+ *dp_itr = *sp_itr;
+
+ sp_itr++;
+ dp_itr--;
+ }
+ sp += src->stride;
+ dp -= dst->stride;
+ }
+}
+
+static void
+_blit_rot_270(Soft16_Image *dst, const Soft16_Image *src,
+ int out_x, int out_y, int w, int h)
+{
+ DATA16 *dp, *sp;
+ int x, y;
+
+ sp = src->pixels;
+ dp = dst->pixels + ((h + out_x - 1) +
+ out_y * dst->stride);
+
+ for (y = 0; y < h; y++)
+ {
+ DATA16 *dp_itr, *sp_itr;
+
+ sp_itr = sp;
+ dp_itr = dp;
+
+ for (x = 0; x < w; x++)
+ {
+ *dp_itr = *sp_itr;
+
+ sp_itr++;
+ dp_itr += dst->stride;
+ }
+ sp += src->stride;
+ dp--;
+ }
+}
+
+static void
+_tmp_out_process(Render_Engine *re, int out_x, int out_y, int w, int h)
+{
+ Soft16_Image *d, *s;
+
+ d = &re->ddob->im;
+ s = re->tmp_out;
+
+ if ((w < 1) || (h < 1) || (out_x >= d->cache_entry.w) || (out_y >= d->cache_entry.h))
+ return;
+
+ if (re->rotation == 90)
+ _blit_rot_90(d, s, out_x, out_y, w, h);
+ else if (re->rotation == 180)
+ _blit_rot_180(d, s, out_x, out_y, w, h);
+ else if (re->rotation == 270)
+ _blit_rot_270(d, s, out_x, out_y, w, h);
+}
+
+static void
+eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
+{
+ Render_Engine *re;
+ HRGN region;
+ int xx;
+ int yy;
+ int width;
+ int height;
+
+ re = (Render_Engine *)data;
+
+ if (!re->clip_rects)
+ re->clip_rects = CreateRectRgn(0, 0, 0, 0);
+
+ if (re->rotation == 0)
+ {
+ xx = x;
+ yy = y;
+ width = w;
+ height = h;
+ }
+ else if (re->rotation == 90)
+ {
+ xx = y;
+ yy = re->width - w - x;
+ width = h;
+ height = w;
+ }
+ else if (re->rotation == 180)
+ {
+ xx = re->width - w - x;
+ yy = re->height - h - y;
+ width = w;
+ height = h;
+ }
+ else if (re->rotation == 270)
+ {
+ xx = re->height - h - y;
+ yy = x;
+ width = h;
+ height = w;
+ }
+
+ region = CreateRectRgn(xx, yy, xx + width, yy + height);
+
+ if (re->rotation != 0)
+ _tmp_out_process(re, xx, yy, w, h);
+ CombineRgn(re->clip_rects, re->clip_rects, region, RGN_OR);
+}
+
+static void
+eng_output_flush(void *data)
+{
+ Render_Engine *re;
+ void *ddraw_data;
+ int ddraw_width;
+ int ddraw_height;
+ int ddraw_pitch;
+ int ddraw_depth;
+
+ re = (Render_Engine *)data;
+ if (re->clip_rects)
+ {
+ /* FIXME : i have to manage that */
+/* XSetRegion(re->disp, re->gc, re->clip_rects); */
+ DeleteObject(re->clip_rects);
+ re->clip_rects = NULL;
+ }
+ else return;
+
+ evas_software_ddraw_output_buffer_paste(re->ddob);
+
+ /* FIXME : i have to manage that */
+/* XSetClipMask(re->disp, re->gc, None); */
+}
+
+static void
+eng_output_idle_flush(void *data)
+{
+ Render_Engine *re;
+
+ re = (Render_Engine *)data;
+ if (re->ddob)
+ {
+ evas_software_ddraw_output_buffer_free(re->ddob, 0);
+ re->ddob = NULL;
+ }
+ if (re->clip_rects)
+ {
+ DeleteObject(re->clip_rects);
+ re->clip_rects = NULL;
+ }
+ if (re->tmp_out)
+ {
+ evas_cache_image_drop(&re->tmp_out->cache_entry);
+ re->tmp_out = NULL;
+ }
+}
+
+static Eina_Bool
+eng_canvas_alpha_get(void *data, void *context)
+{
+ return EINA_FALSE;
+}
+
+/* module advertising code */
+static int
+module_open(Evas_Module *em)
+{
+ if (!em) return 0;
+ /* get whatever engine module we inherit from */
+ if (!_evas_module_engine_inherit(&pfunc, "software_16")) return 0;
+ _evas_engine_soft16_ddraw_log_dom = eina_log_domain_register
+ ("evas-software_16_ddraw", EVAS_DEFAULT_LOG_COLOR);
+ if (_evas_engine_soft16_ddraw_log_dom < 0)
+ {
+ EINA_LOG_ERR("Can not create a module log domain.");
+ return 0;
+ }
+ /* store it for later use */
+ func = pfunc;
+ /* now to override methods */
+#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
+ ORD(info);
+ ORD(info_free);
+ ORD(setup);
+ ORD(canvas_alpha_get);
+ ORD(output_free);
+ ORD(output_resize);
+ ORD(output_tile_size_set);
+ ORD(output_redraws_rect_add);
+ ORD(output_redraws_rect_del);
+ ORD(output_redraws_clear);
+ ORD(output_redraws_next_update_get);
+ ORD(output_redraws_next_update_push);
+ ORD(output_flush);
+ ORD(output_idle_flush);
+ /* now advertise out own api */
+ em->functions = (void *)(&func);
+ return 1;
+}
+
+static void
+module_close(Evas_Module *em)
+{
+ eina_log_domain_unregister(_evas_engine_soft16_ddraw_log_dom);
+}
+
+static Evas_Module_Api evas_modapi =
+{
+ EVAS_MODULE_API_VERSION,
+ "software_16_ddraw",
+ "none",
+ {
+ module_open,
+ module_close
+ }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_16_ddraw);
+
+#ifndef EVAS_STATIC_BUILD_SOFTWARE_16_DDRAW
+EVAS_EINA_MODULE_DEFINE(engine, software_16_ddraw);
+#endif
--- /dev/null
+#ifndef __EVAS_ENGINE_H__
+#define __EVAS_ENGINE_H__
+
+#include <windows.h>
+#include <ddraw.h>
+
+#include "evas_common_soft16.h"
+
+extern int _evas_engine_soft16_ddraw_log_dom ;
+#ifdef ERR
+# undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_soft16_ddraw_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+# undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_soft16_ddraw_log_dom, __VA_ARGS__)
+
+#ifdef INF
+# undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_evas_engine_soft16_ddraw_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+# undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_soft16_ddraw_log_dom, __VA_ARGS__)
+
+#ifdef CRIT
+# undef CRIT
+#endif
+#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_engine_soft16_ddraw_log_dom, __VA_ARGS__)
+
+typedef struct _DDraw_Output_Buffer DDraw_Output_Buffer;
+
+struct _DDraw_Output_Buffer
+{
+ Soft16_Image *im;
+ struct {
+ HWND window;
+ LPDIRECTDRAW object;
+ LPDIRECTDRAWSURFACE surface_primary;
+ LPDIRECTDRAWSURFACE surface_back;
+ LPDIRECTDRAWSURFACE surface_source;
+ } dd;
+ void *data;
+ int x;
+ int y;
+ int width;
+ int height;
+ int depth;
+ int pitch;
+};
+
+/****/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+DDraw_Output_Buffer *evas_software_ddraw_output_buffer_new (HWND window,
+ LPDIRECTDRAW object,
+ LPDIRECTDRAWSURFACE surface_primary,
+ LPDIRECTDRAWSURFACE surface_back,
+ LPDIRECTDRAWSURFACE surface_source,
+ int width,
+ int height);
+void evas_software_ddraw_output_buffer_free (DDraw_Output_Buffer *ddob, int sync);
+void evas_software_ddraw_output_buffer_paste (DDraw_Output_Buffer *ddob);
+
+
+void *evas_software_ddraw_lock(DDraw_Output_Buffer *ddob, int *ddraw_width, int *ddraw_height, int *ddraw_pitch, int *ddraw_depth);
+
+void evas_software_ddraw_unlock_and_flip(DDraw_Output_Buffer *ddob);
+
+void evas_software_ddraw_surface_resize(DDraw_Output_Buffer *ddob);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EVAS_ENGINE_H__ */
}
static Evas_Font_Set *
-eng_font_memory_load(void *data __UNUSED__, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend)
+eng_font_memory_load(void *data __UNUSED__, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend)
{
- return (Evas_Font_Set *) evas_common_font_memory_load(source, name, size,
- fdata, fdata_size, wanted_rend);
+ return (Evas_Font_Set *) evas_common_font_memory_load(name, size, fdata,
+ fdata_size, wanted_rend);
}
static Evas_Font_Set *
}
static Evas_Font_Set *
-eng_font_memory_add(void *data __UNUSED__, Evas_Font_Set *font, const char *source, const char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend)
+eng_font_memory_add(void *data __UNUSED__, Evas_Font_Set *font, char *name, int size, const void *fdata, int fdata_size, Font_Rend_Flags wanted_rend)
{
return (Evas_Font_Set *) evas_common_font_memory_add((RGBA_Font *) font,
- source, name, size, fdata, fdata_size, wanted_rend);
+ name, size, fdata, fdata_size, wanted_rend);
}
static void
/* if we already have a window surface, check for NULL input surface.
* this will mean we are hiding the window and should destroy
* things properly */
- if ((re->win->surface) && (re->info->info.surface == NULL))
+ if ((re->win->surface) && (re->info->info.surface = NULL))
{
if (re->win)
{
evas_textblock_cursor_paragraph_first(cur);
fail_if(evas_textblock_cursor_paragraph_next(cur));
- {
- /* Limit to 1000 iterations so we'll never get into an infinite loop,
- * even if broken */
- int limit = 1000;
- evas_object_textblock_text_markup_set(tb, "this is a test eauoeuaou<ps/>this is a test1<ps/>this is a test 3");
- evas_textblock_cursor_paragraph_last(cur);
- while (evas_textblock_cursor_pos_get(cur) > 0)
- {
- limit--;
- fail_if(limit <= 0);
- evas_textblock_cursor_copy(cur, main_cur);
- evas_textblock_cursor_char_prev(cur);
- evas_textblock_cursor_word_start(cur);
- evas_textblock_cursor_range_delete(cur, main_cur);
- }
- }
-
-
/* Insert illegal characters inside the format. */
{
const char *content;