diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 911dbcfb3f..c672d2268b 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,66 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-11-30 21:31 UTC+0200 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) + + harbour/contrib/hbcairo + + harbour/contrib/hbcairo/Makefile + + harbour/contrib/hbcairo/context.c + + harbour/contrib/hbcairo/core.c + + harbour/contrib/hbcairo/imgae.c + + harbour/contrib/hbcairo/paths.c + + harbour/contrib/hbcairo/pdf.c + + harbour/contrib/hbcairo/png.c + + harbour/contrib/hbcairo/text.c + + harbour/contrib/hbcairo/hbcairo.ch + + harbour/contrib/hbcairo/hbcairo.h + + Added Cairo graphics library + ; It's a 2D graphic library that makes drawing commands platform + independent. Supported backends are: memory image, PDF, PNG, PS, + Win32 DC, SVG, Quartz, Xlib, started Qt development. I.e., you + can forget if you are drawing on screen, printer, PDF, or image + file from know. GTK and FireFox are only a sample of well-known + library/application that uses Cairo as rendering engine. + ; Webpage: http://cairoprahics.org + ; Binaries, development files and related packages (ex., libpng) for + Windows can be found at http://www.gtk.org/download-windows.html + ; I've used multiple .c files so store Harbour level functions. + Functions are split into source files using help sections of + original Cairo docs (http://cairographics.org/manual/) + ; You'll find the full documentation on Cairo webpage. Only a few + functions are spesific to Harbour and could not be found in + original documentaion. It accesses C language structures of Cairo + library. These functions are: + cairo_path_iterator_create( hPath ) --> hIterator + cairo_path_iterator_next( hIterator ) --> nType | NIL + cairo_path_iterator_get_points( hIterator ) --> aPoints + cairo_path_iterator_set_points( hIterator, aPoints ) --> lOk + ; Internal Cairo pointers/handlers are implemented using collectible + pointers. It is destroyed after is not visible to probram any more. + Though original functions cairo_*_destroy() are also implemeted for + those, who wants to make it code clean. + ; TOCHECK: GC pointers implementation, HB_USE_ITEM define. + ; TODO: I've implemted not all functions of Cairo. Actually, the + minority, but it's enough to do some fancy things. + ; TODO: Makefile support. I've completely failed to make a working + make system. I can compile library by copying Cairo *.h files into + source folder and making .dll import library manualy. I guess + Viktor can solve the issues in 3 minutes. + + + harbour/contrib/hbcairo/tests + + harbour/contrib/hbcairo/tests/hbmk.hbm + + harbour/contrib/hbcairo/tests/fancytxt.prg + + harbour/contrib/hbcairo/tests/glyphdbg.prg + + harbour/contrib/hbcairo/tests/hellow.prg + + harbour/contrib/hbcairo/tests/table.prg + + added a few samples to generate .pdf/.png images + ; NOTE: one of the things that make me to spend 3 days for doing this + commit is never ending emails about .pdf library problems on + developers mailing list. I'm using Cairo for a few years, I've + mentioned it a few time on mailing list, but people does not look + at it before you do not show the final result. I hope this library + will be helpful for many, and test code will show both basic + (every day required) and fancy things you can do with Cairo. + 2009-11-30 20:29 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/contrib/xhb/hbcompat.ch + added translations for hb_cdpSelect()<->hb_SetCodepage() diff --git a/harbour/contrib/hbcairo/Makefile b/harbour/contrib/hbcairo/Makefile new file mode 100644 index 0000000000..0ad664c29e --- /dev/null +++ b/harbour/contrib/hbcairo/Makefile @@ -0,0 +1,29 @@ +# +# $Id$ +# + +ROOT := ../../ + +include $(TOP)$(ROOT)config/global.mk + +LIBNAME := hbcairo + +C_SOURCES := \ + context.c \ + core.c \ + image.c \ + paths.c \ + pdf.c \ + png.c \ + text.c \ + +PRG_SOURCES := \ + +C_HEADERS := \ + hbcairo.h \ + +PRG_HEADERS := \ + hbcairo.ch \ + +include $(TOP)$(ROOT)config/header.mk +include $(TOP)$(ROOT)config/lib.mk diff --git a/harbour/contrib/hbcairo/context.c b/harbour/contrib/hbcairo/context.c new file mode 100644 index 0000000000..ac050f2809 --- /dev/null +++ b/harbour/contrib/hbcairo/context.c @@ -0,0 +1,126 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: drawing context + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + + +#include "hbcairo.h" + + +HB_FUNC( CAIRO_CREATE ) +{ + hb_cairo_ret( cairo_create( hb_cairo_surface_param( 1 ) ) ); +} + + +HB_FUNC( CAIRO_FILL ) +{ + cairo_fill( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_FILL_PRESERVE ) +{ + cairo_fill_preserve( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_RESTORE ) +{ + cairo_restore( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_SAVE ) +{ + cairo_save( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_SET_LINE_CAP ) +{ + cairo_set_line_cap( hb_cairo_param( 1 ), hb_parni( 2 ) ); +} + + +HB_FUNC( CAIRO_SET_LINE_WIDTH ) +{ + cairo_set_line_width( hb_cairo_param( 1 ), hb_parnd( 2 ) ); +} + + +HB_FUNC( CAIRO_SET_SOURCE_RGB ) +{ + cairo_set_source_rgb( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ), hb_parnd( 4 ) ); +} + + +HB_FUNC( CAIRO_SET_TOLERANCE ) +{ + cairo_set_tolerance( hb_cairo_param( 1 ), hb_parnd( 2 ) ); +} + +HB_FUNC( CAIRO_SHOW_PAGE ) +{ + cairo_show_page( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_STROKE ) +{ + cairo_stroke( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_STROKE_PRESERVE ) +{ + cairo_stroke_preserve( hb_cairo_param( 1 ) ); +} + diff --git a/harbour/contrib/hbcairo/core.c b/harbour/contrib/hbcairo/core.c new file mode 100644 index 0000000000..a361bd8470 --- /dev/null +++ b/harbour/contrib/hbcairo/core.c @@ -0,0 +1,499 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: core + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#define _HB_API_INTERNAL_ + +#include "hbcairo.h" +#include "hbapiitm.h" +#include "hbapierr.h" + + +/* ============ cairo_t * support ============ */ +static HB_GARBAGE_FUNC( hb_cairo_destructor ) +{ + cairo_t ** ppCairo = ( cairo_t ** ) Cargo; + + if( *ppCairo ) + { + cairo_destroy( *ppCairo ); + *ppCairo = NULL; + } +} + +static const HB_GC_FUNCS s_gcCairoFuncs = +{ + hb_cairo_destructor, + hb_gcDummyMark +}; + + +cairo_t * hb_cairoItemGet( PHB_ITEM pItem ) +{ + cairo_t ** ppCairo = ( cairo_t ** ) hb_itemGetPtrGC( pItem, &s_gcCairoFuncs ); + return ppCairo ? *ppCairo : NULL; +} + + +PHB_ITEM hb_cairoItemPut( PHB_ITEM pItem, cairo_t * pCairo ) +{ + cairo_t ** ppCairo = ( cairo_t ** ) hb_gcAllocate( sizeof( cairo_t * ), &s_gcCairoFuncs ); + + *ppCairo = pCairo; + return hb_itemPutPtrGC( pItem, ppCairo ); +} + + +cairo_t * hb_cairo_param( int iParam ) +{ + cairo_t ** ppCairo = ( cairo_t ** ) hb_parptrGC( &s_gcCairoFuncs, iParam ); + + if( ppCairo && *ppCairo ) + return *ppCairo; + + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); + return NULL; +} + + +void hb_cairo_ret( cairo_t * pCairo ) +{ + hb_cairoItemPut( hb_stackReturnItem(), pCairo ); +} + + +HB_FUNC( CAIRO_DESTROY ) +{ + cairo_t ** ppCairo = ( cairo_t ** ) hb_parptrGC( &s_gcCairoFuncs, 1 ); + + if( ppCairo && *ppCairo ) + { + cairo_destroy( *ppCairo ); + *ppCairo = NULL; + return; + } + + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + +/* ============ cairo_surface_t * support ============ */ +static HB_GARBAGE_FUNC( hb_cairo_surface_destructor ) +{ + cairo_surface_t ** ppSurface = ( cairo_surface_t ** ) Cargo; + + if( *ppSurface ) + { + cairo_surface_destroy( *ppSurface ); + *ppSurface = NULL; + } +} + +static const HB_GC_FUNCS s_gcSurfaceFuncs = +{ + hb_cairo_surface_destructor, + hb_gcDummyMark +}; + + +cairo_surface_t * hb_cairoSurfaceItemGet( PHB_ITEM pItem ) +{ + cairo_surface_t ** ppSurface = ( cairo_surface_t ** ) hb_itemGetPtrGC( pItem, &s_gcSurfaceFuncs ); + return ppSurface ? *ppSurface : NULL; +} + + +PHB_ITEM hb_cairoSurfaceItemPut( PHB_ITEM pItem, cairo_surface_t * pSurface ) +{ + cairo_surface_t ** ppSurface = ( cairo_surface_t ** ) hb_gcAllocate( sizeof( cairo_surface_t * ), &s_gcSurfaceFuncs ); + + *ppSurface = pSurface; + return hb_itemPutPtrGC( pItem, ppSurface ); +} + + +cairo_surface_t * hb_cairo_surface_param( int iParam ) +{ + cairo_surface_t ** ppSurface = ( cairo_surface_t ** ) hb_parptrGC( &s_gcSurfaceFuncs, iParam ); + + if( ppSurface && *ppSurface ) + return *ppSurface; + + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); + return NULL; +} + + +void hb_cairo_surface_ret( cairo_surface_t * pSurface ) +{ + hb_cairoSurfaceItemPut( hb_stackReturnItem(), pSurface ); +} + + +HB_FUNC( CAIRO_SURFACE_DESTROY ) +{ + cairo_surface_t ** ppSurface = ( cairo_surface_t ** ) hb_parptrGC( &s_gcSurfaceFuncs, 1 ); + + if( ppSurface && *ppSurface ) + { + cairo_surface_destroy( *ppSurface ); + *ppSurface = NULL; + return; + } + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + +/* ============ cairo_path_t * support ============ */ +static HB_GARBAGE_FUNC( hb_cairo_path_destructor ) +{ + cairo_path_t ** ppPath = ( cairo_path_t ** ) Cargo; + + if( *ppPath ) + { + cairo_path_destroy( *ppPath ); + *ppPath = NULL; + } +} + +static const HB_GC_FUNCS s_gcPathFuncs = +{ + hb_cairo_path_destructor, + hb_gcDummyMark +}; + + +cairo_path_t * hb_cairoPathItemGet( PHB_ITEM pItem ) +{ + cairo_path_t ** ppPath = ( cairo_path_t ** ) hb_itemGetPtrGC( pItem, &s_gcPathFuncs ); + return ppPath ? *ppPath : NULL; +} + + +PHB_ITEM hb_cairoPathItemPut( PHB_ITEM pItem, cairo_path_t * pPath ) +{ + cairo_path_t ** ppPath = ( cairo_path_t ** ) hb_gcAllocate( sizeof( cairo_path_t * ), &s_gcPathFuncs ); + + *ppPath = pPath; + return hb_itemPutPtrGC( pItem, ppPath ); +} + + +cairo_path_t * hb_cairo_path_param( int iParam ) +{ + cairo_path_t ** ppPath = ( cairo_path_t ** ) hb_parptrGC( &s_gcPathFuncs, iParam ); + + if( ppPath && *ppPath ) + return *ppPath; + + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); + return NULL; +} + + +void hb_cairo_path_ret( cairo_path_t * pPath ) +{ + hb_cairoPathItemPut( hb_stackReturnItem(), pPath ); +} + + +HB_FUNC( CAIRO_PATH_DESTROY ) +{ + cairo_path_t ** ppPath = ( cairo_path_t ** ) hb_parptrGC( &s_gcPathFuncs, 1 ); + + if( ppPath && *ppPath ) + { + cairo_path_destroy( *ppPath ); + *ppPath = NULL; + return; + } + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + +/* ============ cairo_path_t * iterator support ============ */ + +/* + * NOTE: Path iterator functions are is not cairo functions. + * This is only a way to pass path data to .prg level + */ + +typedef struct +{ +#ifdef HB_USE_ITEM + PHB_ITEM pPath; +#else + cairo_path_t * pPath; +#endif + int iPos; +} HB_CAIRO_PATH_ITERATOR, * PHB_CAIRO_PATH_ITERATOR; + + +static HB_GARBAGE_FUNC( hb_cairo_path_iterator_destructor ) +{ + PHB_CAIRO_PATH_ITERATOR pIterator = ( PHB_CAIRO_PATH_ITERATOR ) Cargo; + + if( pIterator->pPath ) + { +#ifdef HB_USE_ITEM + hb_itemRelease( pIterator->pPath ); +#else + hb_gcRefDec( pIterator->pPath ); +#endif + pIterator->pPath = NULL; + } +} + + +static HB_GARBAGE_FUNC( hb_cairo_path_iterator_mark ) +{ + PHB_CAIRO_PATH_ITERATOR pIterator = ( PHB_CAIRO_PATH_ITERATOR ) Cargo; + + if( pIterator->pPath ) + { +#ifdef HB_USE_ITEM + hb_gcGripMark( pIterator->pPath ); +#else + hb_gcMark( pIterator->pPath ); +#endif + } +} + + +static const HB_GC_FUNCS s_gcIteratorFuncs = +{ + hb_cairo_path_iterator_destructor, + hb_cairo_path_iterator_mark +}; + + +HB_FUNC( CAIRO_PATH_ITERATOR_CREATE ) +{ + PHB_CAIRO_PATH_ITERATOR pIterator; + cairo_path_t * pPath = hb_cairo_path_param( 1 ); + + if( pPath ) + { + pIterator = ( PHB_CAIRO_PATH_ITERATOR ) hb_gcAllocate( sizeof( PHB_CAIRO_PATH_ITERATOR ), &s_gcIteratorFuncs ); +#ifdef HB_USE_ITEM + pIterator->pPath = hb_itemNew( hb_param( 1, HB_IT_POINTER ) ); +#else + hb_gcRefInc( pPath ); + pIterator->pPath = pPath; +#endif + pIterator->iPos = -1; + hb_itemPutPtrGC( hb_stackReturnItem(), pIterator ); + } + +} + + +HB_FUNC( CAIRO_PATH_ITERATOR_DESTROY ) +{ + PHB_CAIRO_PATH_ITERATOR pIterator = ( PHB_CAIRO_PATH_ITERATOR ) hb_parptrGC( &s_gcIteratorFuncs, 1 ); + + if( pIterator && pIterator->pPath ) + { +#ifdef HB_USE_ITEM + hb_itemRelease( pIterator->pPath ); +#else + hb_gcRefDec( pIterator->pPath ); +#endif + pIterator->pPath = NULL; + return; + } + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + +HB_FUNC( CAIRO_PATH_ITERATOR_NEXT ) +{ + PHB_CAIRO_PATH_ITERATOR pIterator = ( PHB_CAIRO_PATH_ITERATOR ) hb_parptrGC( &s_gcIteratorFuncs, 1 ); + + if( pIterator ) + { + cairo_path_t * pPath; + +#ifdef HB_USE_ITEM + pPath = hb_itemGetPtr( pIterator->pPath ); +#else + pPath = pIterator->pPath; +#endif + + /* Skip */ + if( pIterator->iPos == -1 ) + pIterator->iPos = 0; + else if( pIterator->iPos < pPath->num_data ) + pIterator->iPos += pPath->data[ pIterator->iPos ].header.length; + + /* return type */ + if( pIterator->iPos < pPath->num_data ) + hb_retni( pPath->data[ pIterator->iPos ].header.type ); + else + hb_ret(); + return; + } + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + +HB_FUNC( CAIRO_PATH_ITERATOR_GET_POINTS ) +{ + PHB_CAIRO_PATH_ITERATOR pIterator = ( PHB_CAIRO_PATH_ITERATOR ) hb_parptrGC( &s_gcIteratorFuncs, 1 ); + + if( pIterator ) + { + cairo_path_t * pPath; + cairo_path_data_t * pData; + +#ifdef HB_USE_ITEM + pPath = hb_itemGetPtr( pIterator->pPath ); +#else + pPath = pIterator->pPath; +#endif + if( pIterator->iPos < pPath->num_data && pIterator->iPos != -1 ) + { + PHB_ITEM pItem, pArray; + int i; + + pData = pPath->data + pIterator->iPos; + pArray = hb_itemArrayNew( pData->header.length - 1 ); + for( i = 1; i < pData->header.length; i++ ) + { + hb_arrayNew( pItem = hb_arrayGetItemPtr( pArray, i ), 2 ); + hb_arraySetND( pItem, 1, pData[ i ].point.x ); + hb_arraySetND( pItem, 2, pData[ i ].point.y ); + } + hb_itemReturnRelease( pArray ); + } + else + hb_ret(); + return; + } + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + +HB_FUNC( CAIRO_PATH_ITERATOR_SET_POINTS ) +{ + PHB_CAIRO_PATH_ITERATOR pIterator = ( PHB_CAIRO_PATH_ITERATOR ) hb_parptrGC( &s_gcIteratorFuncs, 1 ); + PHB_ITEM pArray = hb_param( 2, HB_IT_ARRAY ); + + if( pIterator && pArray ) + { + cairo_path_t * pPath; + cairo_path_data_t * pData; + ULONG ulLen; + +#ifdef HB_USE_ITEM + pPath = hb_itemGetPtr( pIterator->pPath ); +#else + pPath = pIterator->pPath; +#endif + + ulLen = hb_arrayLen( pArray ); + if( pIterator->iPos < pPath->num_data && pIterator->iPos != -1 && + ( ULONG ) pPath->data[ pIterator->iPos ].header.length == ulLen + 1 ) + { + PHB_ITEM pItem; + int i; + + pData = pPath->data + pIterator->iPos; + for( i = 1; i < pData->header.length; i++ ) + { + pItem = hb_arrayGetItemPtr( pArray, i ); + if( hb_arrayLen( pItem ) == 2 ) + { + pData[ i ].point.x = hb_arrayGetND( pItem, 1 ); + pData[ i ].point.y = hb_arrayGetND( pItem, 2 ); + } + else + { + hb_retl( 0 ); + return; + } + } + hb_retl( 1 ); + } + else + hb_retl( 0 ); + return; + } + hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + +/* + +1) + +2) hb_gcRefInc()/hb_gcRefDec() is required without HB_USE_ITEM. This + requires define _HB_API_INTERNAL_. Is this OK? + +3) In function CAIRO_PATH_ITERATOR_CREATE() new item is created using: +pIterator->pPath = hb_itemNew( hb_param( 1, HB_IT_POINTER ) ); + +Does pIterator->pPath need to be unlocked? +If it remains locked, then hb_gcGripMark( pIterator->pPath ) in mark +function is not necessary. + +4) Can be sure that inside CAIRO_PATH_ITERATOR_NEXT() pPath is a valid (not destroyed path)? +(both with and without HB_USE_ITEM) + +5) What is correct way to code: + pCairo = hb_cairo_par( 1 ); // generate RTE if parameter is wrong + if( pData ) + cairo_something( pCairo ); +or this is also ok: + cairo_something( hb_cairo_par( 1 ) ); + +6) Should implementation of procedures end with hb_ret(); ? + +*/ \ No newline at end of file diff --git a/harbour/contrib/hbcairo/hbcairo.ch b/harbour/contrib/hbcairo/hbcairo.ch new file mode 100644 index 0000000000..878fdd3c63 --- /dev/null +++ b/harbour/contrib/hbcairo/hbcairo.ch @@ -0,0 +1,87 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: .prg include file + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#ifndef HB_CAIRO_CH_ +#define HB_CAIRO_CH_ + +/* cairo_font_slant_t */ +#define CAIRO_FONT_SLANT_NORMAL 0 +#define CAIRO_FONT_SLANT_ITALIC 1 +#define CAIRO_FONT_SLANT_OBLIQUE 2 + +/* cairo_font_weight_t */ +#define CAIRO_FONT_WEIGHT_NORMAL 0 +#define CAIRO_FONT_WEIGHT_BOLD 1 + +/* cairo_path_data_type_t */ +#define CAIRO_PATH_MOVE_TO 0 +#define CAIRO_PATH_LINE_TO 1 +#define CAIRO_PATH_CURVE_TO 2 +#define CAIRO_PATH_CLOSE_PATH 3 + +/* cairo_line_cap_t */ +#define CAIRO_LINE_CAP_BUTT 0 +#define CAIRO_LINE_CAP_ROUND 1 +#define CAIRO_LINE_CAP_SQUARE 2 + +/* cairo_line_join_t */ +#define CAIRO_LINE_JOIN_MITER 0 +#define CAIRO_LINE_JOIN_ROUND 1 +#define CAIRO_LINE_JOIN_BEVEL 2 + +/* cairo_format_t */ +#define CAIRO_FORMAT_ARGB32 0 +#define CAIRO_FORMAT_RGB24 1 +#define CAIRO_FORMAT_A8 2 +#define CAIRO_FORMAT_A1 3 + +#endif /* HB_CAIRO_CH_ */ diff --git a/harbour/contrib/hbcairo/hbcairo.h b/harbour/contrib/hbcairo/hbcairo.h new file mode 100644 index 0000000000..48475b38bd --- /dev/null +++ b/harbour/contrib/hbcairo/hbcairo.h @@ -0,0 +1,79 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: .c include file + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#ifndef HB_CAIRO_H_ +#define HB_CAIRO_H_ + +#include "hbapi.h" +#include "hbstack.h" +#include "cairo.h" + +HB_EXTERN_BEGIN + +HB_EXPORT cairo_t * hb_cairoItemGet( PHB_ITEM pItem ); +HB_EXPORT PHB_ITEM hb_cairoItemPut( PHB_ITEM pItem, cairo_t * pCairo ); +HB_EXPORT cairo_t * hb_cairo_param( int iParam ); +HB_EXPORT void hb_cairo_ret( cairo_t * ); + +HB_EXPORT cairo_surface_t * hb_cairoSurfaceItemGet( PHB_ITEM pItem ); +HB_EXPORT PHB_ITEM hb_cairoSurfaceItemPut( PHB_ITEM pItem, cairo_surface_t * pSurface ); +HB_EXPORT cairo_surface_t * hb_cairo_surface_param( int iParam ); +HB_EXPORT void hb_cairo_surface_ret( cairo_surface_t * pSurface ); + +HB_EXPORT cairo_path_t * hb_cairoPathItemGet( PHB_ITEM pItem ); +HB_EXPORT PHB_ITEM hb_cairoPathItemPut( PHB_ITEM pItem, cairo_path_t * pPath ); +HB_EXPORT cairo_path_t * hb_cairo_path_param( int iParam ); +HB_EXPORT void hb_cairo_path_ret( cairo_path_t * pPath ); + +HB_EXTERN_END + +#endif /* HB_CAIRO_H_ */ diff --git a/harbour/contrib/hbcairo/hbcairo.hbc b/harbour/contrib/hbcairo/hbcairo.hbc new file mode 100644 index 0000000000..005c7a29c2 --- /dev/null +++ b/harbour/contrib/hbcairo/hbcairo.hbc @@ -0,0 +1,8 @@ +# +# $Id$ +# + +incpaths=. + +libs=hbcairo +libs=libcairo-2.0 diff --git a/harbour/contrib/hbcairo/image.c b/harbour/contrib/hbcairo/image.c new file mode 100644 index 0000000000..1c9f682936 --- /dev/null +++ b/harbour/contrib/hbcairo/image.c @@ -0,0 +1,64 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: pdf + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + + +#include "hbcairo.h" + + +#ifdef CAIRO_HAS_IMAGE_SURFACE + +HB_FUNC( CAIRO_IMAGE_SURFACE_CREATE ) +{ + hb_cairo_surface_ret( cairo_image_surface_create( hb_parni( 1 ), hb_parnd( 2 ), hb_parnd( 3 ) ) ); +} + +#endif /* CAIRO_HAS_IMAGE_SURFACE */ diff --git a/harbour/contrib/hbcairo/paths.c b/harbour/contrib/hbcairo/paths.c new file mode 100644 index 0000000000..9f78430189 --- /dev/null +++ b/harbour/contrib/hbcairo/paths.c @@ -0,0 +1,136 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: path + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + + +#include "hbcairo.h" +#include "hbapistr.h" + + +HB_FUNC( CAIRO_APPEND_PATH ) +{ + cairo_append_path( hb_cairo_param( 1 ), hb_cairo_path_param( 2 ) ); +} + + +HB_FUNC( CAIRO_CLOSE_PATH ) +{ + cairo_close_path( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_COPY_PATH ) +{ + hb_cairo_path_ret( cairo_copy_path( hb_cairo_param( 1 ) ) ); +} + + +HB_FUNC( CAIRO_COPY_PATH_FLAT ) +{ + hb_cairo_path_ret( cairo_copy_path_flat( hb_cairo_param( 1 ) ) ); +} + + +HB_FUNC( CAIRO_CURVE_TO ) +{ + cairo_curve_to( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ), hb_parnd( 4 ), hb_parnd( 5 ), hb_parnd( 6 ), hb_parnd( 7 ) ); +} + + +HB_FUNC( CAIRO_LINE_TO ) +{ + cairo_line_to( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ) ); +} + + +HB_FUNC( CAIRO_MOVE_TO ) +{ + cairo_move_to( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ) ); +} + + +HB_FUNC( CAIRO_NEW_PATH ) +{ + cairo_new_path( hb_cairo_param( 1 ) ); +} + + +HB_FUNC( CAIRO_RECTANGLE ) +{ + cairo_rectangle( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ), hb_parnd( 4 ), hb_parnd( 5 ) ); +} + + +HB_FUNC( CAIRO_REL_CURVE_TO ) +{ + cairo_rel_curve_to( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ), hb_parnd( 4 ), hb_parnd( 5 ), hb_parnd( 6 ), hb_parnd( 7 ) ); +} + + +HB_FUNC( CAIRO_REL_LINE_TO ) +{ + cairo_rel_line_to( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ) ); +} + + +HB_FUNC( CAIRO_REL_MOVE_TO ) +{ + cairo_rel_move_to( hb_cairo_param( 1 ), hb_parnd( 2 ), hb_parnd( 3 ) ); +} + + +HB_FUNC( CAIRO_TEXT_PATH ) +{ + void * hText; + cairo_text_path( hb_cairo_param( 1 ), hb_parstr_utf8( 2, &hText, NULL ) ); + hb_strfree( hText ); +} + diff --git a/harbour/contrib/hbcairo/pdf.c b/harbour/contrib/hbcairo/pdf.c new file mode 100644 index 0000000000..87efc5f218 --- /dev/null +++ b/harbour/contrib/hbcairo/pdf.c @@ -0,0 +1,65 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: pdf + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + + +#include "hbcairo.h" +#include "cairo-pdf.h" + + +#ifdef CAIRO_HAS_PDF_SURFACE + +HB_FUNC( CAIRO_PDF_SURFACE_CREATE ) +{ + hb_cairo_surface_ret( cairo_pdf_surface_create( hb_parc( 1 ), hb_parnd( 2 ), hb_parnd( 3 ) ) ); +} + +#endif /* CAIRO_HAS_PDF_SURFACE */ diff --git a/harbour/contrib/hbcairo/png.c b/harbour/contrib/hbcairo/png.c new file mode 100644 index 0000000000..05a3e04543 --- /dev/null +++ b/harbour/contrib/hbcairo/png.c @@ -0,0 +1,64 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: png + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + + +#include "hbcairo.h" + + +#ifdef CAIRO_HAS_PNG_FUNCTIONS + +HB_FUNC( CAIRO_SURFACE_WRITE_TO_PNG ) +{ + hb_retni( cairo_surface_write_to_png( hb_cairo_surface_param( 1 ), hb_parc( 2 ) ) ); +} + +#endif /* CAIRO_HAS_PNG_FUNCTIONS */ diff --git a/harbour/contrib/hbcairo/tests/fancytxt.prg b/harbour/contrib/hbcairo/tests/fancytxt.prg new file mode 100644 index 0000000000..45c32b4371 --- /dev/null +++ b/harbour/contrib/hbcairo/tests/fancytxt.prg @@ -0,0 +1,185 @@ + +/* + * $Id$ + */ + +#include "hbcairo.ch" + + +PROC main() + LOCAL hSurface + + hSurface := cairo_pdf_surface_create( "fancytxt.pdf", 566.9, 793.7 ) // 200x280 mm in pt + draw( hSurface ) + cairo_surface_destroy( hSurface ) + + hSurface := cairo_image_surface_create( "fancytxt.pdf", 567, 794 ) + draw( hSurface ) + cairo_surface_write_to_png( hSurface, "fancytxt.png" ) + cairo_surface_destroy( hSurface ) +RETURN + + +PROC draw( hSurface ) + LOCAL hCairo, hPath + + hCairo := cairo_create( hSurface ) + cairo_set_tolerance( hCairo, 0.01 ) + + // Draw base line + cairo_move_to( hCairo, 50, 650 ) + cairo_rel_line_to( hCairo, 250, 50 ) + cairo_rel_curve_to( hCairo, 100, 20, 200, -50, 200, -150 ) + cairo_rel_curve_to( hCairo, 0, -400, -300, -100, -400, -300 ) + hPath := cairo_copy_path_flat( hCairo ) + + cairo_set_line_width( hCairo, 1 ) + cairo_set_source_rgb( hCairo, 0.6, 0.0, 0.0 ) + cairo_stroke( hCairo ) + + // Draw text + cairo_new_path( hCairo ) + cairo_select_font_face( hCairo, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL ) + cairo_set_font_size( hCairo, 72 ) + cairo_move_to( hCairo, 0, -5 ) + cairo_text_path( hCairo, "Welcome to the world of Harbour..." ) + + // Transform + map_path_onto( hCairo, hPath ) + cairo_path_destroy( hPath ) + + // Paint + cairo_set_line_cap( hCairo, CAIRO_LINE_CAP_ROUND ) + cairo_set_source_rgb( hCairo, 0.2, 0.1, 0.8 ) + cairo_fill_preserve( hCairo ) + + cairo_set_line_width( hCairo, 1 ) + cairo_set_source_rgb( hCairo, 0.2, 0.2, 0.2 ) + cairo_stroke( hCairo ) + + cairo_show_page( hCairo ) + cairo_destroy( hCairo ) + +RETURN + + +PROC map_path_onto( hCairo, hPath ) + LOCAL hCurrentPath, aLengths, hIterator, nI, aPoints + + hCurrentPath := cairo_copy_path( hCairo ) + aLengths := path_lengths( hPath ) + hIterator := cairo_path_iterator_create( hCurrentPath ) + DO WHILE cairo_path_iterator_next( hIterator ) != NIL + IF LEN( aPoints := cairo_path_iterator_get_points( hIterator ) ) > 0 + FOR nI := 1 TO LEN( aPoints ) + transform_point( @aPoints[ nI, 1 ], @aPoints[ nI, 2 ], hPath, aLengths ) + NEXT + cairo_path_iterator_set_points( hIterator, aPoints ) + ENDIF + ENDDO + cairo_path_iterator_destroy( hIterator ) + cairo_append_path( hCairo, hCurrentPath ) +RETURN + + +STATIC PROC transform_point( nX, nY, hPath, aLengths ) + LOCAL hIterator, nI, nNX, nNY, nDX, nDY, nRatio, nType, aLast, aPoints, nK1, nK2 + + nNX := nX + nNY := nY + hIterator := cairo_path_iterator_create( hPath ) + nI := 1 + DO WHILE ( nType := cairo_path_iterator_next( hIterator ) ) != NIL + aPoints := cairo_path_iterator_get_points( hIterator ) + IF nNX <= aLengths[ nI ] .AND. nType != CAIRO_PATH_MOVE_TO + EXIT + ENDIF + nNX -= aLengths[ nI ] + nI++ + IF nType == CAIRO_PATH_MOVE_TO .OR. nType == CAIRO_PATH_LINE_TO + aLast := aPoints[ 1 ] + ELSEIF nType == CAIRO_PATH_CURVE_TO + aLast := aPoints[ 3 ] + ENDIF + ENDDO + + IF nType == CAIRO_PATH_MOVE_TO + ELSEIF nType == CAIRO_PATH_LINE_TO + nRatio := nNX / aLengths[ nI ] + nX := aLast[ 1 ] * (1 - nRatio) + aPoints[ 1, 1 ] * nRatio + nY := aLast[ 2 ] * (1 - nRatio) + aPoints[ 1, 2 ] * nRatio + + nDX := -(aLast[ 1 ] - aPoints[ 1, 1 ]) + nDY := -(aLast[ 2 ] - aPoints[ 1, 2 ]) + + nRatio := nNY / aLengths[ nI ] + nX += -nDY * nRatio + nY += nDX * nRatio + ELSEIF nType == CAIRO_PATH_CURVE_TO + nX := aLast[ 1 ] * (1 - nRatio)^3 + 3 * aPoints[ 1, 1 ] * (1 - nRatio)^2 * nRatio + 3 * aPoints[ 2, 1 ] * (1 - nRatio) * nRatio^2 + aPoints[ 3, 1 ] * nRatio^3 + nY := aLast[ 2 ] * (1 - nRatio)^3 + 3 * aPoints[ 1, 2 ] * (1 - nRatio)^2 * nRatio + 3 * aPoints[ 2, 2 ] * (1 - nRatio) * nRatio^2 + aPoints[ 3, 2 ] * nRatio^3 + + nK1 := 1 - 4 * nRatio + 3 * nRatio^2 + nK2 := 2 * nRatio - 3 * nRatio^2 + + nDX := -3 * aLast[ 1 ] * (1 - nRatio)^2 + 3 * aPoints[ 1, 1 ] * nK1 + 3 * aPoints[ 2, 1 ] * nK2 + 3 * aPoints[ 3, 1 ] * nRatio^2 + nDY := -3 * aLast[ 2 ] * (1 - nRatio)^2 + 3 * aPoints[ 1, 2 ] * nK1 + 3 * aPoints[ 2, 2 ] * nK2 + 3 * aPoints[ 3, 2 ] * nRatio^2 + + nRatio := nNY / SQRT( nDX * nDX + nDY * nDY ) + nX += -nDY * nRatio + nY += nDX * nRatio + ENDIF + cairo_path_iterator_destroy( hIterator ) +RETURN + + +STATIC FUNC path_lengths( hPath ) + LOCAL hIterator, nType, aLast, aRet, aPoints, nLen + + aRet := {} + hIterator := cairo_path_iterator_create( hPath ) + DO WHILE ( nType := cairo_path_iterator_next( hIterator ) ) != NIL + aPoints := cairo_path_iterator_get_points( hIterator ) + nLen := 0 + IF nType == CAIRO_PATH_MOVE_TO + aLast := aPoints[ 1 ] + ELSEIF nType == CAIRO_PATH_LINE_TO + nLen := distance( aLast[ 1 ], aLast[ 2 ], aPoints[ 1, 1 ], aPoints[ 1, 2 ] ) + aLast := aPoints[ 1 ] + ELSEIF nType == CAIRO_PATH_CURVE_TO + nLen := curve_length( aLast[ 1 ], aLast[ 2 ], aPoints[ 1, 1 ], aPoints[ 1, 2 ], ; + aPoints[ 2, 1 ], aPoints[ 2, 2 ], aPoints[ 3, 1 ], aPoints[ 3, 2 ] ) + aLast := aPoints[ 3 ] + ENDIF + AADD( aRet, nLen ) + ENDDO + cairo_path_iterator_destroy( hIterator ) +RETURN aRet + + +STATIC FUNC distance( nX1, nY1, nX2, nY2 ) +RETURN sqrt( (nX1-nX2)^2 + (nY1-nY2)^2 ) + + +STATIC FUNC curve_length( nX1, nY1, nX2, nY2, nX3, nY3, nX4, nY4 ) + LOCAL nLength := 0, hSurface, hCairo, hPath, hIterator, nType, aLast, aPoints + + hSurface := cairo_image_surface_create( CAIRO_FORMAT_A8, 0, 0 ) + hCairo := cairo_create( hSurface ) + cairo_move_to( hCairo, nX1, nY1 ) + cairo_curve_to( hCairo, nX2, nY2, nX3, nY3, nX4, nY4 ) + hPath := cairo_copy_path_flat( hCairo ) + hIterator := cairo_path_iterator_create( hPath ) + DO WHILE ( nType := cairo_path_iterator_next( hIterator, @aPoints ) ) != NIL + IF nType == CAIRO_PATH_MOVE_TO + aLast := aPoints + ELSEIF nType == CAIRO_PATH_LINE_TO + nLength += distance(aLast[ 1 ], aLast[ 2 ], aPoints[ 1 ], aPoints[ 2 ] ) + aLast := aPoints + ENDIF + ENDDO + cairo_path_iterator_destroy( hIterator ) + cairo_path_destroy( hPath ) + cairo_destroy( hCairo ) + cairo_surface_destroy( hSurface ) +RETURN nLength diff --git a/harbour/contrib/hbcairo/tests/glyphdbg.prg b/harbour/contrib/hbcairo/tests/glyphdbg.prg new file mode 100644 index 0000000000..1845dc503e --- /dev/null +++ b/harbour/contrib/hbcairo/tests/glyphdbg.prg @@ -0,0 +1,83 @@ +/* + * $Id$ + */ + + +#include "hbcairo.ch" + +PROC main() + LOCAL hSurface, hCairo + + hSurface := cairo_pdf_surface_create( "glyphdbg.pdf", 566.9, 793.7 ) // 200x280 mm in pt + hCairo := cairo_create( hSurface ) + + cairo_select_font_face( hCairo, "Times", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL ) + cairo_set_font_size( hCairo, 200 ) + cairo_set_source_rgb( hCairo, 0, 0, 0.7 ) + + cairo_move_to( hCairo, 100, 250 ) + cairo_text_path( hCairo, "Ag" ) + path_debug( hCairo ) + + cairo_move_to( hCairo, 100, 500 ) + cairo_text_path( hCairo, "Ag" ) + path_debug( hCairo, 4 ) + + cairo_show_page( hCairo ) + cairo_destroy( hCairo ) + cairo_surface_destroy( hSurface ) +RETURN + + +PROC path_debug( hCairo, nTolerance ) + LOCAL hPath, hIterator, nType, aPoints + + cairo_save( hCairo ) + + IF EMPTY( nTolerance ) + hPath = cairo_copy_path( hCairo ) + ELSE + cairo_save( hCairo ) + cairo_set_tolerance( hCairo, nTolerance ) + hPath = cairo_copy_path_flat( hCairo ) + cairo_restore( hCairo ) + ENDIF + + // Draw lines + cairo_new_path( hCairo ) + cairo_append_path( hCairo, hPath ) + cairo_set_source_rgb( hCairo, 0, 0.4, 0 ) + cairo_set_line_width( hCairo, 1.0 ) + cairo_stroke( hCairo ) + + // Draw points + cairo_set_source_rgb( hCairo, 0, 0, 0 ) + cairo_set_line_width( hCairo, 2.0 ) + cairo_set_line_cap( hCairo, CAIRO_LINE_CAP_ROUND ) + hIterator := cairo_path_iterator_create( hPath ) + DO WHILE ( nType := cairo_path_iterator_next( hIterator ) ) != NIL + aPoints := cairo_path_iterator_get_points( hIterator ) + IF nType == CAIRO_PATH_MOVE_TO + cairo_move_to( hCairo, aPoints[ 1, 1 ], aPoints[ 1, 2 ] ) + cairo_rel_line_to( hCairo, 0, 0 ) + ELSEIF nType == CAIRO_PATH_LINE_TO + cairo_move_to( hCairo, aPoints[ 1, 1 ], aPoints[ 1, 2 ] ) + cairo_rel_line_to( hCairo, 0, 0 ) + ELSEIF nType == CAIRO_PATH_CURVE_TO + cairo_stroke( hCairo ) + cairo_set_source_rgb( hCairo, 0.5, 0.5, 0.5 ) + cairo_move_to( hCairo, aPoints[ 1, 1 ], aPoints[ 1, 2 ] ) + cairo_rel_line_to( hCairo, 0, 0 ) + cairo_move_to( hCairo, aPoints[ 2, 1 ], aPoints[ 2, 2 ] ) + cairo_rel_line_to( hCairo, 0, 0 ) + cairo_stroke( hCairo ) + cairo_set_source_rgb( hCairo, 0, 0, 0 ) + cairo_move_to( hCairo, aPoints[ 3, 1 ], aPoints[ 3, 2 ] ) + cairo_rel_line_to( hCairo, 0, 0 ) + ENDIF + ENDDO + cairo_path_iterator_destroy( hIterator ) + cairo_stroke( hCairo ) + cairo_path_destroy( hPath ) + cairo_restore( hCairo ) +RETURN diff --git a/harbour/contrib/hbcairo/tests/hbmk.hbm b/harbour/contrib/hbcairo/tests/hbmk.hbm new file mode 100644 index 0000000000..65ce9db89d --- /dev/null +++ b/harbour/contrib/hbcairo/tests/hbmk.hbm @@ -0,0 +1,7 @@ +# +# $Id$ +# + +../hbcairo.hbc + +-w3 -es2 diff --git a/harbour/contrib/hbcairo/tests/hellow.prg b/harbour/contrib/hbcairo/tests/hellow.prg new file mode 100644 index 0000000000..c1683c2294 --- /dev/null +++ b/harbour/contrib/hbcairo/tests/hellow.prg @@ -0,0 +1,41 @@ +/* + * $Id$ + */ + + +#include "hbcairo.ch" + +REQUEST HB_CODEPAGE_LTWIN + +PROC main() + LOCAL hSurface, hCairo, nI + + HB_SETCODEPAGE("LTWIN") + hSurface := cairo_pdf_surface_create( "hellow.pdf", 566.9, 793.7 ) // 200x280 mm in pt + hCairo := cairo_create( hSurface ) + + cairo_select_font_face( hCairo, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD ) + cairo_set_font_size( hCairo, 16 ) + cairo_set_source_rgb( hCairo, 0, 0, 0 ) // black + + cairo_move_to( hCairo, 50, 50 ) + cairo_show_text( hCairo, "Hello, World!" ) + + cairo_set_line_width( hCairo, 1 ) + FOR nI := 1 TO 10 + cairo_set_source_rgb( hCairo, HB_RANDOM(), HB_RANDOM(), HB_RANDOM() ) + cairo_rectangle( hCairo, 100 + nI * 5, 50 + nI * 5, 100, 70 ) + cairo_stroke( hCairo ) + NEXT + + // Let's try some national characters + cairo_select_font_face( hCairo, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL ) + cairo_set_font_size( hCairo, 10 ) + cairo_set_source_rgb( hCairo, 0, 0, 0 ) + cairo_move_to( hCairo, 50, 300 ) + cairo_show_text( hCairo, "Plaukė žąselė per ežerėlį..." ) + + cairo_show_page( hCairo ) + cairo_destroy( hCairo ) + cairo_surface_destroy( hSurface ) +RETURN diff --git a/harbour/contrib/hbcairo/tests/table.prg b/harbour/contrib/hbcairo/tests/table.prg new file mode 100644 index 0000000000..1650d89f07 --- /dev/null +++ b/harbour/contrib/hbcairo/tests/table.prg @@ -0,0 +1,130 @@ +/* + * $Id$ + */ + + +#include "hbcairo.ch" + + +PROC main() + LOCAL hSurface, hCairo + FIELD CODE, NAME, RESIDENTS + + // Create database + DBCREATE( "country", {{"CODE", "C", 3, 0}, {"NAME", "C", 30, 0}, {"RESIDENTS", "N", 10, 0}},, .T. ) + DBAPPEND(); CODE := "LTU"; NAME := "Lithuania"; RESIDENTS := 3369600 + DBAPPEND(); CODE := "USA"; NAME := "United States of America"; RESIDENTS := 305397000 + DBAPPEND(); CODE := "POR"; NAME := "Portugal"; RESIDENTS := 10617600 + DBAPPEND(); CODE := "POL"; NAME := "Poland"; RESIDENTS := 38115967 + DBAPPEND(); CODE := "AUS"; NAME := "Australia"; RESIDENTS := 21446187 + DBAPPEND(); CODE := "FRA"; NAME := "France"; RESIDENTS := 64473140 + DBAPPEND(); CODE := "RUS"; NAME := "Russia"; RESIDENTS := 141900000 + + // Draw + hSurface := cairo_pdf_surface_create( "table.pdf", 566.9, 793.7 ) // 200x280 mm in pt + hCairo := cairo_create( hSurface ) + + cairo_select_font_face( hCairo, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD ) + cairo_set_font_size( hCairo, 16 ) + cairo_set_source_rgb( hCairo, 0, 0, 0 ) + + cairo_move_to( hCairo, 50, 50 ) + cairo_show_text( hCairo, "Table of countries" ) + + draw_table( hCairo, 50, 75, {{"Code", "CODE"}, {"Country", "NAME"}, {"Residents", "RESIDENTS"}} ) + + cairo_show_page( hCairo ) + cairo_destroy( hCairo ) + cairo_surface_destroy( hSurface ) + DBCLOSEALL() +RETURN + + +STATIC PROC draw_table( hCairo, nX, nY, aCol ) + LOCAL nI, aWidth, nDX, nW, xValue + + cairo_save( hCairo ) + cairo_select_font_face( hCairo, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL ) + cairo_set_font_size( hCairo, 10 ) + cairo_set_source_rgb( hCairo, 0, 0, 0 ) + cairo_set_line_width( hCairo, 1 ) + + DBGOTOP() + aWidth := ARRAY( LEN( aCol ) ) + FOR nI := 1 TO LEN( aCol ) + cairo_text_extents( hCairo, REPLICATE( "9", FIELDLEN( FIELDPOS( aCol[ nI, 2 ] ) ) ),,,,, @nDX ) + aWidth[ nI ] := nDX + cairo_text_extents( hCairo, aCol[ nI, 1 ],,,,, @nDX ) + aWidth[ nI ] := MAX( aWidth[ nI ], nDX ) + 20 + NEXT + nW := 0 + AEVAL( aWidth, {|X| nW += X} ) + + cairo_move_to( hCairo, nX, nY ) + cairo_rel_line_to( hCairo, nW, 0 ) + cairo_stroke( hCairo ) + + nDX := nX + FOR nI := 1 TO LEN( aCol ) + cairo_move_to( hCairo, nDX + aWidth[ nI ] / 2, nY + 10 ) + show_text_center( hCairo, aCol[ nI, 1 ] ) + nDX += aWidth[ nI ] + IF nI < LEN( aCol ) + cairo_move_to( hCairo, nDX, nY ) + cairo_rel_line_to( hCairo, 0, 13 ) + cairo_stroke( hCairo ) + ENDIF + NEXT + nY += 13 + cairo_move_to( hCairo, nX, nY ) + cairo_rel_line_to( hCairo, nW, 0 ) + cairo_stroke( hCairo ) + + DO WHILE ! EOF() + nDX := nX + FOR nI := 1 TO LEN( aCol ) + xValue := FIELDGET( FIELDPOS( aCol[ nI, 2 ] ) ) + IF VALTYPE( xValue ) == "C" + cairo_move_to( hCairo, nDX + 10, nY + 10 ) + cairo_show_text( hCairo, xValue ) + ELSEIF VALTYPE( xValue ) == "N" + cairo_move_to( hCairo, nDX + aWidth[ nI ] - 10, nY + 10 ) + show_text_right( hCairo, STR( xValue ) ) + ELSEIF VALTYPE( xValue ) == "D" + cairo_move_to( hCairo, nDX + 10, nY + 10 ) + show_text_right( hCairo, DTOC( xValue ) ) + ENDIF + nDX += aWidth[ nI ] + IF nI < LEN( aCol ) + cairo_move_to( hCairo, nDX, nY ) + cairo_rel_line_to( hCairo, 0, 13 ) + cairo_stroke( hCairo ) + ENDIF + NEXT + DBSKIP() + nY += 13 + ENDDO + cairo_move_to( hCairo, nX, nY ) + cairo_rel_line_to( hCairo, nW, 0 ) + cairo_stroke( hCairo ) + + cairo_restore( hCairo ) +RETURN + + +STATIC PROC show_text_right( hCairo, cText ) + LOCAL nDX + cairo_text_extents( hCairo, cText,,,,, @nDX ) + cairo_rel_move_to( hCairo, -nDX, 0 ) + cairo_show_text( hCairo, cText ) +RETURN + + +STATIC PROC show_text_center( hCairo, cText ) + LOCAL nDX + cairo_text_extents( hCairo, cText,,,,, @nDX ) + ? nDX + cairo_rel_move_to( hCairo, -nDX/2, 0 ) + cairo_show_text( hCairo, cText ) +RETURN + diff --git a/harbour/contrib/hbcairo/text.c b/harbour/contrib/hbcairo/text.c new file mode 100644 index 0000000000..8878d8aeb7 --- /dev/null +++ b/harbour/contrib/hbcairo/text.c @@ -0,0 +1,93 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Cairo library: text + * + * Copyright 2009 Mindaugas Kavaliauskas + * www - http://www.harbour-project.org + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + + +#include "hbcairo.h" +#include "hbapistr.h" + + +HB_FUNC( CAIRO_SELECT_FONT_FACE ) +{ + void * hFamily; + cairo_select_font_face( hb_cairo_param( 1 ), hb_parstr_utf8( 2, &hFamily, NULL ), ( cairo_font_slant_t ) hb_parni( 3 ), ( cairo_font_weight_t ) hb_parni( 4 ) ); + hb_strfree( hFamily ); +} + + +HB_FUNC( CAIRO_SET_FONT_SIZE ) +{ + cairo_set_font_size( hb_cairo_param( 1 ), hb_parnd( 2 ) ); +} + + +HB_FUNC( CAIRO_SHOW_TEXT ) +{ + void * hText; + cairo_show_text( hb_cairo_param( 1 ), hb_parstr_utf8( 2, &hText, NULL ) ); + hb_strfree( hText ); +} + + +HB_FUNC( CAIRO_TEXT_EXTENTS ) +{ + void * hText; + cairo_text_extents_t te; + cairo_text_extents( hb_cairo_param( 1 ), hb_parstr_utf8( 2, &hText, NULL ), &te ); + hb_strfree( hText ); + hb_stornd( te.x_bearing, 3 ); + hb_stornd( te.y_bearing, 4 ); + hb_stornd( te.width, 5 ); + hb_stornd( te.height, 6 ); + hb_stornd( te.x_advance, 7 ); + hb_stornd( te.y_advance, 8 ); +} +