From ea9ae4923bc169fd74b32aa090fd60b684fbd09a Mon Sep 17 00:00:00 2001 From: Stefan Holst Date: Sun, 6 Apr 2003 15:50:56 +0000 Subject: - freetype2 support for osd - png autoconf improvements CVS patchset: 4554 CVS date: 2003/04/06 15:50:56 --- configure.ac | 45 ++++++++++-- include/xine.h.in | 8 ++- src/xine-engine/Makefile.am | 8 +-- src/xine-engine/osd.c | 163 +++++++++++++++++++++++++++++++++++++++++--- src/xine-engine/osd.h | 4 +- 5 files changed, 207 insertions(+), 21 deletions(-) diff --git a/configure.ac b/configure.ac index d1ceb2bf9..f533f979c 100644 --- a/configure.ac +++ b/configure.ac @@ -628,15 +628,46 @@ AC_SUBST(MNG_LIBS) dnl --------------------------------------------- dnl PNG lib. dnl --------------------------------------------- -AC_CHECK_LIB(png, png_create_read_struct, - [ AC_CHECK_HEADER(png.h, - [ have_libpng=yes - PNG_LIBS="-lpng" ], - AC_MSG_RESULT([*** image decoder will be disabled ***]))], - AC_MSG_RESULT([*** image decoder will be disabled ***])) -AM_CONDITIONAL(HAVE_LIBPNG, test x"$have_libpng" = "xyes") +dnl AC_CHECK_LIB(png, png_create_read_struct, +dnl [ AC_CHECK_HEADER(png.h, +dnl [ have_libpng=yes +dnl PNG_LIBS="-lpng" ], +dnl AC_MSG_RESULT([*** image decoder will be disabled ***]))], +dnl AC_MSG_RESULT([*** image decoder will be disabled ***])) +dnl AM_CONDITIONAL(HAVE_LIBPNG, test x"$have_libpng" = "xyes") +dnl AC_SUBST(PNG_LIBS) + +AC_PATH_PROG(LIBPNG_CONFIG, libpng-config, no) +if test "$LIBPNG_CONFIG" = "no" ; then + AC_MSG_RESULT([*** libpng-config not found, png support disabled ***]) +else + PNG_CFLAGS=`$LIBPNG_CONFIG --cflags` + PNG_LIBS=`$LIBPNG_CONFIG --libs` + have_libpng="yes" + AC_DEFINE(HAVE_LIBPNG,1,[Define this if you have png library]) +fi + +AM_CONDITIONAL(HAVE_LIBPNG, test x"$have_libpng" = "xyes" ) +AC_SUBST(PNG_CFLAGS) AC_SUBST(PNG_LIBS) +dnl --------------------------------------------- +dnl freetype2 lib. +dnl --------------------------------------------- +AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no) +if test "$FREETYPE_CONFIG" = "no" ; then + AC_MSG_RESULT([*** freetype-config not found, freetype2 support disabled ***]) +else + FT2_CFLAGS=`$FREETYPE_CONFIG --cflags` + FT2_LIBS=`$FREETYPE_CONFIG --libs` + have_ft2="yes" + AC_DEFINE(HAVE_FT2,1,[Define this if you have freetype2 library]) +fi + +AM_CONDITIONAL(HAVE_FT2, test x"$have_ft2" = "xyes" ) +AC_SUBST(FT2_CFLAGS) +AC_SUBST(FT2_LIBS) + dnl --------------------------------------------- dnl OSS style audio interface dnl --------------------------------------------- diff --git a/include/xine.h.in b/include/xine.h.in index 263d794da..cedf68c29 100644 --- a/include/xine.h.in +++ b/include/xine.h.in @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine.h.in,v 1.71 2003/04/04 19:20:46 miguelfreitas Exp $ + * $Id: xine.h.in,v 1.72 2003/04/06 15:50:57 holstsn Exp $ * * public xine-lib (libxine) interface and documentation * @@ -1492,13 +1492,19 @@ void xine_osd_draw_line (xine_osd_t *self, int x1, int y1, void xine_osd_draw_rect (xine_osd_t *self, int x1, int y1, int x2, int y2, int color, int filled ); +/* for freetype2 fonts x1 and y1 specifies the beginning of the baseline, + for xine fonts x1 and y1 specifies the upper left corner of the text + to be rendered */ void xine_osd_draw_text (xine_osd_t *self, int x1, int y1, const char *text, int color_base); void xine_osd_draw_bitmap (xine_osd_t *self, uint8_t *bitmap, int x1, int y1, int width, int height, uint8_t *palette_map); +/* for freetype2 fonts the height is taken from _baseline_ to top */ void xine_osd_get_text_size (xine_osd_t *self, const char *text, int *width, int *height); +/* with freetype2 support compiled in, you can also specify a font file + as 'fontname' here */ void xine_osd_set_font (xine_osd_t *self, const char *fontname, int size); /* set position were overlay will be blended */ diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am index 2a4987922..e79353708 100644 --- a/src/xine-engine/Makefile.am +++ b/src/xine-engine/Makefile.am @@ -4,7 +4,7 @@ SUBDIRS = nvtv -AM_CFLAGS = $(THREAD_CFLAGS) $(X_CFLAGS) @ANSI_FLAGS@ +AM_CFLAGS = $(THREAD_CFLAGS) $(X_CFLAGS) $(FT2_CFLAGS) @ANSI_FLAGS@ lib_LTLIBRARIES = libxine.la @@ -20,11 +20,11 @@ libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c \ if HAVE_NVTV libxine_la_DEPENDENCIES = @INTLLIBS@ $(XINEUTILS_LIB) $(NVTVCLIENT_LIB) libxine_la_LIBADD = $(THREAD_LIBS) $(DYNAMIC_LD_LIBS) @INTLLIBS@ $(ZLIB_LIBS) \ - -lm $(XINEUTILS_LIB) $(NVTVCLIENT_LIB) $(GICONV_BSD_LIBS) + -lm $(XINEUTILS_LIB) $(NVTVCLIENT_LIB) $(GICONV_BSD_LIBS) $(FT2_LIBS) else libxine_la_DEPENDENCIES = @INTLLIBS@ $(XINEUTILS_LIB) libxine_la_LIBADD = $(THREAD_LIBS) $(DYNAMIC_LD_LIBS) @INTLLIBS@ $(ZLIB_LIBS) \ - -lm $(XINEUTILS_LIB) $(GICONV_BSD_LIBS) + -lm $(XINEUTILS_LIB) $(GICONV_BSD_LIBS) $(FT2_LIBS) endif libxine_la_LDFLAGS = \ @@ -42,7 +42,7 @@ noinst_HEADERS = bswap.h @INCLUDED_INTL_TRUE@ @cd $(top_builddir)/intl && $(MAKE) libintl.la debug: - @$(MAKE) CFLAGS="$(DEBUG_CFLAGS) $(THREAD_CFLAGS) $(X_CFLAGS)" + @$(MAKE) CFLAGS="$(DEBUG_CFLAGS) $(THREAD_CFLAGS) $(X_CFLAGS) $(FT2_CFLAGS)" install-debug: debug @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am diff --git a/src/xine-engine/osd.c b/src/xine-engine/osd.c index 2aad7e139..6c78c9344 100644 --- a/src/xine-engine/osd.c +++ b/src/xine-engine/osd.c @@ -46,6 +46,11 @@ #include "video_out.h" #include "osd.h" +#ifdef HAVE_FT2 +#include +#include FT_FREETYPE_H +#endif + /* #define LOG_DEBUG 1 */ @@ -81,6 +86,15 @@ struct osd_font_s { osd_font_t *next; }; +struct osd_ft2context_s { +#ifdef HAVE_FT2 + int useme; + FT_Library library; + FT_Face face; + int size; +#endif +}; + /* * open a new osd object. this will allocated an empty (all zero) drawing * area where graphic primitives may be used. @@ -641,6 +655,38 @@ static int osd_set_font( osd_object_t *osd, const char *fontname, int size) { } font = font->next; } + +#ifdef HAVE_FT2 + + if (osd->ft2) { + osd->ft2->useme = 0; + } + + if (!ret) { /* trying to load a font file with ft2 */ + if (!osd->ft2) { + osd->ft2 = xine_xmalloc(sizeof(osd_ft2context_t)); + if(FT_Init_FreeType( &osd->ft2->library )) { + printf("osd: cannot initialize ft2 library\n"); + free(osd->ft2); + osd->ft2 = NULL; + } + } + if (osd->ft2) { + if (FT_New_Face(osd->ft2->library, fontname, 0, &osd->ft2->face)) { + printf("osd: error loading font with ft2\n"); + } else { + if (FT_Set_Pixel_Sizes(osd->ft2->face, 0, size)) { + printf("osd: error setting font size (no scalable font?)"); + } else { + ret = 1; + osd->ft2->useme = 1; + osd->ft2->size = size; + } + } + } + } + +#endif pthread_mutex_unlock (&this->osd_mutex); return ret; @@ -699,11 +745,20 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, color_base = OVL_PALETTE_SIZE - TEXT_PALETTE_SIZE; pthread_mutex_lock (&this->osd_mutex); - - if ((font = osd->font) == NULL) { - printf(_("osd: font isn't defined\n")); - pthread_mutex_unlock(&this->osd_mutex); - return 0; + + { + int proceed = 0; + + if ((font = osd->font)) proceed = 1; +#ifdef HAVE_FT2 + if (osd->ft2 && osd->ft2->useme) proceed = 1; +#endif + + if (proceed == 0) { + printf(_("osd: font isn't defined\n")); + pthread_mutex_unlock(&this->osd_mutex); + return 0; + } } if( x1 < osd->x1 ) osd->x1 = x1; @@ -754,7 +809,13 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, inbuf++; unicode = ALIAS_CHARACTER; } - + +#ifdef HAVE_FT2 + if (osd->ft2 && osd->ft2->useme) { + i = FT_Get_Char_Index( osd->ft2->face, unicode ); + } else { +#endif + #ifdef BINARY_SEARCH i = binsearch(font->fontchar, font->num_fontchars, unicode); #else @@ -764,12 +825,58 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, } #endif +#ifdef HAVE_FT2 + } /* !(osd->ft2 && osd->ft2->useme) */ +#endif + + #ifdef LOG_DEBUG printf("font %s [%d, U+%04X] %dx%d -> %d,%d\n", font->name, i, unicode, font->fontchar[i].code, font->fontchar[i].width, font->fontchar[i].height, x1, y1); #endif +#ifdef HAVE_FT2 + if (osd->ft2 && osd->ft2->useme) { + int gheight, gwidth; + FT_GlyphSlot slot = osd->ft2->face->glyph; + + if (FT_Load_Glyph(osd->ft2->face, i, FT_LOAD_DEFAULT)) { + printf("osd: error loading glyph\n"); + continue; + } + + if (slot->format != ft_glyph_format_bitmap) { + if (FT_Render_Glyph(osd->ft2->face->glyph, ft_render_mode_normal)) + printf("osd: error in rendering glyph\n"); + } + + dst = osd->area + y1 * osd->width + x1; + src = (uint8_t*) slot->bitmap.buffer; + gheight = slot->bitmap.rows; + gwidth = slot->bitmap.width; + + for( y = 0; y < gheight; y++ ) { + uint8_t *s = src; + uint8_t *d = dst + - slot->bitmap_top * osd->width + + slot->bitmap_left; + + while (s < src + gwidth) { + if(d <= (osd->area + (osd->width * osd->height))) + *d = (uint8_t)(*s/26+1) + (uint8_t) color_base; + + d++; + s++; + } + src += slot->bitmap.pitch; + dst += osd->width; + } + x1 += slot->advance.x >> 6; + + } else { +#endif + if ( i != font->num_fontchars ) { dst = osd->area + y1 * osd->width + x1; src = font->fontchar[i].bmp; @@ -794,6 +901,11 @@ static int osd_render_text (osd_object_t *osd, int x1, int y1, if( y1 + font->fontchar[i].height > osd->y2 ) osd->y2 = y1 + font->fontchar[i].height; } + +#ifdef HAVE_FT2 + } /* !(osd->ft2 && osd->ft2->useme) */ +#endif + } iconv_close(cd); @@ -820,8 +932,37 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in font = osd->font; *width = 0; - *height = 0; - + *height = 0; + +#ifdef HAVE_FT2 + if (osd->ft2 && osd->ft2->useme) { + int first = 1, bottom = 0, top = 0; + FT_GlyphSlot slot = osd->ft2->face->glyph; + + while (*text) { + + i = FT_Get_Char_Index( osd->ft2->face, *text); + + if (FT_Load_Glyph(osd->ft2->face, i, FT_LOAD_DEFAULT)) { + printf("osd: error loading glyph %i\n", i); + text++; + continue; + } + + if (slot->format != ft_glyph_format_bitmap) { + if (FT_Render_Glyph(osd->ft2->face->glyph, ft_render_mode_normal)) + printf("osd: error in rendering\n"); + } + if (first) *width += slot->bitmap_left; + first = 0; + *width += slot->advance.x >> 6; + /* font height from baseline to top */ + *height = MAX(*height, slot->bitmap_top); + text++; + } + } else { +#endif + while( font && *text ) { c = *text & 0xff; @@ -838,6 +979,10 @@ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, in text++; } +#ifdef HAVE_FT2 + } /* !(osd->ft2 && osd->ft2->useme) */ +#endif + pthread_mutex_unlock (&this->osd_mutex); return 1; @@ -920,6 +1065,8 @@ static void osd_free_object (osd_object_t *osd_to_close) { last->next = osd->next; else this->osds = osd->next; + + if( osd->ft2 ) free( osd->ft2 ); free( osd ); break; } diff --git a/src/xine-engine/osd.h b/src/xine-engine/osd.h index 9c2959f77..ce5ef93b8 100644 --- a/src/xine-engine/osd.h +++ b/src/xine-engine/osd.h @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * OSD stuff (text and graphic primitives) - * $Id: osd.h,v 1.14 2003/03/26 11:06:58 miguelfreitas Exp $ + * $Id: osd.h,v 1.15 2003/04/06 15:50:57 holstsn Exp $ */ #ifndef HAVE_OSD_H @@ -32,6 +32,7 @@ typedef struct osd_object_s osd_object_t; typedef struct osd_renderer_s osd_renderer_t; typedef struct osd_font_s osd_font_t; +typedef struct osd_ft2context_s osd_ft2context_t; struct osd_object_s { osd_object_t *next; @@ -51,6 +52,7 @@ struct osd_object_s { int32_t handle; osd_font_t *font; + osd_ft2context_t *ft2; }; /* this one is public */ -- cgit v1.2.3