* Makefile
* config/*
* contrib/*
* doc/*
* extras/*
* include/*
* lib/*
* package/*
* src/*
* tests/*
* utils/*
* removed empty lines left after removed '$' + 'Id' + '$' identifiers
191 lines
6.1 KiB
Plaintext
191 lines
6.1 KiB
Plaintext
#require "hbcairo"
|
|
|
|
PROCEDURE 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
|
|
|
|
|
|
PROCEDURE 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
|
|
|
|
|
|
PROCEDURE 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 PROCEDURE 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
|