From a49131316e752f09d459b58f827bc6025cb97af7 Mon Sep 17 00:00:00 2001 From: "N.N." Date: Tue, 22 Nov 2005 06:20:38 +0000 Subject: PiDiP 0.12.20 svn path=/trunk/externals/pidip/; revision=4015 --- CHANGES.LOG | 5 + Makefile | 13 +- Makefile.in | 5 +- acinclude.m4 | 2 +- aclocal.m4 | 2 +- configure | 8 +- configure.ac | 5 +- configure.in | 5 +- doc/help-pdp_imgloader.pd | 115 +++-- doc/help-pdp_qtext.pd | 167 +++++++ doc/help-pdp_text.pd | 68 +-- modules/Makefile | 4 +- modules/Makefile.in | 2 +- modules/pdp_imgloader.c | 211 ++++++--- modules/pdp_qtext.c | 1086 +++++++++++++++++++++++++++++++++++++++++++++ system/pidip.c | 2 + 16 files changed, 1549 insertions(+), 151 deletions(-) create mode 100644 doc/help-pdp_qtext.pd create mode 100755 modules/pdp_qtext.c diff --git a/CHANGES.LOG b/CHANGES.LOG index f37d741..779ffbc 100644 --- a/CHANGES.LOG +++ b/CHANGES.LOG @@ -1,3 +1,8 @@ +0.12.20 ( codename Lavapies ) + added contributions from Pablo Martin Caedes ( caedes@sindominio.net ) : + pdp_qtext : a layered texts object, based on pdp_text and using imlib2 + pdp_imgloader : improved version from PMC, different ways of blending images ( in quality mode ) + 0.12.19 ( codename GISS action force ) addapted to newer Image Magick ( > 6.1.9 ) modified pdp_icedthe~ : added a framerate control diff --git a/Makefile b/Makefile index e673ebf..c03ac87 100644 --- a/Makefile +++ b/Makefile @@ -5,24 +5,25 @@ FFMPEG_SOURCE_DIR = /SOURCES/ffmpeg PDP_PIDIP_LIBS = -lbz2 -lz -ldl -lmp3lame -logg -lvorbis -lvorbisenc IMLIB_CFLAGS = -I/usr/local/include -I/usr/X11R6/include IMLIB_LIBS = -L/usr/local/lib -lImlib2 -lfreetype -lz -lm -ldl -lXext -lXext -lX11 -L/usr/X11R6/lib -MAGICK_CFLAGS = -I/usr/X11R6/include -O2 -g -pipe -m32 -march=i386 -mtune=pentium4 -Wall -pthread -MAGICK_LIBS = -L/usr/X11R6/lib -lMagick -lMagick -ltiff -lfreetype -ljpeg -lpng -ldpstk -ldps -lXext -lXt -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lpthread -lm -lpthread -L/usr/lib -L/usr/X11R6/lib -lfreetype -lz -L/usr/lib -THEORA_LIBS = /usr/lib/libtheora.a /usr/local/lib/libtheora.a /usr/lib/libogg.a /usr/local/lib/libvorbis.a /usr/local/lib/libvorbisenc.a +MAGICK_CFLAGS = -I/usr/X11R6/include -g -O2 -Wall -pthread +MAGICK_LIBS = -L/usr/X11R6/lib -lMagick -lMagick -ltiff -lfreetype -ljpeg -lpng -ldpstk -ldps -lXext -lXt -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lpthread -lm -lpthread -L/usr/local/lib -L/usr/X11R6/lib -lfreetype -lz -L/usr/lib +THEORA_LIBS = /usr/lib/libtheora.a /usr/local/lib/libtheora.a /usr/lib/libogg.a /usr/lib/libvorbis.a /usr/local/lib/libvorbis.a /usr/lib/libvorbisenc.a /usr/local/lib/libvorbisenc.a PDP_PIDIP_INCLUDES = -I/usr/local/pd/src -I. -I/usr/local/pd/pdp/include -I../include -I../charmaps -PDP_PIDIP_VERSION = 0.12.19 +PDP_PIDIP_VERSION = 0.12.20 MPEG4IP_CFLAGS = +CAIRO_CFLAGS = -I/usr/include/cairo/ -I/usr/local/include/cairo/ PDP_PIDIP_DISTRO = /mnt/c/ydegoyon.free.fr/pidip-$(PDP_PIDIP_VERSION) PDP_PIDIP_TARBALL = $(PDP_PIDIP_DISTRO).tar.gz -PDP_PIDIP_CFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) \ +PDP_PIDIP_CFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) $(CAIRO_CFLAGS) \ -DPD -DX_DISPLAY_MISSING -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ -Wall -W -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch \ -DPDP_PIDIP_VERSION=\"$(PDP_PIDIP_VERSION)\" -g -PDP_PIDIP_CPPFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) \ +PDP_PIDIP_CPPFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) $(CAIRO_CFLAGS) \ -DPD -DX_DISPLAY_MISSING -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ -Wall -W -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch \ diff --git a/Makefile.in b/Makefile.in index 0370aab..f589e7f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -11,18 +11,19 @@ THEORA_LIBS = @THEORA_LIBS@ PDP_PIDIP_INCLUDES = @PDP_PIDIP_INCLUDES@ PDP_PIDIP_VERSION = @PDP_PIDIP_VERSION@ MPEG4IP_CFLAGS = @MPEG4IP_CFLAGS@ +CAIRO_CFLAGS = @CAIRO_CFLAGS@ PDP_PIDIP_DISTRO = /mnt/c/ydegoyon.free.fr/pidip-$(PDP_PIDIP_VERSION) PDP_PIDIP_TARBALL = $(PDP_PIDIP_DISTRO).tar.gz -PDP_PIDIP_CFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) \ +PDP_PIDIP_CFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) $(CAIRO_CFLAGS) \ -DPD -DX_DISPLAY_MISSING -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ -Wall -W -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch \ -DPDP_PIDIP_VERSION=\"$(PDP_PIDIP_VERSION)\" -g -PDP_PIDIP_CPPFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) \ +PDP_PIDIP_CPPFLAGS = $(MPEG4IP_CFLAGS) $(MAGICK_CFLAGS) $(IMLIB_CFLAGS) $(CAIRO_CFLAGS) \ -DPD -DX_DISPLAY_MISSING -O2 -funroll-loops -fomit-frame-pointer -ffast-math \ -Wall -W -Wstrict-prototypes \ -Wno-unused -Wno-parentheses -Wno-switch \ diff --git a/acinclude.m4 b/acinclude.m4 index fa559ee..f4f3d42 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -24,7 +24,7 @@ dnl At present there is no support for additional "MODULES" (see AM_PATH_GTK) dnl (shamelessly stolen from gtk.m4 and then hacked around a fair amount) dnl dnl @author Angus Lees -dnl @version $Id: acinclude.m4,v 1.10 2005-07-09 19:35:39 sevyves Exp $ +dnl @version $Id: acinclude.m4,v 1.11 2005-11-22 06:18:01 sevyves Exp $ AC_DEFUN(AC_PATH_GENERIC, [dnl diff --git a/aclocal.m4 b/aclocal.m4 index 75ef28f..ee26855 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -36,7 +36,7 @@ dnl At present there is no support for additional "MODULES" (see AM_PATH_GTK) dnl (shamelessly stolen from gtk.m4 and then hacked around a fair amount) dnl dnl @author Angus Lees -dnl @version $Id: aclocal.m4,v 1.10 2005-07-09 19:35:39 sevyves Exp $ +dnl @version $Id: aclocal.m4,v 1.11 2005-11-22 06:18:01 sevyves Exp $ AC_DEFUN(AC_PATH_GENERIC, [dnl diff --git a/configure b/configure index a5cfd93..faf134c 100755 --- a/configure +++ b/configure @@ -271,7 +271,7 @@ PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT IMLIB2_CONFIG IMLIB_LIBS IMLIB_CFLAGS IMLIB2_CFLAGS IMLIB2_LIBS PDP_PIDIP_VERSION MAGICK_LIBS MAGICK_CFLAGS THEORA_LIBS PD_DIR PDP_DIR FFMPEG_SOURCE_DIR MPEG4IP_SOURCE_DIR MPEG4IP_CFLAGS PDP_STREAMING_OBJECTS PDP_PIDIP_LIBS PDP_PIDIP_INCLUDES LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA SET_MAKE MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT IMLIB2_CONFIG IMLIB_LIBS IMLIB_CFLAGS IMLIB2_CFLAGS IMLIB2_LIBS CAIRO_CFLAGS PDP_PIDIP_VERSION MAGICK_LIBS MAGICK_CFLAGS THEORA_LIBS PD_DIR PDP_DIR FFMPEG_SOURCE_DIR MPEG4IP_SOURCE_DIR MPEG4IP_CFLAGS PDP_STREAMING_OBJECTS PDP_PIDIP_LIBS PDP_PIDIP_INCLUDES LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1267,7 +1267,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers include/pidip_config.h" -PDP_PIDIP_VERSION="0.12.19" +PDP_PIDIP_VERSION="0.12.20" PD_DIR=/usr/local/pd PDP_DIR=/usr/local/pd/pdp FFMPEG_SOURCE_DIR=/SOURCES/ffmpeg @@ -4007,6 +4007,9 @@ IMLIB_CFLAGS=`imlib2-config --cflags` +CAIRO_CFLAGS="-I/usr/include/cairo/ -I/usr/local/include/cairo/" + + echo "$as_me:$LINENO: checking for XWindowByProperty in -lMagick" >&5 echo $ECHO_N "checking for XWindowByProperty in -lMagick... $ECHO_C" >&6 @@ -5457,6 +5460,7 @@ s,@IMLIB_LIBS@,$IMLIB_LIBS,;t t s,@IMLIB_CFLAGS@,$IMLIB_CFLAGS,;t t s,@IMLIB2_CFLAGS@,$IMLIB2_CFLAGS,;t t s,@IMLIB2_LIBS@,$IMLIB2_LIBS,;t t +s,@CAIRO_CFLAGS@,$CAIRO_CFLAGS,;t t s,@PDP_PIDIP_VERSION@,$PDP_PIDIP_VERSION,;t t s,@MAGICK_LIBS@,$MAGICK_LIBS,;t t s,@MAGICK_CFLAGS@,$MAGICK_CFLAGS,;t t diff --git a/configure.ac b/configure.ac index 73d9bca..e540622 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT AC_CONFIG_HEADER(include/pidip_config.h) -PDP_PIDIP_VERSION="0.12.19" +PDP_PIDIP_VERSION="0.12.20" PD_DIR=/usr/local/pd PDP_DIR=/usr/local/pd/pdp FFMPEG_SOURCE_DIR=/SOURCES/ffmpeg @@ -94,6 +94,9 @@ IMLIB_CFLAGS=`imlib2-config --cflags` AC_SUBST(IMLIB_LIBS) AC_SUBST(IMLIB_CFLAGS) +CAIRO_CFLAGS="-I/usr/include/cairo/ -I/usr/local/include/cairo/" +AC_SUBST(CAIRO_CFLAGS) + AC_CHECK_LIB(Magick, XWindowByProperty, , AC_MSG_ERROR(screen captures requires ImageMagick library!!), -I/usr/X11R6/include -L/usr/X11R6/lib ) AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress, , AC_MSG_ERROR(streaming requires bz2 library!!)) AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR(streaming requires compress library!!)) diff --git a/configure.in b/configure.in index 73d9bca..e540622 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT AC_CONFIG_HEADER(include/pidip_config.h) -PDP_PIDIP_VERSION="0.12.19" +PDP_PIDIP_VERSION="0.12.20" PD_DIR=/usr/local/pd PDP_DIR=/usr/local/pd/pdp FFMPEG_SOURCE_DIR=/SOURCES/ffmpeg @@ -94,6 +94,9 @@ IMLIB_CFLAGS=`imlib2-config --cflags` AC_SUBST(IMLIB_LIBS) AC_SUBST(IMLIB_CFLAGS) +CAIRO_CFLAGS="-I/usr/include/cairo/ -I/usr/local/include/cairo/" +AC_SUBST(CAIRO_CFLAGS) + AC_CHECK_LIB(Magick, XWindowByProperty, , AC_MSG_ERROR(screen captures requires ImageMagick library!!), -I/usr/X11R6/include -L/usr/X11R6/lib ) AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress, , AC_MSG_ERROR(streaming requires bz2 library!!)) AC_CHECK_LIB(z, deflate, , AC_MSG_ERROR(streaming requires compress library!!)) diff --git a/doc/help-pdp_imgloader.pd b/doc/help-pdp_imgloader.pd index 49afe7d..ed96599 100644 --- a/doc/help-pdp_imgloader.pd +++ b/doc/help-pdp_imgloader.pd @@ -1,8 +1,8 @@ -#N canvas 238 63 712 664 10; +#N canvas 157 22 787 658 10; #X obj 375 116 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 -1; #X msg 221 148 loop \$1; -#X obj 222 126 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 +#X obj 222 126 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 1; #X msg 249 95 open \$1; #X obj 248 71 openpanel; @@ -19,7 +19,6 @@ #X obj 350 179 pdp_yqt; #X obj 488 441 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1; -#X obj 488 493 pdp_control; #X msg 488 466 thread \$1; #X floatatom 488 554 5 0 0 0 - - -; #X obj 488 525 route pdp_drop; @@ -27,19 +26,18 @@ #X text 345 261 X Offset; #X floatatom 403 279 5 0 0 0 - - -; #X text 403 261 Y Offset; -#X obj 64 301 openpanel; -#X obj 64 274 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 +#X obj 185 299 openpanel; +#X obj 185 272 bng 15 250 50 0 empty empty empty 0 -6 0 8 -262144 -1 -1; -#X text 86 569 pdp_imgloader : load an image and blend it with a video +#X text 345 615 pdp_imgloader : load an image and blend it with a video ; -#X text 86 585 written by Yves Degoyon ( ydegoyon@free.fr ); #X obj 191 438 pdp_xv; -#X msg 66 363 clear; -#X msg 64 325 load \$1 64 32; +#X msg 187 361 clear; +#X msg 185 323 load \$1 64 32; #X text 27 241 load ; #X text 28 228 Load an image ( types supported by imlib2 ); #X obj 469 279 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 --1 -1 10200 1; +-1 -1 0 1; #X text 468 262 Blending factor; #X text 491 364 Unhide ; #X text 439 340 Hide ; @@ -52,10 +50,43 @@ #X msg 419 384 rawhide 0 0.823 0.15 0.234 0.892 0.678; #X obj 191 467 route press; #X obj 191 489 handle-clicks; -#X obj 191 513 route 0; -#X obj 192 536 s rawhide; -#X obj 200 316 r rawhide; +#X obj 191 535 s rawhide; +#X obj 292 401 r rawhide; #X msg 277 438 cursor 1; +#X msg 739 734 estirar \$1; +#X obj 754 695 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 739 734 estirar \$1; +#X obj 754 695 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 22 394 cnv 15 150 180 empty empty empty 20 12 0 14 -233017 -66577 +0; +#X msg 27 484 operation add; +#X msg 27 444 operation substract; +#X msg 27 463 operation reshade; +#X msg 27 424 operation copy; +#X obj 28 528 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 17 287 cnv 15 160 100 empty empty empty 20 12 0 14 -233017 -66577 +0; +#X msg 34 335 quality 0; +#X msg 34 355 quality 1; +#X text 23 403 with quality mode; +#X text 23 391 these only work; +#X text 19 292 quality sets a slower; +#X text 21 315 more possibilities; +#X text 20 303 draw method with; +#X floatatom 407 116 5 0 0 0 - - -; +#X text 607 313 (only if quality = 0 ); +#X obj 488 493 pdp_control; +#X text 344 627 written by Yves Degoyon ( ydegoyon@free.fr ) \, improved +by Pablo Martin Caedes ( caedes@sindominio.net ); +#X msg 48 527 fit \$1; +#X text 24 499 operation: blend; +#X text 24 511 mode for the image; +#X text 23 555 to the video size; +#X text 23 545 fit: fit the image; +#X obj 191 512 route 0; #X connect 0 0 7 0; #X connect 1 0 13 0; #X connect 2 0 1 0; @@ -64,30 +95,42 @@ #X connect 5 0 4 0; #X connect 6 0 7 0; #X connect 7 0 13 0; +#X connect 8 0 36 0; #X connect 9 0 8 0; #X connect 10 0 9 0; #X connect 11 0 9 0; #X connect 12 0 8 0; -#X connect 13 0 38 0; -#X connect 14 0 16 0; -#X connect 15 0 18 0; -#X connect 16 0 15 0; -#X connect 18 0 17 0; -#X connect 19 0 38 1; -#X connect 21 0 38 2; -#X connect 23 0 29 0; -#X connect 24 0 23 0; -#X connect 27 0 43 0; -#X connect 28 0 38 0; -#X connect 29 0 38 0; -#X connect 32 0 38 3; -#X connect 38 0 48 0; -#X connect 38 0 27 0; -#X connect 39 0 38 0; -#X connect 41 0 38 0; -#X connect 42 0 38 0; -#X connect 43 0 44 0; -#X connect 44 0 45 0; -#X connect 45 0 46 0; -#X connect 47 0 38 0; -#X connect 48 0 27 0; +#X connect 13 0 36 0; +#X connect 14 0 15 0; +#X connect 15 0 66 0; +#X connect 17 0 16 0; +#X connect 18 0 36 1; +#X connect 20 0 36 2; +#X connect 22 0 27 0; +#X connect 23 0 22 0; +#X connect 25 0 41 0; +#X connect 26 0 36 0; +#X connect 27 0 36 0; +#X connect 30 0 36 3; +#X connect 36 0 45 0; +#X connect 36 0 25 0; +#X connect 37 0 36 0; +#X connect 39 0 36 0; +#X connect 40 0 36 0; +#X connect 41 0 42 0; +#X connect 42 0 73 0; +#X connect 44 0 36 0; +#X connect 45 0 25 0; +#X connect 47 0 46 0; +#X connect 49 0 48 0; +#X connect 51 0 36 0; +#X connect 52 0 36 0; +#X connect 53 0 36 0; +#X connect 54 0 36 0; +#X connect 55 0 68 0; +#X connect 57 0 36 0; +#X connect 58 0 36 0; +#X connect 64 0 7 1; +#X connect 66 0 17 0; +#X connect 68 0 36 0; +#X connect 73 0 43 0; diff --git a/doc/help-pdp_qtext.pd b/doc/help-pdp_qtext.pd new file mode 100644 index 0000000..e772f86 --- /dev/null +++ b/doc/help-pdp_qtext.pd @@ -0,0 +1,167 @@ +#N canvas 84 12 846 664 10; +#X obj 152 576 pdp_xv; +#X obj 268 13 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 188 88 loop \$1; +#X obj 189 66 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 1 +; +#X msg 303 34 open \$1; +#X obj 302 10 openpanel; +#X obj 287 -7 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X floatatom 340 57 5 0 0 0 - - -; +#X msg 225 14 stop; +#X obj 257 84 metro 70; +#X obj 346 152 pdp_v4l; +#X obj 355 121 metro 70; +#X obj 400 87 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X msg 357 88 stop; +#X msg 442 119 open /dev/video; +#X obj 252 116 pdp_yqt; +#X obj 720 509 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X obj 720 561 pdp_control; +#X msg 720 534 thread \$1; +#X floatatom 720 622 5 0 0 0 - - -; +#X obj 720 593 route pdp_drop; +#X msg 205 232 text moshi-moshi 34 58; +#X msg 224 254 text on%32air!! 150 78; +#X msg 247 334 text %34%48%49:37:58%34 20 220; +#X msg 238 309 text "01:37:58" 230 220; +#X msg 232 280 text a%32hundred%32%% 120 128 255 0 0; +#X obj 265 375 hdl 15 1 0 10 empty empty empty 0 -6 0 8 -262144 -1 +-1 0; +#X text 369 232 Add a simple text; +#X text 391 254 Add a text with special characters; +#X text 502 280 Add a real percent now ( but in red ); +#X text 416 309 Have to put a quote (%34) before starting numbers; +#X text 470 334 This time \, it's real quotes ( tricky \, hey?? ); +#X floatatom 280 401 5 0 0 0 - - -; +#X text 328 400 X coordinate; +#X floatatom 301 422 5 0 0 0 - - -; +#X floatatom 326 443 5 0 0 0 - - -; +#X floatatom 344 463 5 0 0 0 - - -; +#X floatatom 364 483 5 0 0 0 - - -; +#X text 349 421 Y coordinate; +#X text 374 442 R component; +#X text 392 462 G component; +#X text 412 482 B component; +#X msg 445 152 dim 800 600; +#X msg 20 353 clear; +#X msg 20 391 delete 1; +#X msg 16 546 font helmetr/14; +#X text 200 204 text x y [ r g b angle ]; +#X floatatom 392 504 5 0 0 0 - - -; +#X text 440 503 Angle; +#X msg 14 523 font helmetr/5; +#X floatatom 415 522 5 0 0 0 - - -; +#X text 461 522 Scroll; +#X msg 19 204 layermode feed; +#X msg 18 222 layermode scroll; +#X msg 18 240 layermode static; +#X msg 20 127 left; +#X msg 21 317 marginv 0; +#X msg 20 164 direction \$1; +#X obj 118 166 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 +1; +#X msg 58 127 center; +#X obj 155 547 pdp_qtext -----------------; +#X msg 18 262 layermode slow; +#X msg 109 126 right; +#X text 18 108 justification; +#X text 18 148 scroll/feed direction; +#X text 19 188 set current layermode; +#X text 21 284 right and bottom margins; +#X text 17 375 delete texts in specified layer; +#X text 221 564 pdp_qtext : text rendering in several layers in PDP +\, extends pdp_text. each layer can have many texts \, different layer +modes \, and properties (like text colour or type); +#X text 219 605 written by Yves Degoyon (ydegoyon@free.fr) and Pablo +Martin (caedes@sindominio.net); +#X msg 532 425 texta \$1; +#X text 531 457 even line colour (only for feed layer mode); +#X text 530 406 alpha for text; +#X text 424 373 Select layer \, all operations will affect selected +layer; +#X obj 579 162 pdp_noise; +#X obj 585 131 metro 70; +#X obj 630 97 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 +-1; +#X obj 584 97 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 0 1 +; +#X obj 598 426 hsl 128 15 0 255 0 0 empty empty empty -2 -6 0 8 -262144 +-1 -1 0 1; +#X text 18 336 clear all texts; +#X floatatom 603 479 5 0 0 0 - - -; +#X msg 531 478 text2r \$1; +#X floatatom 607 499 5 0 0 0 - - -; +#X msg 534 498 text2g \$1; +#X floatatom 613 520 5 0 0 0 - - -; +#X floatatom 623 544 5 0 0 0 - - -; +#X msg 541 519 text2b \$1; +#X msg 547 542 text2a \$1; +#X msg 21 300 margin 50; +#X connect 1 0 9 0; +#X connect 2 0 15 0; +#X connect 3 0 2 0; +#X connect 4 0 15 0; +#X connect 5 0 4 0; +#X connect 6 0 5 0; +#X connect 7 0 9 1; +#X connect 8 0 9 0; +#X connect 9 0 15 0; +#X connect 10 0 60 0; +#X connect 11 0 10 0; +#X connect 12 0 11 0; +#X connect 13 0 11 0; +#X connect 14 0 10 0; +#X connect 15 0 60 0; +#X connect 16 0 18 0; +#X connect 17 0 20 0; +#X connect 18 0 17 0; +#X connect 20 0 19 0; +#X connect 21 0 60 0; +#X connect 22 0 60 0; +#X connect 23 0 60 0; +#X connect 24 0 60 0; +#X connect 25 0 60 0; +#X connect 26 0 60 1; +#X connect 32 0 60 2; +#X connect 34 0 60 3; +#X connect 35 0 60 4; +#X connect 36 0 60 5; +#X connect 37 0 60 6; +#X connect 42 0 10 0; +#X connect 43 0 60 0; +#X connect 44 0 60 0; +#X connect 45 0 60 0; +#X connect 47 0 60 7; +#X connect 49 0 60 0; +#X connect 50 0 60 8; +#X connect 52 0 60 0; +#X connect 53 0 60 0; +#X connect 54 0 60 0; +#X connect 55 0 60 0; +#X connect 56 0 60 0; +#X connect 57 0 60 0; +#X connect 58 0 57 0; +#X connect 59 0 60 0; +#X connect 60 0 0 0; +#X connect 61 0 60 0; +#X connect 62 0 60 0; +#X connect 70 0 60 0; +#X connect 74 0 60 0; +#X connect 75 0 74 0; +#X connect 76 0 75 0; +#X connect 77 0 75 0; +#X connect 78 0 70 0; +#X connect 80 0 81 0; +#X connect 81 0 60 0; +#X connect 82 0 83 0; +#X connect 83 0 60 0; +#X connect 84 0 86 0; +#X connect 85 0 87 0; +#X connect 86 0 60 0; +#X connect 87 0 60 0; +#X connect 88 0 60 0; diff --git a/doc/help-pdp_text.pd b/doc/help-pdp_text.pd index 4bd5346..a8c05d1 100644 --- a/doc/help-pdp_text.pd +++ b/doc/help-pdp_text.pd @@ -1,9 +1,9 @@ -#N canvas 84 12 763 664 10; +#N canvas 325 39 763 664 10; #X obj 152 627 pdp_xv; #X obj 268 64 bng 15 250 50 0 empty empty empty 20 8 0 8 -262144 -1 -1; #X msg 158 123 loop \$1; -#X obj 159 101 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 0 +#X obj 159 101 tgl 15 0 empty empty empty 20 8 0 8 -262144 -1 -1 1 1; #X msg 370 44 open \$1; #X obj 369 20 openpanel; @@ -12,7 +12,7 @@ #X floatatom 316 99 5 0 0 0 - - -; #X msg 225 65 stop; #X obj 323 68 hsl 300 15 0 1000 0 0 empty empty empty -2 -6 0 8 -262144 --1 -1 0 1; +-1 -1 4000 1; #X obj 257 135 metro 70; #X obj 346 203 pdp_v4l; #X obj 355 172 metro 70; @@ -30,7 +30,6 @@ #X text 221 617 pdp_text : text rendering in PDP; #X text 222 631 written by Yves Degoyon (ydegoyon@free.fr); #X msg 144 282 text moshi-moshi 34 58; -#X msg 163 304 text on%32air!! 150 78; #X msg 186 384 text %34%48%49:37:58%34 20 220; #X msg 177 359 text "01:37:58" 230 220; #X msg 171 330 text a%32hundred%32%% 120 128 255 0 0; @@ -38,7 +37,7 @@ -1 0; #X text 364 424 Select current text ( 10 items by default ); #X text 308 282 Add a simple text; -#X text 330 304 Add a text with special characters; +#X text 349 305 Add a text with special characters; #X text 438 330 Add a real percent now ( but in red ); #X text 355 359 Have to put a quote (%34) before starting numbers; #X text 409 384 This time \, it's real quotes ( tricky \, hey?? ); @@ -73,6 +72,7 @@ #X obj 380 594 hsl 128 15 0 1 0 0 empty empty empty -2 -6 0 8 -262144 -1 -1 0 1; #X text 517 594 Alpha ( global ); +#X msg 163 304 text on%32air!! 150 78; #X connect 1 0 10 0; #X connect 2 0 16 0; #X connect 3 0 2 0; @@ -83,40 +83,40 @@ #X connect 8 0 10 0; #X connect 9 0 7 0; #X connect 10 0 16 0; -#X connect 11 0 51 0; +#X connect 11 0 50 0; #X connect 12 0 11 0; #X connect 13 0 12 0; #X connect 14 0 12 0; #X connect 15 0 11 0; -#X connect 16 0 51 0; +#X connect 16 0 50 0; #X connect 17 0 19 0; #X connect 18 0 21 0; #X connect 19 0 18 0; #X connect 21 0 20 0; -#X connect 24 0 51 0; -#X connect 25 0 51 0; -#X connect 26 0 51 0; -#X connect 27 0 51 0; -#X connect 28 0 51 0; -#X connect 29 0 51 1; -#X connect 36 0 51 2; -#X connect 38 0 51 3; -#X connect 39 0 51 4; -#X connect 40 0 51 5; -#X connect 41 0 51 6; -#X connect 46 0 11 0; -#X connect 47 0 51 0; -#X connect 48 0 51 0; -#X connect 49 0 51 0; -#X connect 50 0 51 0; -#X connect 51 0 0 0; -#X connect 53 0 51 7; -#X connect 55 0 51 0; -#X connect 56 0 55 0; -#X connect 57 0 58 0; -#X connect 58 0 51 0; -#X connect 59 0 60 0; -#X connect 60 0 51 0; -#X connect 61 0 51 0; -#X connect 62 0 51 8; -#X connect 64 0 51 9; +#X connect 24 0 50 0; +#X connect 25 0 50 0; +#X connect 26 0 50 0; +#X connect 27 0 50 0; +#X connect 28 0 50 1; +#X connect 35 0 50 2; +#X connect 37 0 50 3; +#X connect 38 0 50 4; +#X connect 39 0 50 5; +#X connect 40 0 50 6; +#X connect 45 0 11 0; +#X connect 46 0 50 0; +#X connect 47 0 50 0; +#X connect 48 0 50 0; +#X connect 49 0 50 0; +#X connect 50 0 0 0; +#X connect 52 0 50 7; +#X connect 54 0 50 0; +#X connect 55 0 54 0; +#X connect 56 0 57 0; +#X connect 57 0 50 0; +#X connect 58 0 59 0; +#X connect 59 0 50 0; +#X connect 60 0 50 0; +#X connect 61 0 50 8; +#X connect 63 0 50 9; +#X connect 65 0 50 0; diff --git a/modules/Makefile b/modules/Makefile index a00c7d3..171ebfd 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -20,7 +20,7 @@ OBJECTS = pdp_intrusion.o pdp_yqt.o pdp_simura.o pdp_underwatch.o \ pdp_disintegration.o pdp_distance.o pdp_theorin~.o \ pdp_theorout~.o pdp_cropper.o pdp_background.o \ pdp_mapper.o pdp_theonice~.o pdp_icedthe~.o\ - pdp_fdiff.o pdp_hue.o \ - pdp_live~.o pdp_ffmpeg~.o # pdp_xcanvas.o pdp_aa.o + pdp_fdiff.o pdp_hue.o pdp_qtext.o \ + # pdp_xcanvas.o pdp_aa.o all_modules: $(OBJECTS) diff --git a/modules/Makefile.in b/modules/Makefile.in index 128795c..b3c712c 100644 --- a/modules/Makefile.in +++ b/modules/Makefile.in @@ -20,7 +20,7 @@ OBJECTS = pdp_intrusion.o pdp_yqt.o pdp_simura.o pdp_underwatch.o \ pdp_disintegration.o pdp_distance.o pdp_theorin~.o \ pdp_theorout~.o pdp_cropper.o pdp_background.o \ pdp_mapper.o pdp_theonice~.o pdp_icedthe~.o\ - pdp_fdiff.o pdp_hue.o \ + pdp_fdiff.o pdp_hue.o pdp_qtext.o \ @PDP_STREAMING_OBJECTS@ # pdp_xcanvas.o pdp_aa.o all_modules: $(OBJECTS) diff --git a/modules/pdp_imgloader.c b/modules/pdp_imgloader.c index 752e4bc..2d74738 100644 --- a/modules/pdp_imgloader.c +++ b/modules/pdp_imgloader.c @@ -1,6 +1,6 @@ /* * PiDiP module - * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) + * Copyright (c) by Yves Degoyon (ydegoyon@free.fr) and Pablo Martin Caedes ( caedes@sindominio.net ) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ #define MAX_ZONES 20 -static char *pdp_imgloader_version = "pdp_imgloader: version 0.1 : image loading object written by ydegoyon@free.fr "; +static char *pdp_imgloader_version = "pdp_imgloader: version 0.2 : image loading object written by ydegoyon@free.fr, improved by caedes@sindominio.net"; typedef struct _triangle { @@ -66,14 +66,18 @@ typedef struct pdp_imgloader_struct DATA32 *x_imdata; t_int x_iwidth; t_int x_iheight; + t_int x_operation; + t_int b_fit; t_float x_blend; + t_int x_quality; // quality forces an additional yuv->rgb conversion in yuv mode t_triangle x_hiddenzones[ MAX_ZONES ]; // hide these parts of the image unsigned char *x_mask; } t_pdp_imgloader; +static void draw_rgb_image(t_pdp_imgloader *x); /* load an image */ static void pdp_imgloader_load(t_pdp_imgloader *x, t_symbol *filename, t_floatarg fx, t_floatarg fy) { @@ -98,8 +102,16 @@ static void pdp_imgloader_load(t_pdp_imgloader *x, t_symbol *filename, t_floatar x->x_iwidth = imlib_image_get_width(); x->x_iheight = imlib_image_get_height(); post( "pdp_imgloader : loaded : %s (%dx%d)", filename->s_name, x->x_iwidth, x->x_iheight ); - if ( fx!= 0.) x->x_xoffset = (int) fx; - if ( fy!= 0.) x->x_yoffset = (int) fy; + x->x_xoffset = (int) fx; + x->x_yoffset = (int) fy; + + //if ( fx!= 0.) x->x_xoffset = (int) fx; + //if ( fy!= 0.) x->x_yoffset = (int) fy; + DATA8 tablas[768]; + DATA8 *redt,*greent,*bluet; + redt = &tablas[0]; + greent = &tablas[256]; + bluet = &tablas[512]; } static void pdp_imgloader_xoffset(t_pdp_imgloader *x, t_floatarg fx ) @@ -112,14 +124,32 @@ static void pdp_imgloader_yoffset(t_pdp_imgloader *x, t_floatarg fy ) x->x_yoffset = (int) fy; } +static void pdp_imgloader_quality(t_pdp_imgloader *x, t_floatarg fqual ) +{ + x->x_quality = (int) fqual; +} + static void pdp_imgloader_blend(t_pdp_imgloader *x, t_floatarg fblend ) { - if ( ( fblend > 0.0 ) && ( fblend < 1.0 ) ) + if ( ( fblend >= 0.0 ) && ( fblend <= 1.0 ) ) { x->x_blend = fblend; } } - +static void pdp_imgloader_fit(t_pdp_imgloader *x, t_floatarg ffit ) +{ + if ( ( ffit >= 0.0 ) ) + { + x->b_fit = (int)ffit; + } +} +static void pdp_imgloader_operation(t_pdp_imgloader *x, t_symbol *s) +{ + if (s == gensym("copy")) x->x_operation = IMLIB_OP_COPY; + else if (s == gensym("add")) x->x_operation = IMLIB_OP_ADD; + else if (s == gensym("substract")) x->x_operation = IMLIB_OP_SUBTRACT; + else if (s == gensym("reshade")) x->x_operation = IMLIB_OP_RESHADE; +} static t_int pdp_imgloader_isinzone(t_pdp_imgloader *x, t_int px, t_int py, t_int index) { t_int c1=0, c2=0, c3=0; @@ -472,10 +502,12 @@ static void pdp_imgloader_unhide(t_pdp_imgloader *x, t_floatarg findex ) static void pdp_imgloader_clear(t_pdp_imgloader *x ) { - //if ( x->x_image != NULL ) - //{ - // imlib_free_image(); - //} + if ( x->x_image != NULL ) + { + imlib_context_set_image(x->x_image); + imlib_image_put_back_data(x->x_imdata); + imlib_free_image(); + } x->x_image = NULL; } @@ -492,6 +524,46 @@ static void pdp_imgloader_allocate(t_pdp_imgloader *x ) x->x_mask = (unsigned char*)getbytes( x->x_vsize ); } +static void draw_rgb_image(t_pdp_imgloader *x) +{ + Imlib_Image im_target = imlib_context_get_image(); + imlib_context_set_operation(x->x_operation); + + int i; + DATA8 redt[256], greent[256], bluet[256], alphat[256]; + Imlib_Color_Modifier colormod = imlib_create_color_modifier(); + imlib_context_set_color_modifier(colormod); + imlib_context_set_image(x->x_image); + Imlib_Image image_buf= imlib_clone_image(); //clones for color mod + imlib_context_set_image(image_buf); + if ( x->x_blend < 1.0 ) + { + imlib_get_color_modifier_tables( redt, greent, bluet, alphat ); + for ( i=0; i<=255; i++ ) + { + alphat[i]=alphat[i]*x->x_blend; + } + imlib_set_color_modifier_tables( redt, greent, bluet, alphat ); + imlib_apply_color_modifier(); + } + imlib_context_set_image(im_target); + if (x->b_fit) + { + imlib_blend_image_onto_image(image_buf,0,0,0,x->x_iwidth,x->x_iheight,x->x_xoffset,x->x_yoffset, + x->x_xoffset+x->x_vwidth,x->x_yoffset+x->x_vheight); + } + else + { + imlib_blend_image_onto_image(image_buf,0,0,0,x->x_iwidth,x->x_iheight,x->x_xoffset,x->x_yoffset,x->x_iwidth,x->x_iheight); + } + imlib_context_set_operation(IMLIB_OP_COPY); + + imlib_context_set_image(image_buf); + imlib_free_image(); + imlib_free_color_modifier(); + imlib_context_set_image(im_target); +} + static void pdp_imgloader_process_yv12(t_pdp_imgloader *x) { t_pdp *header = pdp_packet_header(x->x_packet0); @@ -516,62 +588,65 @@ static void pdp_imgloader_process_yv12(t_pdp_imgloader *x) newheader->info.image.encoding = header->info.image.encoding; newheader->info.image.width = x->x_vwidth; newheader->info.image.height = x->x_vheight; - - memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); - - if ( x->x_image != NULL ) imlib_context_set_image(x->x_image); - pY = newdata; - pV = newdata+x->x_vsize; - pU = newdata+x->x_vsize+(x->x_vsize>>2); - for ( py=0; pyx_vheight; py++ ) + if (x->x_quality && x->x_image != NULL) { - for ( px=0; pxx_vwidth; px++ ) - { - if ( ( x->x_image != NULL ) - && (px >= x->x_xoffset) && ( px < x->x_xoffset + x->x_iwidth ) - && (py >= x->x_yoffset) && ( py < x->x_yoffset + x->x_iheight ) - && ( !(*(x->x_mask+py*x->x_vwidth+px)) ) - ) + Imlib_Image newframe; //only for quality mode + newframe = imlib_create_image(x->x_vwidth, x->x_vheight); + imlib_context_set_image(newframe); + DATA32 *imdata = imlib_image_get_data(); + yuv_Y122RGB( data, imdata, x->x_vwidth, x->x_vheight ); + draw_rgb_image(x); + yuv_RGB2Y12( imdata, newdata, x->x_vwidth, x->x_vheight ); + imlib_image_put_back_data(imdata); + imlib_free_image(); + } + else + { + if ( x->x_image != NULL ) imlib_context_set_image(x->x_image); + memcpy( newdata, data, (x->x_vsize+(x->x_vsize>>1))<<1 ); + + pY = newdata; + pV = newdata+x->x_vsize; + pU = newdata+x->x_vsize+(x->x_vsize>>2); + for ( py=0; pyx_vheight; py++ ) { - y = yuv_RGBtoY(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); - u = yuv_RGBtoU(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); - v = yuv_RGBtoV(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); - - - if ( imlib_image_has_alpha() ) - { - alpha = (x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)] >> 24)/255; - } - else - { - alpha = 1.0; - } - factor = x->x_blend*alpha; - - *(pY) = (int)((1-factor)*(*(pY)) + factor*(y<<7)); + for ( px=0; pxx_vwidth; px++ ) + { + if ( ( x->x_image != NULL ) + && (px >= x->x_xoffset) && ( px < x->x_xoffset + x->x_iwidth ) + && (py >= x->x_yoffset) && ( py < x->x_yoffset + x->x_iheight ) + && ( !(*(x->x_mask+py*x->x_vwidth+px)) ) + ) + { + y = yuv_RGBtoY(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); + u = yuv_RGBtoU(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); + v = yuv_RGBtoV(x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)]); + + + if ( imlib_image_has_alpha() ) + { + alpha = (x->x_imdata[(py-x->x_yoffset)*x->x_iwidth+(px-x->x_xoffset)] >> 24)/255; + } + else + { + alpha = 1.0; + } + factor = x->x_blend*alpha; + + *(pY) = (int)((1-factor)*(*(pY)) + factor*(y<<7)); + if ( (px%2==0) && (py%2==0) ) + { + *(pV) = (int)((1-factor)*(*(pV)) + factor*((v-128)<<8)); + *(pU) = (int)((1-factor)*(*(pU)) + factor*((u-128)<<8)); + } + } + pY++; if ( (px%2==0) && (py%2==0) ) { - *(pV) = (int)((1-factor)*(*(pV)) + factor*((v-128)<<8)); - *(pU) = (int)((1-factor)*(*(pU)) + factor*((u-128)<<8)); + pV++;pU++; } + } } - // paint it white ( for debugging ) - /* - if ( ( abs( py - x->x_hiddenzones[0].a1*px - x->x_hiddenzones[0].b1 ) < 0.1 ) || - ( abs( py - x->x_hiddenzones[0].a2*px - x->x_hiddenzones[0].b2 ) < 0.1 ) || - ( abs( py - x->x_hiddenzones[0].a3*px - x->x_hiddenzones[0].b3 ) < 0.1 ) ) - { - *(pY) = (0xff<<7); - *(pU) = (0xff<<8); - *(pV) = (0xff<<8); - } - */ - pY++; - if ( (px%2==0) && (py%2==0) ) - { - pV++;pU++; - } - } } return; @@ -609,7 +684,6 @@ static void pdp_imgloader_process(t_pdp_imgloader *x) // should write something to handle these one day // but i don't use this mode break; - default: /* don't know the type, so dont pdp_imgloader_process */ break; @@ -625,8 +699,12 @@ static void pdp_imgloader_input_0(t_pdp_imgloader *x, t_symbol *s, t_floatarg f) /* if this is a register_ro message or register_rw message, register with packet factory */ if (s== gensym("register_rw")) - x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); - + switch(pdp_packet_header((int)f)->info.image.encoding) + { + case PDP_IMAGE_YV12: + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + break; + } if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ /* add the process method and callback to the process queue */ @@ -662,8 +740,10 @@ void *pdp_imgloader_new(void) x->x_queue_id = -1; x->x_image = NULL; - x->x_blend = 1; + x->x_blend = 1.0; x->x_mask = NULL; + x->x_quality = 0; + x->b_fit = 0; for ( ti=0; ti +#include "pdp.h" +#include "yuv.h" +#include +#include +#include +#include // imlib2 is required + +#define DEFAULT_CAPACITY 10 +#define DEFAULT_FONT "helmetr/16" + +#define PIDIP_TEXT_MODE_STATIC 0 +#define PIDIP_TEXT_MODE_SCROLL 1 +#define PIDIP_TEXT_MODE_FEED 2 +#define PIDIP_TEXT_MODE_SLOW 3 + +#define PIDIP_ALIGNMENT_CENTER 0 +#define PIDIP_ALIGNMENT_LEFT 1 +#define PIDIP_ALIGNMENT_RIGHT 2 + +static char *pdp_qtext_version = "pdp_qtext: version 0.2 : modified pdp_text by Pablo Martin Caedes"; + +typedef struct text_frame_struct TEXT_FRAME; +struct text_frame_struct +{ + char *text_array; + TEXT_FRAME *next; + double time; +}; + +typedef struct text_layer_struct +{ + t_int l_xoffset; // x position + t_int l_yoffset; // y position + t_int l_r; // first color + t_int l_g; + t_int l_b; + t_int l_a; + t_int l_2r; // color for even lines of feed + t_int l_2g; + t_int l_2b; + t_int l_2a; + t_int l_borderr; // color for the border + t_int l_borderg; + t_int l_borderb; + t_float l_angle; // angle + t_int l_scroll; + t_int l_alignment; // 0 - center; 1 - left; 2 - right; + t_int l_marginh; // top margin + t_int l_marginv; // bottom margin + t_int l_active; // slot is active? + + t_int l_feed_turn; // even or odd turn + + t_int l_mode; // work mode: static, scroll, feed/chat, slow + t_int l_scroll_speed; + t_int l_upwards; // whether to put new elements at top or bottom of the queue + TEXT_FRAME *l_texts; + TEXT_FRAME *l_last_text; + t_int l_ntexts; // number of texts in the chat queue + Imlib_Font l_font; +} TEXTLAYER; + +typedef struct pdp_qtext_struct +{ + t_object x_obj; + t_float x_f; + + t_int x_packet0; + t_int x_packet1; + t_int x_dropped; + t_int x_queue_id; + + t_outlet *x_outlet0; + t_int x_vwidth; + t_int x_vheight; + t_int x_vsize; + + t_int x_nbtexts; + t_int x_current; // currently selected layer + t_int x_capacity; // maximum texts + + // text layers + TEXTLAYER *x_layers; + /* imlib data */ + Imlib_Image x_image; + +} t_pdp_qtext; + +void text_layer_flush(TEXTLAYER *layer) +{ + while(layer->l_texts != NULL) + { + TEXT_FRAME *oldframe = layer->l_texts; + layer->l_texts = oldframe->next; + free(oldframe->text_array); + free(oldframe); + } + layer->l_last_text = NULL; + layer->l_ntexts = 0; + +} +void text_layer_add_start(TEXTLAYER *layer,char *text) +{ + TEXT_FRAME *newframe = (TEXT_FRAME*)getbytes(sizeof(TEXT_FRAME)); + newframe->text_array = text; + newframe->time = 0; + + if (layer->l_texts == NULL) + { + layer->l_last_text = newframe; + newframe->next = NULL; + } + else + newframe->next = layer->l_texts; + layer->l_texts = newframe; + layer->l_ntexts++; +} + +void text_layer_add_end(TEXTLAYER *layer, char *text) +{ + TEXT_FRAME *newframe = (TEXT_FRAME*)getbytes(sizeof(TEXT_FRAME)); + newframe->text_array = text; + newframe->time = 0; + newframe->next = NULL; + + if (layer->l_texts == NULL) + layer->l_texts = newframe; + else + layer->l_last_text->next = newframe; + layer->l_last_text = newframe; + layer->l_ntexts++; +} +void text_layer_delete_start(TEXTLAYER *layer) +{ + if (layer->l_texts != NULL) + { + TEXT_FRAME *oldframe = layer->l_texts; + //free(oldframe->text_array); + free(oldframe); + layer->l_texts = oldframe->next; + } + layer->l_ntexts--; +} + +TEXT_FRAME * text_layer_find_last(TEXTLAYER *layer) +{ + TEXT_FRAME *actual= layer->l_texts; + if (actual == NULL) + return NULL; + while(actual->next != NULL) + actual = actual->next; + return actual; +} +TEXT_FRAME * text_layer_find_ancestor(TEXTLAYER *layer, TEXT_FRAME *following) +{ + TEXT_FRAME *actual= layer->l_texts; + if (actual == NULL) + return NULL; + while(actual->next != following) + actual = actual->next; + return actual; +} + +void text_layer_delete_end(TEXTLAYER *layer) +{ + if (layer->l_texts != NULL) + { + TEXT_FRAME *oldframe = layer->l_last_text; + //free(oldframe->text_array); + if (oldframe == layer->l_texts) // IF IT WAS FIRST + { + layer->l_last_text = NULL; + layer->l_texts = NULL; + free(oldframe); + } + else + { + layer->l_last_text = text_layer_find_ancestor(layer,layer->l_last_text); + layer->l_last_text->next = NULL; + } + free(oldframe); + } + layer->l_ntexts--; +} + +static void pdp_qtext_delete(t_pdp_qtext *x, t_floatarg fnum ); + /* add a new text : syntax : text x y */ +static void pdp_qtext_add(t_pdp_qtext *x, t_symbol *s, int argc, t_atom *argv) +{ + char *pname; + char *pdname; + t_int len; + + if ( argc < 3 ) + { + post( "pdp_qtext : error in the number of arguments ( minimum is 3 )", argc ); + return; + } + if ( argv[0].a_type != A_SYMBOL || argv[1].a_type != A_FLOAT || argv[2].a_type != A_FLOAT ) { + post( "pdp_qtext : add : wrong arguments" ); + return; + } + + // allocate new text area + len = strlen( argv[0].a_w.w_symbol->s_name ); + if ( x->x_current == -1 ) x->x_current = 0; + + // get memory + pdname = (char *) getbytes( len+1 ); + pname = (char *) getbytes( len+1 ); + memset( pname, 0x0, len+1 ); + memcpy( pname, argv[0].a_w.w_symbol->s_name, len ); + + x->x_layers[x->x_current].l_active = 1; + // add text to selected queue + switch ( x->x_layers[x->x_current].l_mode) + { + case PIDIP_TEXT_MODE_STATIC: // REPLACE_CURRENT_TEXT + text_layer_delete_start(&x->x_layers[x->x_current]); + text_layer_add_start(&x->x_layers[x->x_current],pdname); + break; + case PIDIP_TEXT_MODE_SLOW: // REPLACE_CURRENT_TEXT + text_layer_delete_start(&x->x_layers[x->x_current]); + text_layer_add_start(&x->x_layers[x->x_current],pdname); + break; + case PIDIP_TEXT_MODE_SCROLL: // ADD_TEXT_AT_END + text_layer_add_end(&x->x_layers[x->x_current],pdname); + break; + case PIDIP_TEXT_MODE_FEED: // ADD_TEXT_AT_END_OR_START + if (!x->x_layers[x->x_current].l_upwards) // DOWNWARDS FEED + text_layer_add_start(&x->x_layers[x->x_current],pdname); + else + text_layer_add_end(&x->x_layers[x->x_current],pdname); + break; + } + + // process new text + while (*(pname)) + { + if ( (*pname=='%') && ( isdigit(*(pname+1)) || (*(pname+1)=='%') ) ) + { + t_int ivalue; + t_int ndigits; + char *piname; + + ndigits=0; + piname=pname+1; + while ( isdigit( *(piname++) ) ) ndigits++; + + ivalue=atoi(pname+1); + + // special case %% + if ( ( pname != argv[0].a_w.w_symbol->s_name ) && ( *(pname+1) == '%' ) ) + { + *(pdname++)=*(pname++); + pname++; + continue; + } + *(pdname++)=(char)ivalue; + pname+=ndigits+1; + } + else if ( !strncmp( pname, "\"", 1 ) ) // quotes are ignored unless %34 + { + pname++; + } + else + { + *(pdname++)=*(pname++); + } + } + //freebytes( pname,len+1 ); NOT SO STRANGE CRASHES XXX + *(pdname)='\0'; + + // get other parameters in command + x->x_layers[x->x_current].l_xoffset = (int)argv[1].a_w.w_float; + /*if (x->x_layers[x->x_current].l_mode == PIDIP_TEXT_MODE_SCROLL) + { + x->x_layers[x->x_current].l_yoffset = -10; // XXX: GET REAL STARTING POSITION + }*/ + //else + //{ + x->x_layers[x->x_current].l_yoffset = (int)argv[2].a_w.w_float; + //} + + if ( (argc>=4) && (argv[3].a_type == A_FLOAT) ) + { + x->x_layers[x->x_current].l_r = (int)argv[3].a_w.w_float; + } + if ( (argc>=5) && (argv[4].a_type == A_FLOAT) ) + { + x->x_layers[x->x_current].l_g = (int)argv[4].a_w.w_float; + } + if ( (argc>=6) && (argv[5].a_type == A_FLOAT) ) + { + x->x_layers[x->x_current].l_b = (int)argv[5].a_w.w_float; + } + if ( (argc>=7) && (argv[6].a_type == A_FLOAT) ) + { + x->x_layers[x->x_current].l_angle = argv[6].a_w.w_float; + } + if ( (argc>=8) && (argv[7].a_type == A_FLOAT) ) + { + x->x_layers[x->x_current].l_scroll = (int)argv[7].a_w.w_float; + } + + // post( "pdp_qtext : added text >%s< @ %d", + // x->x_layers[x->x_current].l_texts->text_array, x->x_current); + + /*if ( x->x_current > x->x_chat_base ) + x->x_current = x->x_chat_base; + x->x_nbtexts = x->x_capacity; // XXX why is this exactly ?? */ + //x->x_nbtexts++; + +} + +static void pdp_qtext_current(t_pdp_qtext *x, t_floatarg fcurrent ) +{ + if ( ( fcurrent >= 0 ) && ( fcurrent < x->x_capacity ) ) + { + x->x_current = fcurrent; + } +} + +static void pdp_qtext_textx(t_pdp_qtext *x, t_floatarg fx ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_xoffset = fx; + } +} + +static void pdp_qtext_margin(t_pdp_qtext *x, t_floatarg fx ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_marginh = fx; + } +} + +static void pdp_qtext_marginv(t_pdp_qtext *x, t_floatarg fx ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_marginv = fx; + } +} + +static void pdp_qtext_direction(t_pdp_qtext *x, t_floatarg fx ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_upwards = fx; + // post( "pdp_qtext : set direction to %d for layer %d", fx, x->x_current ); + } +} + +static void pdp_qtext_texty(t_pdp_qtext *x, t_floatarg fy ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_yoffset = fy; + } +} + +static void pdp_qtext_textr(t_pdp_qtext *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_r = fr; + } +} +static void pdp_qtext_texta(t_pdp_qtext *x, t_floatarg fa ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_a = fa; + } +} + +static void pdp_qtext_textg(t_pdp_qtext *x, t_floatarg fg ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_g = fg; + } +} + +static void pdp_qtext_textb(t_pdp_qtext *x, t_floatarg fb ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_b = fb; + } +} +static void pdp_qtext_text2r(t_pdp_qtext *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_2r = fr; + } +} +static void pdp_qtext_text2g(t_pdp_qtext *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_2g = fr; + } +} +static void pdp_qtext_text2b(t_pdp_qtext *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_2b = fr; + } +} +static void pdp_qtext_text2a(t_pdp_qtext *x, t_floatarg fa ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_2a = fa; + } +} +static void pdp_qtext_borderr(t_pdp_qtext *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_borderr = fr; + } +} +static void pdp_qtext_borderg(t_pdp_qtext *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_borderg = fr; + } +} +static void pdp_qtext_borderb(t_pdp_qtext *x, t_floatarg fr ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity) ) + { + x->x_layers[x->x_current].l_borderb = fr; + } +} + +static void pdp_qtext_angle(t_pdp_qtext *x, t_floatarg fangle ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_angle = fangle; + } +} + +static void pdp_qtext_scroll(t_pdp_qtext *x, t_floatarg fscroll ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_scroll = fscroll; + } +} + +static void pdp_qtext_center(t_pdp_qtext *x ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_alignment = PIDIP_ALIGNMENT_CENTER; + } +} +static void pdp_qtext_left(t_pdp_qtext *x ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_alignment = PIDIP_ALIGNMENT_LEFT; + } +} +static void pdp_qtext_right(t_pdp_qtext *x ) +{ + if ( ( x->x_current >= 0 ) && ( x->x_current < x->x_capacity ) ) + { + x->x_layers[x->x_current].l_alignment = PIDIP_ALIGNMENT_RIGHT; + } +} + +static void pdp_qtext_delete(t_pdp_qtext *x, t_floatarg fnum ) +{ + t_int i; + char *lostword; + + text_layer_flush(&x->x_layers[x->x_current]); + /*if ( ( fnum>=0 ) && ( fnumx_capacity ) ) + { + if (fnum >= x->x_chat_base && x->x_active[x->x_chat_base]) + { + lostword = x->x_text_array[ (int)fnum]; + fnum = x->x_chat_base; + if (x->upwards) + x->x_chat_turn++; + for ( i=(int)x->x_chat_base; ix_chat_base+x->x_chat_texts-1; i++ ) + { + x->x_text_array[ i ] = x->x_text_array[ i+1 ]; + } + x->x_active[x->x_chat_base+x->x_chat_texts-1]=0; + x->x_chat_texts--; + free( lostword ); + x->x_nbtexts--; + } + else if (x->x_active[(int)fnum]) + { + lostword = x->x_text_array[ (int)fnum]; + x->x_active[(int)fnum]=0; + free( lostword ); + x->x_nbtexts--; + } + }*/ +} +static void pdp_qtext_clear(t_pdp_qtext *x ) +{ + text_layer_flush(&x->x_layers[x->x_current]); + // must free the texts XXX + x->x_nbtexts = 0; +} +static void pdp_qtext_mode(t_pdp_qtext *x, t_symbol *s) +{ + if (s == gensym("static")) x->x_layers[x->x_current].l_mode = PIDIP_TEXT_MODE_STATIC; + else if (s == gensym("scroll")) x->x_layers[x->x_current].l_mode = PIDIP_TEXT_MODE_SCROLL; + else if (s == gensym("feed")) x->x_layers[x->x_current].l_mode = PIDIP_TEXT_MODE_FEED; + else if (s == gensym("slow")) x->x_layers[x->x_current].l_mode = PIDIP_TEXT_MODE_SLOW; +} + +static void pdp_qtext_resize(t_pdp_qtext *x, t_floatarg fnewsize ) +{ + char **text_array; + t_int *xoffsets; + t_int *yoffsets; + t_int *r; + t_int *g; + t_int *b; + t_float *angle; + t_int *scroll; + + t_int i, csize; + + TEXTLAYER * layers; + if ( (int) fnewsize<=0 ) return; + + // allocate new structures + layers = (TEXTLAYER*) getbytes( x->x_capacity*sizeof(TEXTLAYER) ); + + for ( i=0; ix_layers[i].l_borderg = x->x_layers[i].l_borderb = 255; + layers[i].l_xoffset = 0; + layers[i].l_yoffset = 0; + layers[i].l_marginh = 0; + layers[i].l_marginv = 0; + layers[i].l_active = 0; + layers[i].l_alignment = PIDIP_ALIGNMENT_LEFT; + layers[i].l_mode = PIDIP_TEXT_MODE_STATIC; + layers[i].l_font = imlib_context_get_font(); + layers[i].l_feed_turn = 0; + layers[i].l_upwards = 0; + layers[i].l_ntexts = 0; + layers[i].l_texts = NULL; + layers[i].l_last_text = NULL; + } + + if ( fnewsize < x->x_nbtexts ) + { + post( "pdp_qtext : new size is too small : texts lost !!" ); + csize = fnewsize; + } + else + { + csize = x->x_nbtexts; + } + + // copy all values + for ( i=0; ix_layers[i].l_r; + layers[i].l_g=x->x_layers[i].l_g; + layers[i].l_b=x->x_layers[i].l_b; + layers[i].l_a=x->x_layers[i].l_a; + layers[i].l_2r=x->x_layers[i].l_2r; + layers[i].l_2g=x->x_layers[i].l_2g; + layers[i].l_2b=x->x_layers[i].l_2b; + layers[i].l_2a=x->x_layers[i].l_2a; + layers[i].l_borderr=x->x_layers[i].l_borderr; + layers[i].l_borderg=x->x_layers[i].l_borderg; + layers[i].l_borderb=x->x_layers[i].l_borderb; + layers[i].l_xoffset=x->x_layers[i].l_xoffset; + layers[i].l_yoffset=x->x_layers[i].l_yoffset; + layers[i].l_marginh=x->x_layers[i].l_marginh; + layers[i].l_marginv=x->x_layers[i].l_marginv; + layers[i].l_active=x->x_layers[i].l_active; + layers[i].l_alignment=x->x_layers[i].l_alignment; + layers[i].l_mode=x->x_layers[i].l_mode; + layers[i].l_font=x->x_layers[i].l_font; + layers[i].l_feed_turn=x->x_layers[i].l_feed_turn; + layers[i].l_upwards=x->x_layers[i].l_upwards; + layers[i].l_ntexts=x->x_layers[i].l_ntexts; + layers[i].l_texts=x->x_layers[i].l_texts; + layers[i].l_last_text=x->x_layers[i].l_last_text; + } + + // free old structures + if ( x->x_layers ) freebytes( x->x_layers, x->x_capacity*sizeof(TEXTLAYER) ); + if ((int)fnewsize < x->x_capacity) + { + // do something with left over texts XXX + } + + // set new structures + x->x_layers = layers; + x->x_nbtexts = csize; + x->x_capacity = (int) fnewsize; + x->x_current = 0; + post( "pdp_qtext : resized to %d", (int) fnewsize ); +} + +static void pdp_qtext_font(t_pdp_qtext *x, t_symbol *sfont ) +{ + Imlib_Font font; + + font = imlib_load_font(sfont->s_name); + if ( !font ) + { + post( "pdp_qtext : could not load font : >%s<", sfont->s_name ); + return; + } + imlib_context_set_font( font ); + x->x_layers[x->x_current].l_font = font; +} + +static void pdp_qtext_allocate(t_pdp_qtext *x) +{ + x->x_image = imlib_create_image( x->x_vwidth, x->x_vheight ); + if ( x->x_image == NULL ) + { + post( "pdp_qtext : severe error : could not allocate image !!" ); + return; + } + imlib_context_set_image(x->x_image); +} + +static void pdp_qtext_free_ressources(t_pdp_qtext *x) +{ + // if ( x->x_image != NULL ) imlib_free_image(); +} + +void qtext_line_draw(t_pdp_qtext *x,char *text,int text_width,int text_height,int tlayer, int ti, int linenumber,double stime) +{ + int base = tlayer; + double newyoffset = 0; + int yfinalposition; + int alpha = x->x_layers[base].l_a; + if (x->x_layers[base].l_mode == PIDIP_TEXT_MODE_SCROLL) + { + if ((x->x_layers[base].l_upwards)) + newyoffset = -stime+x->x_vheight; + else + newyoffset = stime; + if (stime<50) + alpha = (alpha*(stime/50)); + if (stime>350) + alpha = alpha-(alpha*((stime-350)/50)); + } + yfinalposition = newyoffset + x->x_layers[base].l_yoffset + ((linenumber)*(text_height)) + (sin(x->x_layers[base].l_angle) * x->x_layers[base].l_scroll); + /*if (ti>=x->x_chat_base) + base = x->x_chat_base;*/ + if (((text_height)*(linenumber+1)) + x->x_layers[base].l_yoffset + x->x_layers[base].l_marginv < x->x_vheight) // CABE EN LOS MARGENES ESPECIFICADOS (DE ALTO) + { + if ((x->x_layers[base].l_feed_turn+ti)%2&&(x->x_layers[base].l_mode==PIDIP_TEXT_MODE_FEED)) + imlib_context_set_color( x->x_layers[base].l_2r, x->x_layers[base].l_2g, x->x_layers[base].l_2b, x->x_layers[base].l_2a); + else + imlib_context_set_color( x->x_layers[base].l_r, x->x_layers[base].l_g, x->x_layers[base].l_b, alpha ); + if (x->x_layers[base].l_alignment == PIDIP_ALIGNMENT_CENTER) + { + imlib_text_draw( x->x_layers[base].l_xoffset - (0.5*text_width) + (cos(x->x_layers[base].l_angle) * x->x_layers[base].l_scroll), + yfinalposition, + text ); + } + else // left aligned text + { + // CODE FOR A NOT SO NICE BORDER + /*imlib_context_set_color( 0, 0, 0, 255 ); + int borde = 2; + imlib_text_draw( x->x_xoffsets[base] + (cos(x->x_angle[base]) * x->x_scroll[base])+borde, + x->x_yoffsets[base] + (linenumber*(text_height)) + (sin(x->x_angle[base]) * x->x_scroll[base])-borde, + text ); + imlib_text_draw( x->x_xoffsets[base] + (cos(x->x_angle[base]) * x->x_scroll[base])-borde, + x->x_yoffsets[base] + (linenumber*(text_height)) + (sin(x->x_angle[base]) * x->x_scroll[base])+borde, + text ); + imlib_text_draw( x->x_xoffsets[base] + (cos(x->x_angle[base]) * x->x_scroll[base])-borde, + x->x_yoffsets[base] + (linenumber*(text_height)) + (sin(x->x_angle[base]) * x->x_scroll[base])-borde, + text ); + imlib_text_draw( x->x_xoffsets[base] + (cos(x->x_angle[base]) * x->x_scroll[base])+borde, + x->x_yoffsets[base] + (linenumber*(text_height)) + (sin(x->x_angle[base]) * x->x_scroll[base])+borde, + text );*/ + // SET ALTERNATING COLORS + imlib_text_draw( x->x_layers[base].l_xoffset + (cos(x->x_layers[base].l_angle) * x->x_layers[base].l_scroll), + yfinalposition,text); + } + } +} + +// DRAW ALL TEXTS + +static void pdp_qtext_draw_all_texts(t_pdp_qtext *x) +{ + int text_width, text_height; + int chat_lines = 0; // total lines of chat rendered + int linenumber; // lines of chat we have rendered in current message + int feed_mes = 0; // messages rendered + t_int tlayer; + + // draw all texts + imlib_context_set_direction(IMLIB_TEXT_TO_ANGLE); + + for (tlayer=0; tlayerx_capacity; tlayer++) + { + TEXT_FRAME *curr_text = x->x_layers[tlayer].l_texts; + while (curr_text != NULL) { + if (x->x_layers[tlayer].l_active) + { + t_int base=tlayer; + linenumber = 0; + int ti = feed_mes; + imlib_context_set_angle( x->x_layers[base].l_angle ); + imlib_context_set_font( x->x_layers[base].l_font ); + if (x->x_layers[base].l_mode == PIDIP_TEXT_MODE_FEED) + { + if ((x->x_layers[base].l_feed_turn+ti)%2) + imlib_context_set_color( x->x_layers[base].l_r, x->x_layers[base].l_g, x->x_layers[base].l_b, x->x_layers[base].l_a ); + else + imlib_context_set_color( x->x_layers[base].l_r, x->x_layers[base].l_g, x->x_layers[base].l_b, x->x_layers[base].l_a ); + } + else + { + imlib_context_set_color( x->x_layers[base].l_r, x->x_layers[base].l_g, x->x_layers[base].l_b, x->x_layers[base].l_a ); + } + + imlib_context_set_font( x->x_layers[base].l_font ); + imlib_get_text_size( curr_text->text_array, &text_width, &text_height); + + // code which separates the message in lines + if (text_width + x->x_layers[base].l_xoffset + x->x_layers[base].l_marginh > x->x_vwidth) + { // MESSAGE CAN'T BE DRAWN IN A LINE + char *token = NULL, *cp; + cp = strdup (curr_text->text_array); + if (x->x_layers[base].l_mode == PIDIP_TEXT_MODE_SLOW && curr_text->time/10text_array)) + cp[(int)(curr_text->time/10)] = '\0'; + token = strtok (cp, " .,;:"); + char buf[256]; + char *position = buf; + char prev[256]; + int wordcount = 0; + while (token != NULL) + { + strcpy(prev,buf); + wordcount++; + if (wordcount != 1) + *(position++) = ' '; + position = stpcpy(position,token); + imlib_get_text_size( buf, &text_width, &text_height); + if (text_width + x->x_layers[base].l_xoffset + x->x_layers[base].l_marginh> x->x_vwidth) + { // YA TENEMOS UNA CADENA PARA LA 1 LINEA + char * textofinal; + if (wordcount == 1) + textofinal = buf; + else + textofinal = prev; + imlib_get_text_size( textofinal, &text_width, &text_height); + qtext_line_draw(x,textofinal, text_width,text_height,tlayer,feed_mes,chat_lines+linenumber,curr_text->time); + if (wordcount == 1) + { + position = stpcpy(buf,""); + wordcount=0; + } + else + { + position = stpcpy(buf,token); + wordcount=1; + } + linenumber++; + } + token = strtok (NULL, " .,;:"); + } + // draw the rests in the buffer + if (strlen(buf)>0) + { + imlib_get_text_size( buf, &text_width, &text_height); + qtext_line_draw(x,buf, text_width,text_height,tlayer,feed_mes,chat_lines+linenumber,curr_text->time); + linenumber++; + } + free(cp); + } + else // MESSAGE CAN BE DRAWN IN A LINE + { + char *cp; + cp = strdup (curr_text->text_array); + if (x->x_layers[base].l_mode == PIDIP_TEXT_MODE_SLOW && curr_text->time/10text_array)) + cp[(int)(curr_text->time/10)] = '\0'; + qtext_line_draw(x,cp, text_width,text_height,tlayer,feed_mes,chat_lines,curr_text->time); + linenumber=1; + free(cp); + } + // if we are in chat mode remember number of lines + if (x->x_layers[base].l_mode == PIDIP_TEXT_MODE_FEED ) + chat_lines+=linenumber; + } + feed_mes++; + curr_text->time++; + if (curr_text->time > 400 && x->x_layers[tlayer].l_mode == PIDIP_TEXT_MODE_SCROLL && curr_text == x->x_layers[tlayer].l_texts) + { + text_layer_delete_start(&x->x_layers[tlayer]); + } + curr_text = curr_text->next; + } // while(curr_text != NULL); + } // for (tlayer=0; tlayerx_capacity; tlayer++) +} + +static void pdp_qtext_process_yv12(t_pdp_qtext *x) +{ + t_pdp *header = pdp_packet_header(x->x_packet0); + short int *data = (short int *)pdp_packet_data(x->x_packet0); + t_pdp *newheader = pdp_packet_header(x->x_packet1); + short int *newdata = (short int *)pdp_packet_data(x->x_packet1); + t_int ti; + t_int px, py; + unsigned char y, u, v; + DATA32 *imdata; + DATA32 bgcolor=0; + short int *pY, *pU, *pV; + int text_width, text_height; + int chat_lines = 0; + + // ensure the prepared surface is the same size as the image + if ( ( (int)(header->info.image.width) != x->x_vwidth ) || + ( (int)(header->info.image.height) != x->x_vheight ) ) + { + pdp_qtext_free_ressources(x); + x->x_vwidth = header->info.image.width; + x->x_vheight = header->info.image.height; + x->x_vsize = x->x_vwidth*x->x_vheight; + pdp_qtext_allocate(x); + } + + // prepare packets + newheader->info.image.encoding = header->info.image.encoding; + newheader->info.image.width = x->x_vwidth; + newheader->info.image.height = x->x_vheight; + + // prepare image + if ( x->x_image != NULL ) imlib_context_set_image(x->x_image); + imdata = imlib_image_get_data(); + + // copy incoming packet to Imlib image + yuv_Y122RGB( data, imdata, x->x_vwidth, x->x_vheight ); + + // draw all texts to imlib surface + pdp_qtext_draw_all_texts(x); + + // copy Imlib image to outgoing packet + yuv_RGB2Y12( imdata, newdata, x->x_vwidth, x->x_vheight ); + + return; +} + +static void pdp_qtext_sendpacket(t_pdp_qtext *x) +{ + /* delete source packet */ + pdp_packet_mark_unused(x->x_packet0); + x->x_packet0 = -1; + + /* unregister and propagate if valid dest packet */ + pdp_packet_pass_if_valid(x->x_outlet0, &x->x_packet1); +} + +static void pdp_qtext_process(t_pdp_qtext *x) +{ + int encoding; + t_pdp *header = 0; + + /* check if image data packets are compatible */ + if ( (header = pdp_packet_header(x->x_packet0)) + && (PDP_IMAGE == header->type)){ + + /* pdp_qtext_process inputs and write into active inlet */ + switch(pdp_packet_header(x->x_packet0)->info.image.encoding) + { + + case PDP_IMAGE_YV12: + x->x_packet1 = pdp_packet_clone_rw(x->x_packet0); + pdp_queue_add(x, pdp_qtext_process_yv12, pdp_qtext_sendpacket, &x->x_queue_id); + break; + + case PDP_IMAGE_GREY: + // should write something to handle these one day + // but i don't use this mode + break; + default: + /* don't know the type, so dont pdp_qtext_process */ + break; + + } + } + +} + +static void pdp_qtext_input_0(t_pdp_qtext *x, t_symbol *s, t_floatarg f) +{ + + /* if this is a register_ro message or register_rw message, register with packet factory */ + + if (s== gensym("register_rw")) + { + switch(pdp_packet_header((int)f)->info.image.encoding) + { + case PDP_IMAGE_YV12: + x->x_dropped = pdp_packet_convert_ro_or_drop(&x->x_packet0, (int)f, pdp_gensym("image/YCrCb/*") ); + break; + } + } + if ((s == gensym("process")) && (-1 != x->x_packet0) && (!x->x_dropped)){ + + /* add the process method and callback to the process queue */ + pdp_qtext_process(x); + + } + +} + +static void pdp_qtext_free(t_pdp_qtext *x) +{ + int i; + + pdp_qtext_free_ressources(x); + pdp_queue_finish(x->x_queue_id); + pdp_packet_mark_unused(x->x_packet0); +} + +t_class *pdp_qtext_class; + +void *pdp_qtext_new(void) +{ + int i; + + t_pdp_qtext *x = (t_pdp_qtext *)pd_new(pdp_qtext_class); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("current")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textx")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("texty")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textr")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textg")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("textb")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("angle")); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("scroll")); + + x->x_outlet0 = outlet_new(&x->x_obj, &s_anything); + x->x_packet0 = -1; + x->x_packet1 = -1; + x->x_queue_id = -1; + x->x_image = NULL; + + + x->x_capacity = DEFAULT_CAPACITY; + + + x->x_layers = (TEXTLAYER*) getbytes( x->x_capacity*sizeof(TEXTLAYER) ); + + for ( i=0; ix_capacity; i++ ) + { + x->x_layers[i].l_r = x->x_layers[i].l_g = x->x_layers[i].l_b = x->x_layers[i].l_a = 255; + x->x_layers[i].l_2r = x->x_layers[i].l_2g = x->x_layers[i].l_2b = x->x_layers[i].l_2a = 255; + x->x_layers[i].l_borderr = x->x_layers[i].l_borderg = x->x_layers[i].l_borderb = 255; + x->x_layers[i].l_xoffset = 0; + x->x_layers[i].l_yoffset = 0; + x->x_layers[i].l_marginh = 0; + x->x_layers[i].l_scroll_speed = 1; + x->x_layers[i].l_marginv = 0; + x->x_layers[i].l_active = 0; + x->x_layers[i].l_alignment = PIDIP_ALIGNMENT_LEFT; + x->x_layers[i].l_mode = PIDIP_TEXT_MODE_STATIC; + x->x_layers[i].l_font = imlib_context_get_font(); + x->x_layers[i].l_feed_turn = 0; + x->x_layers[i].l_upwards = 0; + x->x_layers[i].l_ntexts = 0; + x->x_layers[i].l_texts = NULL; + x->x_layers[i].l_last_text = NULL; + } + x->x_current = 0; + x->x_nbtexts = 0; + return (void *)x; +} + + +#ifdef __cplusplus +extern "C" +{ +#endif + + +void pdp_qtext_setup(void) +{ + Imlib_Font font; + + // post( pdp_qtext_version ); + pdp_qtext_class = class_new(gensym("pdp_qtext"), (t_newmethod)pdp_qtext_new, + (t_method)pdp_qtext_free, sizeof(t_pdp_qtext), 0, A_NULL); + + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_input_0, gensym("pdp"), + A_SYMBOL, A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_add, gensym("text"), A_GIMME, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_current, gensym("current"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_textx, gensym("textx"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_texty, gensym("texty"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_textr, gensym("textr"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_textg, gensym("textg"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_textb, gensym("textb"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_texta, gensym("texta"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_text2r, gensym("text2r"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_text2g, gensym("text2g"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_text2b, gensym("text2b"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_text2a, gensym("text2a"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_borderr, gensym("borderr"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_borderg, gensym("borderg"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_borderb, gensym("borderb"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_clear, gensym("clear"), A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_delete, gensym("delete"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_resize, gensym("resize"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_font, gensym("font"), A_SYMBOL, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_angle, gensym("angle"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_scroll, gensym("scroll"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_left, gensym("left"), A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_right, gensym("right"), A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_center, gensym("center"), A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_margin, gensym("margin"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_marginv, gensym("marginv"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_direction, gensym("direction"), A_DEFFLOAT, A_NULL); + class_addmethod(pdp_qtext_class, (t_method)pdp_qtext_mode, gensym("layermode"), A_SYMBOL, A_NULL); + class_sethelpsymbol( pdp_qtext_class, gensym("pdp_qtext.pd") ); + + imlib_add_path_to_font_path("/usr/X11R6/lib/X11/fonts/TTF"); + font = imlib_load_font(DEFAULT_FONT); + if ( !font ) + { + post( "pdp_qtext : severe error : could not load default font : no rendering !!!" ); + } + imlib_context_set_font( font ); +} + +#ifdef __cplusplus +} +#endif diff --git a/system/pidip.c b/system/pidip.c index 1a75e5f..89d7bc9 100644 --- a/system/pidip.c +++ b/system/pidip.c @@ -42,6 +42,7 @@ extern "C" void pdp_dice_setup(void); void pdp_puzzle_setup(void); void pdp_text_setup(void); + void pdp_qtext_setup(void); void pdp_form_setup(void); void pdp_compose_setup(void); void pdp_cmap_setup(void); @@ -128,6 +129,7 @@ void pidip_setup(void){ pdp_dice_setup(); pdp_puzzle_setup(); pdp_text_setup(); + pdp_qtext_setup(); pdp_form_setup(); pdp_compose_setup(); pdp_cmap_setup(); -- cgit v1.2.1