Initial commit with agg r138 svn files

This commit is contained in:
George Sokianos 2021-12-27 19:14:31 +00:00
commit e1ed5fc219
645 changed files with 163875 additions and 0 deletions

2
AUTHORS Normal file
View File

@ -0,0 +1,2 @@
Anti-Grain Geometry - Version 2.4
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)

244
CMakeLists.txt Normal file
View File

@ -0,0 +1,244 @@
PROJECT( antigrain )
# additional are modified Find routines
SET ( CMAKE_MODULE_PATH "${antigrain_SOURCE_DIR}/bin" )
CMAKE_MINIMUM_REQUIRED( VERSION 2.4.8 )
SET(AGG_MAJOR_VERSION 0 )
SET(AGG_MINOR_VERSION 1 )
SET(AGG_BUILD_VERSION 1 )
SET( AGG_FLAGS "" )
SET( AGG_INCLUDE_DIRS "" )
SET( AGG_LIBRARY_DIRS "" )
SET( AGG_LIBRARIES "" )
SET (LIBRARY_OUTPUT_PATH ${antigrain_BINARY_DIR}/lib/ CACHE PATH "Single output directory for building all libraries." FORCE )
SET( AGG_LIBRARY_DIRS lib )
#SET (EXECUTABLE_OUTPUT_PATH ${antigrain_BINARY_DIR}/exe/ CACHE PATH "Single output directory for building all executables.")
#MARK_AS_ADVANCED(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)
LINK_DIRECTORIES( ${antigrain_BINARY_DIR}/lib )
OPTION( agg_USE_GPC "Use Gpc Boolean library" OFF)
OPTION( agg_USE_FREETYPE "Use Freetype library" OFF)
OPTION( agg_USE_EXPAT "Use Expat library" OFF)
OPTION( agg_USE_SDL_PLATFORM "Use SDL as platform" OFF)
OPTION( agg_USE_PACK "Package Agg" OFF)
OPTION( agg_USE_AGG2D "Agg 2D graphical context" OFF)
OPTION( agg_USE_DEBUG "For debug version" OFF)
IF( agg_USE_DEBUG )
#SET( PFDEBUG "d" )
SET( CMAKE_DEBUG_POSTFIX "d" )
ENDIF( agg_USE_DEBUG )
# for the moment this decides the platform code.
IF(WIN32)
ADD_DEFINITIONS( -D_MSWVC_ -D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE )
SET( WIN32GUI WIN32 )
INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/font_win32_tt )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} font_win32_tt )
ENDIF(WIN32)
IF(UNIX)
ADD_DEFINITIONS( -D__UNIX__ )
SET( WIN32GUI "" )
FIND_PACKAGE(X11)
IF(X11_FOUND)
INCLUDE_DIRECTORIES(${X11_INCLUDE_DIRS})
LINK_LIBRARIES(${X11_LIBRARIES})
ENDIF(X11_FOUND)
ENDIF(UNIX)
# more specific set platform code part to use for different compilers/tool sets
IF ( ${CMAKE_GENERATOR} STREQUAL "MSYS Makefiles" )
SET (CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG" CACHE STRING
"Flags used by the compiler during release builds" FORCE)
SET (CMAKE_CX_FLAGS_RELEASE "-DNDEBUG" CACHE STRING
"Flags used by the compiler during release builds" FORCE)
ENDIF ( ${CMAKE_GENERATOR} STREQUAL "MSYS Makefiles" )
IF ( ${CMAKE_GENERATOR} STREQUAL "MinGW Makefiles" )
ENDIF ( ${CMAKE_GENERATOR} STREQUAL "MinGW Makefiles" )
IF ( ${CMAKE_GENERATOR} STREQUAL "Unix Makefiles" )
IF( CYGWIN OR MINGW )
SET (CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG" CACHE STRING
"Flags used by the compiler during release builds" FORCE)
SET (CMAKE_C_FLAGS_RELEASE "-DNDEBUG" CACHE STRING
"Flags used by the compiler during release builds" FORCE)
ENDIF( CYGWIN OR MINGW )
ENDIF ( ${CMAKE_GENERATOR} STREQUAL "Unix Makefiles" )
IF ( ${CMAKE_GENERATOR} MATCHES "Visual Studio.*" )
ENDIF ( ${CMAKE_GENERATOR} MATCHES "Visual Studio.*" )
IF ( ${CMAKE_GENERATOR} MATCHES "Borland Makefiles" )
ENDIF ( ${CMAKE_GENERATOR} MATCHES "Borland Makefiles" )
##################################################
# Set all includes, flags, libraries, related to expat
##################################################
IF( agg_USE_EXPAT )
FIND_PACKAGE( EXPAT )
IF(EXPAT_FOUND)
INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIRS})
LINK_LIBRARIES(${EXPAT_LIBRARIES})
ELSE(EXPAT_FOUND)
MESSAGE(SEND_ERROR "expat not found")
ENDIF(EXPAT_FOUND)
ENDIF( agg_USE_EXPAT )
##################################################
# Set all includes, flags, libraries, related to freetype
##################################################
IF( agg_USE_FREETYPE )
FIND_PACKAGE( Freetype )
IF( FREETYPE_FOUND )
INCLUDE_DIRECTORIES( ${FREETYPE_INCLUDE_DIRS} )
LINK_LIBRARIES( ${FREETYPE_LIBRARIES} )
LINK_DIRECTORIES( ${FREETYPE_LINK_DIR} )
ELSE( FREETYPE_FOUND )
MESSAGE(SEND_ERROR "freetype not found")
ENDIF( FREETYPE_FOUND )
ENDIF( agg_USE_FREETYPE )
##################################################
# Set all includes, flags, libraries, related to SDL
##################################################
FIND_PACKAGE( SDL QUIET )
IF( SDL_FOUND )
IF ( agg_USE_SDL_PLATFORM )
INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR})
LINK_LIBRARIES(${SDL_LIBRARY})
ENDIF ( agg_USE_SDL_PLATFORM )
ELSE( SDL_FOUND )
IF ( agg_USE_SDL_PLATFORM )
MESSAGE( "SDL libray was not found, disable agg_USE_SDL_PLATFORM please" )
ENDIF ( agg_USE_SDL_PLATFORM )
ENDIF( SDL_FOUND )
# the main include dir of Agg
INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/include )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} include )
# freetype specific lib of Agg
IF( agg_USE_FREETYPE )
INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/font_freetype )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} font_freetype )
ADD_DEFINITIONS( -DAGG_USE_FREETYPE )
SET( AGG_FLAGS ${AGG_FLAGS} -DAGG_USE_FREETYPE )
LINK_LIBRARIES( freetypefont )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} aggfontfreetype${PFDEBUG} )
ENDIF( agg_USE_FREETYPE )
# GPC lib if used within Agg
IF ( agg_USE_GPC )
INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/gpc )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} gpc )
ADD_DEFINITIONS( -DAGG_USE_GPC )
SET( AGG_FLAGS ${AGG_FLAGS} -DAGG_USE_GPC )
LINK_LIBRARIES( gpcbool )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} gpc${PFDEBUG} )
ENDIF ( agg_USE_GPC )
# agg2d lib if used within Agg
IF ( agg_USE_AGG2D )
INCLUDE_DIRECTORIES( ${antigrain_SOURCE_DIR}/agg2d )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} agg2d )
ADD_DEFINITIONS( -DAGG_USE_AGG2D )
OPTION( agg_USE_AGG2D_FREETYPE "Agg 2D graphical context uses freetype" OFF)
SET( AGG_FLAGS ${AGG_FLAGS} -DAGG_USE_AGG2D )
LINK_LIBRARIES( agg2d )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} agg2d${PFDEBUG} )
ENDIF ( agg_USE_AGG2D )
IF ( agg_USE_AGG2D_FREETYPE )
ADD_DEFINITIONS( -DAGG2D_USE_FREETYPE )
SET( AGG_FLAGS ${AGG_FLAGS} -DAGG2D_USE_FREETYPE )
ENDIF ( agg_USE_AGG2D_FREETYPE )
# sld as platform or os
IF( SDL_FOUND AND agg_USE_SDL_PLATFORM )
LINK_LIBRARIES( controls sdlplatform antigrain )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} aggctrl${PFDEBUG} aggsdlplatform${PFDEBUG} agg${PFDEBUG} )
ELSE( SDL_FOUND AND agg_USE_SDL_PLATFORM )
LINK_LIBRARIES( controls platform antigrain )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} aggctrl${PFDEBUG} aggplatform${PFDEBUG} agg${PFDEBUG} )
ENDIF( SDL_FOUND AND agg_USE_SDL_PLATFORM )
SET( AGG_FLAGS ${AGG_FLAGS} CACHE STRING "Agg package flags" FORCE )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} CACHE STRING "Agg package libs include paths" FORCE )
SET( AGG_LIBRARY_DIRS ${AGG_LIBRARY_DIRS} CACHE STRING "Agg package libs directory paths" FORCE )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} CACHE STRING "Agg package libraries" FORCE )
ADD_SUBDIRECTORY( src )
ADD_SUBDIRECTORY( examples )
CONFIGURE_FILE( ${antigrain_SOURCE_DIR}/bin/AggConfig.cmake.in
${antigrain_BINARY_DIR}/bin/AggConfig.cmake
@ONLY IMMEDIATE )
CONFIGURE_FILE( ${antigrain_SOURCE_DIR}/bin/AggConfigOutBuild.cmake.in
${antigrain_BINARY_DIR}/bin/AggConfigOutBuild.cmake
@ONLY IMMEDIATE )
CONFIGURE_FILE( ${antigrain_SOURCE_DIR}/bin/FindAgg.cmake
${antigrain_BINARY_DIR}/myapp/FindAgg.cmake
@ONLY IMMEDIATE )
CONFIGURE_FILE( ${antigrain_SOURCE_DIR}/bin/UseAgg.cmake.in
${antigrain_BINARY_DIR}/bin/UseAgg.cmake
@ONLY IMMEDIATE )
ADD_SUBDIRECTORY( myapp )
INSTALL( FILES ${antigrain_BINARY_DIR}/bin/AggConfigOutBuild.cmake DESTINATION "bin" RENAME AggConfig.cmake )
INSTALL( FILES ${antigrain_BINARY_DIR}/bin/AggConfig.cmake DESTINATION "bin" )
INSTALL( FILES ${antigrain_BINARY_DIR}/bin/UseAgg.cmake DESTINATION "bin" )
#-------------------------------------------------------------------
# Build a CPack installer if CPack is available and this is a build
IF ( agg_USE_PACK )
IF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Agg - Vector Graphics")
SET(CPACK_PACKAGE_VENDOR "Agg")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/copying")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/copying")
SET(CPACK_PACKAGE_VERSION_MAJOR "${AGG_MAJOR_VERSION}")
SET(CPACK_PACKAGE_VERSION_MINOR "${AGG_MINOR_VERSION}")
SET(CPACK_PACKAGE_VERSION_PATCH "${AGG_BUILD_VERSION}")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "AGG_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}")
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "agg-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
SET(CPACK_PACKAGE_EXECUTABLES
"agg" "AGG"
)
SET(CPACK_SOURCE_STRIP_FILES "")
SET(CPACK_STRIP_FILES "bin/ccmake;bin/cmake;bin/cpack;bin/ctest")
IF(WIN32)
SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
SET(CPACK_NSIS_HELP_LINK "http://agg.sourceforge.net")
SET(CPACK_NSIS_URL_INFO_ABOUT "http://agg.sourceforge.net")
SET(CPACK_NSIS_CONTACT "http://agg.sourceforge.net")
ENDIF(WIN32)
INCLUDE(CPack)
ENDIF(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake")
ENDIF ( agg_USE_PACK )
INCLUDE( myapp/myproject.cmake )

1
ChangeLog Normal file
View File

@ -0,0 +1 @@
Visit http://antigrain.com/news

9
Makefile Normal file
View File

@ -0,0 +1,9 @@
all: lib
src/libagg.a:
cd src; make
lib: src/libagg.a
clean:
cd src; make clean

398
Makefile.AmigaOS Normal file
View File

@ -0,0 +1,398 @@
#
# Makefile for AmigaOS 4.0
#
CXX = g++
CXXFLAGS = -mcrt=clib2 -O3 -Iinclude -Igpc -Ifont_freetype
CXXLIBS = -Llib -lagg
CC = gcc
CFLAGS = -mcrt=clib2 -O3 -Igpc
AR = ar
ARFLAGS = cr
STRIP = strip -R.comment
LIBNAME = lib/libagg.a
SVGNAME = bin/svg_test
EXAMPLES =\
bin/aa_demo \
bin/aa_test \
bin/alpha_gradient \
bin/alpha_mask \
bin/alpha_mask2 \
bin/alpha_mask3 \
bin/bezier_div \
bin/bspline \
bin/circles \
bin/component_rendering \
bin/compositing \
bin/compositing2 \
bin/conv_contour \
bin/conv_dash_marker \
bin/conv_stroke \
bin/distortions \
bin/flash_rasterizer \
bin/flash_rasterizer2 \
bin/gamma_correction \
bin/gamma_ctrl \
bin/gamma_tuner \
bin/gouraud \
bin/gouraud_mesh \
bin/gpc_test \
bin/gradients \
bin/graph_test \
bin/idea \
bin/image_alpha \
bin/image_filters \
bin/image_filters2 \
bin/image_fltr_graph \
bin/image_perspective \
bin/image_resample \
bin/image_transforms \
bin/image1 \
bin/line_patterns_clip \
bin/line_patterns \
bin/lion \
bin/lion_lens \
bin/lion_outline \
bin/mol_view \
bin/multi_clip \
bin/pattern_fill \
bin/pattern_perspective \
bin/pattern_resample \
bin/perspective \
bin/polymorphic_renderer \
bin/raster_text \
bin/rasterizers \
bin/rasterizers2 \
bin/rounded_rect \
bin/scanline_boolean \
bin/scanline_boolean2 \
bin/simple_blur \
bin/trans_polar
FREETYPE_EXAMPLES=\
bin/freetype_test \
bin/trans_curve1_ft \
bin/trans_curve2_ft
PLATFORM_SRC=\
src/platform/AmigaOS/agg_platform_support.cpp
FREETYPE_SRC=\
font_freetype/agg_font_freetype.cpp
LIB_CXXSRC=\
src/agg_arc.cpp \
src/agg_arrowhead.cpp \
src/agg_bezier_arc.cpp \
src/agg_bspline.cpp \
src/agg_curves.cpp \
src/agg_embedded_raster_fonts.cpp \
src/agg_gsv_text.cpp \
src/agg_image_filters.cpp \
src/agg_line_aa_basics.cpp \
src/agg_line_profile_aa.cpp \
src/agg_rounded_rect.cpp \
src/agg_sqrt_tables.cpp \
src/agg_trans_affine.cpp \
src/agg_trans_double_path.cpp \
src/agg_trans_single_path.cpp \
src/agg_trans_warp_magnifier.cpp \
src/agg_vcgen_bspline.cpp \
src/agg_vcgen_contour.cpp \
src/agg_vcgen_dash.cpp \
src/agg_vcgen_markers_term.cpp \
src/agg_vcgen_smooth_poly1.cpp \
src/agg_vcgen_stroke.cpp \
src/agg_vpgen_clip_polygon.cpp \
src/agg_vpgen_clip_polyline.cpp \
src/agg_vpgen_segmentator.cpp \
src/ctrl/agg_bezier_ctrl.cpp \
src/ctrl/agg_cbox_ctrl.cpp \
src/ctrl/agg_gamma_ctrl.cpp \
src/ctrl/agg_gamma_spline.cpp \
src/ctrl/agg_polygon_ctrl.cpp \
src/ctrl/agg_rbox_ctrl.cpp \
src/ctrl/agg_scale_ctrl.cpp \
src/ctrl/agg_slider_ctrl.cpp \
src/ctrl/agg_spline_ctrl.cpp
LIB_CSRC=\
gpc/gpc.c
SVG_SRC=\
examples/svg_viewer/agg_svg_parser.cpp \
examples/svg_viewer/agg_svg_path_renderer.cpp \
examples/svg_viewer/agg_svg_path_tokenizer.cpp \
examples/svg_viewer/svg_test.cpp \
$(PLATFORM_SRC)
PLATFORM_OBJ = $(PLATFORM_SRC:.cpp=.o)
FREETYPE_OBJ = $(FREETYPE_SRC:.cpp=.o)
LIB_OBJ = $(LIB_CXXSRC:.cpp=.o) $(LIB_CSRC:.c=.o)
SVG_OBJ = $(SVG_SRC:.cpp=.o)
#
# Targets
#
.PHONY : help all lib examples svg freetype clean install wget
help:
@Echo Requirements:
@Echo - AmigaOS 4.0
@Echo - SDK 51.22
@Echo - optional: libexpat.a for SVG viewer
@Echo - optional: libft2.a for FreeType examples
@Echo ""
@Echo Targets:
@Echo all - build AGG library and all tests/examples
@Echo lib - build AGG library only
@Echo examples - build AGG library and examples
@Echo svg - build AGG library and SVG viewer
@Echo freetype - build AGG library and FreeType examples
@Echo clean - clean all build files
@Echo install - build AGG library and install into SDK
@Echo wget - download and install example test files with wget
all: lib examples svg freetype
$(STRIP) $(EXAMPLES) $(SVGNAME) $(FREETYPE_EXAMPLES)
lib: $(LIBNAME)
examples: lib $(EXAMPLES)
svg: lib $(SVGNAME)
freetype: lib $(FREETYPE_EXAMPLES)
clean:
-@Delete *>NIL: FORCE QUIET examples/#?.o
-@Delete *>NIL: FORCE QUIET $(PLATFORM_OBJ) $(FREETYPE_OBJ) $(LIB_OBJ) $(SVG_OBJ)
-@Delete *>NIL: FORCE QUIET ALL lib bin
install: lib
-@Copy CLONE $(LIBNAME) SDK:Local/clib2/lib
-@Copy CLONE ALL include/#?.h SDK:Local/common/include/agg
-@Copy CLONE ALL gpc/#?.h SDK:Local/common/include/gpc
$(LIBNAME): $(LIB_OBJ)
$(AR) $(ARFLAGS) $@ $^
$(SVGNAME): $(SVG_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS) -lexpat
#
# Examples binaries
#
bin/aa_test: examples/aa_test.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/aa_demo: examples/aa_demo.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/alpha_gradient: examples/alpha_gradient.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/alpha_mask: examples/alpha_mask.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/alpha_mask2: examples/alpha_mask2.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/alpha_mask3: examples/alpha_mask3.o examples/make_arrows.o examples/make_gb_poly.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/bezier_div: examples/bezier_div.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/bspline: examples/bspline.o examples/interactive_polygon.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/circles: examples/circles.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/component_rendering: examples/component_rendering.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/compositing: examples/compositing.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/compositing2: examples/compositing2.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/conv_contour: examples/conv_contour.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/conv_dash_marker: examples/conv_dash_marker.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/conv_stroke: examples/conv_stroke.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/distortions: examples/distortions.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/flash_rasterizer: examples/flash_rasterizer.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/flash_rasterizer2: examples/flash_rasterizer2.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/gamma_correction: examples/gamma_correction.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/gamma_ctrl: examples/gamma_ctrl.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/gamma_tuner: examples/gamma_tuner.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/gouraud: examples/gouraud.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/gouraud_mesh: examples/gouraud_mesh.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/gpc_test: examples/gpc_test.o examples/make_arrows.o examples/make_gb_poly.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/gradients: examples/gradients.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/graph_test: examples/graph_test.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/idea: examples/idea.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image1: examples/image1.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image_alpha: examples/image_alpha.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image_filters: examples/image_filters.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image_filters2: examples/image_filters2.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image_fltr_graph: examples/image_fltr_graph.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image_perspective: examples/image_perspective.o examples/interactive_polygon.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image_resample: examples/image_resample.o examples/interactive_polygon.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/image_transforms: examples/image_transforms.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/line_patterns: examples/line_patterns.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/line_patterns_clip: examples/line_patterns_clip.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/lion: examples/lion.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/lion_lens: examples/lion_lens.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/lion_outline: examples/lion_outline.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/mol_view: examples/mol_view.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/multi_clip: examples/multi_clip.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/pattern_fill: examples/pattern_fill.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/pattern_perspective: examples/pattern_perspective.o examples/interactive_polygon.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/pattern_resample: examples/pattern_resample.o examples/interactive_polygon.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/perspective: examples/perspective.o examples/interactive_polygon.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/polymorphic_renderer: examples/polymorphic_renderer.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/rasterizers: examples/rasterizers.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/rasterizers2: examples/rasterizers2.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/raster_text: examples/raster_text.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/rounded_rect: examples/rounded_rect.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/scanline_boolean: examples/scanline_boolean.o examples/interactive_polygon.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/scanline_boolean2: examples/scanline_boolean2.o examples/make_arrows.o examples/make_gb_poly.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/simple_blur: examples/simple_blur.o examples/parse_lion.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/trans_polar: examples/trans_polar.o $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS)
bin/freetype_test: examples/freetype_test.o $(FREETYPE_OBJ) $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS) -lft2
bin/trans_curve1_ft: examples/trans_curve1_ft.o examples/interactive_polygon.o $(FREETYPE_OBJ) $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS) -lft2
bin/trans_curve2_ft: examples/trans_curve2_ft.o examples/interactive_polygon.o $(FREETYPE_OBJ) $(PLATFORM_OBJ)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CXXLIBS) -lft2
#
# Examples files
#
wget:
wget http://www.antigrain.com/svg/tiger.svg
move tiger.svg bin
wget http://www.antigrain.com/agg.bmp
move agg.bmp bin
wget http://www.antigrain.com/compositing.bmp
move compositing.bmp bin
wget http://www.antigrain.com/spheres.bmp
move spheres.bmp bin
wget http://www.antigrain.com/shapes.txt
move shapes.txt bin
wget http://www.antigrain.com/1.sdf
move 1.sdf bin
wget http://www.antigrain.com/line_patterns.bmp.zip
xadunfile line_patterns.bmp.zip bin overwrite
delete line_patterns.bmp.zip
wget http://www.antigrain.com/timesi.zip
xadunfile timesi.zip bin overwrite
delete timesi.zip
#
# Pattern Rules
#
%.o: %.cpp
@MakeDir lib bin force
$(CXX) -c $(CXXFLAGS) $< -o $@
%.o: %.c
@MakeDir lib bin force
$(CC) -c $(CFLAGS) $< -o $@

21
Makefile.am Normal file
View File

@ -0,0 +1,21 @@
SUBDIRS = gpc src font_freetype font_win32_tt include examples
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libagg.pc
EXTRA_DIST = Makefile.AmigaOS \
Makefile.in.BeOS \
Makefile.in.CYGWIN_NT-5.0 \
Makefile.in.CYGWIN_NT-5.1 \
Makefile.in.Darwin \
Makefile.in.Darwin.SDL \
Makefile.in.IRIX64 \
Makefile.in.Linux \
Makefile.in.Linux.SDL \
Makefile.in.MINGW32_NT-5.0 \
Makefile.in.MINGW32_NT-5.1 \
Makefile.in.SunOS
# M4 macro file for inclusion with autoconf
m4datadir = $(datadir)/aclocal
m4data_DATA = libagg.m4

7
Makefile.in.BeOS Normal file
View File

@ -0,0 +1,7 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O1
CXX = g++
C = cc
LIB = ar -cru
.PHONY : clean

View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O3 -I/usr/X11R6/include -L/usr/X11R6/lib
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr
.PHONY : clean

View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O3 -I/usr/X11R6/include -L/usr/X11R6/lib
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr
.PHONY : clean

8
Makefile.in.Darwin Normal file
View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O3 -I/usr/X11R6/include -L/usr/X11R6/lib
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr -s
.PHONY : clean

8
Makefile.in.Darwin.SDL Normal file
View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg -L/usr/local/lib -lSDLmain -lSDL -framework Cocoa -framework OpenGL
AGGCXXFLAGS = -O3 -I/Library/Frameworks/SDL.framework/Headers -L/usr/lib
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr -s
.PHONY : clean

7
Makefile.in.IRIX64 Normal file
View File

@ -0,0 +1,7 @@
AGGLIBS= -lagg
AGGCXXFLAGS =
CXX = CC
C = cc
LIB = CC -ar -o
.PHONY : clean

8
Makefile.in.Linux Normal file
View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O3 -I/usr/X11R6/include -L/usr/X11R6/lib
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr
.PHONY : clean

8
Makefile.in.Linux.SDL Normal file
View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg -lSDL
AGGCXXFLAGS = -O3 -I/usr/include/SDL -L/usr/lib
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr
.PHONY : clean

View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O3
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr
.PHONY : clean

View File

@ -0,0 +1,8 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O3
CXX = g++
C = gcc
#CXX = icc
LIB = ar cr
.PHONY : clean

7
Makefile.in.SunOS Normal file
View File

@ -0,0 +1,7 @@
AGGLIBS= -lagg
AGGCXXFLAGS = -O3 -I/usr/openwin/include -L/usr/openwin/lib
CXX = CC
C = cc
LIB = CC -xar -o
.PHONY : clean

1
NEWS Normal file
View File

@ -0,0 +1 @@
Visit http://antigrain.com/news

63
README Normal file
View File

@ -0,0 +1,63 @@
The Anti-Grain Geometry Project
A high quality rendering engine for C++
http://antigrain.com
Anti-Grain Geometry - Version 2.4
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
Permission to copy, use, modify, sell and distribute this software
is granted provided this copyright notice appears in all copies.
This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
---------------------------------
Use automake to build the library.
If automake is not available you still can use the old make.
There is a very simple Makefile that can be used. Note that
if you use automake it will overwrite Makefile.
---------------------------------
If building on AmigaOS 4.0 or higher type the following for
instructions on what targets are available.
make -f Makefile.AmigaOS
To just build and install AGG into the standard AmigaOS SDK
ready for use type:
make -f Makefile.AmigaOS install
If you just want to build one demo (e.g. lion) use:
make -f Makefile.AmigaOS bin/lion
If you have any questions about the AmigaOS port please
contact Steven Solie (ssolie@telus.net) for help.
---------------------------------
To build all examples using SDL (Mac or Linux) just type:
cd /examples/sdl
make
Individual examples can be built with
make aa_test
In the same way the native Carbon examples can be built with
cd /examples/macosx_carbon
make
In both cases the static library will be built (if it was not already)
from the existing global Makefile in /src/.
The Makefiles for both SDL and Carbon will also attempt to download the
required .bmp files if they are not found in the system for a given
example. If the files could not be fetched (wget) the user will receive
a message explaining where to download the samples from (sphere.bmp,
etc.) Since all programs reside in the same directory there is no need
to duplicate the .bmp files for each program that needs to use them.
---------------------------------

1837
agg2d/agg2d.cpp Normal file

File diff suppressed because it is too large Load Diff

599
agg2d/agg2d.h Normal file
View File

@ -0,0 +1,599 @@
//----------------------------------------------------------------------------
// Agg2D - Version 1.0
// Based on Anti-Grain Geometry
// Copyright (C) 2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
//----------------------------------------------------------------------------
// Contact: mcseem@antigrain.com
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//
// 25 Jan 2007 - Ported to AGG 2.4 Jerry Evans (jerry@novadsp.com)
//
//----------------------------------------------------------------------------
#ifndef AGG2D_INCLUDED
#define AGG2D_INCLUDED
// With this define uncommented you can use FreeType font engine
//#define AGG2D_USE_FREETYPE
// With this define uncommented you can use floating-point pixel format
//#define AGG2D_USE_FLOAT_FORMAT
#include "agg_basics.h"
#include "agg_trans_affine.h"
#include "agg_trans_viewport.h"
#include "agg_path_storage.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
#include "agg_conv_curve.h"
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_renderer_scanline.h"
#include "agg_span_gradient.h"
#include "agg_span_image_filter_rgba.h"
#include "agg_span_allocator.h"
#include "agg_span_converter.h"
#include "agg_span_interpolator_linear.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_gamma_functions.h"
#include "agg_scanline_u.h"
#include "agg_bezier_arc.h"
#include "agg_rounded_rect.h"
#include "agg_font_cache_manager.h"
#ifdef AGG2D_USE_FREETYPE
#include "agg_font_freetype.h"
#else
#include "agg_font_win32_tt.h"
#endif
#include "agg_pixfmt_rgba.h"
#include "agg_image_accessors.h"
class Agg2D
{
#ifdef AGG2D_USE_FLOAT_FORMAT
typedef agg::rgba32 ColorType;
#else
typedef agg::rgba8 ColorType;
#endif
typedef agg::order_bgra ComponentOrder; // Platform dependent!
typedef agg::blender_rgba<ColorType, ComponentOrder> Blender;
typedef agg::comp_op_adaptor_rgba<ColorType, ComponentOrder> BlenderComp;
typedef agg::blender_rgba_pre<ColorType, ComponentOrder> BlenderPre;
typedef agg::comp_op_adaptor_rgba_pre<ColorType, ComponentOrder> BlenderCompPre;
typedef agg::pixfmt_alpha_blend_rgba<Blender, agg::rendering_buffer> PixFormat;
typedef agg::pixfmt_custom_blend_rgba<BlenderComp, agg::rendering_buffer> PixFormatComp;
typedef agg::pixfmt_alpha_blend_rgba<BlenderPre, agg::rendering_buffer> PixFormatPre;
typedef agg::pixfmt_custom_blend_rgba<BlenderCompPre, agg::rendering_buffer> PixFormatCompPre;
typedef agg::renderer_base<PixFormat> RendererBase;
typedef agg::renderer_base<PixFormatComp> RendererBaseComp;
typedef agg::renderer_base<PixFormatPre> RendererBasePre;
typedef agg::renderer_base<PixFormatCompPre> RendererBaseCompPre;
typedef agg::renderer_scanline_aa_solid<RendererBase> RendererSolid;
typedef agg::renderer_scanline_aa_solid<RendererBaseComp> RendererSolidComp;
typedef agg::span_allocator<ColorType> SpanAllocator;
typedef agg::pod_auto_array<ColorType, 256> GradientArray;
typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_x, GradientArray> LinearGradientSpan;
typedef agg::span_gradient<ColorType, agg::span_interpolator_linear<>, agg::gradient_circle, GradientArray> RadialGradientSpan;
#ifdef AGG2D_USE_FREETYPE
typedef agg::font_engine_freetype_int32 FontEngine;
#else
typedef agg::font_engine_win32_tt_int32 FontEngine;
#endif
typedef agg::font_cache_manager<FontEngine> FontCacheManager;
typedef FontCacheManager::gray8_adaptor_type FontRasterizer;
typedef FontCacheManager::gray8_scanline_type FontScanline;
typedef agg::conv_curve<agg::path_storage> ConvCurve;
typedef agg::conv_stroke<ConvCurve> ConvStroke;
typedef agg::conv_transform<ConvCurve> PathTransform;
typedef agg::conv_transform<ConvStroke> StrokeTransform;
enum Gradient
{
Solid,
Linear,
Radial
};
public:
friend class Agg2DRenderer;
// Use srgba8 as the "user" color type, even though the underlying color type
// might be something else, such as rgba32. This allows code based on
// 8-bit sRGB values to carry on working as before.
typedef agg::srgba8 Color;
typedef agg::rect_i Rect;
typedef agg::rect_d RectD;
typedef agg::trans_affine Affine;
enum LineJoin
{
JoinMiter = agg::miter_join,
JoinRound = agg::round_join,
JoinBevel = agg::bevel_join
};
enum LineCap
{
CapButt = agg::butt_cap,
CapSquare = agg::square_cap,
CapRound = agg::round_cap
};
enum TextAlignment
{
AlignLeft,
AlignRight,
AlignCenter,
AlignTop = AlignRight,
AlignBottom = AlignLeft
};
enum DrawPathFlag
{
FillOnly,
StrokeOnly,
FillAndStroke,
FillWithLineColor
};
enum ViewportOption
{
Anisotropic,
XMinYMin,
XMidYMin,
XMaxYMin,
XMinYMid,
XMidYMid,
XMaxYMid,
XMinYMax,
XMidYMax,
XMaxYMax
};
struct Transformations
{
double affineMatrix[6];
};
struct Image
{
agg::rendering_buffer renBuf;
Image() {}
Image(unsigned char* buf, unsigned width, unsigned height, int stride) :
renBuf(buf, width, height, stride) {}
void attach(unsigned char* buf, unsigned width, unsigned height, int stride)
{
renBuf.attach(buf, width, height, stride);
}
int width() const { return renBuf.width(); }
int height() const { return renBuf.height(); }
void premultiply();
void demultiply();
};
enum ImageFilter
{
NoFilter,
Bilinear,
Hanning,
Hermite,
Quadric,
Bicubic,
Catrom,
Spline16,
Spline36,
Blackman144
};
enum ImageResample
{
NoResample,
ResampleAlways,
ResampleOnZoomOut
};
enum FontCacheType
{
RasterFontCache,
VectorFontCache
};
enum BlendMode
{
BlendAlpha = agg::end_of_comp_op_e,
BlendClear = agg::comp_op_clear,
BlendSrc = agg::comp_op_src,
BlendDst = agg::comp_op_dst,
BlendSrcOver = agg::comp_op_src_over,
BlendDstOver = agg::comp_op_dst_over,
BlendSrcIn = agg::comp_op_src_in,
BlendDstIn = agg::comp_op_dst_in,
BlendSrcOut = agg::comp_op_src_out,
BlendDstOut = agg::comp_op_dst_out,
BlendSrcAtop = agg::comp_op_src_atop,
BlendDstAtop = agg::comp_op_dst_atop,
BlendXor = agg::comp_op_xor,
BlendAdd = agg::comp_op_plus,
BlendMultiply = agg::comp_op_multiply,
BlendScreen = agg::comp_op_screen,
BlendOverlay = agg::comp_op_overlay,
BlendDarken = agg::comp_op_darken,
BlendLighten = agg::comp_op_lighten,
BlendColorDodge = agg::comp_op_color_dodge,
BlendColorBurn = agg::comp_op_color_burn,
BlendHardLight = agg::comp_op_hard_light,
BlendSoftLight = agg::comp_op_soft_light,
BlendDifference = agg::comp_op_difference,
BlendExclusion = agg::comp_op_exclusion,
};
enum Direction
{
CW, CCW
};
~Agg2D();
Agg2D();
// Setup
//-----------------------
void attach(unsigned char* buf, unsigned width, unsigned height, int stride);
void attach(Image& img);
void clipBox(double x1, double y1, double x2, double y2);
RectD clipBox() const;
void clearAll(Color c);
void clearAll(unsigned r, unsigned g, unsigned b, unsigned a = 255);
void clearClipBox(Color c);
void clearClipBox(unsigned r, unsigned g, unsigned b, unsigned a = 255);
// Conversions
//-----------------------
void worldToScreen(double& x, double& y) const;
void screenToWorld(double& x, double& y) const;
double worldToScreen(double scalar) const;
double screenToWorld(double scalar) const;
void alignPoint(double& x, double& y) const;
bool inBox(double worldX, double worldY) const;
// General Attributes
//-----------------------
void blendMode(BlendMode m);
BlendMode blendMode() const;
void imageBlendMode(BlendMode m);
BlendMode imageBlendMode() const;
void imageBlendColor(Color c);
void imageBlendColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
Color imageBlendColor() const;
void masterAlpha(double a);
double masterAlpha() const;
void antiAliasGamma(double g);
double antiAliasGamma() const;
void fillColor(Color c);
void fillColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
void noFill();
void lineColor(Color c);
void lineColor(unsigned r, unsigned g, unsigned b, unsigned a = 255);
void noLine();
Color fillColor() const;
Color lineColor() const;
void fillLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0);
void lineLinearGradient(double x1, double y1, double x2, double y2, Color c1, Color c2, double profile=1.0);
void fillRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0);
void lineRadialGradient(double x, double y, double r, Color c1, Color c2, double profile=1.0);
void fillRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3);
void lineRadialGradient(double x, double y, double r, Color c1, Color c2, Color c3);
void fillRadialGradient(double x, double y, double r);
void lineRadialGradient(double x, double y, double r);
void lineWidth(double w);
double lineWidth(double w) const;
void lineCap(LineCap cap);
LineCap lineCap() const;
void lineJoin(LineJoin join);
LineJoin lineJoin() const;
void fillEvenOdd(bool evenOddFlag);
bool fillEvenOdd() const;
// Transformations
//-----------------------
Transformations transformations() const;
void transformations(const Transformations& tr);
void resetTransformations();
void affine(const Affine& tr);
void affine(const Transformations& tr);
void rotate(double angle);
void scale(double sx, double sy);
void skew(double sx, double sy);
void translate(double x, double y);
void parallelogram(double x1, double y1, double x2, double y2, const double* para);
void viewport(double worldX1, double worldY1, double worldX2, double worldY2,
double screenX1, double screenY1, double screenX2, double screenY2,
ViewportOption opt=XMidYMid);
// Basic Shapes
//-----------------------
void line(double x1, double y1, double x2, double y2);
void triangle(double x1, double y1, double x2, double y2, double x3, double y3);
void rectangle(double x1, double y1, double x2, double y2);
void roundedRect(double x1, double y1, double x2, double y2, double r);
void roundedRect(double x1, double y1, double x2, double y2, double rx, double ry);
void roundedRect(double x1, double y1, double x2, double y2,
double rxBottom, double ryBottom,
double rxTop, double ryTop);
void ellipse(double cx, double cy, double rx, double ry);
void arc(double cx, double cy, double rx, double ry, double start, double sweep);
void star(double cx, double cy, double r1, double r2, double startAngle, int numRays);
void curve(double x1, double y1, double x2, double y2, double x3, double y3);
void curve(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4);
void polygon(double* xy, int numPoints);
void polyline(double* xy, int numPoints);
// Text
//-----------------------
void flipText(bool flip);
void font(const char* fileName, double height,
bool bold = false,
bool italic = false,
FontCacheType ch = RasterFontCache,
double angle = 0.0);
double fontHeight() const;
void textAlignment(TextAlignment alignX, TextAlignment alignY);
bool textHints() const;
void textHints(bool hints);
double textWidth(const char* str);
void text(double x, double y, const char* str, bool roundOff=false, double dx=0.0, double dy=0.0);
// Path commands
//-----------------------
void resetPath();
void moveTo(double x, double y);
void moveRel(double dx, double dy);
void lineTo(double x, double y);
void lineRel(double dx, double dy);
void horLineTo(double x);
void horLineRel(double dx);
void verLineTo(double y);
void verLineRel(double dy);
void arcTo(double rx, double ry,
double angle,
bool largeArcFlag,
bool sweepFlag,
double x, double y);
void arcRel(double rx, double ry,
double angle,
bool largeArcFlag,
bool sweepFlag,
double dx, double dy);
void quadricCurveTo(double xCtrl, double yCtrl,
double xTo, double yTo);
void quadricCurveRel(double dxCtrl, double dyCtrl,
double dxTo, double dyTo);
void quadricCurveTo(double xTo, double yTo);
void quadricCurveRel(double dxTo, double dyTo);
void cubicCurveTo(double xCtrl1, double yCtrl1,
double xCtrl2, double yCtrl2,
double xTo, double yTo);
void cubicCurveRel(double dxCtrl1, double dyCtrl1,
double dxCtrl2, double dyCtrl2,
double dxTo, double dyTo);
void cubicCurveTo(double xCtrl2, double yCtrl2,
double xTo, double yTo);
void cubicCurveRel(double xCtrl2, double yCtrl2,
double xTo, double yTo);
void addEllipse(double cx, double cy, double rx, double ry, Direction dir);
void closePolygon();
void drawPath(DrawPathFlag flag = FillAndStroke);
void drawPathNoTransform(DrawPathFlag flag = FillAndStroke);
// Image Transformations
//-----------------------
void imageFilter(ImageFilter f);
ImageFilter imageFilter() const;
void imageResample(ImageResample f);
ImageResample imageResample() const;
void transformImage(const Image& img,
int imgX1, int imgY1, int imgX2, int imgY2,
double dstX1, double dstY1, double dstX2, double dstY2);
void transformImage(const Image& img,
double dstX1, double dstY1, double dstX2, double dstY2);
void transformImage(const Image& img,
int imgX1, int imgY1, int imgX2, int imgY2,
const double* parallelogram);
void transformImage(const Image& img, const double* parallelogram);
void transformImagePath(const Image& img,
int imgX1, int imgY1, int imgX2, int imgY2,
double dstX1, double dstY1, double dstX2, double dstY2);
void transformImagePath(const Image& img,
double dstX1, double dstY1, double dstX2, double dstY2);
void transformImagePath(const Image& img,
int imgX1, int imgY1, int imgX2, int imgY2,
const double* parallelogram);
void transformImagePath(const Image& img, const double* parallelogram);
// Image Blending (no transformations available)
void blendImage(Image& img,
int imgX1, int imgY1, int imgX2, int imgY2,
double dstX, double dstY, unsigned alpha=255);
void blendImage(Image& img, double dstX, double dstY, unsigned alpha=255);
// Copy image directly, together with alpha-channel
void copyImage(Image& img,
int imgX1, int imgY1, int imgX2, int imgY2,
double dstX, double dstY);
void copyImage(Image& img, double dstX, double dstY);
// Auxiliary
//-----------------------
static double pi() { return agg::pi; }
static double deg2Rad(double v) { return v * agg::pi / 180.0; }
static double rad2Deg(double v) { return v * 180.0 / agg::pi; }
private:
void render(bool fillColor);
void render(FontRasterizer& ras, FontScanline& sl);
void addLine(double x1, double y1, double x2, double y2);
void updateRasterizerGamma();
void renderImage(const Image& img, int x1, int y1, int x2, int y2, const double* parl);
agg::rendering_buffer m_rbuf;
PixFormat m_pixFormat;
PixFormatComp m_pixFormatComp;
PixFormatPre m_pixFormatPre;
PixFormatCompPre m_pixFormatCompPre;
RendererBase m_renBase;
RendererBaseComp m_renBaseComp;
RendererBasePre m_renBasePre;
RendererBaseCompPre m_renBaseCompPre;
RendererSolid m_renSolid;
RendererSolidComp m_renSolidComp;
SpanAllocator m_allocator;
RectD m_clipBox;
BlendMode m_blendMode;
BlendMode m_imageBlendMode;
Color m_imageBlendColor;
agg::scanline_u8 m_scanline;
agg::rasterizer_scanline_aa<> m_rasterizer;
double m_masterAlpha;
double m_antiAliasGamma;
Color m_fillColor;
Color m_lineColor;
GradientArray m_fillGradient;
GradientArray m_lineGradient;
LineCap m_lineCap;
LineJoin m_lineJoin;
Gradient m_fillGradientFlag;
Gradient m_lineGradientFlag;
agg::trans_affine m_fillGradientMatrix;
agg::trans_affine m_lineGradientMatrix;
double m_fillGradientD1;
double m_lineGradientD1;
double m_fillGradientD2;
double m_lineGradientD2;
double m_textAngle;
TextAlignment m_textAlignX;
TextAlignment m_textAlignY;
bool m_textHints;
double m_fontHeight;
double m_fontAscent;
double m_fontDescent;
FontCacheType m_fontCacheType;
ImageFilter m_imageFilter;
ImageResample m_imageResample;
agg::image_filter_lut m_imageFilterLut;
agg::span_interpolator_linear<> m_fillGradientInterpolator;
agg::span_interpolator_linear<> m_lineGradientInterpolator;
agg::gradient_x m_linearGradientFunction;
agg::gradient_circle m_radialGradientFunction;
double m_lineWidth;
bool m_evenOddFlag;
agg::path_storage m_path;
agg::trans_affine m_transform;
ConvCurve m_convCurve;
ConvStroke m_convStroke;
PathTransform m_pathTransform;
StrokeTransform m_strokeTransform;
#ifndef AGG2D_USE_FREETYPE
HDC m_fontDC;
#endif
FontEngine m_fontEngine;
FontCacheManager m_fontCacheManager;
};
inline bool operator == (const Agg2D::Color& c1, const Agg2D::Color& c2)
{
return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b && c1.a == c2.a;
}
inline bool operator != (const Agg2D::Color& c1, const Agg2D::Color& c2)
{
return !(c1 == c2);
}
#endif

23
autogen.sh Normal file
View File

@ -0,0 +1,23 @@
# autogen.sh
#
# invoke the auto* tools to create the configuration/build system
# build aclocal.m4
aclocal
# build config.h
autoheader
# build the configure script
autoconf
# set up libtool
libtoolize --force
# invoke automake
automake --foreign --add-missing --ignore-deps
# and finally invoke our new configure
./configure $*
# end

36
bin/AggConfig.cmake.in Normal file
View File

@ -0,0 +1,36 @@
#set where AggConfig.cmake was found, all else relative to that.
SET( AGG_FLAGS "" )
SET( AGG_INCLUDE_DIRS "" )
SET( AGG_LIBRARY_DIRS "" )
SET( AGG_LIBRARIES "" )
SET( AGG_FLAGS @AGG_FLAGS@ )
SET( AGG_INCLUDE_DIRS_CONFIG @AGG_INCLUDE_DIRS@ )
#convert relative to absolute
FOREACH( includedir ${AGG_INCLUDE_DIRS_CONFIG} )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} "@antigrain_SOURCE_DIR@/${includedir}" )
ENDFOREACH( includedir )
SET( AGG_LIBRARIES @AGG_LIBRARIES@ )
SET( AGG_LIBRARY_DIRS_CONFIG @AGG_LIBRARY_DIRS@ )
#convert relative to absolute
FOREACH( libdir ${AGG_LIBRARY_DIRS_CONFIG} )
SET( AGG_LIBRARY_DIRS ${AGG_LIBRARY_DIRS} "${AGG_DIR_BIN}/../${libdir}" )
ENDFOREACH( libdir )
SET( AGG_USE_FILE ${AGG_DIR_BIN}/UseAgg.cmake )
#options that where set
SET( agg_USE_GPC @agg_USE_GPC@ )
SET( agg_USE_FREETYPE @agg_USE_FREETYPE@ )
SET( agg_USE_EXPAT @agg_USE_EXPAT@ )
SET( agg_USE_AGG2D @agg_USE_AGG2D@ )
SET( AGG_DIR ${AGG_DIR} CACHE STRING "Agg root directory" FORCE )
SET( AGG_FLAGS ${AGG_FLAGS} CACHE STRING "Agg package flags" FORCE )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} CACHE STRING "Agg package libs include paths" FORCE )
SET( AGG_LIBRARY_DIRS ${AGG_LIBRARY_DIRS} CACHE STRING "Agg package libs directory paths" FORCE )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} CACHE STRING "Agg package libraries" FORCE )

View File

@ -0,0 +1,37 @@
#set where AggConfig.cmake was found, all else relative to that.
# one higher as "bin" dir is all of agg
SET( AGG_FLAGS "" )
SET( AGG_INCLUDE_DIRS "" )
SET( AGG_LIBRARY_DIRS "" )
SET( AGG_LIBRARIES "" )
SET( AGG_FLAGS @AGG_FLAGS@ )
SET( AGG_INCLUDE_DIRS_CONFIG @AGG_INCLUDE_DIRS@ )
#convert relative to absolute
FOREACH( includedir ${AGG_INCLUDE_DIRS_CONFIG} )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} "${AGG_DIR_BIN}/../agg/${includedir}" )
ENDFOREACH( includedir )
SET( AGG_LIBRARIES @AGG_LIBRARIES@ )
SET( AGG_LIBRARY_DIRS_CONFIG @AGG_LIBRARY_DIRS@ )
#convert relative to absolute
FOREACH( libdir ${AGG_LIBRARY_DIRS_CONFIG} )
SET( AGG_LIBRARY_DIRS ${AGG_LIBRARY_DIRS} "${AGG_DIR_BIN}/../${libdir}" )
ENDFOREACH( libdir )
SET( AGG_USE_FILE ${AGG_DIR_BIN}/UseAgg.cmake )
#options that where set
SET( agg_USE_GPC @agg_USE_GPC@ )
SET( agg_USE_FREETYPE @agg_USE_FREETYPE@ )
SET( agg_USE_EXPAT @agg_USE_EXPAT@ )
SET( agg_USE_AGG2D @agg_USE_AGG2D@ )
SET( AGG_DIR ${AGG_DIR} CACHE STRING "Agg root directory" FORCE )
SET( AGG_FLAGS ${AGG_FLAGS} CACHE STRING "Agg package flags" FORCE )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} CACHE STRING "Agg package libs include paths" FORCE )
SET( AGG_LIBRARY_DIRS ${AGG_LIBRARY_DIRS} CACHE STRING "Agg package libs directory paths" FORCE )
SET( AGG_LIBRARIES ${AGG_LIBRARIES} CACHE STRING "Agg package libraries" FORCE )

157
bin/FindAgg.cmake Normal file
View File

@ -0,0 +1,157 @@
# - Locate Agg libraries
# This module defines
# AGG_LIBRARIES, the library to link against
# AGG_FOUND, if false, do not try to link to AGG
# AGG_INCLUDE_DIRS, where to find headers.
#
# $AGG_DIR is an environment variable that would
# correspond to the install directory on e.g. windows.
# Created by Klaas Holwerda.
# Search only if the location is not already known.
SET( AGG_DIR_BIN AGG_DIR_BIN-NOTFOUND CACHE INTERNAL "" )
#
# Look for an installation or build tree.
#
FIND_PATH(AGG_DIR_BIN AggConfig.cmake
# Look for an environment variable AGG_DIR.
$ENV{AGG_DIR}/bin
${AGG_DIR}/bin
# Look in search path.
$ENV{PATH}
NO_DEFAULT_PATH
DOC "WXART2D_DIR found"]
# Help the user find it if we cannot.
DOC "The Agg bin dir"
)
FIND_PATH(AGG_DIR_BIN AggConfig.cmake
# Look in standard UNIX install locations.
/usr/local/bin
/usr/local/lib/agg
/usr/lib/agg
/usr/local/include/agg
/usr/local/include
/usr/include
/usr/local/agg
/usr/X11R6/include
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Agg\\antigrain 0.1.1]/bin"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Agg_is1;Inno Setup: App Path]/bin"
# Read from the CMakeSetup registry entries. It is likely that
# AGG will have been recently built.
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild1]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild2]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild3]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild4]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild5]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild6]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild7]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild8]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild9]/bin
[HKEY_CURRENT_USER\\Software\\Kitware\\CMakeSetup\\Settings\\StartPath;WhereBuild10]/bin
# Help the user find it if we cannot.
DOC "The Agg bin dir"
)
# If AGG was found, load the configuration file to get the rest of the
# settings.
IF( AGG_DIR_BIN )
# Check if AGG was built using CMake
IF(EXISTS ${AGG_DIR_BIN}/AggConfig.cmake)
SET(AGG_BUILT_WITH_CMAKE 1)
ENDIF(EXISTS ${AGG_DIR_BIN}/AggConfig.cmake)
IF(AGG_BUILT_WITH_CMAKE)
INCLUDE(${AGG_DIR_BIN}/AggConfig.cmake)
# at this point AGG_LIBRARIES AGG_INCLUDE_DIRS etc. are set .
ELSE(AGG_BUILT_WITH_CMAKE)
# oh no! Oke lets do things the hard way.
FIND_PATH(AGG_INCLUDE_DIR agg_config.h
${AGG_DIR}/include
NO_DEFAULT_PATH
)
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIRS} ${AGG_INCLUDE_DIR} )
FIND_LIBRARY(AGG_LIBRARY_agg
NAMES agg
PATHS
${AGG_DIR}
NO_DEFAULT_PATH
PATH_SUFFIXES lib64 lib
)
SET( AGG_LIBRARIES ${AGG_LIBRARIES} ${AGG_LIBRARY_agg} )
FIND_LIBRARY(AGG_LIBRARY_aggctrl
NAMES aggctrl
PATHS
${AGG_DIR}
NO_DEFAULT_PATH
PATH_SUFFIXES lib64 lib
)
SET( AGG_LIBRARIES ${AGG_LIBRARIES} ${AGG_LIBRARY_aggctrl} )
FIND_LIBRARY(AGG_LIBRARY_aggfontfreetype
NAMES aggfontfreetype
PATHS
${AGG_DIR}
NO_DEFAULT_PATH
PATH_SUFFIXES lib64 lib
)
SET( AGG_LIBRARIES ${AGG_LIBRARIES} ${AGG_LIBRARY_aggfontfreetype} )
FIND_LIBRARY(AGG_LIBRARY_aggplatform
NAMES aggplatform
PATHS
${AGG_DIR}
NO_DEFAULT_PATH
PATH_SUFFIXES lib64 lib
)
SET( AGG_LIBRARIES ${AGG_LIBRARIES} ${AGG_LIBRARY_aggplatform} )
FIND_LIBRARY(AGG_LIBRARY_gpc
NAMES gpc
PATHS
${AGG_DIR}
NO_DEFAULT_PATH
PATH_SUFFIXES lib64 lib
)
SET( AGG_LIBRARIES ${AGG_LIBRARIES} ${AGG_LIBRARY_gpc} )
SET( AGG_INCLUDE_DIRS ${AGG_INCLUDE_DIR} )
ENDIF(AGG_BUILT_WITH_CMAKE)
ENDIF( AGG_DIR_BIN)
#MESSAGE ( "AGG_INCLUDE_DIRS => ${AGG_INCLUDE_DIRS}" )
#MESSAGE ( "AGG_LIBRARIES => ${AGG_LIBRARIES}" )
#MESSAGE ( "AGG_DIR_BIN => ${AGG_DIR_BIN}" )
# handle the QUIETLY and REQUIRED arguments and set AGG_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Agg DEFAULT_MSG AGG_DIR_BIN AGG_LIBRARIES AGG_INCLUDE_DIRS)
MARK_AS_ADVANCED( AGG_DIR_BIN AGG_LIBRARIES AGG_INCLUDE_DIRS)

38
bin/FindEXPAT.cmake Normal file
View File

@ -0,0 +1,38 @@
# - Find expat
# Find the native EXPAT headers and libraries.
#
# EXPAT_INCLUDE_DIRS - where to find expat.h, etc.
# EXPAT_LIBRARIES - List of libraries when using expat.
# EXPAT_FOUND - True if expat found.
# Look for the header file.
FIND_PATH( EXPAT_INCLUDE_DIR expat.h
$ENV{EXPAT_DIR}/Source/lib
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\expat_is1;Inno Setup: App Path]/Source/lib"
)
# Look for the library.
FIND_LIBRARY( EXPAT_LIBRARY NAMES expat libexpat
PATHS
$ENV{EXPAT_DIR}/Bin
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\expat_is1;Inno Setup: App Path]/bin"
)
#MESSAGE ( "EXPAT_INCLUDE_DIR => ${EXPAT_INCLUDE_DIR}" )
#MESSAGE ( "EXPAT_LIBRARY => ${EXPAT_LIBRARY}" )
# handle the QUIETLY and REQUIRED arguments and set EXPAT_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(EXPAT DEFAULT_MSG EXPAT_LIBRARY EXPAT_INCLUDE_DIR)
# Copy the results to the output variables.
IF(EXPAT_FOUND)
SET(EXPAT_LIBRARIES ${EXPAT_LIBRARY})
SET(EXPAT_INCLUDE_DIRS ${EXPAT_INCLUDE_DIR})
ELSE(EXPAT_FOUND)
SET(EXPAT_LIBRARIES)
SET(EXPAT_INCLUDE_DIRS)
ENDIF(EXPAT_FOUND)
MARK_AS_ADVANCED(EXPAT_INCLUDE_DIR EXPAT_LIBRARY)

98
bin/FindFreetype.cmake Normal file
View File

@ -0,0 +1,98 @@
# - Locate FreeType library
# This module defines
# FREETYPE_LIBRARIES, the library to link against
# FREETYPE_FOUND, if false, do not try to link to FREETYPE
# FREETYPE_INCLUDE_DIRS, where to find headers.
# This is the concatenation of the paths:
# FREETYPE_INCLUDE_DIR_ft2build
# FREETYPE_INCLUDE_DIR_freetype2
#
# $FREETYPE_DIR is an environment variable that would
# correspond to the ./configure --prefix=$FREETYPE_DIR
# used in building FREETYPE.
# Created by Eric Wing.
# Modifications by Alexander Neundorf.
# This file has been renamed to "FindFreetype.cmake" instead of the correct
# "FindFreeType.cmake" in order to be compatible with the one from KDE4, Alex.
# Ugh, FreeType seems to use some #include trickery which
# makes this harder than it should be. It looks like they
# put ft2build.h in a common/easier-to-find location which
# then contains a #include to a more specific header in a
# more specific location (#include <freetype/config/ftheader.h>).
# Then from there, they need to set a bunch of #define's
# so you can do something like:
# #include FT_FREETYPE_H
# Unfortunately, using CMake's mechanisms like INCLUDE_DIRECTORIES()
# wants explicit full paths and this trickery doesn't work too well.
# I'm going to attempt to cut out the middleman and hope
# everything still works.
FIND_PATH(FREETYPE_INCLUDE_DIR_ft2build ft2build.h
$ENV{FREETYPE_DIR}/include
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\FreeType-2.3.5-1_is1;Inno Setup: App Path]/include"
NO_DEFAULT_PATH
)
FIND_PATH(FREETYPE_INCLUDE_DIR_ft2build ft2build.h
PATHS
/usr/local/X11R6/include
/usr/local/X11/include
/usr/X11/include
/sw/include
/opt/local/include
/usr/freeware/include
)
FIND_PATH(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h
$ENV{FREETYPE_DIR}/include/freetype2
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\FreeType-2.3.5-1_is1;Inno Setup: App Path]/include/freetype2"
NO_DEFAULT_PATH
)
FIND_PATH(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h
/usr/local/X11R6/include
/usr/local/X11/include
/usr/X11/include
/sw/include
/opt/local/include
/usr/freeware/include
PATH_SUFFIXES freetype2
)
FIND_LIBRARY(FREETYPE_LIBRARY
NAMES freetype libfreetype freetype219
PATHS
$ENV{FREETYPE_DIR}
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\FreeType-2.3.5-1_is1;Inno Setup: App Path]"
NO_DEFAULT_PATH
PATH_SUFFIXES lib64 lib
)
FIND_LIBRARY(FREETYPE_LIBRARY
NAMES freetype libfreetype freetype219
PATHS
/usr/local/X11R6
/usr/local/X11
/usr/X11
/sw
/usr/freeware
PATH_SUFFIXES lib64 lib
)
# set the user variables
IF(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2)
SET(FREETYPE_INCLUDE_DIRS "${FREETYPE_INCLUDE_DIR_ft2build};${FREETYPE_INCLUDE_DIR_freetype2}")
ENDIF(FREETYPE_INCLUDE_DIR_ft2build AND FREETYPE_INCLUDE_DIR_freetype2)
SET(FREETYPE_LIBRARIES "${FREETYPE_LIBRARY}")
#MESSAGE ( "FREETYPE_INCLUDE_DIRS => ${FREETYPE_INCLUDE_DIRS}" )
#MESSAGE ( "FREETYPE_LIBRARIES => ${FREETYPE_LIBRARIES}" )
# handle the QUIETLY and REQUIRED arguments and set FREETYPE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Freetype DEFAULT_MSG FREETYPE_LIBRARY FREETYPE_INCLUDE_DIRS)
MARK_AS_ADVANCED(FREETYPE_LIBRARY FREETYPE_INCLUDE_DIR_freetype2 FREETYPE_INCLUDE_DIR_ft2build)

34
bin/UseAgg.cmake.in Normal file
View File

@ -0,0 +1,34 @@
#
# This module is provided as AGG_USE_FILE by AggConfig.cmake. It can
# be included in a project to load the needed compiler and linker
# settings to use AGG.
#
IF(NOT AGG_USE_FILE_INCLUDED)
SET(AGG_USE_FILE_INCLUDED 1)
# Add compiler flags needed to use AGG.
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${AGG_REQUIRED_C_FLAGS}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${AGG_REQUIRED_CXX_FLAGS}")
# Add include directories needed to use AGG.
INCLUDE_DIRECTORIES(${AGG_INCLUDE_DIRS})
# Add link directories needed to use AGG.
LINK_DIRECTORIES(${AGG_LIBRARY_DIRS})
FOREACH( flag ${AGG_FLAGS} )
ADD_DEFINITIONS( ${flag} )
ENDFOREACH( flag )
LINK_LIBRARIES(${AGG_LIBRARIES})
#options that where set
SET( agg_USE_GPC @agg_USE_GPC@ )
SET( agg_USE_FREETYPE @agg_USE_FREETYPE@ )
SET( agg_USE_EXPAT @agg_USE_EXPAT@ )
SET( agg_USE_AGG2D @agg_USE_AGG2D@ )
ENDIF(NOT AGG_USE_FILE_INCLUDED)

234
cmake_install.html Normal file
View File

@ -0,0 +1,234 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1><youros>Cmake to generate projects files or makefile.</youros></h1>
<youros><br>
You start with downloading and installing Cmake &nbsp;<a href="http:://www.cmake.org">http:://www.cmake.org </a><br>
<br>
</youros>
<ul>
<li><a href="#On_windows">On Windows</a></li>
<li><a href="#On_Unix_alikes">On Unix alikes</a></li>
<li><a href="#My_Own_Application">My Own Application</a></li>
<li><a href="#Cpack_to_make_distributions">Cpack for making distribution</a></li>
</ul>
<youros>
</youros>
<h2 style="font-style: italic; text-decoration: underline;">On windows</h2>
<youros>On windows call the program CmakeSetup.exe, distributed with
Cmake.<br>
This has a graphical interface used to generate your project files or
makefiles.<br>
<br>
Asumming Agg is installed at </youros>C:\agg\agg-2.4<br>
<youros><br>
</youros>In CmakeSetup.exe choose:<br>
<youros><br>
Where is the source code: </youros>C:\agg\agg-2.4<br>
Where to build the binaries: C:\agg\agg-2.4_Build<br>
<br>
The options:<br>
<ul>
<li>
agg_USE_EXPAT</li>
<ul>
<li>At <a href="http://expat.sourceforge.net/">http://expat.sourceforge.net/&nbsp;</a></li>
<li>you will find&nbsp;<a href="http://garr.dl.sourceforge.net/sourceforge/expat/expat-win32bin-2.0.1.exe">expat-win32bin-2.0.1.exe</a> &nbsp;</li>
<li>This will add a key to your registry, which is searched for by Cmake, if not oke, use next step.</li>
<li><span style="font-family: monospace;">Do set EXPAT_DIR in your environment to the location where you installed the above.</span></li>
</ul>
<li>
agg_USE_FREETYPE</li>
<ul>
<li>Get the library + headers from: <a href="http://gnuwin32.sourceforge.net/packages/freetype.htm">http://gnuwin32.sourceforge.net/packages/freetype.htm</a></li>
<li>tested with the download called: "Complete package, except sources"&nbsp;</li>
<li>This will add a key to your registry, which is searched for by Cmake, if not oke, use next step.</li>
<li><span style="font-family: monospace;">Do set FREETYPE_DIR in your environment to the location where you installed the above.<br>
</span></li>
</ul>
<li>
agg_USE_GPC</li>
<ul>
<li>Internal files, but GPL, so an option.</li>
</ul>
<li>
agg_USE_SDL_PLATFORM</li>
<ul>
<li>Todo</li>
</ul>
<li>agg_USE_PACK</li>
<ul>
<li><a href="cmake_install.html#Cpack_to_make_distributions">See Cpack for making distribution</a></li>
</ul>
</ul>
For windows the routines to find expat and freetype are script found in
C:\agg\agg-2.4\bin. They are available in Cmake itself, but the ones
here are better.<br>
In case of problem, un-comment the MESSAGE statements in those script, to see what is going on.
<h2 style="font-style: italic; text-decoration: underline;">On Unix alikes</h2>
Asumming Agg is installed at /home/me/agg/agg-2.4<br>
<youros><br>
</youros><span style="font-family: monospace; font-weight: bold;">cd /home/me/agg</span><br style="font-family: monospace; font-weight: bold;">
<span style="font-family: monospace; font-weight: bold;">
mkdir agg_build</span><br style="font-family: monospace; font-weight: bold;">
<span style="font-family: monospace; font-weight: bold;">
cd /home/me/agg/agg_build</span><br>
<br>
Here you generate makefiles with a GUI with:<br>
<br>
<span style="font-family: monospace; font-weight: bold;">ccmake ../agg-2.4</span><br>
<br>
OR using commandline for example:<br>
<br>
<span style="font-family: monospace; font-weight: bold;">cmake &nbsp;-Dagg_USE_FREETYPE:BOOL=ON -Dagg_USE_EXPAT:BOOL=ON ../agg-2.4</span><br style="font-family: monospace;">
<br>
The options:<br>
<ul>
<li>
agg_USE_EXPAT</li>
<ul>
<li>Requires expat to be installed.</li>
</ul>
<li>
agg_USE_FREETYPE</li>
<ul>
<li>Requires freetype-devel to be installed. (e.g. on Fedora:&nbsp; yum install freetype-devel&nbsp;)</li>
</ul>
<li>
agg_USE_GPC</li>
<ul>
<li>Part of Agg for the moment, but GPL, that is why its optional.</li>
</ul>
<li>
agg_USE_SDL_PLATFORM</li>
<ul>
<li>SDL needs to be installed.</li>
</ul>
<li>agg_USE_PACK</li>
<ul>
<li><a href="cmake_install.html#Cpack_to_make_distributions">See Cpack for making distribution</a></li>
</ul>
</ul>
After generating the makefiles, you just type:<br>
<span style="font-weight: bold; font-family: monospace;">make</span>
You can also build directly in the agg checkout dircetory, but that is bad habit.<br>
<br>
When all is compiled, you can execute the samples already from the examples directory in your build tree.<br>
Now you can login as root and install Agg as you compiled it.<br>
So you type:<br>
<br>
<span style="font-weight: bold;">make install</span><br>
<br>
This installes your file in <span style="font-weight: bold;">/usr/local.</span><br>
<h2><span style="font-weight: bold;"></span><span style="font-style: italic; text-decoration: underline;">My Own Application</span></h2>
Nice but what if i want to detect Agg libraries and headers etc. for
use in &nbsp;my own application. For that you find in the resulting
build directory created by Cmake, &nbsp;a template directory called
myapp, containing a simple application. This show you how to do it for
your own application. In there you see CMakeLists.txt, this file you
can use in CMakeSetup.exe/ccmake as the&nbsp;source directory. Again
choose your build directory, and configure.<br>
This will result in project/make files for the demo application contained in my_demo.cpp.<br>
<br>
In principle this is needed ( see myapp/CMakeLists.txt ):<br>
<br>
FIND_PACKAGE( Agg )<br>
IF( AGG_FOUND )<br>
&nbsp;&nbsp;&nbsp; INCLUDE_DIRECTORIES(${AGG_INCLUDE_DIRS})<br>
&nbsp;&nbsp;&nbsp; LINK_LIBRARIES(${AGG_LIBRARIES})<br>
&nbsp;&nbsp;&nbsp; INCLUDE(${AGG_USE_FILE})<br>
ELSE( AGG_FOUND )<br>
&nbsp;&nbsp;&nbsp; MESSAGE( "AGG library was not found" )<br>
ENDIF( AGG_FOUND )<br>
<br>
If you look in your&nbsp;C:\agg\agg-2.4_Build you will see that <span style="font-weight: bold;">AggConfig.cmake</span> and <span style="font-weight: bold;">UseAgg.cmake</span>, they contain all the information you need to have to use Agg in your application. Study <span style="font-weight: bold;">FindAgg.cmake</span> to know who Agg install dir is found.<br>
Also be aware &nbsp;that the file C:\agg\agg-2.4_Build\bin\<span style="font-weight: bold;">AggConfigOutBuild.cmake</span> is installed as&nbsp;<span style="font-weight: bold;">AggConfig.cmake</span> by <span style="font-weight: bold;">make install</span> are inside the packages.<br>
The file C:\agg\agg-2.4_Build<span style="font-weight: bold;">\AggConfig.cmake </span>is setup such that you can use it from with in the build directory itself, using the Agg header files from the source directory.<br>
This is the same as when building the agg libraries itself.<br>
Only when packaging and/or doing a <span style="font-weight: bold;">make install</span>, the headers will be really installed. <br>
On windows you need to set the environment variable AGG_DIR, if
automatic detection via the registry fails. But if you use a package
like <span style="font-weight: bold;">antigrain-0.1.1-win32.exe </span>to install on windows<span style="font-weight: bold;">, </span>a registry key<span style="font-weight: bold;">&nbsp; "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Agg\\antigrain 0.1.1]/bin" </span>is generated, which is used by FindAgg.cmake to find the installation.<br>
<br>
On Unix you can, after installing Agg, go to <span style="font-family: monospace; font-weight: bold;">/home/me/agg/agg_build/myapp </span><span style="font-family: monospace;">and type this for an inside build:<br>
<br>
</span><span style="font-family: monospace; font-weight: bold;">cmake .<br>
</span><span style="font-family: monospace;"><br>
or for an outside build:<br>
<br>
</span><span style="font-family: monospace; font-weight: bold;">mkdir ../buildmyapp<br>
cd </span><span style="font-family: monospace; font-weight: bold;">../buildmyapp</span><br>
<span style="font-family: monospace; font-weight: bold;">cmake ../myapp</span><span style="font-weight: bold;"><br>
</span><br>
If you do not want to install, you can set<span style="font-weight: bold;"> </span>AGG_DIR first, to use the build without installing, like:<br>
<br>
<span style="font-weight: bold;">export AGG_DIR=</span><span style="font-family: monospace; font-weight: bold;">/home/me/agg/agg_build<br>
<br>
</span>
<h2 style="font-style: italic; text-decoration: underline;">Cpack to make distributions</h2>
If enabled agg_USE_PACK, you get an extra target.<br>
On windows have gzip and nsis installed, they are used to generate the
setup/installer script and zip files, and found automatically:<br>
<br style="font-weight: bold;">
<span style="font-weight: bold;">http://nsis.sourceforge.net</span><br style="font-weight: bold;">
<span style="font-weight: bold;">http://www.7-zip.org</span><br>
<br>
Parts of the Cmake system &nbsp;is Cpack. After a build of Agg,
&nbsp;you get an extra target to PACKAGE, but you can do it by hand
also.<br>
Calling the Cmake tool:&nbsp;<span style="font-weight: bold;">cpack.exe -C debug </span>or<span style="font-weight: bold;"> </span><span style="font-weight: bold;">cpack.exe -C &nbsp;release </span>on the command line, will result in files like:<br>
<br style="font-weight: bold;">
<span style="font-weight: bold;">antigrain-0.1.1-win32.exe &nbsp; &nbsp; </span>&nbsp;# this is the installers script for Agg on windows.<br style="font-weight: bold;">
<span style="font-weight: bold;">antigrain-0.1.1-win32.zip &nbsp; &nbsp; &nbsp; </span>#contains the same, and can be installed by hand<span style="font-weight: bold;"><br>
<br>
</span><span style="font-weight: bold;"></span>The first gives you a
registery key like this: [HKEY_LOCAL_MACHINE\SOFTWARE\Agg\antigrain
0.1.1] And that is used to detect Agg in <span style="font-weight: bold;">FindAgg.cmake</span>, if you use the zip file, you will need to set AGG_DIR in your environment to reach the same.<br>
<br>
On unix you type:<br>
<br>
<span style="font-weight: bold;">cpack -C debug</span> on the&nbsp;line, and this gives you files like:<br>
<br>
<span style="font-weight: bold;">antigrain-0.1.1-Linux.sh</span><br style="font-weight: bold;">
<span style="font-weight: bold;">antigrain-0.1.1-Linux.tar.gz</span><br style="font-weight: bold;">
<span style="font-weight: bold;">antigrain-0.1.1-Linux.tar.Z</span><br style="font-weight: bold;">
<span style="font-weight: bold;">antigrain-0.1.1-Linux.tar.bz2</span><br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<youros><br>
</youros>
</body>
</html>

166
configure.ac Normal file
View File

@ -0,0 +1,166 @@
AC_INIT(agg, 2.7.0)
AC_CONFIG_SRCDIR(src/agg_arc.cpp)
AC_CANONICAL_TARGET
AC_CONFIG_HEADERS(include/config.h)
AM_INIT_AUTOMAKE
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AC_ISC_POSIX
dnl AM_C_PROTOTYPES
dnl if test "x$U" != "x"; then
dnl AC_MSG_ERROR(Compiler not ANSI compliant)
dnl fi
AM_PROG_LIBTOOL
AC_PROG_INSTALL
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_ARG_ENABLE(examples,
AC_HELP_STRING([--enable-examples],[Antigrain examples]))
AM_CONDITIONAL(ENABLE_EXAMPLES,test x$enable_examples != xno)
AC_ARG_ENABLE(ctrl,
AC_HELP_STRING([--enable-ctrl],[a gui libray used in examples]))
AC_ARG_ENABLE(platform,
AC_HELP_STRING([--enable-platform],[portable platform layers]))
if test x$enable_examples != xno ; then
enable_platform="yes"
fi
if test x$enable_platform != xno ; then
enable_ctrl="yes"
fi
AM_CONDITIONAL(ENABLE_CTRL,test x$enable_ctrl != xno)
# used as platform library in examples:
# todo, make the PREFERED_PLATFORM selectable, after the set of possible
# Platforms to link the examples have been evaluated.
PREFERED_PLATFORM=X11
case "$host" in
*darwin* )
OSX_LIBS="-framework Carbon -framework QuickTime"
OSX_CFLAGS="-I/System/Library/Frameworks/Carbon.framework/Headers -I/System/Library/Frameworks/QuickTime.framework/Headers "
AC_SUBST(OSX_CFLAGS)
AC_SUBST(OSX_LIBS)
osx_host=yes
PREFERED_PLATFORM=mac
;;
dnl #### Check if we are compiling for win32 #####
*mingw*)
win32_host=yes
WINDOWS_LIBS=-lgdi32
WINDOWS_CFLAGS=
AC_SUBST(WINDOWS_CFLAGS)
AC_SUBST(WINDOWS_LIBS)
PREFERED_PLATFORM=win32
;;
esac
AM_CONDITIONAL(ENABLE_WIN32,[test x$win32_host = xyes -a x$enable_platform != xno ])
AM_CONDITIONAL(ENABLE_OSX,[test x$osx_host = xyes -a x$enable_platform != xno ])
dnl then enable font_win32tt
AC_ARG_ENABLE(win32tt,
AC_HELP_STRING([--enable-win32tt],[Win32 TrueType font support library]),
enable_tt=$enable_win32tt,
enable_tt=$win32_host)
AM_CONDITIONAL(ENABLE_WIN32_TT, test x$enable_tt = xyes )
dnl ######### Check for FT2: #####################
ft_enabled=""
PKG_CHECK_MODULES([FREETYPE],
freetype2,
[ft_enabled="yes"],
AC_MSG_WARN([*** Freetype2 not found! Building without font library.])
)
AC_ARG_ENABLE(freetype,
AC_HELP_STRING([--enable-freetype],[freetype font support library]),
ft_enabled=$enable_freetype)
AM_CONDITIONAL(ENABLE_FT,[test xyes = x$ft_enabled])
dnl ###############################################
dnl ######### Ask for GPC: #######################
AC_ARG_ENABLE(gpc,
AC_HELP_STRING([--enable-gpc],[gpc polygon clipper library]) )
AM_CONDITIONAL(ENABLE_GPC,[test xyes = x$enable_gpc])
dnl ###############################################
dnl ######### Check for SDL: #####################
dnl the sdl script pollutes our global values:
temp_LIBS="$LIBS"
temp_CFLAGS="$CFLAGS"
temp_CXXFLAGS="$CXXFLAGS"
sdl_enabled=""
SDL_VERSION=1.2.0
AM_PATH_SDL($SDL_VERSION,
[sdl_enabled="yes"],
AC_MSG_WARN([*** SDL version $SDL_VERSION not found! Omitting sdl layer.])
)
dnl ### Restore old values
CFLAGS=$temp_CFLAGS
CXXFLAGS=$temp_CXXFLAGS
LIBS=$temp_LIBS
dnl ### the sdl script already does that:
dnl AC_SUBST(SDL_CFLAGS)
dnl AC_SUBST(SDL_LIBS)
AM_CONDITIONAL(ENABLE_SDL,[test xyes = x$sdl_enabled -a xno != x$enable_platform -a x$win32_host != xyes])
dnl ###############################################
dnl ######### Checking for X11: ##################
AC_PATH_X
if test "$no_x" = "yes"; then
AC_MSG_WARN([*** X11 not found! Omitting X11 layer.])
fi
AM_CONDITIONAL(ENABLE_X11,[test x$no_x = x -a xno != x$enable_platform -a x$win32_host != xyes])
AC_SUBST(x_includes)
AC_SUBST(x_libraries)
dnl ###############################################
dnl Settung up library version
AGG_LIB_VERSION="2:7:0"
dnl current-´ / /
dnl revision--´ /
dnl age---´
dnl Update the version information only immediately before a public release of antigrain
dnl If the library source code has changed, increment revision (c:r:a becomes c:r+1:a).
dnl If any interfaces have been added, removed, or changed since the last update,
dnl increment current, and set revision to 0.
dnl If any interfaces have been added since the last public release, then increment age.
dnl If any interfaces have been removed since the last public release, then set age to 0.
AC_SUBST(AGG_LIB_VERSION)
AC_SUBST(PREFERED_PLATFORM)
AC_OUTPUT(
Makefile
libagg.pc
gpc/Makefile
font_freetype/Makefile
font_win32_tt/Makefile
src/Makefile
src/ctrl/Makefile
src/platform/Makefile
src/platform/X11/Makefile
src/platform/sdl/Makefile
src/platform/mac/Makefile
src/platform/win32/Makefile
src/platform/BeOS/Makefile
src/platform/AmigaOS/Makefile
include/Makefile
include/ctrl/Makefile
include/util/Makefile
include/platform/Makefile
examples/Makefile
)

65
copying Normal file
View File

@ -0,0 +1,65 @@
The Anti-Grain Geometry Project
A high quality rendering engine for C++
http://antigrain.com
Anti-Grain Geometry has dual licensing model. The Modified BSD
License was first added in version v2.4 just for convenience.
It is a simple, permissive non-copyleft free software license,
compatible with the GNU GPL. It's well proven and recognizable.
See http://www.fsf.org/licensing/licenses/index_html#ModifiedBSD
for details.
Note that the Modified BSD license DOES NOT restrict your rights
if you choose the Anti-Grain Geometry Public License.
Anti-Grain Geometry Public License
====================================================
Anti-Grain Geometry - Version 2.4
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
Permission to copy, use, modify, sell and distribute this software
is granted provided this copyright notice appears in all copies.
This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
Modified BSD License
====================================================
Anti-Grain Geometry - Version 2.4
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The name of the author may not be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

24
distclean Normal file
View File

@ -0,0 +1,24 @@
#! /bin/sh
find . -iname '*.[oa]' -exec \rm -f {} \;
find . -iname '*.ppm' -exec \rm -f {} \;
find . -iname '*~' -exec \rm -f {} \;
find . -iname 'gamma.*' -exec \rm -f {} \;
find . -iname Debug -exec \rm -rf {} \;
find . -iname Release -exec \rm -rf {} \;
find . -iname '*.exe' -exec \rm -rf {} \;
find . -iname '*.lib' -exec \rm -rf {} \;
find . -iname '*.dll' -exec \rm -rf {} \;
find . -iname '*.obj' -exec \rm -rf {} \;
find . -iname '*.aps' -exec \rm -rf {} \;
find . -iname '*.clw' -exec \rm -rf {} \;
find . -iname '*.ilk' -exec \rm -rf {} \;
find . -iname '*.ncb' -exec \rm -rf {} \;
find . -iname '*.opt' -exec \rm -rf {} \;
find . -iname '*.plg' -exec \rm -rf {} \;
find . -iname '*.pch' -exec \rm -rf {} \;
find . -iname '*.idb' -exec \rm -rf {} \;
find . -iname '*.pdb' -exec \rm -rf {} \;
find . -iname '*.res' -exec \rm -rf {} \;

View File

@ -0,0 +1,85 @@
================================================================================
AGG Contribution Pack - Gradients 1 (AGG CP - Gradients 1)
http://milan.marusinec.sk/aggcp
For Anti-Grain Geometry - Version 2.4
http://www.antigrain.org
Contribution Created By:
Milan Marusinec alias Milano
milan@marusinec.sk
Copyright (c) 2007-2008
================================================================================
How To Install
================================================================================
1. Copy \examples and \include directories directly to the \agg-2.4 directory.
2. MS Visual Studio: In Solution Explorer click "Add Existing Project ..."
from \examples\win32_api\gradients_contour subdirectory.
3. Build, Run, Enjoy.
================================================================================
About
================================================================================
This AGG Contribution Pack (CP) extends existing set of gradient functions
found in AGG 2.4 and later and is not a part of original source code
distribution package, so you have to download and install this CP separately.
Following additional gradient functions are included:
gradient_contour
================
located in "agg_span_gradient_contour.h"
Creates color transitions from shape defined by an arbitrary (in fact any)
path. It computes so called Distance Transform (DT) from image produced by
only stroking the path, which is then the source of color level in
the underlying gradient function.
Contour gradient can be used in two forms:
One is to define shape for contour different from shape of object being drawn.
Second is to use the same shape for contour and for drawing (AutoContour).
gradient_conic_angle
====================
located in "gradients_contour.cpp"
Assymetric conic gradient (also called angle) is the same as conic, but the ray
of light with color transitions going counter clockwise travels whole circle
instead of just half (as with conic).
Note: Implementation of this one is so tiny, it doesn't have it's own header
file. If you want to use it, just copy and paste it from the demo file.
gradient_image
==============
located in "agg_span_gradient_image.h"
Bitmap gradient is very similar to pattern fill, but works in the framework
of gradient functions interfaces. Because of that all interpolator
transformations from gradient span generator can be applied to this kind
of fill (all affine transformations, perspective, bilinear & warp).
Note: This gradient function doesn't generates indexes for colors used.
When constructing the span_gradient object, the color function type is
eg. agg::one_color_function<agg::rgba8> and instance of that color
function is retrieved by calling special function of gradient_image
class -> gradient_func.color_function().
See the "gradients_countour.cpp" demo for more details.
================================================================================
End of file
================================================================================

391
examples/BeOS/Makefile Normal file
View File

@ -0,0 +1,391 @@
include ../../Makefile.in.$(shell uname)
PLATFORM=BeOS
PLATFORMSOURCES=../../src/platform/$(PLATFORM)/agg_platform_support.o
CXXFLAGS= $(AGGCXXFLAGS) -I../../include \
-L../../src \
$(PIXFMT)
CXXFREETYPEFLAGS= $(AGGCXXFLAGS) -Wall \
-I../../include \
-I../../font_freetype \
-I/boot/home/config/include/ \
-L../../src \
-L/boot/home/config/lib/ \
$(PIXFMT)
LIBS = $(AGGLIBS) -lroot -lbe -ltranslation
base:
cd ../../src/; make
make aa_demo
make aa_test
make alpha_gradient
make alpha_mask
make alpha_mask2
make alpha_mask3
make bezier_div
make blur
make blend_color
make bspline
make circles
make component_rendering
make conv_contour
make conv_dash_marker
make conv_stroke
make flash_rasterizer
make flash_rasterizer2
make gamma_correction
make gamma_ctrl
make gamma_tuner
make gouraud
make gouraud_mesh
make gradient_focal
make gradients
make graph_test
make idea
make lion
make lion_lens
make lion_outline
make multi_clip
make pattern_fill
make perspective
make polymorphic_renderer
make raster_text
make rasterizers
make rasterizers2
make rasterizer_compound
make rounded_rect
make scanline_boolean
make scanline_boolean2
make simple_blur
make trans_polar
make image_alpha
make image_filters
make image_filters2
make image_fltr_graph
make image_perspective
make image_resample
make image_transforms
make image1
make distortions
make pattern_perspective
make compositing
make compositing2
make line_patterns
make line_patterns_clip
make mol_view
freetype:
make freetype_test
make trans_curve1_ft
make trans_curve2_ft
gpc:
make gpc_test
all:
make base
make freetype
make gpc
aa_demo: ../aa_demo.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o aa_demo $(LIBS)
aa_test: ../aa_test.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o aa_test $(LIBS)
alpha_gradient: ../alpha_gradient.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_gradient $(LIBS)
alpha_mask: ../alpha_mask.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_mask $(LIBS)
alpha_mask2: ../alpha_mask2.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_mask2 $(LIBS)
alpha_mask3: ../alpha_mask3.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_mask3 $(LIBS)
bezier_div: ../bezier_div.o ../interactive_polygon.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o bezier_div $(LIBS)
blur: ../blur.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o blur $(LIBS)
blend_color: ../blend_color.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o blend_color $(LIBS)
bspline: ../bspline.o ../interactive_polygon.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o bspline $(LIBS)
circles: ../circles.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o circles $(LIBS)
component_rendering: ../component_rendering.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o component_rendering $(LIBS)
compositing: ../compositing.o $(PLATFORMSOURCES) compositing.ppm
$(CXX) $(CXXFLAGS) ../compositing.o $(PLATFORMSOURCES) -o compositing $(LIBS)
compositing2: ../compositing2.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o compositing2 $(LIBS)
conv_contour: ../conv_contour.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o conv_contour $(LIBS)
conv_dash_marker: ../conv_dash_marker.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o conv_dash_marker $(LIBS)
conv_stroke: ../conv_stroke.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o conv_stroke $(LIBS)
distortions: ../distortions.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../distortions.o $(PLATFORMSOURCES) -o distortions $(LIBS)
flash_rasterizer: ../flash_rasterizer.o $(PLATFORMSOURCES) shapes.txt
$(CXX) $(CXXFLAGS) ../flash_rasterizer.o $(PLATFORMSOURCES) -o flash_rasterizer $(LIBS)
flash_rasterizer2: ../flash_rasterizer2.o $(PLATFORMSOURCES) shapes.txt
$(CXX) $(CXXFLAGS) ../flash_rasterizer2.o $(PLATFORMSOURCES) -o flash_rasterizer2 $(LIBS)
gamma_correction: ../gamma_correction.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gamma_correction $(LIBS)
gamma_ctrl: ../gamma_ctrl.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gamma_ctrl $(LIBS)
gamma_tuner: ../gamma_tuner.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gamma_tuner $(LIBS)
gouraud: ../gouraud.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gouraud $(LIBS)
gouraud_mesh: ../gouraud_mesh.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gouraud_mesh $(LIBS)
gradient_focal: ../gradient_focal.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gradient_focal $(LIBS)
gradients: ../gradients.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gradients $(LIBS)
graph_test: ../graph_test.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o graph_test $(LIBS)
idea: ../idea.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o idea $(LIBS)
image_alpha: ../image_alpha.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_alpha.o $(PLATFORMSOURCES) -o image_alpha $(LIBS)
image_filters: ../image_filters.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_filters.o $(PLATFORMSOURCES) -o image_filters $(LIBS)
image_filters2: ../image_filters2.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_filters2.o $(PLATFORMSOURCES) -o image_filters2 $(LIBS)
image_fltr_graph: ../image_fltr_graph.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_fltr_graph.o $(PLATFORMSOURCES) -o image_fltr_graph $(LIBS)
image_perspective: ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_perspective $(LIBS)
image_resample: ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_resample $(LIBS)
image_transforms: ../image_transforms.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_transforms.o $(PLATFORMSOURCES) -o image_transforms $(LIBS)
image1: ../image1.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image1.o $(PLATFORMSOURCES) -o image1 $(LIBS)
line_patterns: ../line_patterns.o $(PLATFORMSOURCES) 1.ppm 2.ppm 3.ppm 4.ppm 5.ppm 6.ppm 7.ppm 8.ppm 9.ppm
$(CXX) $(CXXFLAGS) ../line_patterns.o $(PLATFORMSOURCES) -o line_patterns $(LIBS)
line_patterns_clip: ../line_patterns_clip.o $(PLATFORMSOURCES) 1.ppm
$(CXX) $(CXXFLAGS) ../line_patterns_clip.o $(PLATFORMSOURCES) -o line_patterns_clip $(LIBS)
lion: ../lion.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o lion $(LIBS)
lion_lens: ../lion_lens.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o lion_lens $(LIBS)
lion_outline: ../lion_outline.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o lion_outline $(LIBS)
mol_view: ../mol_view.o $(PLATFORMSOURCES) 1.sdf
$(CXX) $(CXXFLAGS) ../mol_view.o $(PLATFORMSOURCES) -o mol_view $(LIBS)
multi_clip: ../multi_clip.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o multi_clip $(LIBS)
pattern_fill: ../pattern_fill.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o pattern_fill $(LIBS)
pattern_perspective: ../pattern_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) agg.ppm
$(CXX) $(CXXFLAGS) ../pattern_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) -o pattern_perspective $(LIBS)
perspective: ../perspective.o ../interactive_polygon.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o perspective $(LIBS)
polymorphic_renderer: ../polymorphic_renderer.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o polymorphic_renderer $(LIBS)
raster_text: ../raster_text.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o raster_text $(LIBS)
rasterizers: ../rasterizers.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rasterizers $(LIBS)
rasterizers2: ../rasterizers2.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rasterizers2 $(LIBS)
rasterizer_compound: ../rasterizer_compound.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rasterizer_compound $(LIBS)
rounded_rect: ../rounded_rect.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rounded_rect $(LIBS)
scanline_boolean: ../scanline_boolean.o ../interactive_polygon.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o scanline_boolean $(LIBS)
scanline_boolean2: ../scanline_boolean2.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o scanline_boolean2 $(LIBS)
simple_blur: ../simple_blur.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o simple_blur $(LIBS)
trans_polar: ../trans_polar.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o trans_polar $(LIBS)
freetype_test: ../freetype_test.o ../../font_freetype/agg_font_freetype.o $(PLATFORMSOURCES) timesi.ttf
$(CXX) $(CXXFREETYPEFLAGS) ../freetype_test.o ../../font_freetype/agg_font_freetype.o $(PLATFORMSOURCES) -o freetype_test $(LIBS) -lfreetype
trans_curve1_ft: ../trans_curve1_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) timesi.ttf
$(CXX) $(CXXFLAGS) ../trans_curve1_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) -o trans_curve1_ft $(LIBS) -lfreetype
trans_curve2_ft: ../trans_curve2_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) timesi.ttf
$(CXX) $(CXXFLAGS) ../trans_curve2_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) -o trans_curve2_ft $(LIBS) -lfreetype
gpc_test: ../gpc_test.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gpc_test $(LIBS)
clean:
rm -f ../*.o
rm -f ../../src/platform/$(PLATFORM)/agg_platform_support.o
rm -rf aa_demo
rm -rf aa_test
rm -rf alpha_gradient
rm -rf alpha_mask
rm -rf alpha_mask2
rm -rf alpha_mask3
rm -rf bezier_div
rm -rf bspline
rm -rf blur
rn -rf blend_color
rm -rf circles
rm -rf component_rendering
rm -rf conv_contour
rm -rf conv_dash_marker
rm -rf conv_stroke
rm -rf flash_rasterizer
rm -rf flash_rasterizer2
rm -rf gamma_correction
rm -rf gamma_ctrl
rm -rf gamma_tuner
rm -rf gouraud
rm -rf gouraud_mesh
rm -rf gradient_focal
rm -rf gradients
rm -rf graph_test
rm -rf idea
rm -rf lion
rm -rf lion_lens
rm -rf lion_outline
rm -rf multi_clip
rm -rf pattern_fill
rm -rf perspective
rm -rf polymorphic_renderer
rm -rf raster_text
rm -rf rasterizers
rm -rf rasterizers2
rm -rf rounded_rect
rm -rf scanline_boolean
rm -rf scanline_boolean2
rm -rf simple_blur
rm -rf trans_polar
rm -rf image_alpha
rm -rf image_filters
rm -rf image_filters2
rm -rf image_fltr_graph
rm -rf image_perspective
rm -rf image_resample
rm -rf image_transforms
rm -rf image1
rm -rf distortions
rm -rf pattern_perspective
rm -rf compositing
rm -rf line_patterns
rm -rf line_patterns_clip
rm -rf mol_view
rm -rf freetype_test
rm -rf trans_curve1_ft
rm -rf trans_curve2_ft
rm -rf gpc_test
agg.ppm:
cp ../art/agg.ppm .
compositing.ppm:
cp ../art/compositing.ppm .
spheres.ppm:
cp ../art/spheres.ppm .
shapes.txt:
cp ../art/shapes.txt .
1.sdf:
cp ../art/1.sdf .
1.ppm:
cp ../art/line_patterns.tar.gz .
gunzip line_patterns.tar.gz
tar -xvf line_patterns.tar
timesi.ttf:
cp ../art/timesi.zip .
unzip -o timesi.zip
../freetype_test.o: ../freetype_test.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../trans_curve1_ft.o: ../trans_curve1_ft.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../trans_curve2_ft.o: ../trans_curve2_ft.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../../font_freetype/agg_font_freetype.o: ../../font_freetype/agg_font_freetype.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../gpc_test.o: ../gpc_test.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFLAGS) -I../../gpc $*.cpp -o $@
%.o: %.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFLAGS) $*.cpp -o $@
.PHONY : clean

36
examples/BeOS/readme.txt Normal file
View File

@ -0,0 +1,36 @@
The Anti-Grain Geometry Project
A high quality rendering engine for C++
http://antigrain.com
Anti-Grain Geometry
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
Permission to copy, use, modify, sell and distribute this software
is granted provided this copyright notice appears in all copies.
This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
By default only the examples that do not require extra dependancies are built.
with the following commands:
cd (AGGDIRECTORY)/examples/BeOS
make clean
make
Some examples (freetype_test, trans_curve1_ft and trans_curve2_ft) require the Freetype Library, and can be built with:
make freetype
There is also an example (gpc_test) that requires the GPC library, build it with:
make gpc
Of course, to build ALL examples run:
make all
Alternatively you can also build the examples one by one, using the example name directly:
make aa_demo
make aa_test
...

331
examples/CMakeLists.txt Normal file
View File

@ -0,0 +1,331 @@
ADD_EXECUTABLE( aa_demo ${WIN32GUI}
aa_demo.cpp
)
ADD_EXECUTABLE( aa_test ${WIN32GUI}
aa_test.cpp
)
ADD_EXECUTABLE( alpha_gradient ${WIN32GUI}
alpha_gradient.cpp
)
ADD_EXECUTABLE( alpha_mask ${WIN32GUI}
alpha_mask.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( alpha_mask2 ${WIN32GUI}
alpha_mask.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( alpha_mask3 ${WIN32GUI}
alpha_mask.cpp
make_arrows.cpp
make_gb_poly.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( bezier_div ${WIN32GUI}
bezier_div.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( blend_color ${WIN32GUI}
blend_color.cpp
)
ADD_EXECUTABLE( blur ${WIN32GUI}
blur.cpp
)
ADD_EXECUTABLE( bspline ${WIN32GUI}
bspline.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( circles ${WIN32GUI}
circles.cpp
)
ADD_EXECUTABLE( component_rendering ${WIN32GUI}
component_rendering.cpp
)
ADD_EXECUTABLE( compositing ${WIN32GUI}
compositing.cpp
)
ADD_EXECUTABLE( compositing2 ${WIN32GUI}
compositing2.cpp
)
ADD_EXECUTABLE( conv_contour ${WIN32GUI}
conv_contour.cpp
)
ADD_EXECUTABLE( conv_dash_marker ${WIN32GUI}
conv_dash_marker.cpp
)
ADD_EXECUTABLE( conv_stroke ${WIN32GUI}
conv_stroke.cpp
)
ADD_EXECUTABLE( distortions ${WIN32GUI}
distortions.cpp
)
ADD_EXECUTABLE( flash_rasterizer ${WIN32GUI}
flash_rasterizer.cpp
)
ADD_EXECUTABLE( flash_rasterizer2 ${WIN32GUI}
flash_rasterizer2.cpp
)
IF ( agg_USE_FREETYPE )
ADD_EXECUTABLE( freetype_test ${WIN32GUI}
freetype_test.cpp
make_arrows.cpp
make_gb_poly.cpp
)
ENDIF ( agg_USE_FREETYPE )
ADD_EXECUTABLE( gamma_correction ${WIN32GUI}
gamma_correction.cpp
)
ADD_EXECUTABLE( gamma_ctrl ${WIN32GUI}
gamma_ctrl.cpp
)
ADD_EXECUTABLE( gamma_tuner ${WIN32GUI}
gamma_tuner.cpp
)
ADD_EXECUTABLE( gouraud ${WIN32GUI}
gouraud.cpp
)
ADD_EXECUTABLE( gouraud_mesh ${WIN32GUI}
gouraud_mesh.cpp
)
IF ( agg_USE_GPC )
ADD_EXECUTABLE( gpc_test ${WIN32GUI}
gpc_test.cpp
make_arrows.cpp
make_gb_poly.cpp
)
ENDIF ( agg_USE_GPC )
ADD_EXECUTABLE( gradients ${WIN32GUI}
gradients.cpp
)
ADD_EXECUTABLE( gradient_focal ${WIN32GUI}
gradient_focal.cpp
)
ADD_EXECUTABLE( gradients_contour ${WIN32GUI}
gradients_contour.cpp
make_arrows.cpp
make_gb_poly.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( graph_test ${WIN32GUI}
graph_test.cpp
)
ADD_EXECUTABLE( idea ${WIN32GUI}
idea.cpp
)
ADD_EXECUTABLE( image1 ${WIN32GUI}
image1.cpp
)
ADD_EXECUTABLE( image_alpha ${WIN32GUI}
image_alpha.cpp
)
ADD_EXECUTABLE( image_filters ${WIN32GUI}
image_filters.cpp
)
ADD_EXECUTABLE( image_filters2 ${WIN32GUI}
image_filters2.cpp
)
ADD_EXECUTABLE( image_fltr_graph ${WIN32GUI}
image_fltr_graph.cpp
)
ADD_EXECUTABLE( image_perspective ${WIN32GUI}
image_perspective.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( image_resample ${WIN32GUI}
image_resample.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( image_transforms ${WIN32GUI}
image_transforms.cpp
)
ADD_EXECUTABLE( line_patterns ${WIN32GUI}
line_patterns.cpp
)
ADD_EXECUTABLE( line_patterns_clip ${WIN32GUI}
line_patterns_clip.cpp
)
ADD_EXECUTABLE( lion ${WIN32GUI}
lion.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( lion_lens ${WIN32GUI}
lion_lens.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( lion_outline ${WIN32GUI}
lion_outline.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( mol_view ${WIN32GUI}
mol_view.cpp
)
ADD_EXECUTABLE( multi_clip ${WIN32GUI}
multi_clip.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( pattern_fill ${WIN32GUI}
pattern_fill.cpp
)
ADD_EXECUTABLE( pattern_perspective ${WIN32GUI}
pattern_perspective.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( pattern_resample ${WIN32GUI}
pattern_resample.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( perspective ${WIN32GUI}
perspective.cpp
interactive_polygon.cpp
parse_lion.cpp
)
ADD_EXECUTABLE( polymorphic_renderer ${WIN32GUI}
polymorphic_renderer.cpp
)
ADD_EXECUTABLE( rasterizers ${WIN32GUI}
rasterizers.cpp
)
ADD_EXECUTABLE( rasterizers2 ${WIN32GUI}
rasterizers2.cpp
)
ADD_EXECUTABLE( rasterizer_compound ${WIN32GUI}
rasterizer_compound.cpp
)
ADD_EXECUTABLE( raster_text ${WIN32GUI}
raster_text.cpp
)
ADD_EXECUTABLE( rounded_rect ${WIN32GUI}
rounded_rect.cpp
)
ADD_EXECUTABLE( scanline_boolean ${WIN32GUI}
scanline_boolean.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( scanline_boolean2 ${WIN32GUI}
scanline_boolean2.cpp
make_arrows.cpp
make_gb_poly.cpp
)
ADD_EXECUTABLE( simple_blur ${WIN32GUI}
simple_blur.cpp
parse_lion.cpp
)
IF(WIN32)
ADD_EXECUTABLE( trans_curve1 ${WIN32GUI}
trans_curve1.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( trans_curve2 ${WIN32GUI}
trans_curve2.cpp
interactive_polygon.cpp
)
ADD_EXECUTABLE( truetype_test ${WIN32GUI}
truetype_test.cpp
)
ENDIF(WIN32)
ADD_EXECUTABLE( trans_polar ${WIN32GUI}
trans_polar.cpp
)
IF ( agg_USE_EXPAT )
ADD_EXECUTABLE( svg_test ${WIN32GUI}
./svg_viewer/svg_test.cpp
./svg_viewer/agg_svg_exception.h
./svg_viewer/agg_svg_parser.cpp
./svg_viewer/agg_svg_parser.h
./svg_viewer/agg_svg_path_renderer.cpp
./svg_viewer/agg_svg_path_renderer.h
./svg_viewer/agg_svg_path_tokenizer.cpp
./svg_viewer/agg_svg_path_tokenizer.h
)
ENDIF ( agg_USE_EXPAT )
IF(WIN32)
ADD_EXECUTABLE( pure_api ${WIN32GUI}
./win32_api/pure_api/pure_api.h
./win32_api/pure_api/pure_api.cpp
./win32_api/pure_api/resource.h
./win32_api/pure_api/StdAfx.h
./win32_api/pure_api/StdAfx.cpp
./win32_api/pure_api/pure_api.rc
parse_lion.cpp
)
ENDIF(WIN32)
IF( agg_USE_AGG2D )
ADD_EXECUTABLE( agg2_demo ${WIN32GUI}
agg2d_demo.cpp
)
ENDIF( agg_USE_AGG2D )

248
examples/Makefile.am Normal file

File diff suppressed because one or more lines are too long

340
examples/X11/Makefile Normal file
View File

@ -0,0 +1,340 @@
include ../../Makefile.in.$(shell uname)
PLATFORM=X11
PLATFORMSOURCES=../../src/platform/$(PLATFORM)/agg_platform_support.o
CXXFLAGS= $(AGGCXXFLAGS) -I../../include \
-L../../src \
$(PIXFMT)
CXXFREETYPEFLAGS= $(AGGCXXFLAGS) -Wall \
-I../../include \
-I../../font_freetype \
-I/usr/local/include/freetype2 \
-I/usr/include/freetype2 \
-L../../src \
$(PIXFMT)
LIBS = $(AGGLIBS) -lm -lX11
base:
cd ../../src/; make
make aa_demo
make aa_test
make alpha_gradient
make alpha_mask
make alpha_mask2
make alpha_mask3
make bezier_div
make bspline
make circles
make component_rendering
make conv_contour
make conv_dash_marker
make conv_stroke
make flash_rasterizer
make flash_rasterizer2
make gamma_correction
make gamma_ctrl
make gamma_tuner
make gouraud
make gouraud_mesh
make gradient_focal
make gradients
make graph_test
make idea
make lion
make lion_lens
make lion_outline
make multi_clip
make pattern_fill
make perspective
make polymorphic_renderer
make raster_text
make rasterizers
make rasterizers2
make rounded_rect
make scanline_boolean
make scanline_boolean2
make simple_blur
make trans_polar
make image_alpha
make image_filters
make image_filters2
make image_fltr_graph
make image_perspective
make image_resample
make image_transforms
make image1
make distortions
make pattern_perspective
make compositing
make compositing2
make line_patterns
make line_patterns_clip
make mol_view
make blur
make rasterizer_compound
make blend_color
freetype:
make freetype_test
make trans_curve1_ft
make trans_curve2_ft
gpc:
make gpc_test
all:
make base
make freetype
make gpc
make svg_test
aa_demo: ../aa_demo.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o aa_demo $(LIBS)
aa_test: ../aa_test.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o aa_test $(LIBS)
alpha_gradient: ../alpha_gradient.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_gradient $(LIBS)
alpha_mask: ../alpha_mask.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_mask $(LIBS)
alpha_mask2: ../alpha_mask2.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_mask2 $(LIBS)
alpha_mask3: ../alpha_mask3.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o alpha_mask3 $(LIBS)
bezier_div: ../bezier_div.o ../interactive_polygon.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o bezier_div $(LIBS)
blur: ../blur.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o blur $(LIBS)
bspline: ../bspline.o ../interactive_polygon.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o bspline $(LIBS)
circles: ../circles.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o circles $(LIBS)
component_rendering: ../component_rendering.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o component_rendering $(LIBS)
compositing: ../compositing.o $(PLATFORMSOURCES) compositing.ppm
$(CXX) $(CXXFLAGS) ../compositing.o $(PLATFORMSOURCES) -o compositing $(LIBS)
compositing2: ../compositing2.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o compositing2 $(LIBS)
conv_contour: ../conv_contour.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o conv_contour $(LIBS)
conv_dash_marker: ../conv_dash_marker.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o conv_dash_marker $(LIBS)
conv_stroke: ../conv_stroke.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o conv_stroke $(LIBS)
distortions: ../distortions.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../distortions.o $(PLATFORMSOURCES) -o distortions $(LIBS)
flash_rasterizer: ../flash_rasterizer.o $(PLATFORMSOURCES) shapes.txt
$(CXX) $(CXXFLAGS) ../flash_rasterizer.o $(PLATFORMSOURCES) -o flash_rasterizer $(LIBS)
flash_rasterizer2: ../flash_rasterizer2.o $(PLATFORMSOURCES) shapes.txt
$(CXX) $(CXXFLAGS) ../flash_rasterizer2.o $(PLATFORMSOURCES) -o flash_rasterizer2 $(LIBS)
gamma_correction: ../gamma_correction.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gamma_correction $(LIBS)
gamma_ctrl: ../gamma_ctrl.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gamma_ctrl $(LIBS)
gamma_tuner: ../gamma_tuner.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gamma_tuner $(LIBS)
gouraud: ../gouraud.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gouraud $(LIBS)
gouraud_mesh: ../gouraud_mesh.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gouraud_mesh $(LIBS)
gradient_focal: ../gradient_focal.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gradient_focal $(LIBS)
gradients: ../gradients.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gradients $(LIBS)
graph_test: ../graph_test.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o graph_test $(LIBS)
idea: ../idea.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o idea $(LIBS)
image_alpha: ../image_alpha.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_alpha.o $(PLATFORMSOURCES) -o image_alpha $(LIBS)
image_filters: ../image_filters.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_filters.o $(PLATFORMSOURCES) -o image_filters $(LIBS)
image_filters2: ../image_filters2.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_filters2.o $(PLATFORMSOURCES) -o image_filters2 $(LIBS)
image_fltr_graph: ../image_fltr_graph.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_fltr_graph.o $(PLATFORMSOURCES) -o image_fltr_graph $(LIBS)
image_perspective: ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_perspective $(LIBS)
image_resample: ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_resample.o ../interactive_polygon.o $(PLATFORMSOURCES) -o image_resample $(LIBS)
image_transforms: ../image_transforms.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image_transforms.o $(PLATFORMSOURCES) -o image_transforms $(LIBS)
image1: ../image1.o $(PLATFORMSOURCES) spheres.ppm
$(CXX) $(CXXFLAGS) ../image1.o $(PLATFORMSOURCES) -o image1 $(LIBS)
line_patterns: ../line_patterns.o $(PLATFORMSOURCES) 1.ppm 2.ppm 3.ppm 4.ppm 5.ppm 6.ppm 7.ppm 8.ppm 9.ppm
$(CXX) $(CXXFLAGS) ../line_patterns.o $(PLATFORMSOURCES) -o line_patterns $(LIBS)
line_patterns_clip: ../line_patterns_clip.o $(PLATFORMSOURCES) 1.ppm
$(CXX) $(CXXFLAGS) ../line_patterns_clip.o $(PLATFORMSOURCES) -o line_patterns_clip $(LIBS)
lion: ../lion.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o lion $(LIBS)
lion_lens: ../lion_lens.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o lion_lens $(LIBS)
lion_outline: ../lion_outline.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o lion_outline $(LIBS)
mol_view: ../mol_view.o $(PLATFORMSOURCES) 1.sdf
$(CXX) $(CXXFLAGS) ../mol_view.o $(PLATFORMSOURCES) -o mol_view $(LIBS)
multi_clip: ../multi_clip.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o multi_clip $(LIBS)
pattern_fill: ../pattern_fill.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o pattern_fill $(LIBS)
pattern_perspective: ../pattern_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) agg.ppm
$(CXX) $(CXXFLAGS) ../pattern_perspective.o ../interactive_polygon.o $(PLATFORMSOURCES) -o pattern_perspective $(LIBS)
perspective: ../perspective.o ../interactive_polygon.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o perspective $(LIBS)
polymorphic_renderer: ../polymorphic_renderer.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o polymorphic_renderer $(LIBS)
raster_text: ../raster_text.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o raster_text $(LIBS)
rasterizers: ../rasterizers.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rasterizers $(LIBS)
rasterizers2: ../rasterizers2.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rasterizers2 $(LIBS)
rasterizer_compound: ../rasterizer_compound.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rasterizer_compound $(LIBS)
blend_color: ../blend_color.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o blend_color $(LIBS)
rounded_rect: ../rounded_rect.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o rounded_rect $(LIBS)
scanline_boolean: ../scanline_boolean.o ../interactive_polygon.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o scanline_boolean $(LIBS)
scanline_boolean2: ../scanline_boolean2.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o scanline_boolean2 $(LIBS)
simple_blur: ../simple_blur.o ../parse_lion.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o simple_blur $(LIBS)
trans_polar: ../trans_polar.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o trans_polar $(LIBS)
freetype_test: ../freetype_test.o ../../font_freetype/agg_font_freetype.o $(PLATFORMSOURCES) timesi.ttf
$(CXX) $(CXXFREETYPEFLAGS) ../freetype_test.o ../../font_freetype/agg_font_freetype.o $(PLATFORMSOURCES) -o freetype_test $(LIBS) -lfreetype
trans_curve1_ft: ../trans_curve1_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) timesi.ttf
$(CXX) $(CXXFLAGS) ../trans_curve1_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) -o trans_curve1_ft $(LIBS) -lfreetype
trans_curve2_ft: ../trans_curve2_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) timesi.ttf
$(CXX) $(CXXFLAGS) ../trans_curve2_ft.o ../../font_freetype/agg_font_freetype.o ../interactive_polygon.o $(PLATFORMSOURCES) -o trans_curve2_ft $(LIBS) -lfreetype
gpc_test: ../gpc_test.o ../make_arrows.o ../make_gb_poly.o $(PLATFORMSOURCES)
$(CXX) $(CXXFLAGS) $^ -o gpc_test $(LIBS)
svg_test: ../svg_viewer/agg_svg_parser.o ../svg_viewer/agg_svg_path_renderer.o ../svg_viewer/agg_svg_path_tokenizer.o ../svg_viewer/svg_test.o $(PLATFORMSOURCES) tiger.svg
$(CXX) $(CXXFLAGS) ../svg_viewer/agg_svg_parser.o ../svg_viewer/agg_svg_path_renderer.o ../svg_viewer/agg_svg_path_tokenizer.o ../svg_viewer/svg_test.o $(PLATFORMSOURCES) -o svg_test $(LIBS) -lfreetype -lexpat
clean:
rm -f ../*.o
rm -f ../svg_viewer/*.o
rm -f ../../src/platform/$(PLATFORM)/agg_platform_support.o
agg.ppm:
cp ../art/agg.ppm .
compositing.ppm:
cp ../art/compositing.ppm .
spheres.ppm:
cp ../art/spheres.ppm .
shapes.txt:
cp ../art/shapes.txt .
1.sdf:
cp ../art/1.sdf .
1.ppm:
cp ../art/line_patterns.tar.gz .
gunzip line_patterns.tar.gz
tar -xvf line_patterns.tar
timesi.ttf:
cp ../art/timesi.zip .
unzip -o timesi.zip
tiger.svg:
cp ../art/tiger.svg .
../freetype_test.o: ../freetype_test.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../trans_curve1_ft.o: ../trans_curve1_ft.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../trans_curve2_ft.o: ../trans_curve2_ft.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../../font_freetype/agg_font_freetype.o: ../../font_freetype/agg_font_freetype.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFREETYPEFLAGS) $*.cpp -o $@
../gpc_test.o: ../gpc_test.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFLAGS) -I../../gpc $*.cpp -o $@
%.o: %.cpp
@echo \< $*.cpp \>
$(CXX) -c $(CXXFLAGS) $*.cpp -o $@
.PHONY : clean

36
examples/X11/readme.txt Normal file
View File

@ -0,0 +1,36 @@
The Anti-Grain Geometry Project
A high quality rendering engine for C++
http://antigrain.com
Anti-Grain Geometry
Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
Permission to copy, use, modify, sell and distribute this software
is granted provided this copyright notice appears in all copies.
This software is provided "as is" without express or implied
warranty, and with no claim as to its suitability for any purpose.
By default only the examples that do not require extra dependancies are built.
with the following commands:
cd (AGGDIRECTORY)/examples/X11
make clean
make
Some examples (freetype_test, trans_curve1_ft and trans_curve2_ft) require the Freetype Library, and can be built with:
make freetype
There is also an example (gpc_test) that requires the GPC library, build it with:
make gpc
Of course, to build ALL examples run:
make all
Alternatively you can also build the examples one by one, using the example name directly:
make aa_demo
make aa_test
...

290
examples/aa_demo.cpp Normal file
View File

@ -0,0 +1,290 @@
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#define AGG_BGR24
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
namespace agg
{
class square
{
public:
square(double size) : m_size(size) {}
template<class Rasterizer, class Scanline, class Renderer, class ColorT>
void draw(Rasterizer& ras, Scanline& sl, Renderer& ren, ColorT color,
double x, double y)
{
ras.reset();
ras.move_to_d(x*m_size, y*m_size);
ras.line_to_d(x*m_size+m_size, y*m_size);
ras.line_to_d(x*m_size+m_size, y*m_size+m_size);
ras.line_to_d(x*m_size, y*m_size+m_size);
agg::render_scanlines_aa_solid(ras, sl, ren, color);
}
private:
double m_size;
};
template<class Renderer> class renderer_enlarged
{
public:
renderer_enlarged(Renderer& ren, double size) :
m_ren(ren),
m_square(size),
m_size(size) {}
//--------------------------------------------------------------------
void color(srgba8 c) { m_color = c; }
//--------------------------------------------------------------------
void prepare() {}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
int y = sl.y();
unsigned num_spans = sl.num_spans();
typename Scanline::const_iterator span = sl.begin();
do
{
int x = span->x;
const typename Scanline::cover_type* covers = span->covers;
int num_pix = span->len;
do
{
int a = (*covers++ * m_color.a) >> 8;
m_square.draw(m_ras, m_sl, m_ren,
srgba8(m_color.r, m_color.g, m_color.b, a),
x, y);
++x;
}
while(--num_pix);
}
while(--num_spans);
}
private:
rasterizer_scanline_aa<> m_ras;
scanline_u8 m_sl;
Renderer& m_ren;
square m_square;
srgba8 m_color;
double m_size;
};
};
class the_application : public agg::platform_support
{
double m_x[3];
double m_y[3];
double m_dx;
double m_dy;
int m_idx;
agg::slider_ctrl<color_type> m_slider1;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_slider1(80, 10, 600-10, 19, !flip_y)
{
m_idx = -1;
m_x[0] = 57; m_y[0] = 100;
m_x[1] = 369; m_y[1] = 170;
m_x[2] = 143; m_y[2] = 310;
add_ctrl(m_slider1);
m_slider1.range(8.0, 100.0);
m_slider1.num_steps(23);
m_slider1.value(32.0);
m_slider1.label("Pixel size=%1.0f");
m_slider1.no_transform();
}
virtual ~the_application()
{
}
virtual void on_init()
{
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base ren(pixf);
agg::scanline_u8 sl;
ren.clear(agg::rgba(1,1,1));
agg::rasterizer_scanline_aa<> ras;
int size_mul = int(m_slider1.value());
agg::renderer_enlarged<ren_base> ren_en(ren, size_mul);
ras.reset();
ras.move_to_d(m_x[0]/size_mul, m_y[0]/size_mul);
ras.line_to_d(m_x[1]/size_mul, m_y[1]/size_mul);
ras.line_to_d(m_x[2]/size_mul, m_y[2]/size_mul);
ren_en.color(agg::srgba8(0,0,0, 255));
agg::render_scanlines(ras, sl, ren_en);
agg::render_scanlines_aa_solid(ras, sl, ren, agg::srgba8(0,0,0));
agg::path_storage ps;
agg::conv_stroke<agg::path_storage> pg(ps);
pg.width(2.0);
ps.remove_all();
ps.move_to(m_x[0], m_y[0]);
ps.line_to(m_x[1], m_y[1]);
ras.add_path(pg);
agg::render_scanlines_aa_solid(ras, sl, ren, agg::srgba8(0,150,160, 200));
ps.remove_all();
ps.move_to(m_x[1], m_y[1]);
ps.line_to(m_x[2], m_y[2]);
ras.add_path(pg);
agg::render_scanlines_aa_solid(ras, sl, ren, agg::srgba8(0,150,160, 200));
ps.remove_all();
ps.move_to(m_x[2], m_y[2]);
ps.line_to(m_x[0], m_y[0]);
ras.add_path(pg);
agg::render_scanlines_aa_solid(ras, sl, ren, agg::srgba8(0,150,160, 200));
// Render the controls
agg::render_ctrl(ras, sl, ren, m_slider1);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
unsigned i;
for (i = 0; i < 3; i++)
{
if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 10.0)
{
m_dx = x - m_x[i];
m_dy = y - m_y[i];
m_idx = i;
break;
}
}
if(i == 3)
{
if(agg::point_in_triangle(m_x[0], m_y[0],
m_x[1], m_y[1],
m_x[2], m_y[2],
x, y))
{
m_dx = x - m_x[0];
m_dy = y - m_y[0];
m_idx = 3;
}
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_idx == 3)
{
double dx = x - m_dx;
double dy = y - m_dy;
m_x[1] -= m_x[0] - dx;
m_y[1] -= m_y[0] - dy;
m_x[2] -= m_x[0] - dx;
m_y[2] -= m_y[0] - dy;
m_x[0] = dx;
m_y[0] = dy;
force_redraw();
return;
}
if(m_idx >= 0)
{
m_x[m_idx] = x - m_dx;
m_y[m_idx] = y - m_dy;
force_redraw();
}
}
else
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_idx = -1;
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Anti-Aliasing Demo");
if(app.init(600, 400, agg::window_resize))
{
return app.run();
}
return 1;
}

581
examples/aa_test.cpp Normal file
View File

@ -0,0 +1,581 @@
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "agg_conv_dash.h"
#include "agg_conv_stroke.h"
#include "agg_span_gradient.h"
#include "agg_span_interpolator_linear.h"
#include "agg_span_gouraud_rgba.h"
#include "agg_span_allocator.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#define AGG_BGR24
//#define AGG_SBGR24
#include "pixel_formats.h"
enum flip_y_e { flip_y = false };
typedef agg::renderer_base<pixfmt> renderer_base_type;
typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type;
typedef agg::scanline_u8 scanline_type;
typedef agg::rasterizer_scanline_aa<> rasterizer_type;
template<class T> T min(T a, T b) { return (a < b) ? a : b; }
inline double frand(double x)
{
return ((((rand() << 15) | rand()) & 0x3FFFFFFF) % 1000000) * x / 1000000.0;
}
class simple_vertex_source
{
public:
simple_vertex_source() : m_num_vertices(0), m_count(0)
{
m_cmd[0] = agg::path_cmd_stop;
}
simple_vertex_source(double x1, double y1, double x2, double y2)
{
init(x1, y1, x2, y2);
}
simple_vertex_source(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
init(x1, y1, x2, y2, x3, y3);
}
void init(double x1, double y1, double x2, double y2)
{
m_num_vertices = 2;
m_count = 0;
m_x[0] = x1;
m_y[0] = y1;
m_x[1] = x2;
m_y[1] = y2;
m_cmd[0] = agg::path_cmd_move_to;
m_cmd[1] = agg::path_cmd_line_to;
m_cmd[2] = agg::path_cmd_stop;
}
void init(double x1, double y1,
double x2, double y2,
double x3, double y3)
{
m_num_vertices = 3;
m_count = 0;
m_x[0] = x1;
m_y[0] = y1;
m_x[1] = x2;
m_y[1] = y2;
m_x[2] = x3;
m_y[2] = y3;
m_x[3] = m_y[3] = m_x[4] = m_y[4] = 0.0;
m_cmd[0] = agg::path_cmd_move_to;
m_cmd[1] = agg::path_cmd_line_to;
m_cmd[2] = agg::path_cmd_line_to;
m_cmd[3] = agg::path_cmd_end_poly | agg::path_flags_close;
m_cmd[4] = agg::path_cmd_stop;
}
void rewind(unsigned)
{
m_count = 0;
}
unsigned vertex(double* x, double* y)
{
*x = m_x[m_count];
*y = m_y[m_count];
return m_cmd[m_count++];
}
private:
unsigned m_num_vertices;
unsigned m_count;
double m_x[8];
double m_y[8];
unsigned m_cmd[8];
};
template<class Ras, class Ren, class Scanline> class dashed_line
{
public:
dashed_line(Ras& ras, Ren& ren, Scanline& sl) :
m_ras(ras), m_ren(ren), m_sl(sl),
m_src(),
m_dash(m_src),
m_stroke(m_src),
m_dash_stroke(m_dash)
{}
void draw(double x1, double y1, double x2, double y2,
double line_width, double dash_length)
{
m_src.init(x1 + 0.5, y1 + 0.5, x2 + 0.5, y2 + 0.5);
m_ras.reset();
if(dash_length > 0.0)
{
m_dash.remove_all_dashes();
m_dash.add_dash(dash_length, dash_length);
m_dash_stroke.width(line_width);
m_dash_stroke.line_cap(agg::round_cap);
m_ras.add_path(m_dash_stroke);
}
else
{
m_stroke.width(line_width);
m_stroke.line_cap(agg::round_cap);
m_ras.add_path(m_stroke);
}
agg::render_scanlines(m_ras, m_sl, m_ren);
}
private:
Ras& m_ras;
Ren& m_ren;
Scanline& m_sl;
simple_vertex_source m_src;
agg::conv_dash<simple_vertex_source> m_dash;
agg::conv_stroke<simple_vertex_source> m_stroke;
agg::conv_stroke<agg::conv_dash<simple_vertex_source> > m_dash_stroke;
};
// Calculate the affine transformation matrix for the linear gradient
// from (x1, y1) to (x2, y2). gradient_d2 is the "base" to scale the
// gradient. Here d1 must be 0.0, and d2 must equal gradient_d2.
//---------------------------------------------------------------
void calc_linear_gradient_transform(double x1, double y1, double x2, double y2,
agg::trans_affine& mtx,
double gradient_d2 = 100.0)
{
double dx = x2 - x1;
double dy = y2 - y1;
mtx.reset();
mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / gradient_d2);
mtx *= agg::trans_affine_rotation(atan2(dy, dx));
mtx *= agg::trans_affine_translation(x1 + 0.5, y1 + 0.5);
mtx.invert();
}
// A simple function to form the gradient color array
// consisting of 3 colors, "begin", "middle", "end"
//---------------------------------------------------
template<class ColorArrayT>
void fill_color_array(ColorArrayT& array,
typename ColorArrayT::value_type begin,
typename ColorArrayT::value_type end)
{
unsigned i;
for(i = 0; i < 256; ++i)
{
array[i] = begin.gradient(end, i / 255.0);
}
}
class the_application : public agg::platform_support
{
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y)
{
}
virtual ~the_application()
{
}
virtual void on_init()
{
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
renderer_base_type ren_base(pixf);
renderer_scanline_type ren_sl(ren_base);
scanline_type sl;
rasterizer_type ras;
ren_base.clear(agg::rgba(0,0,0));
int i;
// radial line test
//-------------------------
dashed_line<rasterizer_type,
renderer_scanline_type,
scanline_type> dash(ras, ren_sl, sl);
double cx = width() / 2.0;
double cy = height() / 2.0;
ren_sl.color(agg::rgba(1.0, 1.0, 1.0, 0.2));
for(i = 180; i > 0; i--)
{
double n = 2.0 * agg::pi * i / 180.0;
dash.draw(cx + min(cx, cy) * sin(n), cy + min(cx, cy) * cos(n),
cx, cy,
1.0, (i < 90) ? i : 0.0);
}
typedef agg::gradient_x gradient_func_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_allocator<color_type> span_allocator_type;
typedef agg::pod_auto_array<agg::srgba8, 256> color_array_type;
typedef agg::span_gradient<color_type,
interpolator_type,
gradient_func_type,
color_array_type> span_gradient_type;
typedef agg::renderer_scanline_aa<renderer_base_type,
span_allocator_type,
span_gradient_type> renderer_gradient_type;
gradient_func_type gradient_func; // The gradient function
agg::trans_affine gradient_mtx; // Affine transformer
interpolator_type span_interpolator(gradient_mtx); // Span interpolator
span_allocator_type span_allocator; // Span Allocator
color_array_type gradient_colors; // The gradient colors
span_gradient_type span_gradient(span_interpolator,
gradient_func,
gradient_colors,
0, 100);
renderer_gradient_type ren_gradient(ren_base, span_allocator, span_gradient);
dashed_line<rasterizer_type,
renderer_gradient_type,
scanline_type> dash_gradient(ras, ren_gradient, sl);
double x1, y1, x2, y2;
for(i = 1; i <= 20; i++)
{
ren_sl.color(agg::rgba(1,1,1));
// integral point sizes 1..20
//----------------
agg::ellipse ell;
ell.init(20 + i * (i + 1) + 0.5,
20.5,
i / 2.0,
i / 2.0,
8 + i);
ras.reset();
ras.add_path(ell);
agg::render_scanlines(ras, sl, ren_sl);
// fractional point sizes 0..2
//----------------
ell.init(18 + i * 4 + 0.5, 33 + 0.5,
i/20.0, i/20.0,
8);
ras.reset();
ras.add_path(ell);
agg::render_scanlines(ras, sl, ren_sl);
// fractional point positioning
//---------------
ell.init(18 + i * 4 + (i-1) / 10.0 + 0.5,
27 + (i - 1) / 10.0 + 0.5,
0.5, 0.5, 8);
ras.reset();
ras.add_path(ell);
agg::render_scanlines(ras, sl, ren_sl);
// integral line widths 1..20
//----------------
fill_color_array(gradient_colors,
agg::rgba(1,1,1),
agg::rgba(i % 2, (i % 3) * 0.5, (i % 5) * 0.25));
x1 = 20 + i* (i + 1);
y1 = 40.5;
x2 = 20 + i * (i + 1) + (i - 1) * 4;
y2 = 100.5;
calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
dash_gradient.draw(x1, y1, x2, y2, i, 0);
fill_color_array(gradient_colors,
agg::rgba(1,0,0),
agg::rgba(0,0,1));
// fractional line lengths H (red/blue)
//----------------
x1 = 17.5 + i * 4;
y1 = 107;
x2 = 17.5 + i * 4 + i/6.66666667;
y2 = 107;
calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
dash_gradient.draw(x1, y1, x2, y2, 1.0, 0);
// fractional line lengths V (red/blue)
//---------------
x1 = 18 + i * 4;
y1 = 112.5;
x2 = 18 + i * 4;
y2 = 112.5 + i / 6.66666667;
calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
dash_gradient.draw(x1, y1, x2, y2, 1.0, 0);
// fractional line positioning (red)
//---------------
fill_color_array(gradient_colors,
agg::rgba(1,0,0),
agg::rgba(1,1,1));
x1 = 21.5;
y1 = 120 + (i - 1) * 3.1;
x2 = 52.5;
y2 = 120 + (i - 1) * 3.1;
calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
dash_gradient.draw(x1, y1, x2, y2, 1.0, 0);
// fractional line width 2..0 (green)
fill_color_array(gradient_colors,
agg::rgba(0,1,0),
agg::rgba(1,1,1));
x1 = 52.5;
y1 = 118 + i * 3;
x2 = 83.5;
y2 = 118 + i * 3;
calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
dash_gradient.draw(x1, y1, x2, y2, 2.0 - (i - 1) / 10.0, 0);
// stippled fractional width 2..0 (blue)
fill_color_array(gradient_colors,
agg::rgba(0,0,1),
agg::rgba(1,1,1));
x1 = 83.5;
y1 = 119 + i * 3;
x2 = 114.5;
y2 = 119 + i * 3;
calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
dash_gradient.draw(x1, y1, x2, y2, 2.0 - (i - 1) / 10.0, 3.0);
ren_sl.color(agg::rgba(1,1,1));
if(i <= 10)
{
// integral line width, horz aligned (mipmap test)
//-------------------
dash.draw(125.5, 119.5 + (i + 2) * (i / 2.0),
135.5, 119.5 + (i + 2) * (i / 2.0),
i, 0.0);
}
// fractional line width 0..2, 1 px H
//-----------------
dash.draw(17.5 + i * 4, 192, 18.5 + i * 4, 192, i / 10.0, 0);
// fractional line positioning, 1 px H
//-----------------
dash.draw(17.5 + i * 4 + (i - 1) / 10.0, 186,
18.5 + i * 4 + (i - 1) / 10.0, 186,
1.0, 0);
}
// Triangles
//---------------
for (i = 1; i <= 13; i++)
{
fill_color_array(gradient_colors,
agg::rgba(1,1,1),
agg::rgba(i % 2, (i % 3) * 0.5, (i % 5) * 0.25));
calc_linear_gradient_transform(width() - 150,
height() - 20 - i * (i + 1.5),
width() - 20,
height() - 20 - i * (i + 1),
gradient_mtx);
ras.reset();
ras.move_to_d(width() - 150, height() - 20 - i * (i + 1.5));
ras.line_to_d(width() - 20, height() - 20 - i * (i + 1));
ras.line_to_d(width() - 20, height() - 20 - i * (i + 2));
agg::render_scanlines(ras, sl, ren_gradient);
}
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
srand(123);
pixfmt pixf(rbuf_window());
renderer_base_type ren_base(pixf);
renderer_scanline_type ren_sl(ren_base);
scanline_type sl;
rasterizer_type ras;
ren_base.clear(agg::rgba(0,0,0));
int i;
double w = width();
double h = height();
agg::ellipse ell;
start_timer();
for(i = 0; i < 20000; i++)
{
double r = frand(20.0) + 1.0;
ell.init(frand(w), frand(h), r/2, r/2, int(r) + 10);
ras.reset();
ras.add_path(ell);
agg::render_scanlines(ras, sl, ren_sl);
ren_sl.color(agg::rgba(frand(1.0), frand(1.0), frand(1.0), 0.5+frand(0.5)));
}
double t1 = elapsed_time();
typedef agg::gradient_x gradient_func_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_allocator<color_type> span_allocator_type;
typedef agg::pod_auto_array<color_type, 256> color_array_type;
typedef agg::span_gradient<color_type,
interpolator_type,
gradient_func_type,
color_array_type> span_gradient_type;
typedef agg::renderer_scanline_aa<renderer_base_type,
span_allocator_type,
span_gradient_type> renderer_gradient_type;
gradient_func_type gradient_func; // The gradient function
agg::trans_affine gradient_mtx; // Affine transformer
interpolator_type span_interpolator(gradient_mtx); // Span interpolator
span_allocator_type span_allocator; // Span Allocator
color_array_type gradient_colors;
span_gradient_type span_gradient(span_interpolator,
gradient_func,
gradient_colors,
0, 100);
renderer_gradient_type ren_gradient(ren_base,
span_allocator,
span_gradient);
dashed_line<rasterizer_type,
renderer_gradient_type,
scanline_type> dash_gradient(ras, ren_gradient, sl);
double x1, y1, x2, y2, x3, y3;
start_timer();
for(i = 0; i < 2000; i++)
{
x1 = frand(w);
y1 = frand(h);
x2 = x1 + frand(w * 0.5) - w * 0.25;
y2 = y1 + frand(h * 0.5) - h * 0.25;
fill_color_array(gradient_colors,
agg::rgba(frand(1.0), frand(1.0), frand(1.0), 0.5+frand(0.5)),
agg::rgba(frand(1.0), frand(1.0), frand(1.0), frand(1.0)));
calc_linear_gradient_transform(x1, y1, x2, y2, gradient_mtx);
dash_gradient.draw(x1, y1, x2, y2, 10.0, 0);
}
double t2 = elapsed_time();
typedef agg::span_gouraud_rgba<color_type> gouraud_span_gen_type;
typedef agg::renderer_scanline_aa<renderer_base_type,
span_allocator_type,
gouraud_span_gen_type> renderer_gouraud_type;
gouraud_span_gen_type span_gouraud;
renderer_gouraud_type ren_gouraud(ren_base, span_allocator, span_gouraud);
start_timer();
for(i = 0; i < 2000; i++)
{
x1 = frand(w);
y1 = frand(h);
x2 = x1 + frand(w * 0.4) - w * 0.2;
y2 = y1 + frand(h * 0.4) - h * 0.2;
x3 = x1 + frand(w * 0.4) - w * 0.2;
y3 = y1 + frand(h * 0.4) - h * 0.2;
span_gouraud.colors(agg::rgba(frand(1.0), frand(1.0), frand(1.0), 0.5+frand(0.5)),
agg::rgba(frand(1.0), frand(1.0), frand(1.0), frand(1.0)),
agg::rgba(frand(1.0), frand(1.0), frand(1.0), frand(1.0)));
span_gouraud.triangle(x1, y1, x2, y2, x3, y3, 0.0);
ras.add_path(span_gouraud);
agg::render_scanlines(ras, sl, ren_gouraud);
}
double t3 = elapsed_time();
char buf[256];
sprintf(buf, "Points=%.2fK/sec, Lines=%.2fK/sec, Triangles=%.2fK/sec", 20000.0/t1, 2000.0/t2, 2000.0/t3);
message(buf);
update_window();
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Anti-Aliasing Test");
if(app.init(480, 350, agg::window_resize))
{
return app.run();
}
return 1;
}

419
examples/agg2d_demo.cpp Normal file
View File

@ -0,0 +1,419 @@
#include <stdio.h>
#include "platform/agg_platform_support.h"
#include "agg2d.h"
enum { flip_y = true };
class the_application : public agg::platform_support
{
Agg2D m_graphics;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_graphics()
{
}
~the_application()
{
}
virtual void on_init()
{
}
virtual void on_draw()
{
m_graphics.attach(rbuf_window().buf(),
rbuf_window().width(),
rbuf_window().height(),
rbuf_window().stride());
m_graphics.clearAll(255, 255, 255);
//m_graphics.clearAll(0, 0, 0);
//m_graphics.blendMode(Agg2D::BlendSub);
//m_graphics.blendMode(Agg2D::BlendAdd);
// Set flipText(true) if you have the Y axis upside down.
//m_graphics.flipText(true);
// ClipBox.
//m_graphics.clipBox(50, 50, rbuf_window().width() - 50, rbuf_window().height() - 50);
// Transfornations - Rotate around (300,300) to 5 degree
//m_graphics.translate(-300, -300);
//m_graphics.rotate(Agg2D::deg2Rad(5.0));
//m_graphics.translate(300, 300);
// Viewport - set 0,0,600,600 to the actual window size
// preserving aspect ratio and placing the viewport in the center.
// To ignore aspect ratio use Agg2D::Anisotropic
// Note that the viewport just adds transformations to the current
// affine matrix. So that, set the viewport *after* all transformations!
m_graphics.viewport(0, 0, 600, 600,
0, 0, width(), height(),
//Agg2D::Anisotropic);
Agg2D::XMidYMid);
// Rounded Rect
m_graphics.lineColor(0, 0, 0);
m_graphics.noFill();
m_graphics.roundedRect(0.5, 0.5, 600-0.5, 600-0.5, 20.0);
// Reglar Text
#ifdef AGG2D_USE_FREETYPE
m_graphics.font("c:/WINDOWS/fonts/timesi.ttf", 14.0, false, false);
#else
m_graphics.font("Times New Roman", 14.0, false, false);
#endif
m_graphics.fillColor(0, 0, 0);
m_graphics.noLine();
m_graphics.text(100, 20, "Regular Raster Text -- Fast, but can't be rotated");
// Outlined Text
#ifdef AGG2D_USE_FREETYPE
m_graphics.font("c:/WINDOWS/fonts/timesi.ttf", 50.0, false, false, Agg2D::VectorFontCache);
#else
m_graphics.font("Times New Roman", 50.0, false, false, Agg2D::VectorFontCache);
#endif
m_graphics.lineColor(50, 0, 0);
m_graphics.fillColor(180, 200, 100);
m_graphics.lineWidth(1.0);
m_graphics.text(100.5, 50.5, "Outlined Text");
// Text Alignment
m_graphics.line(250.5-150, 150.5, 250.5+150, 150.5);
m_graphics.line(250.5, 150.5-20, 250.5, 150.5+20);
m_graphics.line(250.5-150, 200.5, 250.5+150, 200.5);
m_graphics.line(250.5, 200.5-20, 250.5, 200.5+20);
m_graphics.line(250.5-150, 250.5, 250.5+150, 250.5);
m_graphics.line(250.5, 250.5-20, 250.5, 250.5+20);
m_graphics.line(250.5-150, 300.5, 250.5+150, 300.5);
m_graphics.line(250.5, 300.5-20, 250.5, 300.5+20);
m_graphics.line(250.5-150, 350.5, 250.5+150, 350.5);
m_graphics.line(250.5, 350.5-20, 250.5, 350.5+20);
m_graphics.line(250.5-150, 400.5, 250.5+150, 400.5);
m_graphics.line(250.5, 400.5-20, 250.5, 400.5+20);
m_graphics.line(250.5-150, 450.5, 250.5+150, 450.5);
m_graphics.line(250.5, 450.5-20, 250.5, 450.5+20);
m_graphics.line(250.5-150, 500.5, 250.5+150, 500.5);
m_graphics.line(250.5, 500.5-20, 250.5, 500.5+20);
m_graphics.line(250.5-150, 550.5, 250.5+150, 550.5);
m_graphics.line(250.5, 550.5-20, 250.5, 550.5+20);
m_graphics.fillColor(100, 50, 50);
m_graphics.noLine();
//m_graphics.textHints(false);
#ifdef AGG2D_USE_FREETYPE
m_graphics.font("c:/WINDOWS/fonts/timesi.ttf", 40.0, false, false, Agg2D::VectorFontCache);
#else
m_graphics.font("Times New Roman", 40.0, false, false, Agg2D::VectorFontCache);
#endif
m_graphics.textAlignment(Agg2D::AlignLeft, Agg2D::AlignBottom);
m_graphics.text(250.0, 150.0, "Left-Bottom", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignCenter, Agg2D::AlignBottom);
m_graphics.text(250.0, 200.0, "Center-Bottom", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignRight, Agg2D::AlignBottom);
m_graphics.text(250.0, 250.0, "Right-Bottom", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignLeft, Agg2D::AlignCenter);
m_graphics.text(250.0, 300.0, "Left-Center", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignCenter, Agg2D::AlignCenter);
m_graphics.text(250.0, 350.0, "Center-Center", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignRight, Agg2D::AlignCenter);
m_graphics.text(250.0, 400.0, "Right-Center", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignLeft, Agg2D::AlignTop);
m_graphics.text(250.0, 450.0, "Left-Top", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignCenter, Agg2D::AlignTop);
m_graphics.text(250.0, 500.0, "Center-Top", true, 0, 0);
m_graphics.textAlignment(Agg2D::AlignRight, Agg2D::AlignTop);
m_graphics.text(250.0, 550.0, "Right-Top", true, 0, 0);
// Gradients (Aqua Buttons)
//=======================================
#ifdef AGG2D_USE_FREETYPE
m_graphics.font("c:/WINDOWS/fonts/verdanab.ttf", 20.0, false, false, Agg2D::VectorFontCache);
#else
m_graphics.font("Verdana", 20.0, false, false, Agg2D::VectorFontCache);
#endif
double xb1 = 400;
double yb1 = 80;
double xb2 = xb1 + 150;
double yb2 = yb1 + 36;
m_graphics.fillColor(Agg2D::Color(0,50,180,180));
m_graphics.lineColor(Agg2D::Color(0,0,80, 255));
m_graphics.lineWidth(1.0);
m_graphics.roundedRect(xb1, yb1, xb2, yb2, 12, 18);
m_graphics.lineColor(Agg2D::Color(0,0,0,0));
m_graphics.fillLinearGradient(xb1, yb1, xb1, yb1+30,
Agg2D::Color(100,200,255,255),
Agg2D::Color(255,255,255,0));
m_graphics.roundedRect(xb1+3, yb1+2.5, xb2-3, yb1+30, 9, 18, 1, 1);
m_graphics.fillColor(Agg2D::Color(0,0,50, 200));
m_graphics.noLine();
m_graphics.textAlignment(Agg2D::AlignCenter, Agg2D::AlignCenter);
m_graphics.text((xb1 + xb2) / 2.0, (yb1 + yb2) / 2.0, "Aqua Button", true, 0.0, 0.0);
m_graphics.fillLinearGradient(xb1, yb2-20, xb1, yb2-3,
Agg2D::Color(0, 0, 255,0),
Agg2D::Color(100,255,255,255));
m_graphics.roundedRect(xb1+3, yb2-20, xb2-3, yb2-2, 1, 1, 9, 18);
// Aqua Button Pressed
xb1 = 400;
yb1 = 30;
xb2 = xb1 + 150;
yb2 = yb1 + 36;
m_graphics.fillColor(Agg2D::Color(0,50,180,180));
m_graphics.lineColor(Agg2D::Color(0,0,0, 255));
m_graphics.lineWidth(2.0);
m_graphics.roundedRect(xb1, yb1, xb2, yb2, 12, 18);
m_graphics.lineColor(Agg2D::Color(0,0,0,0));
m_graphics.fillLinearGradient(xb1, yb1+2, xb1, yb1+25,
Agg2D::Color(60, 160,255,255),
Agg2D::Color(100,255,255,0));
m_graphics.roundedRect(xb1+3, yb1+2.5, xb2-3, yb1+30, 9, 18, 1, 1);
m_graphics.fillColor(Agg2D::Color(0,0,50, 255));
m_graphics.noLine();
m_graphics.textAlignment(Agg2D::AlignCenter, Agg2D::AlignCenter);
m_graphics.text((xb1 + xb2) / 2.0, (yb1 + yb2) / 2.0, "Aqua Pressed", 0.0, 0.0);
m_graphics.fillLinearGradient(xb1, yb2-25, xb1, yb2-5,
Agg2D::Color(0, 180,255,0),
Agg2D::Color(0, 200,255,255));
m_graphics.roundedRect(xb1+3, yb2-25, xb2-3, yb2-2, 1, 1, 9, 18);
// Basic Shapes -- Ellipse
//===========================================
m_graphics.lineWidth(3.5);
m_graphics.lineColor(20, 80, 80);
m_graphics.fillColor(200, 255, 80, 200);
m_graphics.ellipse(450, 200, 50, 90);
// Paths
//===========================================
m_graphics.resetPath();
m_graphics.fillColor(255, 0, 0, 100);
m_graphics.lineColor(0, 0, 255, 100);
m_graphics.lineWidth(2);
m_graphics.moveTo(300/2, 200/2);
m_graphics.horLineRel(-150/2);
m_graphics.arcRel(150/2, 150/2, 0, 1, 0, 150/2, -150/2);
m_graphics.closePolygon();
m_graphics.drawPath();
m_graphics.resetPath();
m_graphics.fillColor(255, 255, 0, 100);
m_graphics.lineColor(0, 0, 255, 100);
m_graphics.lineWidth(2);
m_graphics.moveTo(275/2, 175/2);
m_graphics.verLineRel(-150/2);
m_graphics.arcRel(150/2, 150/2, 0, 0, 0, -150/2, 150/2);
m_graphics.closePolygon();
m_graphics.drawPath();
m_graphics.resetPath();
m_graphics.noFill();
m_graphics.lineColor(127, 0, 0);
m_graphics.lineWidth(5);
m_graphics.moveTo(600/2, 350/2);
m_graphics.lineRel(50/2, -25/2);
m_graphics.arcRel(25/2, 25/2, Agg2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
m_graphics.lineRel(50/2, -25/2);
m_graphics.arcRel(25/2, 50/2, Agg2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
m_graphics.lineRel(50/2, -25/2);
m_graphics.arcRel(25/2, 75/2, Agg2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
m_graphics.lineRel(50, -25);
m_graphics.arcRel(25/2, 100/2, Agg2D::deg2Rad(-30), 0, 1, 50/2, -25/2);
m_graphics.lineRel(50/2, -25/2);
m_graphics.drawPath();
// Master Alpha. From now on everything will be translucent
//===========================================
m_graphics.masterAlpha(0.85);
// Image Transformations
//===========================================
Agg2D::Image img(rbuf_img(0).buf(),
rbuf_img(0).width(),
rbuf_img(0).height(),
rbuf_img(0).stride());
m_graphics.imageFilter(Agg2D::Bilinear);
//m_graphics.imageResample(Agg2D::NoResample);
//m_graphics.imageResample(Agg2D::ResampleAlways);
m_graphics.imageResample(Agg2D::ResampleOnZoomOut);
// Set the initial image blending operation as BlendDst, that actually
// does nothing.
//-----------------
m_graphics.imageBlendMode(Agg2D::BlendDst);
// Transform the whole image to the destination rectangle
//-----------------
//m_graphics.transformImage(img, 450, 200, 595, 350);
// Transform the rectangular part of the image to the destination rectangle
//-----------------
//m_graphics.transformImage(img, 60, 60, img.width()-60, img.height()-60,
// 450, 200, 595, 350);
// Transform the whole image to the destination parallelogram
//-----------------
//double parl[6] = { 450, 200, 595, 220, 575, 350 };
//m_graphics.transformImage(img, parl);
// Transform the rectangular part of the image to the destination parallelogram
//-----------------
//double parl[6] = { 450, 200, 595, 220, 575, 350 };
//m_graphics.transformImage(img, 60, 60, img.width()-60, img.height()-60, parl);
// Transform image to the destination path. The scale is determined by a rectangle
//-----------------
//m_graphics.resetPath();
//m_graphics.moveTo(450, 200);
//m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
//m_graphics.lineTo(470, 340);
//m_graphics.transformImagePath(img, 450, 200, 595, 350);
// Transform image to the destination path.
// The scale is determined by a rectangle
//-----------------
m_graphics.resetPath();
m_graphics.moveTo(450, 200);
m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
m_graphics.lineTo(470, 340);
m_graphics.transformImagePath(img, 60, 60, img.width()-60, img.height()-60,
450, 200, 595, 350);
// Transform image to the destination path.
// The transformation is determined by a parallelogram
//m_graphics.resetPath();
//m_graphics.moveTo(450, 200);
//m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
//m_graphics.lineTo(470, 340);
//double parl[6] = { 450, 200, 595, 220, 575, 350 };
//m_graphics.transformImagePath(img, parl);
// Transform the rectangular part of the image to the destination path.
// The transformation is determined by a parallelogram
//m_graphics.resetPath();
//m_graphics.moveTo(450, 200);
//m_graphics.cubicCurveTo(595, 220, 575, 350, 595, 350);
//m_graphics.lineTo(470, 340);
//double parl[6] = { 450, 200, 595, 220, 575, 350 };
//m_graphics.transformImagePath(img, 60, 60, img.width()-60, img.height()-60, parl);
// Add/Sub/Contrast Blending Modes
m_graphics.noLine();
m_graphics.fillColor(70, 70, 0);
m_graphics.blendMode(Agg2D::BlendAdd);
m_graphics.ellipse(500, 280, 20, 40);
m_graphics.fillColor(255, 255, 255);
m_graphics.blendMode(Agg2D::BlendOverlay);
m_graphics.ellipse(500+40, 280, 20, 40);
// Radial gradient.
m_graphics.blendMode(Agg2D::BlendAlpha);
m_graphics.fillRadialGradient(400, 500, 40,
Agg2D::Color(255, 255, 0, 0),
Agg2D::Color(0, 0, 127),
Agg2D::Color(0, 255, 0, 0));
m_graphics.ellipse(400, 500, 40, 40);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
}
};
int agg_main(int argc, char* argv[])
{
#ifdef AGG2D_USE_FLOAT_FORMAT
the_application app(agg::pix_format_bgra128, flip_y);
#else
the_application app(agg::pix_format_bgra32, flip_y);
#endif
app.caption("Agg2DDemo");
char buf[256];
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
if(app.init(600, 600, agg::window_resize))
{
return app.run();
}
return 1;
}

373
examples/alpha_gradient.cpp Normal file
View File

@ -0,0 +1,373 @@
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_span_gradient.h"
#include "agg_span_gradient_alpha.h"
#include "agg_span_interpolator_linear.h"
#include "agg_span_allocator.h"
#include "agg_span_converter.h"
#include "agg_ellipse.h"
#include "agg_pixfmt_rgb.h"
#include "agg_vcgen_stroke.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_spline_ctrl.h"
#define AGG_BGR24
//#define AGG_BGR48
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
double m_x[3];
double m_y[3];
double m_dx;
double m_dy;
int m_idx;
agg::spline_ctrl<color_type> m_alpha;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_idx(-1),
m_alpha(2, 2, 200, 30, 6, !flip_y)
{
m_x[0] = 257; m_y[0] = 60;
m_x[1] = 369; m_y[1] = 170;
m_x[2] = 143; m_y[2] = 310;
m_alpha.point(0, 0.0, 0.0);
m_alpha.point(1, 1.0/5.0, 1.0 - 4.0/5.0);
m_alpha.point(2, 2.0/5.0, 1.0 - 3.0/5.0);
m_alpha.point(3, 3.0/5.0, 1.0 - 2.0/5.0);
m_alpha.point(4, 4.0/5.0, 1.0 - 1.0/5.0);
m_alpha.point(5, 1.0, 1.0);
m_alpha.update_spline();
add_ctrl(m_alpha);
}
// A simple function to form the gradient color array
// consisting of 3 colors, "begin", "middle", "end"
//---------------------------------------------------
template<class ColorArrayT>
static void fill_color_array(ColorArrayT& array,
color_type begin,
color_type middle,
color_type end)
{
unsigned i;
for(i = 0; i < 128; ++i)
{
array[i] = begin.gradient(middle, i / 128.0);
}
for(; i < 256; ++i)
{
array[i] = middle.gradient(end, (i - 128) / 128.0);
}
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> base_ren_type;
pixfmt pf(rbuf_window());
base_ren_type ren_base(pf);
ren_base.clear(agg::rgba(1,1,1));
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
// Draw some background
agg::ellipse ell;
srand(1234);
unsigned i;
unsigned w = unsigned(width());
unsigned h = unsigned(height());
for(i = 0; i < 100; i++)
{
ell.init(rand() % w, rand() % h, rand() % 60 + 5, rand() % 60 + 5, 50);
ras.add_path(ell);
agg::render_scanlines_aa_solid(ras, sl, ren_base,
agg::rgba(rand() / double(RAND_MAX),
rand() / double(RAND_MAX),
rand() / double(RAND_MAX),
rand() / double(RAND_MAX) / 2.0));
}
double parallelogram[6];
parallelogram[0] = m_x[0];
parallelogram[1] = m_y[0];
parallelogram[2] = m_x[1];
parallelogram[3] = m_y[1];
parallelogram[4] = m_x[2];
parallelogram[5] = m_y[2];
// Gradient shape function (linear, radial, custom, etc)
//-----------------
typedef agg::gradient_circle gradient_func_type;
// Alpha gradient shape function (linear, radial, custom, etc)
//-----------------
typedef agg::gradient_xy gradient_alpha_func_type;
// Span interpolator. This object is used in all span generators
// that operate with transformations during iterating of the spans,
// for example, image transformers use the interpolator too.
//-----------------
typedef agg::span_interpolator_linear<> interpolator_type;
// Span allocator is an object that allocates memory for
// the array of colors that will be used to render the
// color spans. One object can be shared between different
// span generators.
//-----------------
typedef agg::span_allocator<color_type> span_allocator_type;
// Gradient colors array adaptor
//-----------------
typedef agg::pod_auto_array<color_type, 256> gradient_colors_type;
// Finally, the gradient span generator working with the color_type
// color type.
//-----------------
typedef agg::span_gradient<color_type,
interpolator_type,
gradient_func_type,
gradient_colors_type> span_gradient_type;
// Gradient alpha array adaptor
//-----------------
typedef agg::pod_auto_array<color_type::value_type, 256> gradient_alpha_type;
// The alpha gradient span converter working with the color_type
// color type.
//-----------------
typedef agg::span_gradient_alpha<color_type,
interpolator_type,
gradient_alpha_func_type,
gradient_alpha_type> span_gradient_alpha_type;
// Span converter type
//-----------------
typedef agg::span_converter<span_gradient_type,
span_gradient_alpha_type> span_conv_type;
// The gradient objects declarations
//----------------
gradient_func_type gradient_func; // The gradient function
gradient_alpha_func_type alpha_func; // The gradient function
agg::trans_affine gradient_mtx; // Gradient affine transformer
agg::trans_affine alpha_mtx; // Alpha affine transformer
interpolator_type span_interpolator(gradient_mtx); // Span gradient interpolator
interpolator_type span_interpolator_alpha(alpha_mtx); // Span alpha interpolator
span_allocator_type span_allocator; // Span Allocator
gradient_colors_type color_array; // The gradient colors
// Declare the gradient span itself.
// The last two arguments are so called "d1" and "d2"
// defining two distances in pixels, where the gradient starts
// and where it ends. The actual meaning of "d1" and "d2" depands
// on the gradient function.
//----------------
span_gradient_type span_gradient(span_interpolator,
gradient_func,
color_array,
0, 150);
// Declare the gradient span itself.
// The last two arguments are so called "d1" and "d2"
// defining two distances in pixels, where the gradient starts
// and where it ends. The actual meaning of "d1" and "d2" depands
// on the gradient function.
//----------------
gradient_alpha_type alpha_array;
span_gradient_alpha_type span_gradient_alpha(span_interpolator_alpha,
alpha_func,
alpha_array,
0, 100);
// Span converter declaration
span_conv_type span_conv(span_gradient, span_gradient_alpha);
// Finally we can draw a circle.
//----------------
gradient_mtx *= agg::trans_affine_scaling(0.75, 1.2);
gradient_mtx *= agg::trans_affine_rotation(-agg::pi/3.0);
gradient_mtx *= agg::trans_affine_translation(width()/2, height()/2);
gradient_mtx.invert();
alpha_mtx.parl_to_rect(parallelogram, -100, -100, 100, 100);
fill_color_array(color_array,
agg::rgba(0, 0.19, 0.19),
agg::rgba(0.7, 0.7, 0.19),
agg::rgba(0.31, 0, 0));
// Fill Alpha array
//----------------
for(i = 0; i < 256; i++)
{
alpha_array[i] = color_type::from_double(m_alpha.value(i / 255.0));
}
ell.init(width()/2, height()/2, 150, 150, 100);
ras.add_path(ell);
// Render the circle with gradient plus alpha-gradient
agg::render_scanlines_aa(ras, sl, ren_base, span_allocator, span_conv);
// Draw the control points and the parallelogram
//-----------------
agg::rgba color_pnt(0, 0.4, 0.4, 0.31);
ell.init(m_x[0], m_y[0], 5, 5, 20);
ras.add_path(ell);
agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
ell.init(m_x[1], m_y[1], 5, 5, 20);
ras.add_path(ell);
agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
ell.init(m_x[2], m_y[2], 5, 5, 20);
ras.add_path(ell);
agg::render_scanlines_aa_solid(ras, sl, ren_base, color_pnt);
agg::vcgen_stroke stroke;
stroke.add_vertex(m_x[0], m_y[0], agg::path_cmd_move_to);
stroke.add_vertex(m_x[1], m_y[1], agg::path_cmd_line_to);
stroke.add_vertex(m_x[2], m_y[2], agg::path_cmd_line_to);
stroke.add_vertex(m_x[0]+m_x[2]-m_x[1], m_y[0]+m_y[2]-m_y[1], agg::path_cmd_line_to);
stroke.add_vertex(0, 0, agg::path_cmd_end_poly | agg::path_flags_close);
ras.add_path(stroke);
agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba(0, 0, 0));
agg::render_ctrl(ras, sl, ren_base, m_alpha);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
unsigned i;
if(flags & agg::mouse_left)
{
for (i = 0; i < 3; i++)
{
if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 10.0)
{
m_dx = x - m_x[i];
m_dy = y - m_y[i];
m_idx = i;
break;
}
}
if(i == 3)
{
if(agg::point_in_triangle(m_x[0], m_y[0],
m_x[1], m_y[1],
m_x[2], m_y[2],
x, y))
{
m_dx = x - m_x[0];
m_dy = y - m_y[0];
m_idx = 3;
}
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_idx == 3)
{
double dx = x - m_dx;
double dy = y - m_dy;
m_x[1] -= m_x[0] - dx;
m_y[1] -= m_y[0] - dy;
m_x[2] -= m_x[0] - dx;
m_y[2] -= m_y[0] - dy;
m_x[0] = dx;
m_y[0] = dy;
force_redraw();
return;
}
if(m_idx >= 0)
{
m_x[m_idx] = x - m_dx;
m_y[m_idx] = y - m_dy;
force_redraw();
}
}
else
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_idx = -1;
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
double dx = 0;
double dy = 0;
switch(key)
{
case agg::key_left: dx = -0.1; break;
case agg::key_right: dx = 0.1; break;
case agg::key_up: dy = 0.1; break;
case agg::key_down: dy = -0.1; break;
}
m_x[0] += dx;
m_y[0] += dy;
m_x[1] += dx;
m_y[1] += dy;
force_redraw();
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Alpha channel gradient");
if(app.init(400, 320, agg::window_resize))
{
return app.run();
}
return 1;
}

203
examples/alpha_mask.cpp Normal file
View File

@ -0,0 +1,203 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_bounding_rect.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "agg_pixfmt_gray.h"
#include "agg_alpha_mask_u8.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_ellipse.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_BGR48
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
agg::path_storage g_path;
agg::srgba8 g_colors[100];
unsigned g_path_idx[100];
unsigned g_npaths = 0;
double g_x1 = 0;
double g_y1 = 0;
double g_x2 = 0;
double g_y2 = 0;
double g_base_dx = 0;
double g_base_dy = 0;
double g_angle = 0;
double g_scale = 1.0;
double g_skew_x = 0;
double g_skew_y = 0;
int g_nclick = 0;
unsigned parse_lion(agg::path_storage& ps, agg::srgba8* colors, unsigned* path_idx);
void parse_lion()
{
g_npaths = parse_lion(g_path, g_colors, g_path_idx);
agg::pod_array_adaptor<unsigned> path_idx(g_path_idx, 100);
agg::bounding_rect(g_path, path_idx, 0, g_npaths, &g_x1, &g_y1, &g_x2, &g_y2);
g_base_dx = (g_x2 - g_x1) / 2.0;
g_base_dy = (g_y2 - g_y1) / 2.0;
}
agg::rendering_buffer g_alpha_mask_rbuf;
agg::alpha_mask_gray8 g_alpha_mask(g_alpha_mask_rbuf);
agg::rasterizer_scanline_aa<> g_rasterizer;
class the_application : public agg::platform_support
{
unsigned char* m_alpha_buf;
agg::rendering_buffer m_alpha_rbuf;
public:
virtual ~the_application()
{
delete [] m_alpha_buf;
}
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_alpha_buf(0)
{
parse_lion();
}
void generate_alpha_mask(int cx, int cy)
{
delete [] m_alpha_buf;
m_alpha_buf = new unsigned char[cx * cy];
g_alpha_mask_rbuf.attach(m_alpha_buf, cx, cy, cx);
typedef agg::renderer_base<agg::pixfmt_sgray8> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
agg::pixfmt_sgray8 pixf(g_alpha_mask_rbuf);
ren_base rb(pixf);
renderer r(rb);
agg::scanline_p8 sl;
rb.clear(agg::sgray8(0));
agg::ellipse ell;
int i;
for(i = 0; i < 10; i++)
{
ell.init(rand() % cx,
rand() % cy,
rand() % 100 + 20,
rand() % 100 + 20,
100);
g_rasterizer.add_path(ell);
r.color(agg::sgray8(rand() & 0xFF, rand() & 0xFF));
agg::render_scanlines(g_rasterizer, sl, r);
}
}
virtual void on_resize(int cx, int cy)
{
generate_alpha_mask(cx, cy);
}
virtual void on_draw()
{
int width = rbuf_window().width();
int height = rbuf_window().height();
typedef agg::scanline_u8_am<agg::alpha_mask_gray8> scanline_type;
typedef agg::renderer_base<pixfmt> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
pixfmt pixf(rbuf_window());
ren_base rb(pixf);
renderer r(rb);
scanline_type sl(g_alpha_mask);
rb.clear(agg::srgba8(255, 255, 255));
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
mtx *= agg::trans_affine_scaling(g_scale, g_scale);
mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0);
mtx *= agg::trans_affine_translation(width/2, height/2);
agg::conv_transform<agg::path_storage, agg::trans_affine> trans(g_path, mtx);
agg::render_all_paths(g_rasterizer, sl, r, trans, g_colors, g_path_idx, g_npaths);
}
void transform(double width, double height, double x, double y)
{
x -= width / 2;
y -= height / 2;
g_angle = atan2(y, x);
g_scale = sqrt(y * y + x * x) / 100.0;
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
int width = rbuf_window().width();
int height = rbuf_window().height();
transform(width, height, x, y);
force_redraw();
}
if(flags & agg::mouse_right)
{
g_skew_x = x;
g_skew_y = y;
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
on_mouse_button_down(x, y, flags);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Lion with Alpha-Masking");
if(app.init(512, 400, agg::window_resize))
{
return app.run();
}
return 1;
}

419
examples/alpha_mask2.cpp Normal file
View File

@ -0,0 +1,419 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_color_gray.h"
#include "agg_renderer_mclip.h"
#include "agg_renderer_scanline.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_bounding_rect.h"
#include "agg_renderer_outline_aa.h"
#include "agg_pixfmt_gray.h"
#include "agg_pixfmt_amask_adaptor.h"
#include "agg_renderer_primitives.h"
#include "agg_renderer_markers.h"
#include "agg_span_allocator.h"
#include "agg_span_gradient.h"
#include "agg_span_interpolator_linear.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_alpha_mask_u8.h"
#include "agg_ellipse.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
//#define AGG_GRAY8
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGR48
//#define AGG_BGR96
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
agg::rasterizer_scanline_aa<> g_rasterizer;
agg::scanline_u8 g_scanline;
agg::path_storage g_path;
agg::srgba8 g_colors[100];
unsigned g_path_idx[100];
unsigned g_npaths = 0;
double g_x1 = 0;
double g_y1 = 0;
double g_x2 = 0;
double g_y2 = 0;
double g_base_dx = 0;
double g_base_dy = 0;
double g_angle = 0;
double g_scale = 1.0;
double g_skew_x = 0;
double g_skew_y = 0;
int g_nclick = 0;
unsigned parse_lion(agg::path_storage& ps, agg::srgba8* colors, unsigned* path_idx);
void parse_lion()
{
g_npaths = parse_lion(g_path, g_colors, g_path_idx);
agg::pod_array_adaptor<unsigned> path_idx(g_path_idx, 100);
agg::bounding_rect(g_path, path_idx, 0, g_npaths, &g_x1, &g_y1, &g_x2, &g_y2);
g_base_dx = (g_x2 - g_x1) / 2.0;
g_base_dy = (g_y2 - g_y1) / 2.0;
}
namespace agg
{
// Specializations of the gradient_linear_color for srgba8 and sgray8
// color types. Only for the sake of performance.
//========================================================================
template<> struct gradient_linear_color<srgba8>
{
typedef srgba8 color_type;
gradient_linear_color() {}
gradient_linear_color(const color_type& c1, const color_type& c2) :
m_c1(c1), m_c2(c2) {}
static unsigned size() { return 256; }
color_type operator [] (unsigned v) const
{
color_type c;
c.r = (int8u)((((m_c2.r - m_c1.r) * int(v)) + (m_c1.r << 8)) >> 8);
c.g = (int8u)((((m_c2.g - m_c1.g) * int(v)) + (m_c1.g << 8)) >> 8);
c.b = (int8u)((((m_c2.b - m_c1.b) * int(v)) + (m_c1.b << 8)) >> 8);
c.a = (int8u)((((m_c2.a - m_c1.a) * int(v)) + (m_c1.a << 8)) >> 8);
return c;
}
void colors(const color_type& c1, const color_type& c2)
{
m_c1 = c1;
m_c2 = c2;
}
color_type m_c1;
color_type m_c2;
};
//========================================================================
template<> struct gradient_linear_color<sgray8>
{
typedef sgray8 color_type;
gradient_linear_color() {}
gradient_linear_color(const color_type& c1, const color_type& c2) :
m_c1(c1), m_c2(c2) {}
static unsigned size() { return 256; }
color_type operator [] (unsigned v) const
{
color_type c;
c.v = (int8u)((((m_c2.v - m_c1.v) * int(v)) + (m_c1.v << 8)) >> 8);
c.a = (int8u)((((m_c2.a - m_c1.a) * int(v)) + (m_c1.a << 8)) >> 8);
return c;
}
void colors(const color_type& c1, const color_type& c2)
{
m_c1 = c1;
m_c2 = c2;
}
color_type m_c1;
color_type m_c2;
};
}
class the_application : public agg::platform_support
{
agg::slider_ctrl<agg::rgba> m_num_cb;
typedef agg::amask_no_clip_gray8 alpha_mask_type;
//typedef agg::alpha_mask_gray8 alpha_mask_type;
unsigned char* m_alpha_buf;
agg::rendering_buffer m_alpha_mask_rbuf;
alpha_mask_type m_alpha_mask;
double m_slider_value;
public:
~the_application()
{
delete [] m_alpha_buf;
}
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_num_cb(5, 5, 150, 12, !flip_y),
m_alpha_buf(0),
m_alpha_mask_rbuf(),
m_alpha_mask(m_alpha_mask_rbuf),
m_slider_value(0.0)
{
parse_lion();
add_ctrl(m_num_cb);
m_num_cb.range(5, 100);
m_num_cb.value(10);
m_num_cb.label("N=%.2f");
m_num_cb.no_transform();
}
void generate_alpha_mask(int cx, int cy)
{
delete [] m_alpha_buf;
m_alpha_buf = new unsigned char[cx * cy];
m_alpha_mask_rbuf.attach(m_alpha_buf, cx, cy, cx);
typedef agg::renderer_base<agg::pixfmt_sgray8> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
agg::pixfmt_sgray8 pixf(m_alpha_mask_rbuf);
ren_base rb(pixf);
renderer r(rb);
agg::scanline_p8 sl;
rb.clear(agg::sgray8(0));
agg::ellipse ell;
srand(1432);
int i;
for(i = 0; i < (int)m_num_cb.value(); i++)
{
ell.init(rand() % cx,
rand() % cy,
rand() % 100 + 20,
rand() % 100 + 20,
100);
g_rasterizer.add_path(ell);
r.color(agg::sgray8((rand() & 127) + 128, (rand() & 127) + 128));
agg::render_scanlines(g_rasterizer, sl, r);
}
}
virtual void on_resize(int cx, int cy)
{
generate_alpha_mask(cx, cy);
}
virtual void on_draw()
{
unsigned i;
int width = rbuf_window().width();
int height = rbuf_window().height();
if(m_num_cb.value() != m_slider_value)
{
generate_alpha_mask(width, height);
m_slider_value = m_num_cb.value();
}
pixfmt pf(rbuf_window());
typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
typedef agg::renderer_base<pixfmt> base_ren_type;
pixfmt_amask_type pfa(pf, m_alpha_mask);
amask_ren_type r(pfa);
base_ren_type rbase(pf);
agg::renderer_scanline_aa_solid<amask_ren_type> rs(r);
agg::renderer_scanline_aa_solid<base_ren_type> rb(rbase);
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
mtx *= agg::trans_affine_scaling(g_scale, g_scale);
mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0);
mtx *= agg::trans_affine_translation(width/2, height/2);
rbase.clear(agg::rgba(1, 1, 1));
int x, y;
// Render the lion
agg::conv_transform<agg::path_storage, agg::trans_affine> trans(g_path, mtx);
agg::render_all_paths(g_rasterizer, g_scanline, rs, trans, g_colors, g_path_idx, g_npaths);
// Render random Bresenham lines and markers
agg::renderer_markers<amask_ren_type> m(r);
for(i = 0; i < 50; i++)
{
m.line_color(agg::srgba8(rand() & 0x7F,
rand() & 0x7F,
rand() & 0x7F,
(rand() & 0x7F) + 0x7F));
m.fill_color(agg::srgba8(rand() & 0x7F,
rand() & 0x7F,
rand() & 0x7F,
(rand() & 0x7F) + 0x7F));
m.line(m.coord(rand() % width), m.coord(rand() % height),
m.coord(rand() % width), m.coord(rand() % height));
m.marker(rand() % width, rand() % height, rand() % 10 + 5,
agg::marker_e(rand() % agg::end_of_markers));
}
// Render random anti-aliased lines
double w = 5.0;
agg::line_profile_aa profile;
profile.width(w);
typedef agg::renderer_outline_aa<amask_ren_type> renderer_type;
renderer_type ren(r, profile);
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
rasterizer_type ras(ren);
ras.round_cap(true);
for(i = 0; i < 50; i++)
{
ren.color(agg::srgba8(rand() & 0x7F,
rand() & 0x7F,
rand() & 0x7F,
//255));
(rand() & 0x7F) + 0x7F));
ras.move_to_d(rand() % width, rand() % height);
ras.line_to_d(rand() % width, rand() % height);
ras.render(false);
}
// Render random circles with gradient
typedef agg::gradient_linear_color<color_type> grad_color;
typedef agg::gradient_circle grad_func;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_gradient<color_type,
interpolator_type,
grad_func,
grad_color> span_grad_type;
agg::trans_affine grm;
grad_func grf;
grad_color grc(agg::srgba8(0,0,0), agg::srgba8(0,0,0));
agg::ellipse ell;
agg::span_allocator<color_type> sa;
interpolator_type inter(grm);
span_grad_type sg(inter, grf, grc, 0, 10);
agg::renderer_scanline_aa<amask_ren_type,
agg::span_allocator<color_type>,
span_grad_type> rg(r, sa, sg);
for(i = 0; i < 50; i++)
{
x = rand() % width;
y = rand() % height;
double r = rand() % 10 + 5;
grm.reset();
grm *= agg::trans_affine_scaling(r / 10.0);
grm *= agg::trans_affine_translation(x, y);
grm.invert();
grc.colors(agg::srgba8(255, 255, 255, 0),
agg::srgba8(rand() & 0x7F,
rand() & 0x7F,
rand() & 0x7F,
255));
sg.color_function(grc);
ell.init(x, y, r, r, 32);
g_rasterizer.add_path(ell);
agg::render_scanlines(g_rasterizer, g_scanline, rg);
}
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_num_cb);
}
void transform(double width, double height, double x, double y)
{
x -= width / 2;
y -= height / 2;
g_angle = atan2(y, x);
g_scale = sqrt(y * y + x * x) / 100.0;
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
int width = rbuf_window().width();
int height = rbuf_window().height();
transform(width, height, x, y);
force_redraw();
}
if(flags & agg::mouse_right)
{
g_skew_x = x;
g_skew_y = y;
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
on_mouse_button_down(x, y, flags);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Clipping to multiple rectangle regions");
if(app.init(512, 400, agg::window_resize))
{
return app.run();
}
return 1;
}

569
examples/alpha_mask3.cpp Normal file
View File

@ -0,0 +1,569 @@
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_renderer_primitives.h"
#include "agg_conv_curve.h"
#include "agg_conv_stroke.h"
#include "agg_gsv_text.h"
#include "agg_pixfmt_rgb.h"
#include "agg_pixfmt_gray.h"
#include "agg_pixfmt_amask_adaptor.h"
#include "agg_span_allocator.h"
#include "agg_alpha_mask_u8.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
//#define AGG_GRAY8
//#define AGG_GRAY32
#define AGG_BGR24
//#define AGG_BGR96
//#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class spiral
{
public:
spiral(double x, double y, double r1, double r2, double step, double start_angle=0) :
m_x(x),
m_y(y),
m_r1(r1),
m_r2(r2),
m_step(step),
m_start_angle(start_angle),
m_angle(start_angle),
m_da(agg::deg2rad(4.0)),
m_dr(m_step / 90.0)
{
}
void rewind(unsigned)
{
m_angle = m_start_angle;
m_curr_r = m_r1;
m_start = true;
}
unsigned vertex(double* x, double* y)
{
if(m_curr_r > m_r2) return agg::path_cmd_stop;
*x = m_x + cos(m_angle) * m_curr_r;
*y = m_y + sin(m_angle) * m_curr_r;
m_curr_r += m_dr;
m_angle += m_da;
if(m_start)
{
m_start = false;
return agg::path_cmd_move_to;
}
return agg::path_cmd_line_to;
}
private:
double m_x;
double m_y;
double m_r1;
double m_r2;
double m_step;
double m_start_angle;
double m_angle;
double m_curr_r;
double m_da;
double m_dr;
bool m_start;
};
void make_gb_poly(agg::path_storage& ps);
void make_arrows(agg::path_storage& ps);
class the_application : public agg::platform_support
{
agg::rbox_ctrl<color_type> m_polygons;
agg::rbox_ctrl<color_type> m_operation;
typedef agg::amask_no_clip_gray8 alpha_mask_type;
//typedef agg::alpha_mask_gray8 alpha_mask_type;
typedef pixfmt pixfmt_type;
unsigned char* m_alpha_buf;
agg::rendering_buffer m_alpha_mask_rbuf;
alpha_mask_type m_alpha_mask;
agg::rasterizer_scanline_aa<> m_ras;
agg::scanline_p8 m_sl;
double m_x;
double m_y;
public:
~the_application()
{
delete [] m_alpha_buf;
}
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_polygons (5.0, 5.0, 5.0+205.0, 110.0, !flip_y),
m_operation(555.0, 5.0, 555.0+80.0, 55.0, !flip_y),
m_alpha_buf(0),
m_alpha_mask_rbuf(),
m_alpha_mask(m_alpha_mask_rbuf),
m_x(0),
m_y(0)
{
m_operation.add_item("AND");
m_operation.add_item("SUB");
m_operation.cur_item(0);
add_ctrl(m_operation);
m_operation.no_transform();
m_polygons.add_item("Two Simple Paths");
m_polygons.add_item("Closed Stroke");
m_polygons.add_item("Great Britain and Arrows");
m_polygons.add_item("Great Britain and Spiral");
m_polygons.add_item("Spiral and Glyph");
m_polygons.cur_item(3);
add_ctrl(m_polygons);
m_polygons.no_transform();
}
void draw_text(double x, double y, const char* str)
{
pixfmt_type pf(rbuf_window());
agg::renderer_base<pixfmt_type> rb(pf);
agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt_type> > ren(rb);
agg::gsv_text txt;
agg::conv_stroke<agg::gsv_text> txt_stroke(txt);
txt_stroke.width(1.5);
txt_stroke.line_cap(agg::round_cap);
txt.size(10.0);
txt.start_point(x, y);
txt.text(str);
m_ras.add_path(txt_stroke);
ren.color(agg::rgba(0.0, 0.0, 0.0));
agg::render_scanlines(m_ras, m_sl, ren);
}
template<class VertexSource> void generate_alpha_mask(VertexSource& vs)
{
unsigned cx = (unsigned)width();
unsigned cy = (unsigned)height();
delete [] m_alpha_buf;
m_alpha_buf = new unsigned char[cx * cy];
m_alpha_mask_rbuf.attach(m_alpha_buf, cx, cy, cx);
typedef agg::renderer_base<agg::pixfmt_sgray8> ren_base;
typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
agg::pixfmt_sgray8 pixf(m_alpha_mask_rbuf);
ren_base rb(pixf);
renderer ren(rb);
start_timer();
if(m_operation.cur_item() == 0)
{
rb.clear(agg::sgray8(0));
ren.color(agg::sgray8(255));
}
else
{
rb.clear(agg::sgray8(255));
ren.color(agg::sgray8(0));
}
m_ras.add_path(vs);
agg::render_scanlines(m_ras, m_sl, ren);
double t1 = elapsed_time();
char buf[100];
sprintf(buf, "Generate AlphaMask: %.3fms", t1);
draw_text(250, 20, buf);
}
template<class VertexSource>
void perform_rendering(VertexSource& vs)
{
pixfmt_type pixf(rbuf_window());
typedef agg::pixfmt_amask_adaptor<pixfmt_type, alpha_mask_type> pixfmt_amask_type;
typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
pixfmt_amask_type pixfa(pixf, m_alpha_mask);
amask_ren_type rbase(pixfa);
agg::renderer_scanline_aa_solid<amask_ren_type> ren(rbase);
ren.color(agg::rgba(0.5, 0.0, 0, 0.5));
start_timer();
m_ras.reset();
m_ras.add_path(vs);
agg::render_scanlines(m_ras, m_sl, ren);
double t1 = elapsed_time();
char buf[100];
sprintf(buf, "Render with AlphaMask: %.3fms", t1);
draw_text(250, 5, buf);
}
unsigned render()
{
pixfmt_type pf(rbuf_window());
agg::renderer_base<pixfmt_type> rb(pf);
agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt_type> > ren(rb);
switch(m_polygons.cur_item())
{
case 0:
{
//------------------------------------
// Two simple paths
//
agg::path_storage ps1;
agg::path_storage ps2;
double x = m_x - initial_width()/2 + 100;
double y = m_y - initial_height()/2 + 100;
ps1.move_to(x+140, y+145);
ps1.line_to(x+225, y+44);
ps1.line_to(x+296, y+219);
ps1.close_polygon();
ps1.line_to(x+226, y+289);
ps1.line_to(x+82, y+292);
ps1.move_to(x+220, y+222);
ps1.line_to(x+363, y+249);
ps1.line_to(x+265, y+331);
ps1.move_to(x+242, y+243);
ps1.line_to(x+268, y+309);
ps1.line_to(x+325, y+261);
ps1.move_to(x+259, y+259);
ps1.line_to(x+273, y+288);
ps1.line_to(x+298, y+266);
ps2.move_to(100+32, 100+77);
ps2.line_to(100+473, 100+263);
ps2.line_to(100+351, 100+290);
ps2.line_to(100+354, 100+374);
m_ras.reset();
m_ras.add_path(ps1);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
m_ras.reset();
m_ras.add_path(ps2);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
generate_alpha_mask(ps1);
perform_rendering(ps2);
}
break;
case 1:
{
//------------------------------------
// Closed stroke
//
agg::path_storage ps1;
agg::path_storage ps2;
agg::conv_stroke<agg::path_storage> stroke(ps2);
stroke.width(10.0);
double x = m_x - initial_width()/2 + 100;
double y = m_y - initial_height()/2 + 100;
ps1.move_to(x+140, y+145);
ps1.line_to(x+225, y+44);
ps1.line_to(x+296, y+219);
ps1.close_polygon();
ps1.line_to(x+226, y+289);
ps1.line_to(x+82, y+292);
ps1.move_to(x+220-50, y+222);
ps1.line_to(x+265-50, y+331);
ps1.line_to(x+363-50, y+249);
ps1.close_polygon(agg::path_flags_ccw);
ps2.move_to(100+32, 100+77);
ps2.line_to(100+473, 100+263);
ps2.line_to(100+351, 100+290);
ps2.line_to(100+354, 100+374);
ps2.close_polygon();
m_ras.reset();
m_ras.add_path(ps1);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
m_ras.reset();
m_ras.add_path(stroke);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
generate_alpha_mask(ps1);
perform_rendering(stroke);
}
break;
case 2:
{
//------------------------------------
// Great Britain and Arrows
//
agg::path_storage gb_poly;
agg::path_storage arrows;
make_gb_poly(gb_poly);
make_arrows(arrows);
agg::trans_affine mtx1;
agg::trans_affine mtx2;
mtx1 *= agg::trans_affine_translation(-1150, -1150);
mtx1 *= agg::trans_affine_scaling(2.0);
mtx2 = mtx1;
mtx2 *= agg::trans_affine_translation(m_x - initial_width()/2,
m_y - initial_height()/2);
agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx1);
agg::conv_transform<agg::path_storage> trans_arrows(arrows, mtx2);
m_ras.add_path(trans_gb_poly);
ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
stroke_gb_poly.width(0.1);
m_ras.add_path(stroke_gb_poly);
ren.color(agg::rgba(0, 0, 0));
agg::render_scanlines(m_ras, m_sl, ren);
m_ras.add_path(trans_arrows);
ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
generate_alpha_mask(trans_gb_poly);
perform_rendering(trans_arrows);
}
break;
case 3:
{
//------------------------------------
// Great Britain and a Spiral
//
spiral sp(m_x, m_y, 10, 150, 30, 0.0);
agg::conv_stroke<spiral> stroke(sp);
stroke.width(15.0);
agg::path_storage gb_poly;
make_gb_poly(gb_poly);
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-1150, -1150);
mtx *= agg::trans_affine_scaling(2.0);
agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx);
m_ras.add_path(trans_gb_poly);
ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
stroke_gb_poly.width(0.1);
m_ras.add_path(stroke_gb_poly);
ren.color(agg::rgba(0, 0, 0));
agg::render_scanlines(m_ras, m_sl, ren);
m_ras.add_path(stroke);
ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
generate_alpha_mask(trans_gb_poly);
perform_rendering(stroke);
}
break;
case 4:
{
//------------------------------------
// Spiral and glyph
//
spiral sp(m_x, m_y, 10, 150, 30, 0.0);
agg::conv_stroke<spiral> stroke(sp);
stroke.width(15.0);
agg::path_storage glyph;
glyph.move_to(28.47, 6.45);
glyph.curve3(21.58, 1.12, 19.82, 0.29);
glyph.curve3(17.19, -0.93, 14.21, -0.93);
glyph.curve3(9.57, -0.93, 6.57, 2.25);
glyph.curve3(3.56, 5.42, 3.56, 10.60);
glyph.curve3(3.56, 13.87, 5.03, 16.26);
glyph.curve3(7.03, 19.58, 11.99, 22.51);
glyph.curve3(16.94, 25.44, 28.47, 29.64);
glyph.line_to(28.47, 31.40);
glyph.curve3(28.47, 38.09, 26.34, 40.58);
glyph.curve3(24.22, 43.07, 20.17, 43.07);
glyph.curve3(17.09, 43.07, 15.28, 41.41);
glyph.curve3(13.43, 39.75, 13.43, 37.60);
glyph.line_to(13.53, 34.77);
glyph.curve3(13.53, 32.52, 12.38, 31.30);
glyph.curve3(11.23, 30.08, 9.38, 30.08);
glyph.curve3(7.57, 30.08, 6.42, 31.35);
glyph.curve3(5.27, 32.62, 5.27, 34.81);
glyph.curve3(5.27, 39.01, 9.57, 42.53);
glyph.curve3(13.87, 46.04, 21.63, 46.04);
glyph.curve3(27.59, 46.04, 31.40, 44.04);
glyph.curve3(34.28, 42.53, 35.64, 39.31);
glyph.curve3(36.52, 37.21, 36.52, 30.71);
glyph.line_to(36.52, 15.53);
glyph.curve3(36.52, 9.13, 36.77, 7.69);
glyph.curve3(37.01, 6.25, 37.57, 5.76);
glyph.curve3(38.13, 5.27, 38.87, 5.27);
glyph.curve3(39.65, 5.27, 40.23, 5.62);
glyph.curve3(41.26, 6.25, 44.19, 9.18);
glyph.line_to(44.19, 6.45);
glyph.curve3(38.72, -0.88, 33.74, -0.88);
glyph.curve3(31.35, -0.88, 29.93, 0.78);
glyph.curve3(28.52, 2.44, 28.47, 6.45);
glyph.close_polygon();
glyph.move_to(28.47, 9.62);
glyph.line_to(28.47, 26.66);
glyph.curve3(21.09, 23.73, 18.95, 22.51);
glyph.curve3(15.09, 20.36, 13.43, 18.02);
glyph.curve3(11.77, 15.67, 11.77, 12.89);
glyph.curve3(11.77, 9.38, 13.87, 7.06);
glyph.curve3(15.97, 4.74, 18.70, 4.74);
glyph.curve3(22.41, 4.74, 28.47, 9.62);
glyph.close_polygon();
agg::trans_affine mtx;
mtx *= agg::trans_affine_scaling(4.0);
mtx *= agg::trans_affine_translation(220, 200);
agg::conv_transform<agg::path_storage> trans(glyph, mtx);
agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans);
m_ras.reset();
m_ras.add_path(stroke);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
m_ras.reset();
m_ras.add_path(curve);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(m_ras, m_sl, ren);
generate_alpha_mask(stroke);
perform_rendering(curve);
}
break;
}
return 0;
}
virtual void on_init()
{
m_x = width() / 2.0;
m_y = height() / 2.0;
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt_type> base_ren_type;
pixfmt_type pf(rbuf_window());
base_ren_type ren_base(pf);
ren_base.clear(agg::rgba(1,1,1));
render();
agg::render_ctrl(m_ras, m_sl, ren_base, m_polygons);
agg::render_ctrl(m_ras, m_sl, ren_base, m_operation);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_x = x;
m_y = y;
force_redraw();
}
if(flags & agg::mouse_right)
{
char buf[100];
sprintf(buf, "%d %d", x, y);
message(buf);
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_x = x;
m_y = y;
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Alpha-Mask as a Polygon Clipper");
if(app.init(640, 520, agg::window_resize))
{
return app.run();
}
return 1;
}

2825
examples/art/1.sdf Normal file

File diff suppressed because it is too large Load Diff

BIN
examples/art/agg.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
examples/art/agg.ppm Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

10740
examples/art/shapes.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
examples/art/spheres.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

BIN
examples/art/spheres.ppm Normal file

Binary file not shown.

728
examples/art/tiger.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 95 KiB

BIN
examples/art/timesi.zip Normal file

Binary file not shown.

572
examples/bezier_div.cpp Normal file
View File

@ -0,0 +1,572 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "agg_rendering_buffer.h"
#include "agg_conv_transform.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_pattern_filters_rgba.h"
#include "agg_renderer_outline_aa.h"
#include "agg_renderer_outline_image.h"
#include "agg_arc.h"
#include "agg_bezier_arc.h"
#include "agg_pixfmt_rgb.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_bezier_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
//#define AGG_GRAY8
//#define AGG_GRAY32
#define AGG_BGR24
//#define AGG_BGR96
//#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
void bezier4_point(double x1, double y1, double x2, double y2,
double x3, double y3, double x4, double y4,
double mu,
double* x, double* y)
{
double mum1, mum13, mu3;
mum1 = 1 - mu;
mum13 = mum1 * mum1 * mum1;
mu3 = mu * mu * mu;
*x = mum13*x1 + 3*mu*mum1*mum1*x2 + 3*mu*mu*mum1*x3 + mu3*x4;
*y = mum13*y1 + 3*mu*mum1*mum1*y2 + 3*mu*mu*mum1*y3 + mu3*y4;
}
class the_application : public agg::platform_support
{
agg::srgba8 m_ctrl_color;
agg::bezier_ctrl<color_type> m_curve1;
agg::slider_ctrl<color_type> m_angle_tolerance;
agg::slider_ctrl<color_type> m_approximation_scale;
agg::slider_ctrl<color_type> m_cusp_limit;
agg::slider_ctrl<color_type> m_width;
agg::cbox_ctrl<color_type> m_show_points;
agg::cbox_ctrl<color_type> m_show_outline;
agg::rbox_ctrl<color_type> m_curve_type;
agg::rbox_ctrl<color_type> m_case_type;
agg::rbox_ctrl<color_type> m_inner_join;
agg::rbox_ctrl<color_type> m_line_join;
agg::rbox_ctrl<color_type> m_line_cap;
int m_cur_case_type;
public:
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
typedef agg::rasterizer_scanline_aa<> rasterizer_scanline;
typedef agg::scanline_u8 scanline;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_ctrl_color(agg::rgba(0, 0.3, 0.5, 0.8)),
m_angle_tolerance (5.0, 5.0, 240.0, 12.0, !flip_y),
m_approximation_scale(5.0, 17+5.0, 240.0, 17+12.0, !flip_y),
m_cusp_limit (5.0, 17+17+5.0, 240.0, 17+17+12.0, !flip_y),
m_width (245.0, 5.0, 495.0, 12.0, !flip_y),
m_show_points (250.0, 15+5, "Show Points", !flip_y),
m_show_outline (250.0, 30+5, "Show Stroke Outline", !flip_y),
m_curve_type (535.0, 5.0, 535.0+115.0, 55.0, !flip_y),
m_case_type (535.0, 60.0, 535.0+115.0, 195.0, !flip_y),
m_inner_join (535.0, 200.0, 535.0+115.0, 290.0, !flip_y),
m_line_join (535.0, 295.0, 535.0+115.0, 385.0, !flip_y),
m_line_cap (535.0, 395.0, 535.0+115.0, 455.0, !flip_y),
m_cur_case_type(-1)
{
m_curve1.line_color(m_ctrl_color);
m_curve1.curve(170, 424, 13, 87, 488, 423, 26, 333);
//m_curve1.curve(26.000, 333.000, 276.000, 126.000, 402.000, 479.000, 26.000, 333.000); // Loop with p1==p4
//m_curve1.curve(378.000, 439.000, 378.000, 497.000, 487.000, 432.000, 14.000, 338.000); // Narrow loop
//m_curve1.curve(288.000, 283.000, 232.000, 89.000, 66.000, 197.000, 456.000, 241.000); // Loop
//m_curve1.curve(519.000, 142.000, 97.000, 147.000, 69.000, 147.000, 30.000, 144.000); // Almost straight
//m_curve1.curve(100, 100, 200, 100, 100, 200, 200, 200); // A "Z" case
//m_curve1.curve(150, 150, 350, 150, 150, 150, 350, 150); // Degenerate
//m_curve1.curve(409, 330, 300, 200, 200, 200, 401, 263); // Strange cusp
//m_curve1.curve(129, 233, 172, 320, 414, 253, 344, 236); // Curve cap
//m_curve1.curve(100,100, 100,200, 100,100, 110,100); // A "boot"
//m_curve1.curve(225, 150, 60, 150, 460, 150, 295, 150); // 2----1----4----3
//m_curve1.curve(162.2, 248.801, 162.2, 248.801, 266, 284, 394, 335); // Coinciding 1-2
//m_curve1.curve(162.200, 248.801, 162.200, 248.801, 257.000, 301.000, 394.000, 335.000); // Coinciding 1-2
//m_curve1.curve(394.000, 335.000, 257.000, 301.000, 162.200, 248.801, 162.200, 248.801); // Coinciding 3-4
//m_curve1.curve(84.200000,302.80100, 84.200000,302.80100, 79.000000,292.40100, 97.001000,304.40100); // From tiger.svg
//m_curve1.curve(97.001000,304.40100, 79.000000,292.40100, 84.200000,302.80100, 84.200000,302.80100); // From tiger.svg opposite dir
//m_curve1.curve(475, 157, 200, 100, 453, 100, 222, 157); // Cusp, failure for Adobe SVG
add_ctrl(m_curve1);
m_curve1.no_transform();
m_angle_tolerance.label("Angle Tolerance=%.0f deg");
m_angle_tolerance.range(0, 90);
m_angle_tolerance.value(15);
add_ctrl(m_angle_tolerance);
m_angle_tolerance.no_transform();
m_approximation_scale.label("Approximation Scale=%.3f");
m_approximation_scale.range(0.1, 5);
m_approximation_scale.value(1.0);
add_ctrl(m_approximation_scale);
m_approximation_scale.no_transform();
m_cusp_limit.label("Cusp Limit=%.0f deg");
m_cusp_limit.range(0, 90);
m_cusp_limit.value(0);
add_ctrl(m_cusp_limit);
m_cusp_limit.no_transform();
m_width.label("Width=%.2f");
m_width.range(-50, 100);
m_width.value(50.0);
add_ctrl(m_width);
m_width.no_transform();
add_ctrl(m_show_points);
m_show_points.no_transform();
m_show_points.status(true);
add_ctrl(m_show_outline);
m_show_outline.no_transform();
m_show_outline.status(true);
m_curve_type.add_item("Incremental");
m_curve_type.add_item("Subdiv");
m_curve_type.cur_item(1);
add_ctrl(m_curve_type);
m_curve_type.no_transform();
m_case_type.text_size(7);
m_case_type.text_thickness(1.0);
m_case_type.add_item("Random");
m_case_type.add_item("13---24");
m_case_type.add_item("Smooth Cusp 1");
m_case_type.add_item("Smooth Cusp 2");
m_case_type.add_item("Real Cusp 1");
m_case_type.add_item("Real Cusp 2");
m_case_type.add_item("Fancy Stroke");
m_case_type.add_item("Jaw");
m_case_type.add_item("Ugly Jaw");
add_ctrl(m_case_type);
m_case_type.no_transform();
m_inner_join.text_size(8);
m_inner_join.add_item("Inner Bevel");
m_inner_join.add_item("Inner Miter");
m_inner_join.add_item("Inner Jag");
m_inner_join.add_item("Inner Round");
m_inner_join.cur_item(3);
add_ctrl(m_inner_join);
m_inner_join.no_transform();
m_line_join.text_size(8);
m_line_join.add_item("Miter Join");
m_line_join.add_item("Miter Revert");
m_line_join.add_item("Round Join");
m_line_join.add_item("Bevel Join");
m_line_join.add_item("Miter Round");
m_line_join.cur_item(1);
add_ctrl(m_line_join);
m_line_join.no_transform();
m_line_cap.text_size(8);
m_line_cap.add_item("Butt Cap");
m_line_cap.add_item("Square Cap");
m_line_cap.add_item("Round Cap");
m_line_cap.cur_item(0);
add_ctrl(m_line_cap);
m_line_cap.no_transform();
}
template<class Curve> double measure_time(Curve& curve)
{
start_timer();
for(int i = 0; i < 100; i++)
{
double x, y;
curve.init(m_curve1.x1(), m_curve1.y1(),
m_curve1.x2(), m_curve1.y2(),
m_curve1.x3(), m_curve1.y3(),
m_curve1.x4(), m_curve1.y4());
curve.rewind(0);
while(!agg::is_stop(curve.vertex(&x, &y)));
}
return elapsed_time() * 10;
}
template<class Path>
bool find_point(const Path& path, double dist, unsigned* i, unsigned* j)
{
int k;
*j = path.size() - 1;
for(*i = 0; (*j - *i) > 1; )
{
if(dist < path[k = (*i + *j) >> 1].dist) *j = k;
else *i = k;
}
return true;
}
struct curve_point
{
curve_point() {}
curve_point(double x1, double y1, double mu1) : x(x1), y(y1), mu(mu1) {}
double x, y, dist, mu;
};
template<class Curve> double calc_max_error(Curve& curve, double scale,
double* max_angle_error)
{
curve.approximation_scale(m_approximation_scale.value() * scale);
curve.init(m_curve1.x1(), m_curve1.y1(),
m_curve1.x2(), m_curve1.y2(),
m_curve1.x3(), m_curve1.y3(),
m_curve1.x4(), m_curve1.y4());
agg::pod_bvector<agg::vertex_dist, 8> curve_points;
unsigned cmd;
double x, y;
curve.rewind(0);
while(!agg::is_stop(cmd = curve.vertex(&x, &y)))
{
if(agg::is_vertex(cmd))
{
curve_points.add(agg::vertex_dist(x, y));
}
}
unsigned i;
double curve_dist = 0;
for(i = 1; i < curve_points.size(); i++)
{
curve_points[i - 1].dist = curve_dist;
curve_dist += agg::calc_distance(curve_points[i-1].x, curve_points[i-1].y,
curve_points[i].x, curve_points[i].y);
}
curve_points[curve_points.size() - 1].dist = curve_dist;
agg::pod_bvector<curve_point, 8> reference_points;
for(i = 0; i < 4096; i++)
{
double mu = i / 4095.0;
bezier4_point(m_curve1.x1(), m_curve1.y1(),
m_curve1.x2(), m_curve1.y2(),
m_curve1.x3(), m_curve1.y3(),
m_curve1.x4(), m_curve1.y4(),
mu, &x, &y);
reference_points.add(curve_point(x, y, mu));
}
double reference_dist = 0;
for(i = 1; i < reference_points.size(); i++)
{
reference_points[i - 1].dist = reference_dist;
reference_dist += agg::calc_distance(reference_points[i-1].x, reference_points[i-1].y,
reference_points[i].x, reference_points[i].y);
}
reference_points[reference_points.size() - 1].dist = reference_dist;
unsigned idx1 = 0;
unsigned idx2 = 1;
double max_error = 0;
for(i = 0; i < reference_points.size(); i++)
{
if(find_point(curve_points, reference_points[i].dist, &idx1, &idx2))
{
double err = fabs(agg::calc_line_point_distance(curve_points[idx1].x, curve_points[idx1].y,
curve_points[idx2].x, curve_points[idx2].y,
reference_points[i].x, reference_points[i].y));
if(err > max_error) max_error = err;
}
}
double aerr = 0;
for(i = 2; i < curve_points.size(); i++)
{
double a1 = atan2(curve_points[i-1].y - curve_points[i-2].y,
curve_points[i-1].x - curve_points[i-2].x);
double a2 = atan2(curve_points[i].y - curve_points[i-1].y,
curve_points[i].x - curve_points[i-1].x);
double da = fabs(a1 - a2);
if(da >= agg::pi) da = 2*agg::pi - da;
if(da > aerr) aerr = da;
}
*max_angle_error = aerr * 180.0 / agg::pi;
return max_error * scale;
}
virtual void on_draw()
{
pixfmt pf(rbuf_window());
renderer_base ren_base(pf);
ren_base.clear(agg::rgba(1.0, 1.0, 0.95));
renderer_scanline ren(ren_base);
rasterizer_scanline ras;
scanline sl;
agg::path_storage path;
double x, y;
double curve_time = 0;
path.remove_all();
agg::curve4 curve;
curve.approximation_method(agg::curve_approximation_method_e(m_curve_type.cur_item()));
curve.approximation_scale(m_approximation_scale.value());
curve.angle_tolerance(agg::deg2rad(m_angle_tolerance.value()));
curve.cusp_limit(agg::deg2rad(m_cusp_limit.value()));
curve_time = measure_time(curve);
double max_angle_error_01 = 0;
double max_angle_error_1 = 0;
double max_angle_error1 = 0;
double max_angle_error_10 = 0;
double max_angle_error_100 = 0;
double max_error_01 = 0;
double max_error_1 = 0;
double max_error1 = 0;
double max_error_10 = 0;
double max_error_100 = 0;
max_error_01 = calc_max_error(curve, 0.01, &max_angle_error_01);
max_error_1 = calc_max_error(curve, 0.1, &max_angle_error_1);
max_error1 = calc_max_error(curve, 1, &max_angle_error1);
max_error_10 = calc_max_error(curve, 10, &max_angle_error_10);
max_error_100 = calc_max_error(curve, 100, &max_angle_error_100);
curve.approximation_scale(m_approximation_scale.value());
curve.angle_tolerance(agg::deg2rad(m_angle_tolerance.value()));
curve.cusp_limit(agg::deg2rad(m_cusp_limit.value()));
curve.init(m_curve1.x1(), m_curve1.y1(),
m_curve1.x2(), m_curve1.y2(),
m_curve1.x3(), m_curve1.y3(),
m_curve1.x4(), m_curve1.y4());
path.concat_path(curve);
//path.move_to(m_curve1.x1(), m_curve1.y1());
//path.line_to(m_curve1.x2(), m_curve1.y2());
//path.line_to(m_curve1.x3(), m_curve1.y3());
//path.line_to(m_curve1.x4(), m_curve1.y4());
agg::conv_stroke<agg::path_storage> stroke(path);
stroke.width(m_width.value());
stroke.line_join(agg::line_join_e(m_line_join.cur_item()));
stroke.line_cap(agg::line_cap_e(m_line_cap.cur_item()));
stroke.inner_join(agg::inner_join_e(m_inner_join.cur_item()));
stroke.inner_miter_limit(1.01);
ras.add_path(stroke);
ren.color(agg::rgba(0, 0.5, 0, 0.5));
agg::render_scanlines(ras, sl, ren);
unsigned cmd;
unsigned num_points1 = 0;
path.rewind(0);
while(!agg::is_stop(cmd = path.vertex(&x, &y)))
{
if(m_show_points.status())
{
agg::ellipse ell(x, y, 1.5, 1.5, 8);
ras.add_path(ell);
ren.color(agg::rgba(0,0,0, 0.5));
agg::render_scanlines(ras, sl, ren);
}
++num_points1;
}
if(m_show_outline.status())
{
// Draw a stroke of the stroke to see the internals
//--------------
agg::conv_stroke<agg::conv_stroke<agg::path_storage> > stroke2(stroke);
ras.add_path(stroke2);
ren.color(agg::rgba(0,0,0, 0.5));
agg::render_scanlines(ras, sl, ren);
}
// Check ellipse and arc for the number of points
//---------------
//agg::ellipse a(100, 100, m_width.value(), m_width.value(), 0);
//ras.add_path(a);
//ren.color(agg::rgba(0.5,0,0, 0.5));
//agg::render_scanlines(ras, sl, ren);
//a.rewind(0);
//while(!agg::is_stop(cmd = a.vertex(&x, &y)))
//{
// if(agg::is_vertex(cmd))
// {
// agg::ellipse ell(x, y, 1.5, 1.5, 8);
// ras.add_path(ell);
// ren.color(agg::rgba(0,0,0,0.5));
// agg::render_scanlines(ras, sl, ren);
// }
//}
// Check a circle with huge radius (10,000,000) and high approximation accuracy
//---------------
//double circle_pnt_count = 0;
//agg::bezier_arc ell(0,0, 10000000, 10000000, 0, 2*agg::pi);
//agg::conv_curve<agg::bezier_arc, agg::curve3_div, agg::curve4_div3> crv(ell);
//crv.approximation_scale(10.0);
//crv.rewind(0);
//while(crv.vertex(&x, &y)) ++circle_pnt_count;
char buf[512];
agg::gsv_text t;
t.size(8.0);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.line_cap(agg::round_cap);
pt.line_join(agg::round_join);
pt.width(1.5);
sprintf(buf, "Num Points=%d Time=%.2fmks\n\n"
" Dist Error: x0.01=%.5f x0.1=%.5f x1=%.5f x10=%.5f x100=%.5f\n\n"
"Angle Error: x0.01=%.1f x0.1=%.1f x1=%.1f x10=%.1f x100=%.1f",
num_points1, curve_time,
max_error_01,
max_error_1,
max_error1,
max_error_10,
max_error_100,
max_angle_error_01,
max_angle_error_1,
max_angle_error1,
max_angle_error_10,
max_angle_error_100);
t.start_point(10.0, 85.0);
t.text(buf);
ras.add_path(pt);
ren.color(agg::rgba(0,0,0));
agg::render_scanlines(ras, sl, ren);
agg::render_ctrl(ras, sl, ren_base, m_curve1);
agg::render_ctrl(ras, sl, ren_base, m_angle_tolerance);
agg::render_ctrl(ras, sl, ren_base, m_approximation_scale);
agg::render_ctrl(ras, sl, ren_base, m_cusp_limit);
agg::render_ctrl(ras, sl, ren_base, m_width);
agg::render_ctrl(ras, sl, ren_base, m_show_points);
agg::render_ctrl(ras, sl, ren_base, m_show_outline);
agg::render_ctrl(ras, sl, ren_base, m_curve_type);
agg::render_ctrl(ras, sl, ren_base, m_case_type);
agg::render_ctrl(ras, sl, ren_base, m_inner_join);
agg::render_ctrl(ras, sl, ren_base, m_line_join);
agg::render_ctrl(ras, sl, ren_base, m_line_cap);
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
FILE* fd = fopen(full_file_name("coord"), "w");
fprintf(fd, "%.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f, %.3f",
m_curve1.x1(), m_curve1.y1(),
m_curve1.x2(), m_curve1.y2(),
m_curve1.x3(), m_curve1.y3(),
m_curve1.x4(), m_curve1.y4());
fclose(fd);
}
}
virtual void on_ctrl_change()
{
if(m_case_type.cur_item() != m_cur_case_type)
{
switch(m_case_type.cur_item())
{
case 0: //m_case_type.add_item("Random");
{
int w = int(width() - 120);
int h = int(height() - 80);
m_curve1.curve(rand() % w, rand() % h + 80, rand() % w, rand() % h + 80,
rand() % w, rand() % h + 80, rand() % w, rand() % h + 80);
}
break;
case 1: //m_case_type.add_item("13---24");
m_curve1.curve(150, 150, 350, 150, 150, 150, 350, 150);
//m_curve1.curve(252, 227, 16, 227, 506, 227, 285, 227);
//m_curve1.curve(252, 227, 16, 227, 387, 227, 285, 227);
break;
case 2: //m_case_type.add_item("Smooth Cusp 1");
m_curve1.curve(50, 142, 483, 251, 496, 62, 26, 333);
break;
case 3: //m_case_type.add_item("Smooth Cusp 2");
m_curve1.curve(50, 142, 484, 251, 496, 62, 26, 333);
break;
case 4: //m_case_type.add_item("Real Cusp 1");
m_curve1.curve(100, 100, 300, 200, 200, 200, 200, 100);
break;
case 5: //m_case_type.add_item("Real Cusp 2");
m_curve1.curve(475, 157, 200, 100, 453, 100, 222, 157);
break;
case 6: //m_case_type.add_item("Fancy Stroke");
m_curve1.curve(129, 233, 32, 283, 258, 285, 159, 232);
m_width.value(100);
break;
case 7: //m_case_type.add_item("Jaw");
m_curve1.curve(100, 100, 300, 200, 264, 286, 264, 284);
break;
case 8: //m_case_type.add_item("Ugly Jaw");
m_curve1.curve(100, 100, 413, 304, 264, 286, 264, 284);
break;
}
force_redraw();
m_cur_case_type = m_case_type.cur_item();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example");
if(app.init(655, 520, agg::window_resize))
{
return app.run();
}
return 1;
}

555
examples/blend_color.cpp Normal file
View File

@ -0,0 +1,555 @@
#include <math.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_curve.h"
#include "agg_conv_contour.h"
#include "agg_conv_stroke.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_bounding_rect.h"
#include "agg_trans_perspective.h"
#include "agg_blur.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_polygon_ctrl.h"
#include "platform/agg_platform_support.h"
//#define AGG_GRAY8
//#define AGG_GRAY16
//#define AGG_GRAY32
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGR48
//#define AGG_RGB48
//#define AGG_BGR96
//#define AGG_RGB96
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGRA64
//#define AGG_RGBA64
//#define AGG_ARGB64
//#define AGG_ABGR64
//#define AGG_BGRA128
//#define AGG_RGBA128
//#define AGG_ARGB128
//#define AGG_ABGR128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
static agg::int8u g_gradient_colors[] =
{
255, 255, 255, 255,
255, 255, 254, 255,
255, 255, 254, 255,
255, 255, 254, 255,
255, 255, 253, 255,
255, 255, 253, 255,
255, 255, 252, 255,
255, 255, 251, 255,
255, 255, 250, 255,
255, 255, 248, 255,
255, 255, 246, 255,
255, 255, 244, 255,
255, 255, 241, 255,
255, 255, 238, 255,
255, 255, 235, 255,
255, 255, 231, 255,
255, 255, 227, 255,
255, 255, 222, 255,
255, 255, 217, 255,
255, 255, 211, 255,
255, 255, 206, 255,
255, 255, 200, 255,
255, 254, 194, 255,
255, 253, 188, 255,
255, 252, 182, 255,
255, 250, 176, 255,
255, 249, 170, 255,
255, 247, 164, 255,
255, 246, 158, 255,
255, 244, 152, 255,
254, 242, 146, 255,
254, 240, 141, 255,
254, 238, 136, 255,
254, 236, 131, 255,
253, 234, 126, 255,
253, 232, 121, 255,
253, 229, 116, 255,
252, 227, 112, 255,
252, 224, 108, 255,
251, 222, 104, 255,
251, 219, 100, 255,
251, 216, 96, 255,
250, 214, 93, 255,
250, 211, 89, 255,
249, 208, 86, 255,
249, 205, 83, 255,
248, 202, 80, 255,
247, 199, 77, 255,
247, 196, 74, 255,
246, 193, 72, 255,
246, 190, 69, 255,
245, 187, 67, 255,
244, 183, 64, 255,
244, 180, 62, 255,
243, 177, 60, 255,
242, 174, 58, 255,
242, 170, 56, 255,
241, 167, 54, 255,
240, 164, 52, 255,
239, 161, 51, 255,
239, 157, 49, 255,
238, 154, 47, 255,
237, 151, 46, 255,
236, 147, 44, 255,
235, 144, 43, 255,
235, 141, 41, 255,
234, 138, 40, 255,
233, 134, 39, 255,
232, 131, 37, 255,
231, 128, 36, 255,
230, 125, 35, 255,
229, 122, 34, 255,
228, 119, 33, 255,
227, 116, 31, 255,
226, 113, 30, 255,
225, 110, 29, 255,
224, 107, 28, 255,
223, 104, 27, 255,
222, 101, 26, 255,
221, 99, 25, 255,
220, 96, 24, 255,
219, 93, 23, 255,
218, 91, 22, 255,
217, 88, 21, 255,
216, 86, 20, 255,
215, 83, 19, 255,
214, 81, 18, 255,
213, 79, 17, 255,
212, 77, 17, 255,
211, 74, 16, 255,
210, 72, 15, 255,
209, 70, 14, 255,
207, 68, 13, 255,
206, 66, 13, 255,
205, 64, 12, 255,
204, 62, 11, 255,
203, 60, 10, 255,
202, 58, 10, 255,
201, 56, 9, 255,
199, 55, 9, 255,
198, 53, 8, 255,
197, 51, 7, 255,
196, 50, 7, 255,
195, 48, 6, 255,
193, 46, 6, 255,
192, 45, 5, 255,
191, 43, 5, 255,
190, 42, 4, 255,
188, 41, 4, 255,
187, 39, 3, 255,
186, 38, 3, 255,
185, 37, 2, 255,
183, 35, 2, 255,
182, 34, 1, 255,
181, 33, 1, 255,
179, 32, 1, 255,
178, 30, 0, 255,
177, 29, 0, 255,
175, 28, 0, 255,
174, 27, 0, 255,
173, 26, 0, 255,
171, 25, 0, 255,
170, 24, 0, 255,
168, 23, 0, 255,
167, 22, 0, 255,
165, 21, 0, 255,
164, 21, 0, 255,
163, 20, 0, 255,
161, 19, 0, 255,
160, 18, 0, 255,
158, 17, 0, 255,
156, 17, 0, 255,
155, 16, 0, 255,
153, 15, 0, 255,
152, 14, 0, 255,
150, 14, 0, 255,
149, 13, 0, 255,
147, 12, 0, 255,
145, 12, 0, 255,
144, 11, 0, 255,
142, 11, 0, 255,
140, 10, 0, 255,
139, 10, 0, 255,
137, 9, 0, 255,
135, 9, 0, 255,
134, 8, 0, 255,
132, 8, 0, 255,
130, 7, 0, 255,
128, 7, 0, 255,
126, 6, 0, 255,
125, 6, 0, 255,
123, 5, 0, 255,
121, 5, 0, 255,
119, 4, 0, 255,
117, 4, 0, 255,
115, 4, 0, 255,
113, 3, 0, 255,
111, 3, 0, 255,
109, 2, 0, 255,
107, 2, 0, 255,
105, 2, 0, 255,
103, 1, 0, 255,
101, 1, 0, 255,
99, 1, 0, 255,
97, 0, 0, 255,
95, 0, 0, 255,
93, 0, 0, 255,
91, 0, 0, 255,
90, 0, 0, 255,
88, 0, 0, 255,
86, 0, 0, 255,
84, 0, 0, 255,
82, 0, 0, 255,
80, 0, 0, 255,
78, 0, 0, 255,
77, 0, 0, 255,
75, 0, 0, 255,
73, 0, 0, 255,
72, 0, 0, 255,
70, 0, 0, 255,
68, 0, 0, 255,
67, 0, 0, 255,
65, 0, 0, 255,
64, 0, 0, 255,
63, 0, 0, 255,
61, 0, 0, 255,
60, 0, 0, 255,
59, 0, 0, 255,
58, 0, 0, 255,
57, 0, 0, 255,
56, 0, 0, 255,
55, 0, 0, 255,
54, 0, 0, 255,
53, 0, 0, 255,
53, 0, 0, 255,
52, 0, 0, 255,
52, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
50, 0, 0, 255,
50, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
52, 0, 0, 255,
52, 0, 0, 255,
53, 0, 0, 255,
54, 1, 0, 255,
55, 2, 0, 255,
56, 3, 0, 255,
57, 4, 0, 255,
58, 5, 0, 255,
59, 6, 0, 255,
60, 7, 0, 255,
62, 8, 0, 255,
63, 9, 0, 255,
64, 11, 0, 255,
66, 12, 0, 255,
68, 13, 0, 255,
69, 14, 0, 255,
71, 16, 0, 255,
73, 17, 0, 255,
75, 18, 0, 255,
77, 20, 0, 255,
79, 21, 0, 255,
81, 23, 0, 255,
83, 24, 0, 255,
85, 26, 0, 255,
87, 28, 0, 255,
90, 29, 0, 255,
92, 31, 0, 255,
94, 33, 0, 255,
97, 34, 0, 255,
99, 36, 0, 255,
102, 38, 0, 255,
104, 40, 0, 255,
107, 41, 0, 255,
109, 43, 0, 255,
112, 45, 0, 255,
115, 47, 0, 255,
117, 49, 0, 255,
120, 51, 0, 255,
123, 52, 0, 255,
126, 54, 0, 255,
128, 56, 0, 255,
131, 58, 0, 255,
134, 60, 0, 255,
137, 62, 0, 255,
140, 64, 0, 255,
143, 66, 0, 255,
145, 68, 0, 255,
148, 70, 0, 255,
151, 72, 0, 255,
154, 74, 0, 255
};
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::rbox_ctrl<color_type> m_method;
agg::slider_ctrl<color_type> m_radius;
agg::polygon_ctrl<color_type> m_shadow_ctrl;
agg::path_storage m_path;
typedef agg::conv_curve<agg::path_storage> shape_type;
shape_type m_shape;
agg::rasterizer_scanline_aa<> m_ras;
agg::scanline_p8 m_sl;
agg::rect_d m_shape_bounds;
agg::pod_array<agg::int8u> m_gray8_buf;
agg::rendering_buffer m_gray8_rbuf;
agg::rendering_buffer m_gray8_rbuf2;
agg::pod_array<color_type> m_color_lut;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_method (10.0, 10.0, 130.0, 55.0, !flip_y),
m_radius (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y),
m_shadow_ctrl(4),
m_shape(m_path)
{
add_ctrl(m_method);
m_method.text_size(8);
m_method.add_item("Single Color");
m_method.add_item("Color LUT");
m_method.cur_item(1);
add_ctrl(m_radius);
m_radius.range(0.0, 40.0);
m_radius.value(15.0);
m_radius.label("Blur Radius=%1.2f");
add_ctrl(m_shadow_ctrl);
m_path.remove_all();
m_path.move_to(28.47, 6.45);
m_path.curve3(21.58, 1.12, 19.82, 0.29);
m_path.curve3(17.19, -0.93, 14.21, -0.93);
m_path.curve3(9.57, -0.93, 6.57, 2.25);
m_path.curve3(3.56, 5.42, 3.56, 10.60);
m_path.curve3(3.56, 13.87, 5.03, 16.26);
m_path.curve3(7.03, 19.58, 11.99, 22.51);
m_path.curve3(16.94, 25.44, 28.47, 29.64);
m_path.line_to(28.47, 31.40);
m_path.curve3(28.47, 38.09, 26.34, 40.58);
m_path.curve3(24.22, 43.07, 20.17, 43.07);
m_path.curve3(17.09, 43.07, 15.28, 41.41);
m_path.curve3(13.43, 39.75, 13.43, 37.60);
m_path.line_to(13.53, 34.77);
m_path.curve3(13.53, 32.52, 12.38, 31.30);
m_path.curve3(11.23, 30.08, 9.38, 30.08);
m_path.curve3(7.57, 30.08, 6.42, 31.35);
m_path.curve3(5.27, 32.62, 5.27, 34.81);
m_path.curve3(5.27, 39.01, 9.57, 42.53);
m_path.curve3(13.87, 46.04, 21.63, 46.04);
m_path.curve3(27.59, 46.04, 31.40, 44.04);
m_path.curve3(34.28, 42.53, 35.64, 39.31);
m_path.curve3(36.52, 37.21, 36.52, 30.71);
m_path.line_to(36.52, 15.53);
m_path.curve3(36.52, 9.13, 36.77, 7.69);
m_path.curve3(37.01, 6.25, 37.57, 5.76);
m_path.curve3(38.13, 5.27, 38.87, 5.27);
m_path.curve3(39.65, 5.27, 40.23, 5.62);
m_path.curve3(41.26, 6.25, 44.19, 9.18);
m_path.line_to(44.19, 6.45);
m_path.curve3(38.72, -0.88, 33.74, -0.88);
m_path.curve3(31.35, -0.88, 29.93, 0.78);
m_path.curve3(28.52, 2.44, 28.47, 6.45);
m_path.close_polygon();
m_path.move_to(28.47, 9.62);
m_path.line_to(28.47, 26.66);
m_path.curve3(21.09, 23.73, 18.95, 22.51);
m_path.curve3(15.09, 20.36, 13.43, 18.02);
m_path.curve3(11.77, 15.67, 11.77, 12.89);
m_path.curve3(11.77, 9.38, 13.87, 7.06);
m_path.curve3(15.97, 4.74, 18.70, 4.74);
m_path.curve3(22.41, 4.74, 28.47, 9.62);
m_path.close_polygon();
agg::trans_affine shape_mtx;
shape_mtx *= agg::trans_affine_scaling(4.0);
shape_mtx *= agg::trans_affine_translation(150, 100);
m_path.transform(shape_mtx);
agg::bounding_rect_single(m_shape, 0,
&m_shape_bounds.x1, &m_shape_bounds.y1,
&m_shape_bounds.x2, &m_shape_bounds.y2);
m_shadow_ctrl.xn(0) = m_shape_bounds.x1;
m_shadow_ctrl.yn(0) = m_shape_bounds.y1;
m_shadow_ctrl.xn(1) = m_shape_bounds.x2;
m_shadow_ctrl.yn(1) = m_shape_bounds.y1;
m_shadow_ctrl.xn(2) = m_shape_bounds.x2;
m_shadow_ctrl.yn(2) = m_shape_bounds.y2;
m_shadow_ctrl.xn(3) = m_shape_bounds.x1;
m_shadow_ctrl.yn(3) = m_shape_bounds.y2;
m_shadow_ctrl.line_color(agg::rgba(0, 0.3, 0.5, 0.3));
m_color_lut.resize(256);
unsigned i;
const agg::int8u* p = g_gradient_colors;
for(i = 0; i < 256; i++)
{
m_color_lut[i] = agg::srgba8(p[0], p[1], p[2], (i > 63) ? 255 : i * 4);//p[3]);
//m_color_lut[i].premultiply();
p += 4;
}
}
virtual void on_resize(int sx, int sy)
{
m_gray8_buf.resize(sx * sy);
m_gray8_rbuf.attach(m_gray8_buf.data(), sx, sy, sx);
}
virtual void on_draw()
{
typedef agg::pixfmt_sgray8 pixfmt_gray8;
typedef agg::renderer_base<pixfmt_gray8> ren_base_gray8;
m_ras.clip_box(0,0, width(), height());
pixfmt_gray8 pixf_gray8(m_gray8_rbuf);
ren_base_gray8 renb_gray8(pixf_gray8);
renb_gray8.clear(agg::sgray8(0));
// Testing enhanced compositing operations.
// Uncomment and replace renb.blend_from_* to renb_blend.blend_from_*
//----------------
//typedef agg::comp_op_rgba_minus<color_type, component_order> blender_type;
//typedef agg::comp_adaptor_rgba<blender_type> blend_adaptor_type;
//typedef agg::pixfmt_custom_blend_rgba<blend_adaptor_type, agg::rendering_buffer> pixfmt_type;
//typedef agg::renderer_base<pixfmt_type> ren_base;
//pixfmt_type pixf_blend(rbuf_window());
//agg::renderer_base<pixfmt_type> renb_blend(pixf_blend);
pixfmt pixf(rbuf_window());
agg::renderer_base<pixfmt> renb(pixf);
renb.clear(agg::rgba(1, 0.95, 0.95));
agg::trans_perspective shadow_persp(m_shape_bounds.x1, m_shape_bounds.y1,
m_shape_bounds.x2, m_shape_bounds.y2,
m_shadow_ctrl.polygon());
agg::conv_transform<shape_type,
agg::trans_perspective> shadow_trans(m_shape,
shadow_persp);
start_timer();
// Render shadow
m_ras.add_path(shadow_trans);
agg::render_scanlines_aa_solid(m_ras, m_sl, renb_gray8, agg::sgray8(255));
// Calculate the bounding box and extend it by the blur radius
agg::rect_d bbox;
agg::bounding_rect_single(shadow_trans, 0, &bbox.x1, &bbox.y1, &bbox.x2, &bbox.y2);
bbox.x1 -= m_radius.value();
bbox.y1 -= m_radius.value();
bbox.x2 += m_radius.value();
bbox.y2 += m_radius.value();
if(bbox.clip(agg::rect_d(0, 0, width(), height())))
{
// Create a new pixel renderer and attach it to the main one as a child image.
// It returns true if the attachment suceeded. It fails if the rectangle
// (bbox) is fully clipped.
//------------------
pixfmt_gray8 pixf2(m_gray8_rbuf2);
if(pixf2.attach(pixf_gray8, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)))
{
// Blur it
agg::stack_blur_gray8(pixf2, agg::uround(m_radius.value()),
agg::uround(m_radius.value()));
}
if(m_method.cur_item() == 0)
{
renb.blend_from_color(pixf2,
agg::srgba8(0, 100, 0),
0,
int(bbox.x1),
int(bbox.y1));
}
else
{
renb.blend_from_lut(pixf2,
m_color_lut.data(),
0,
int(bbox.x1),
int(bbox.y1));
}
}
double tm = elapsed_time();
char buf[64];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> st(t);
st.width(1.5);
sprintf(buf, "%3.2f ms", tm);
t.start_point(140.0, 30.0);
t.text(buf);
m_ras.add_path(st);
agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0,0,0));
agg::render_ctrl(m_ras, m_sl, renb, m_method);
agg::render_ctrl(m_ras, m_sl, renb, m_radius);
agg::render_ctrl(m_ras, m_sl, renb, m_shadow_ctrl);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Gaussian and Stack Blur");
if(app.init(440, 330, 0))
{
return app.run();
}
return 1;
}

327
examples/blur.cpp Normal file
View File

@ -0,0 +1,327 @@
#include <math.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_curve.h"
#include "agg_conv_contour.h"
#include "agg_conv_stroke.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "agg_pixfmt_rgba.h"
#include "agg_pixfmt_gray.h"
#include "agg_bounding_rect.h"
#include "agg_trans_perspective.h"
#include "agg_blur.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_polygon_ctrl.h"
#include "platform/agg_platform_support.h"
// Stack blur is limited to integer pixel formats, so we
// can't use it for floating-point formats.
#define USE_STACK_BLUR 1
#define AGG_BGR24
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::rbox_ctrl<color_type> m_method;
agg::slider_ctrl<color_type> m_radius;
agg::polygon_ctrl<color_type> m_shadow_ctrl;
agg::cbox_ctrl<color_type> m_channel_r;
agg::cbox_ctrl<color_type> m_channel_g;
agg::cbox_ctrl<color_type> m_channel_b;
agg::path_storage m_path;
typedef agg::conv_curve<agg::path_storage> shape_type;
shape_type m_shape;
agg::rasterizer_scanline_aa<> m_ras;
agg::scanline_p8 m_sl;
agg::rendering_buffer m_rbuf2;
agg::stack_blur <color_type, agg::stack_blur_calc_rgb<> > m_stack_blur;
agg::recursive_blur<color_type, agg::recursive_blur_calc_rgb<> > m_recursive_blur;
agg::rect_d m_shape_bounds;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_method (10.0, 10.0, 130.0, 70.0, !flip_y),
m_radius (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y),
m_shadow_ctrl(4),
m_channel_r (10.0, 80.0, "Red", !flip_y),
m_channel_g (10.0, 95.0, "Green", !flip_y),
m_channel_b (10.0, 110.0, "Blue", !flip_y),
m_shape(m_path)
{
add_ctrl(m_method);
m_method.text_size(8);
#if USE_STACK_BLUR
m_method.add_item("Stack blur");
#else
m_method.add_item("No blur");
#endif
m_method.add_item("Recursive blur");
m_method.add_item("Channels");
m_method.cur_item(0);
add_ctrl(m_radius);
m_radius.range(0.0, 40.0);
m_radius.value(15.0);
m_radius.label("Blur Radius=%1.2f");
add_ctrl(m_shadow_ctrl);
add_ctrl(m_channel_r);
add_ctrl(m_channel_g);
add_ctrl(m_channel_b);
m_channel_g.status(true);
m_path.remove_all();
m_path.move_to(28.47, 6.45);
m_path.curve3(21.58, 1.12, 19.82, 0.29);
m_path.curve3(17.19, -0.93, 14.21, -0.93);
m_path.curve3(9.57, -0.93, 6.57, 2.25);
m_path.curve3(3.56, 5.42, 3.56, 10.60);
m_path.curve3(3.56, 13.87, 5.03, 16.26);
m_path.curve3(7.03, 19.58, 11.99, 22.51);
m_path.curve3(16.94, 25.44, 28.47, 29.64);
m_path.line_to(28.47, 31.40);
m_path.curve3(28.47, 38.09, 26.34, 40.58);
m_path.curve3(24.22, 43.07, 20.17, 43.07);
m_path.curve3(17.09, 43.07, 15.28, 41.41);
m_path.curve3(13.43, 39.75, 13.43, 37.60);
m_path.line_to(13.53, 34.77);
m_path.curve3(13.53, 32.52, 12.38, 31.30);
m_path.curve3(11.23, 30.08, 9.38, 30.08);
m_path.curve3(7.57, 30.08, 6.42, 31.35);
m_path.curve3(5.27, 32.62, 5.27, 34.81);
m_path.curve3(5.27, 39.01, 9.57, 42.53);
m_path.curve3(13.87, 46.04, 21.63, 46.04);
m_path.curve3(27.59, 46.04, 31.40, 44.04);
m_path.curve3(34.28, 42.53, 35.64, 39.31);
m_path.curve3(36.52, 37.21, 36.52, 30.71);
m_path.line_to(36.52, 15.53);
m_path.curve3(36.52, 9.13, 36.77, 7.69);
m_path.curve3(37.01, 6.25, 37.57, 5.76);
m_path.curve3(38.13, 5.27, 38.87, 5.27);
m_path.curve3(39.65, 5.27, 40.23, 5.62);
m_path.curve3(41.26, 6.25, 44.19, 9.18);
m_path.line_to(44.19, 6.45);
m_path.curve3(38.72, -0.88, 33.74, -0.88);
m_path.curve3(31.35, -0.88, 29.93, 0.78);
m_path.curve3(28.52, 2.44, 28.47, 6.45);
m_path.close_polygon();
m_path.move_to(28.47, 9.62);
m_path.line_to(28.47, 26.66);
m_path.curve3(21.09, 23.73, 18.95, 22.51);
m_path.curve3(15.09, 20.36, 13.43, 18.02);
m_path.curve3(11.77, 15.67, 11.77, 12.89);
m_path.curve3(11.77, 9.38, 13.87, 7.06);
m_path.curve3(15.97, 4.74, 18.70, 4.74);
m_path.curve3(22.41, 4.74, 28.47, 9.62);
m_path.close_polygon();
agg::trans_affine shape_mtx;
shape_mtx *= agg::trans_affine_scaling(4.0);
shape_mtx *= agg::trans_affine_translation(150, 100);
m_path.transform(shape_mtx);
agg::bounding_rect_single(m_shape, 0,
&m_shape_bounds.x1, &m_shape_bounds.y1,
&m_shape_bounds.x2, &m_shape_bounds.y2);
m_shadow_ctrl.xn(0) = m_shape_bounds.x1 + 10;
m_shadow_ctrl.yn(0) = m_shape_bounds.y1 - 10;
m_shadow_ctrl.xn(1) = m_shape_bounds.x2 + 10;
m_shadow_ctrl.yn(1) = m_shape_bounds.y1 - 10;
m_shadow_ctrl.xn(2) = m_shape_bounds.x2 + 10;
m_shadow_ctrl.yn(2) = m_shape_bounds.y2 - 10;
m_shadow_ctrl.xn(3) = m_shape_bounds.x1 + 10;
m_shadow_ctrl.yn(3) = m_shape_bounds.y2 - 10;
m_shadow_ctrl.line_color(agg::rgba(0, 0.3, 0.5, 0.3));
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base renb(pixf);
renb.clear(agg::rgba(1, 1, 1));
m_ras.clip_box(0,0, width(), height());
agg::trans_perspective shadow_persp(m_shape_bounds.x1, m_shape_bounds.y1,
m_shape_bounds.x2, m_shape_bounds.y2,
m_shadow_ctrl.polygon());
agg::conv_transform<shape_type,
agg::trans_perspective> shadow_trans(m_shape,
shadow_persp);
// Render shadow
m_ras.add_path(shadow_trans);
agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0.1, 0.1, 0.1));
// Calculate the bounding box and extend it by the blur radius
agg::rect_d bbox;
agg::bounding_rect_single(shadow_trans, 0, &bbox.x1, &bbox.y1, &bbox.x2, &bbox.y2);
bbox.x1 -= m_radius.value();
bbox.y1 -= m_radius.value();
bbox.x2 += m_radius.value();
bbox.y2 += m_radius.value();
// The recursive blur method represents the true Gussian Blur,
// with theoretically infinite kernel. The restricted window size
// results in extra influence of edge pixels. It's impossible to
// solve correctly, but extending the right and top areas to another
// radius value produces fair result.
//------------------
bbox.x2 += m_radius.value();
bbox.y2 += m_radius.value();
start_timer();
if(m_method.cur_item() != 2)
{
// Create a new pixel renderer and attach it to the main one as a child image.
// It returns true if the attachment suceeded. It fails if the rectangle
// (bbox) is fully clipped.
//------------------
pixfmt pixf2(m_rbuf2);
if(pixf2.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)))
{
// Blur it
if(m_method.cur_item() == 0)
{
#if USE_STACK_BLUR
// More general method, but 30-40% slower.
//------------------
m_stack_blur.blur(pixf2, agg::uround(m_radius.value()));
// Faster, but bore specific.
// Works only for 8 bits per channel and only with radii <= 254.
//------------------
//agg::stack_blur_rgb24(pixf2, agg::uround(m_radius.value()),
// agg::uround(m_radius.value()));
#endif
}
else
{
// True Gaussian Blur, 3-5 times slower than Stack Blur,
// but still constant time of radius. Very sensitive
// to precision, doubles are must here.
//------------------
m_recursive_blur.blur(pixf2, m_radius.value());
}
}
}
else
{
typedef agg::pixfmt_alpha_blend_gray<
agg::blender_gray<gray_type>,
agg::rendering_buffer,
3, component_order::R> pixfmt_r;
typedef agg::pixfmt_alpha_blend_gray<
agg::blender_gray<gray_type>,
agg::rendering_buffer,
3, component_order::G> pixfmt_g;
typedef agg::pixfmt_alpha_blend_gray<
agg::blender_gray<gray_type>,
agg::rendering_buffer,
3, component_order::B> pixfmt_b;
pixfmt_r pixf2r(m_rbuf2);
pixfmt_g pixf2g(m_rbuf2);
pixfmt_b pixf2b(m_rbuf2);
agg::recursive_blur<gray_type, agg::recursive_blur_calc_gray<> > blurrer;
// Blur separate channels
//------------------
if(m_channel_r.status())
{
if(pixf2r.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)))
{
blurrer.blur(pixf2r, agg::uround(m_radius.value()));
}
}
if(m_channel_g.status())
{
if(pixf2g.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)))
{
blurrer.blur(pixf2g, agg::uround(m_radius.value()));
}
}
if(m_channel_b.status())
{
if(pixf2b.attach(pixf, int(bbox.x1), int(bbox.y1), int(bbox.x2), int(bbox.y2)))
{
blurrer.blur(pixf2b, agg::uround(m_radius.value()));
}
}
}
double tm = elapsed_time();
agg::render_ctrl(m_ras, m_sl, renb, m_shadow_ctrl);
// Render the shape itself
//------------------
m_ras.add_path(m_shape);
agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0.6, 0.9, 0.7, 0.8));
char buf[64];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> st(t);
st.width(1.5);
sprintf(buf, "%3.2f ms", tm);
t.start_point(140.0, 30.0);
t.text(buf);
m_ras.add_path(st);
agg::render_scanlines_aa_solid(m_ras, m_sl, renb, agg::rgba(0,0,0));
agg::render_ctrl(m_ras, m_sl, renb, m_method);
agg::render_ctrl(m_ras, m_sl, renb, m_radius);
agg::render_ctrl(m_ras, m_sl, renb, m_channel_r);
agg::render_ctrl(m_ras, m_sl, renb, m_channel_g);
agg::render_ctrl(m_ras, m_sl, renb, m_channel_b);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Gaussian and Stack Blur");
if(app.init(440, 330, 0))
{
return app.run();
}
return 1;
}

207
examples/bspline.cpp Normal file
View File

@ -0,0 +1,207 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_conv_bspline.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
#include "interactive_polygon.h"
#define AGG_BGR24
//#define AGG_BGR96
//#define AGG_RGB24
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
public:
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::scanline_p8 scanline_type;
agg::interactive_polygon m_poly;
agg::slider_ctrl<color_type> m_num_points;
agg::cbox_ctrl<color_type> m_close;
int m_flip;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_poly(6, 5.0),
m_num_points(5.0, 5.0, 340.0, 12.0, !flip_y),
m_close (350, 5.0, "Close", !flip_y),
m_flip(0)
{
add_ctrl(m_close);
m_num_points.range(1.0, 40.0);
m_num_points.value(20.0);
m_num_points.label("Number of intermediate Points = %.3f");
add_ctrl(m_num_points);
}
virtual void on_init()
{
if(m_flip)
{
m_poly.xn(0) = 100;
m_poly.yn(0) = height() - 100;
m_poly.xn(1) = width() - 100;
m_poly.yn(1) = height() - 100;
m_poly.xn(2) = width() - 100;
m_poly.yn(2) = 100;
m_poly.xn(3) = 100;
m_poly.yn(3) = 100;
}
else
{
m_poly.xn(0) = 100;
m_poly.yn(0) = 100;
m_poly.xn(1) = width() - 100;
m_poly.yn(1) = 100;
m_poly.xn(2) = width() - 100;
m_poly.yn(2) = height() - 100;
m_poly.xn(3) = 100;
m_poly.yn(3) = height() - 100;
}
m_poly.xn(4) = width() / 2;
m_poly.yn(4) = height() / 2;
m_poly.xn(5) = width() / 2;
m_poly.yn(5) = height() / 3;
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
rb.clear(agg::rgba(1, 1, 1));
scanline_type sl;
agg::rasterizer_scanline_aa<> ras;
agg::simple_polygon_vertex_source path(m_poly.polygon(),
m_poly.num_points(),
false,
m_close.status());
typedef agg::conv_bspline<agg::simple_polygon_vertex_source> conv_bspline_type;
conv_bspline_type bspline(path);
bspline.interpolation_step(1.0 / m_num_points.value());
typedef agg::conv_stroke<conv_bspline_type> conv_stroke_type;
conv_stroke_type stroke(bspline);
stroke.width(2.0);
ras.add_path(stroke);
agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba(0, 0, 0));
//--------------------------
// Render the "poly" tool and controls
ras.add_path(m_poly);
agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba(0, 0.3, 0.5, 0.6));
agg::render_ctrl(ras, sl, rb, m_close);
agg::render_ctrl(ras, sl, rb, m_num_points);
//--------------------------
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_poly.on_mouse_button_down(x, y))
{
force_redraw();
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_poly.on_mouse_move(x, y))
{
force_redraw();
}
}
if((flags & agg::mouse_left) == 0)
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
if(m_poly.on_mouse_button_up(x, y))
{
force_redraw();
}
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
m_flip ^= 1;
on_init();
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. BSpline Interpolator");
if(app.init(600, 600, agg::window_resize))
{
return app.run();
}
return 1;
}

268
examples/circles.cpp Normal file
View File

@ -0,0 +1,268 @@
#include <stdio.h>
#include <stdlib.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_transform.h"
#include "agg_bspline.h"
#include "agg_ellipse.h"
#include "agg_gsv_text.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_scale_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGR96
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
enum default_num_points_e { default_num_points = 10000 };
enum start_size_e
{
start_width = 400,
start_height = 400
};
static double spline_r_x[] = { 0.000000, 0.200000, 0.400000, 0.910484, 0.957258, 1.000000 };
static double spline_r_y[] = { 1.000000, 0.800000, 0.600000, 0.066667, 0.169697, 0.600000 };
static double spline_g_x[] = { 0.000000, 0.292244, 0.485655, 0.564859, 0.795607, 1.000000 };
static double spline_g_y[] = { 0.000000, 0.607260, 0.964065, 0.892558, 0.435571, 0.000000 };
static double spline_b_x[] = { 0.000000, 0.055045, 0.143034, 0.433082, 0.764859, 1.000000 };
static double spline_b_y[] = { 0.385480, 0.128493, 0.021416, 0.271507, 0.713974, 1.000000 };
struct scatter_point
{
double x;
double y;
double z;
agg::rgba color;
};
double random_dbl(double start, double end)
{
unsigned r = rand() & 0x7FFF;
return double(r) * (end - start) / 32768.0 + start;
}
class the_application : public agg::platform_support
{
unsigned m_num_points;
scatter_point* m_points;
agg::scale_ctrl<color_type> m_scale_ctrl_z;
agg::slider_ctrl<color_type> m_slider_ctrl_sel;
agg::slider_ctrl<color_type> m_slider_ctrl_size;
agg::bspline m_spline_r;
agg::bspline m_spline_g;
agg::bspline m_spline_b;
public:
virtual ~the_application()
{
delete [] m_points;
}
the_application(agg::pix_format_e format, bool flip_y, unsigned num_points) :
agg::platform_support(format, flip_y),
m_num_points(num_points),
m_points(new scatter_point [num_points]),
m_scale_ctrl_z (5, 5, start_width-5, 12, !flip_y),
m_slider_ctrl_sel (5, 20, start_width-5, 27, !flip_y),
m_slider_ctrl_size(5, 35, start_width-5, 42, !flip_y)
{
m_spline_r.init(6, spline_r_x, spline_r_y);
m_spline_g.init(6, spline_g_x, spline_g_y);
m_spline_b.init(6, spline_b_x, spline_b_y);
add_ctrl(m_scale_ctrl_z);
add_ctrl(m_slider_ctrl_sel);
add_ctrl(m_slider_ctrl_size);
m_slider_ctrl_size.label("Size");
m_slider_ctrl_sel.label("Selectivity");
}
void generate()
{
unsigned i;
double rx = initial_width()/3.5;
double ry = initial_height()/3.5;
for(i = 0; i < m_num_points; i++)
{
double z = m_points[i].z = random_dbl(0.0, 1.0);
double x = cos(z * 2.0 * agg::pi) * rx;
double y = sin(z * 2.0 * agg::pi) * ry;
double dist = random_dbl(0.0, rx/2.0);
double angle = random_dbl(0.0, agg::pi * 2.0);
m_points[i].x = initial_width()/2.0 + x + cos(angle) * dist;
m_points[i].y = initial_height()/2.0 + y + sin(angle) * dist;
m_points[i].color = agg::rgba(m_spline_r.get(z)*0.8,
m_spline_g.get(z)*0.8,
m_spline_b.get(z)*0.8,
1.0);
}
}
virtual void on_init()
{
generate();
}
virtual void on_draw()
{
agg::rasterizer_scanline_aa<> pf;
agg::scanline_p8 sl;
typedef agg::renderer_base<pixfmt> renderer_base;
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
rb.clear(agg::rgba(1,1,1));
agg::ellipse e1;
agg::conv_transform<agg::ellipse> t1(e1, trans_affine_resizing());
unsigned i;
unsigned n_drawn = 0;
for(i = 0; i < m_num_points; i++)
{
double z = m_points[i].z;
double alpha = 1.0;
if(z < m_scale_ctrl_z.value1())
{
alpha =
1.0 -
(m_scale_ctrl_z.value1() - z) *
m_slider_ctrl_sel.value() * 100.0;
}
if(z > m_scale_ctrl_z.value2())
{
alpha =
1.0 -
(z - m_scale_ctrl_z.value2()) *
m_slider_ctrl_sel.value() * 100.0;
}
if(alpha > 1.0) alpha = 1.0;
if(alpha < 0.0) alpha = 0.0;
if(alpha > 0.0)
{
e1.init(m_points[i].x,
m_points[i].y,
m_slider_ctrl_size.value() * 5.0,
m_slider_ctrl_size.value() * 5.0,
8);
pf.add_path(t1);
agg::render_scanlines_aa_solid(
pf, sl, rb,
agg::rgba(m_points[i].color.r,
m_points[i].color.g,
m_points[i].color.b,
alpha));
n_drawn++;
}
}
agg::render_ctrl(pf, sl, rb, m_scale_ctrl_z);
agg::render_ctrl(pf, sl, rb, m_slider_ctrl_sel);
agg::render_ctrl(pf, sl, rb, m_slider_ctrl_size);
char buf[10];
sprintf(buf, "%08u", n_drawn);
agg::gsv_text txt;
txt.size(15.0);
txt.text(buf);
txt.start_point(10.0, initial_height() - 20.0);
agg::gsv_text_outline<> txt_o(txt, trans_affine_resizing());
pf.add_path(txt_o);
agg::render_scanlines_aa_solid(pf, sl, rb, agg::rgba(0,0,0));
}
virtual void on_idle()
{
unsigned i;
for(i = 0; i < m_num_points; i++)
{
m_points[i].x += random_dbl(0, m_slider_ctrl_sel.value()) - m_slider_ctrl_sel.value()*0.5;
m_points[i].y += random_dbl(0, m_slider_ctrl_sel.value()) - m_slider_ctrl_sel.value()*0.5;
m_points[i].z += random_dbl(0, m_slider_ctrl_sel.value()*0.01) - m_slider_ctrl_sel.value()*0.005;
if(m_points[i].z < 0.0) m_points[i].z = 0.0;
if(m_points[i].z > 1.0) m_points[i].z = 1.0;
}
force_redraw();
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
generate();
force_redraw();
}
if(flags & agg::mouse_right)
{
wait_mode(!wait_mode());
}
}
};
int agg_main(int argc, char* argv[])
{
unsigned num_points = default_num_points;
if(argc > 1)
{
num_points = atoi(argv[1]);
if(num_points == 0) num_points = default_num_points;
if(num_points > 20000) num_points = 20000;
}
the_application app(pix_format, flip_y, num_points);
app.caption("AGG Drawing random circles - A scatter plot prototype");
if(app.init(start_width, start_height, agg::window_resize | agg::window_keep_aspect_ratio))
{
return app.run();
}
return 1;
}

View File

@ -0,0 +1,93 @@
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_ellipse.h"
#include "agg_pixfmt_gray.h"
#include "agg_pixfmt_rgb.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_BGR48
//#define AGG_BGR96
#include "pixel_formats.h"
typedef agg::blender_gray<gray_type> gray_blender;
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_alpha;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_alpha(5, 5, 320-5, 10+5, !flip_y)
{
m_alpha.label("Alpha=%1.0f");
m_alpha.range(0, 255);
m_alpha.value(255);
add_ctrl(m_alpha);
}
virtual void on_draw()
{
pixfmt pf(rbuf_window());
typedef agg::pixfmt_alpha_blend_gray<gray_blender, agg::rendering_buffer, 3, 2> pixfmt_r;
typedef agg::pixfmt_alpha_blend_gray<gray_blender, agg::rendering_buffer, 3, 1> pixfmt_g;
typedef agg::pixfmt_alpha_blend_gray<gray_blender, agg::rendering_buffer, 3, 0> pixfmt_b;
pixfmt_r pfr(rbuf_window());
pixfmt_g pfg(rbuf_window());
pixfmt_b pfb(rbuf_window());
agg::renderer_base<pixfmt> rbase(pf);
agg::renderer_base<pixfmt_r> rbr(pfr);
agg::renderer_base<pixfmt_g> rbg(pfg);
agg::renderer_base<pixfmt_b> rbb(pfb);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
rbase.clear(agg::rgba(1,1,1));
agg::ellipse er(width() / 2 - 0.87*50, height() / 2 - 0.5*50, 100, 100, 100);
ras.add_path(er);
agg::render_scanlines_aa_solid(ras, sl, rbr,
gray_type(0, unsigned(m_alpha.value())));
agg::ellipse eg(width() / 2 + 0.87*50, height() / 2 - 0.5*50, 100, 100, 100);
ras.add_path(eg);
agg::render_scanlines_aa_solid(ras, sl, rbg,
gray_type(0, unsigned(m_alpha.value())));
agg::ellipse eb(width() / 2, height() / 2 + 50, 100, 100, 100);
ras.add_path(eb);
agg::render_scanlines_aa_solid(ras, sl, rbb,
gray_type(0, unsigned(m_alpha.value())));
agg::render_ctrl(ras, sl, rbase, m_alpha);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Component Rendering");
if(app.init(320, 320, 0))
{
return app.run();
}
return 1;
}

374
examples/compositing.cpp Normal file
View File

@ -0,0 +1,374 @@
#include <stdio.h>
#include <cassert>
#include "agg_rendering_buffer.h"
#include "agg_renderer_base.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_rounded_rect.h"
#include "agg_pixfmt_rgba.h"
#include "agg_span_allocator.h"
#include "agg_span_gradient.h"
#include "agg_gsv_text.h"
#include "agg_span_interpolator_linear.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
//#define AGG_BGRA32
#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
typedef color_type color;
typedef component_order order;
typedef agg::rendering_buffer rbuf_type;
typedef agg::blender_rgba<color, order> prim_blender_type;
typedef agg::pixfmt_alpha_blend_rgba<prim_blender_type, rbuf_type> prim_pixfmt_type;
typedef agg::renderer_base<prim_pixfmt_type> prim_ren_base_type;
void force_comp_op_link()
{
// For unknown reason Digital Mars C++ doesn't want to link these
// functions if they are not specified explicitly.
color_type::value_type p[4] = {0};
//agg::comp_op_rgba_invert_rgb <color, order>::blend_pix(p,0,0,0,0,0);
//agg::comp_op_rgba_invert <color, order>::blend_pix(p,0,0,0,0,0);
//agg::comp_op_rgba_contrast <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_darken <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_lighten <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_color_dodge<color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_color_burn <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_hard_light <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_soft_light <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_difference <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_exclusion <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_atop <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_atop <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_xor <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_plus <color, order>::blend_pix(p,0,0,0,0,0);
//agg::comp_op_rgba_minus <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_multiply <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_screen <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_overlay <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_over <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_over <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_in <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_in <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_out <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_out <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_clear <color, order>::blend_pix(p,0,0,0,0,0);
}
agg::trans_affine gradient_affine(double x1, double y1, double x2, double y2,
double gradient_d2 = 100.0)
{
agg::trans_affine mtx;
double dx = x2 - x1;
double dy = y2 - y1;
mtx.reset();
mtx *= agg::trans_affine_scaling(sqrt(dx * dx + dy * dy) / gradient_d2);
mtx *= agg::trans_affine_rotation(atan2(dy, dx));
mtx *= agg::trans_affine_translation(x1, y1);
mtx.invert();
return mtx;
}
template<class RenBase>
void circle(RenBase& rbase, color c1, color c2,
double x1, double y1, double x2, double y2,
double shadow_alpha)
{
typedef RenBase renderer_base_type;
typedef agg::gradient_x gradient_func_type;
typedef agg::gradient_linear_color<color> color_func_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_allocator<color> span_allocator_type;
typedef agg::span_gradient<color,
interpolator_type,
gradient_func_type,
color_func_type> span_gradient_type;
gradient_func_type gradient_func; // The gradient function
agg::trans_affine gradient_mtx = gradient_affine(x1, y1, x2, y2, 100);
interpolator_type span_interpolator(gradient_mtx); // Span interpolator
span_allocator_type span_allocator; // Span Allocator
color_func_type color_func(c1, c2);
span_gradient_type span_gradient(span_interpolator,
gradient_func,
color_func,
0, 100);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
double r = agg::calc_distance(x1, y1, x2, y2) / 2;
agg::ellipse ell((x1+x2)/2+5, (y1+y2)/2-3, r, r, 100);
ras.add_path(ell);
agg::render_scanlines_aa_solid(ras, sl, rbase,
agg::rgba(0.6, 0.6, 0.6, 0.7*shadow_alpha));
ell.init((x1+x2)/2, (y1+y2)/2, r, r, 100);
ras.add_path(ell);
agg::render_scanlines_aa(ras, sl, rbase, span_allocator, span_gradient);
}
template<class RenBase>
void src_shape(RenBase& rbase, color c1, color c2,
double x1, double y1, double x2, double y2)
{
typedef RenBase renderer_base_type;
typedef agg::gradient_x gradient_func_type;
typedef agg::gradient_linear_color<color> color_func_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_allocator<color> span_allocator_type;
typedef agg::span_gradient<color,
interpolator_type,
gradient_func_type,
color_func_type> span_gradient_type;
gradient_func_type gradient_func; // The gradient function
agg::trans_affine gradient_mtx = gradient_affine(x1, y1, x2, y2, 100);
interpolator_type span_interpolator(gradient_mtx); // Span interpolator
span_allocator_type span_allocator; // Span Allocator
color_func_type color_func(c1, c2);
span_gradient_type span_gradient(span_interpolator,
gradient_func,
color_func,
0, 100);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::rounded_rect shape(x1, y1, x2, y2, 40);
// agg::ellipse shape((x1+x2)/2, (y1+y2)/2, fabs(x2-x1)/2, fabs(y2-y1)/2, 100);
ras.add_path(shape);
agg::render_scanlines_aa(ras, sl, rbase, span_allocator, span_gradient);
}
class the_application : public agg::platform_support
{
agg::slider_ctrl<color> m_alpha_src;
agg::slider_ctrl<color> m_alpha_dst;
agg::rbox_ctrl<color_type> m_comp_op;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_alpha_src(5, 5, 400, 11, !flip_y),
m_alpha_dst(5, 5+15, 400, 11+15, !flip_y),
m_comp_op(420, 5.0, 420+170.0, 340.0, !flip_y)
{
m_alpha_src.label("Src Alpha=%.2f");
m_alpha_src.value(0.75);
add_ctrl(m_alpha_src);
m_alpha_dst.label("Dst Alpha=%.2f");
m_alpha_dst.value(1.0);
add_ctrl(m_alpha_dst);
m_comp_op.text_size(6.8);
m_comp_op.add_item("clear");
m_comp_op.add_item("src");
m_comp_op.add_item("dst");
m_comp_op.add_item("src-over");
m_comp_op.add_item("dst-over");
m_comp_op.add_item("src-in");
m_comp_op.add_item("dst-in");
m_comp_op.add_item("src-out");
m_comp_op.add_item("dst-out");
m_comp_op.add_item("src-atop");
m_comp_op.add_item("dst-atop");
m_comp_op.add_item("xor");
m_comp_op.add_item("plus");
//m_comp_op.add_item("minus");
m_comp_op.add_item("multiply");
m_comp_op.add_item("screen");
m_comp_op.add_item("overlay");
m_comp_op.add_item("darken");
m_comp_op.add_item("lighten");
m_comp_op.add_item("color-dodge");
m_comp_op.add_item("color-burn");
m_comp_op.add_item("hard-light");
m_comp_op.add_item("soft-light");
m_comp_op.add_item("difference");
m_comp_op.add_item("exclusion");
//m_comp_op.add_item("contrast");
//m_comp_op.add_item("invert");
//m_comp_op.add_item("invert-rgb");
m_comp_op.cur_item(3);
add_ctrl(m_comp_op);
}
virtual ~the_application()
{
}
virtual void on_init()
{
}
void render_scene(rbuf_type& rbuf, prim_pixfmt_type& pixf)
{
typedef agg::comp_op_adaptor_rgba<color, order> blender_type;
typedef agg::pixfmt_custom_blend_rgba<blender_type, rbuf_type> pixfmt_type;
typedef agg::renderer_base<pixfmt_type> renderer_type;
pixfmt_type ren_pixf(rbuf);
renderer_type renderer(ren_pixf);
agg::renderer_base<prim_pixfmt_type> rb(pixf);
rb.blend_from(prim_pixfmt_type(rbuf_img(1)),
0, 250, 180,
agg::cover_type(m_alpha_dst.value() * agg::cover_full));
circle(rb,
agg::srgba8(0xFD, 0xF0, 0x6F, unsigned(m_alpha_dst.value() * 255)),
agg::srgba8(0xFE, 0x9F, 0x34, unsigned(m_alpha_dst.value() * 255)),
70*3, 100+24*3, 37*3, 100+79*3,
m_alpha_dst.value());
ren_pixf.comp_op(m_comp_op.cur_item());
src_shape(renderer,
agg::srgba8(0x7F, 0xC1, 0xFF, unsigned(m_alpha_src.value() * 255)),
agg::srgba8(0x05, 0x00, 0x5F, unsigned(m_alpha_src.value() * 255)),
300+50, 100+24*3, 107+50, 100+79*3);
/*
src_shape(renderer,
agg::srgba8(0xFF, 0xFF, 0xFF, unsigned(m_alpha_src.value() * 255)),
agg::srgba8(0xFF, 0xFF, 0xFF, unsigned(m_alpha_src.value() * 255)),
300+50, 100+24*3, 107+50, 100+79*3);
*/
}
virtual void on_draw()
{
prim_pixfmt_type pixf(rbuf_window());
prim_ren_base_type rb(pixf);
rb.clear(agg::srgba8(255, 255, 255));
unsigned y;
for(y = 0; y < rb.height(); y += 8)
{
unsigned x;
for(x = ((y >> 3) & 1) << 3; x < rb.width(); x += 16)
{
rb.copy_bar(x, y, x+7, y+7, agg::srgba8(0xdf, 0xdf, 0xdf));
}
}
create_img(0, rbuf_window().width(), rbuf_window().height()); // agg_platform_support functionality
prim_pixfmt_type pixf2(rbuf_img(0));
prim_ren_base_type rb2(pixf2);
rb2.clear(agg::srgba8(0,0,0,0));
//rb2.clear(agg::srgba8(255,255,255,255));
typedef agg::blender_rgba_pre<color, order> blender_type_pre;
typedef agg::pixfmt_alpha_blend_rgba<blender_type_pre, rbuf_type> pixfmt_pre;
typedef agg::renderer_base<pixfmt_pre> ren_base_pre;
pixfmt_pre pixf_pre(rbuf_window());
ren_base_pre rb_pre(pixf_pre);
start_timer();
render_scene(rbuf_img(0), pixf2);
double tm = elapsed_time();
rb_pre.blend_from(pixf2);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::renderer_scanline_aa_solid<prim_ren_base_type> ren(rb);
char buf[64];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
sprintf(buf, "%3.2f ms", tm);
t.start_point(10.0, 35.0);
t.text(buf);
ras.add_path(pt);
ren.color(agg::rgba(0,0,0));
agg::render_scanlines(ras, sl, ren);
agg::render_ctrl_rs(ras, sl, ren, m_alpha_src);
agg::render_ctrl_rs(ras, sl, ren, m_alpha_dst);
agg::render_ctrl_rs(ras, sl, ren, m_comp_op);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
}
};
int agg_main(int argc, char* argv[])
{
force_comp_op_link();
the_application app(pix_format, flip_y);
app.caption("AGG Example. Compositing Modes");
const char* img_name = "compositing";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(1, img_name))
{
char buf[256];
if(strcmp(img_name, "compositing") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
if(app.init(600, 400, agg::window_resize))
{
return app.run();
}
return 1;
}

251
examples/compositing2.cpp Normal file
View File

@ -0,0 +1,251 @@
#include <stdio.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_rounded_rect.h"
#include "agg_pixfmt_rgba.h"
#include "agg_span_allocator.h"
#include "agg_span_gradient.h"
#include "agg_gsv_text.h"
#include "agg_span_interpolator_linear.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
typedef color_type color;
typedef component_order order;
typedef agg::blender_rgba<color, order> prim_blender_type;
typedef agg::pixfmt_alpha_blend_rgba<prim_blender_type, agg::rendering_buffer> prim_pixfmt_type;
typedef agg::renderer_base<prim_pixfmt_type> prim_ren_base_type;
void force_comp_op_link()
{
// For unknown reason Digital Mars C++ doesn't want to link these
// functions if they are not specified explicitly.
color::value_type p[4] = {0};
//agg::comp_op_rgba_invert_rgb <color, order>::blend_pix(p,0,0,0,0,0);
//agg::comp_op_rgba_invert <color, order>::blend_pix(p,0,0,0,0,0);
//agg::comp_op_rgba_contrast <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_darken <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_lighten <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_color_dodge<color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_color_burn <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_hard_light <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_soft_light <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_difference <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_exclusion <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_atop <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_atop <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_xor <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_plus <color, order>::blend_pix(p,0,0,0,0,0);
//agg::comp_op_rgba_minus <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_multiply <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_screen <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_overlay <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_over <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_over <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_in <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_in <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_src_out <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_dst_out <color, order>::blend_pix(p,0,0,0,0,0);
agg::comp_op_rgba_clear <color, order>::blend_pix(p,0,0,0,0,0);
}
template<class Container, class ColorT>
void generate_color_ramp(Container& c,
ColorT c1, ColorT c2, ColorT c3, ColorT c4)
{
unsigned i;
for(i = 0; i < 85; i++)
{
c[i] = c1.gradient(c2, i/85.0);
}
for(; i < 170; i++)
{
c[i] = c2.gradient(c3, (i - 85)/85.0);
}
for(; i < 256; i++)
{
c[i] = c3.gradient(c4, (i - 170)/85.0);
}
}
class the_application : public agg::platform_support
{
agg::slider_ctrl<color> m_alpha_dst;
agg::slider_ctrl<color> m_alpha_src;
agg::rbox_ctrl<color_type> m_comp_op;
agg::pod_auto_array<color, 256> m_ramp1;
agg::pod_auto_array<color, 256> m_ramp2;
agg::rasterizer_scanline_aa<> m_ras;
agg::scanline_u8 m_sl;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_alpha_dst(5, 5, 400, 11, !flip_y),
m_alpha_src(5, 5+15, 400, 11+15, !flip_y),
m_comp_op(420, 5.0, 420+170.0, 340.0, !flip_y)
{
m_alpha_dst.label("Dst Alpha=%.2f");
m_alpha_dst.value(1.0);
add_ctrl(m_alpha_dst);
m_alpha_src.label("Src Alpha=%.2f");
m_alpha_src.value(1.0);
add_ctrl(m_alpha_src);
m_comp_op.text_size(6.8);
m_comp_op.add_item("clear");
m_comp_op.add_item("src");
m_comp_op.add_item("dst");
m_comp_op.add_item("src-over");
m_comp_op.add_item("dst-over");
m_comp_op.add_item("src-in");
m_comp_op.add_item("dst-in");
m_comp_op.add_item("src-out");
m_comp_op.add_item("dst-out");
m_comp_op.add_item("src-atop");
m_comp_op.add_item("dst-atop");
m_comp_op.add_item("xor");
m_comp_op.add_item("plus");
//m_comp_op.add_item("minus");
m_comp_op.add_item("multiply");
m_comp_op.add_item("screen");
m_comp_op.add_item("overlay");
m_comp_op.add_item("darken");
m_comp_op.add_item("lighten");
m_comp_op.add_item("color-dodge");
m_comp_op.add_item("color-burn");
m_comp_op.add_item("hard-light");
m_comp_op.add_item("soft-light");
m_comp_op.add_item("difference");
m_comp_op.add_item("exclusion");
//m_comp_op.add_item("contrast");
//m_comp_op.add_item("invert");
//m_comp_op.add_item("invert-rgb");
m_comp_op.cur_item(3);
add_ctrl(m_comp_op);
}
template<class RenBase, class ColorRamp>
void radial_shape(RenBase& rbase, ColorRamp& colors,
double x1, double y1, double x2, double y2)
{
typedef RenBase renderer_base_type;
typedef agg::gradient_radial gradient_func_type;
typedef ColorRamp color_func_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_allocator<color> span_allocator_type;
typedef agg::span_gradient<color,
interpolator_type,
gradient_func_type,
color_func_type> span_gradient_type;
gradient_func_type gradient_func; // The gradient function
agg::trans_affine gradient_mtx;
interpolator_type span_interpolator(gradient_mtx); // Span interpolator
span_allocator_type span_allocator; // Span Allocator
span_gradient_type span_gradient(span_interpolator,
gradient_func,
colors,
0, 100);
double cx = (x1 + x2) / 2.0;
double cy = (y1 + y2) / 2.0;
double r = 0.5 * (((x2 - x1) < (y2 - y1)) ? (x2 - x1) : (y2 - y1));
gradient_mtx *= agg::trans_affine_scaling(r / 100.0);
gradient_mtx *= agg::trans_affine_translation(cx, cy);
gradient_mtx *= trans_affine_resizing();
gradient_mtx.invert();
agg::ellipse ell(cx, cy, r, r, 100);
agg::conv_transform<agg::ellipse> trans(ell, trans_affine_resizing());
m_ras.add_path(trans);
agg::render_scanlines_aa(m_ras, m_sl, rbase, span_allocator, span_gradient);
}
template<class RenBase> void render_scene(RenBase& rb)
{
typedef agg::comp_op_adaptor_rgba<color, order> blender_type;
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
typedef agg::renderer_base<pixfmt_type> renderer_type;
pixfmt_type pixf(rbuf_window());
renderer_type ren(pixf);
pixf.comp_op(agg::comp_op_difference);
radial_shape(ren, m_ramp1, 50, 50, 50+320, 50+320);
pixf.comp_op(m_comp_op.cur_item());
double cx = 50;
double cy = 50;
radial_shape(ren, m_ramp2, cx+120-70, cy+120-70, cx+120+70, cy+120+70);
radial_shape(ren, m_ramp2, cx+200-70, cy+120-70, cx+200+70, cy+120+70);
radial_shape(ren, m_ramp2, cx+120-70, cy+200-70, cx+120+70, cy+200+70);
radial_shape(ren, m_ramp2, cx+200-70, cy+200-70, cx+200+70, cy+200+70);
}
virtual void on_draw()
{
prim_pixfmt_type pixf(rbuf_window());
prim_ren_base_type rb(pixf);
rb.clear(agg::srgba8(255, 255, 255));
generate_color_ramp(m_ramp1,
agg::rgba(0, 0, 0, m_alpha_dst.value()),
agg::rgba(0, 0, 1, m_alpha_dst.value()),
agg::rgba(0, 1, 0, m_alpha_dst.value()),
agg::rgba(1, 0, 0, 0));
generate_color_ramp(m_ramp2,
agg::rgba(0, 0, 0, m_alpha_src.value()),
agg::rgba(0, 0, 1, m_alpha_src.value()),
agg::rgba(0, 1, 0, m_alpha_src.value()),
agg::rgba(1, 0, 0, 0));
render_scene(rb);
agg::renderer_scanline_aa_solid<prim_ren_base_type> ren(rb);
agg::render_ctrl_rs(m_ras, m_sl, ren, m_alpha_dst);
agg::render_ctrl_rs(m_ras, m_sl, ren, m_alpha_src);
agg::render_ctrl_rs(m_ras, m_sl, ren, m_comp_op);
}
};
int agg_main(int argc, char* argv[])
{
force_comp_op_link();
the_application app(pix_format, flip_y);
app.caption("AGG Example. Compositing Modes");
if(app.init(600, 400, agg::window_resize|agg::window_keep_aspect_ratio))
{
return app.run();
}
return 1;
}

164
examples/conv_contour.cpp Normal file
View File

@ -0,0 +1,164 @@
#include <math.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_curve.h"
#include "agg_conv_contour.h"
#include "agg_conv_stroke.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::rbox_ctrl<color_type> m_close;
agg::slider_ctrl<color_type> m_width;
agg::cbox_ctrl<color_type> m_auto_detect;
agg::path_storage m_path;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_close (10.0, 10.0, 130.0, 80.0, !flip_y),
m_width (130 + 10.0, 10.0 + 4.0, 130 + 300.0, 10.0 + 8.0 + 4.0, !flip_y),
m_auto_detect(130 + 10.0, 10.0 + 4.0 + 16.0, "Autodetect orientation if not defined", !flip_y)
{
add_ctrl(m_close);
m_close.add_item("Close");
m_close.add_item("Close CW");
m_close.add_item("Close CCW");
m_close.cur_item(0);
add_ctrl(m_width);
m_width.range(-100.0, 100.0);
m_width.value(0.0);
m_width.label("Width=%1.2f");
add_ctrl(m_auto_detect);
}
void compose_path()
{
unsigned flag = 0;
if (m_close.cur_item() == 1) flag = agg::path_flags_cw;
if (m_close.cur_item() == 2) flag = agg::path_flags_ccw;
m_path.remove_all();
m_path.move_to(28.47, 6.45);
m_path.curve3(21.58, 1.12, 19.82, 0.29);
m_path.curve3(17.19, -0.93, 14.21, -0.93);
m_path.curve3(9.57, -0.93, 6.57, 2.25);
m_path.curve3(3.56, 5.42, 3.56, 10.60);
m_path.curve3(3.56, 13.87, 5.03, 16.26);
m_path.curve3(7.03, 19.58, 11.99, 22.51);
m_path.curve3(16.94, 25.44, 28.47, 29.64);
m_path.line_to(28.47, 31.40);
m_path.curve3(28.47, 38.09, 26.34, 40.58);
m_path.curve3(24.22, 43.07, 20.17, 43.07);
m_path.curve3(17.09, 43.07, 15.28, 41.41);
m_path.curve3(13.43, 39.75, 13.43, 37.60);
m_path.line_to(13.53, 34.77);
m_path.curve3(13.53, 32.52, 12.38, 31.30);
m_path.curve3(11.23, 30.08, 9.38, 30.08);
m_path.curve3(7.57, 30.08, 6.42, 31.35);
m_path.curve3(5.27, 32.62, 5.27, 34.81);
m_path.curve3(5.27, 39.01, 9.57, 42.53);
m_path.curve3(13.87, 46.04, 21.63, 46.04);
m_path.curve3(27.59, 46.04, 31.40, 44.04);
m_path.curve3(34.28, 42.53, 35.64, 39.31);
m_path.curve3(36.52, 37.21, 36.52, 30.71);
m_path.line_to(36.52, 15.53);
m_path.curve3(36.52, 9.13, 36.77, 7.69);
m_path.curve3(37.01, 6.25, 37.57, 5.76);
m_path.curve3(38.13, 5.27, 38.87, 5.27);
m_path.curve3(39.65, 5.27, 40.23, 5.62);
m_path.curve3(41.26, 6.25, 44.19, 9.18);
m_path.line_to(44.19, 6.45);
m_path.curve3(38.72, -0.88, 33.74, -0.88);
m_path.curve3(31.35, -0.88, 29.93, 0.78);
m_path.curve3(28.52, 2.44, 28.47, 6.45);
m_path.close_polygon(flag);
m_path.move_to(28.47, 9.62);
m_path.line_to(28.47, 26.66);
m_path.curve3(21.09, 23.73, 18.95, 22.51);
m_path.curve3(15.09, 20.36, 13.43, 18.02);
m_path.curve3(11.77, 15.67, 11.77, 12.89);
m_path.curve3(11.77, 9.38, 13.87, 7.06);
m_path.curve3(15.97, 4.74, 18.70, 4.74);
m_path.curve3(22.41, 4.74, 28.47, 9.62);
m_path.close_polygon(flag);
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base renb(pixf);
renb.clear(agg::rgba(1, 1, 1));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
agg::trans_affine mtx;
mtx *= agg::trans_affine_scaling(4.0);
mtx *= agg::trans_affine_translation(150, 100);
agg::conv_transform<agg::path_storage> trans(m_path, mtx);
agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans);
agg::conv_contour
<agg::conv_curve
<agg::conv_transform
<agg::path_storage> > > contour(curve);
contour.width(m_width.value());
//contour.inner_join(agg::inner_bevel);
//contour.line_join(agg::miter_join);
//contour.inner_line_join(agg::miter_join);
//contour.inner_miter_limit(4.0);
contour.auto_detect_orientation(m_auto_detect.status());
compose_path();
ras.add_path(contour);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0,0,0));
agg::render_ctrl(ras, sl, renb, m_close);
agg::render_ctrl(ras, sl, renb, m_width);
agg::render_ctrl(ras, sl, renb, m_auto_detect);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Contour Tool & Polygon Orientation");
if(app.init(440, 330, 0))
{
return app.run();
}
return 1;
}

View File

@ -0,0 +1,286 @@
#include <math.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"
#include "agg_conv_curve.h"
#include "agg_conv_contour.h"
#include "agg_conv_smooth_poly1.h"
#include "agg_conv_marker.h"
#include "agg_arrowhead.h"
#include "agg_vcgen_markers_term.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
double m_x[3];
double m_y[3];
double m_dx;
double m_dy;
int m_idx;
agg::rbox_ctrl<color_type> m_cap;
agg::slider_ctrl<color_type> m_width;
agg::slider_ctrl<color_type> m_smooth;
agg::cbox_ctrl<color_type> m_close;
agg::cbox_ctrl<color_type> m_even_odd;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_idx(-1),
m_cap(10.0, 10.0, 130.0, 80.0, !flip_y),
m_width(130 + 10.0, 10.0 + 4.0, 130 + 150.0, 10.0 + 8.0 + 4.0, !flip_y),
m_smooth(130 + 150.0 + 10.0, 10.0 + 4.0, 500 - 10.0, 10.0 + 8.0 + 4.0, !flip_y),
m_close(130 + 10.0, 10.0 + 4.0 + 16.0, "Close Polygons", !flip_y),
m_even_odd(130 + 150.0 + 10.0, 10.0 + 4.0 + 16.0, "Even-Odd Fill", !flip_y)
{
m_x[0] = 57 + 100; m_y[0] = 60;
m_x[1] = 369 + 100; m_y[1] = 170;
m_x[2] = 143 + 100; m_y[2] = 310;
add_ctrl(m_cap);
m_cap.add_item("Butt Cap");
m_cap.add_item("Square Cap");
m_cap.add_item("Round Cap");
m_cap.cur_item(0);
m_cap.no_transform();
add_ctrl(m_width);
m_width.range(0.0, 10.0);
m_width.value(3.0);
m_width.label("Width=%1.2f");
m_width.no_transform();
add_ctrl(m_smooth);
m_smooth.range(0.0, 2.0);
m_smooth.value(1.0);
m_smooth.label("Smooth=%1.2f");
m_smooth.no_transform();
add_ctrl(m_close);
m_close.no_transform();
add_ctrl(m_even_odd);
m_even_odd.no_transform();
}
virtual void on_init()
{
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base renb(pixf);
renb.clear(agg::rgba(1, 1, 1));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::line_cap_e cap = agg::butt_cap;
if(m_cap.cur_item() == 1) cap = agg::square_cap;
if(m_cap.cur_item() == 2) cap = agg::round_cap;
// Here we declare a very cheap-in-use path storage.
// It allocates space for at most 20 vertices in stack and
// never allocates memory. But be aware that adding more than
// 20 vertices is fatal!
//------------------------
typedef agg::path_base<
agg::vertex_stl_storage<
agg::pod_auto_vector<
agg::vertex_d, 20> > > path_storage_type;
path_storage_type path;
path.move_to(m_x[0], m_y[0]);
path.line_to(m_x[1], m_y[1]);
path.line_to((m_x[0]+m_x[1]+m_x[2]) / 3.0, (m_y[0]+m_y[1]+m_y[2]) / 3.0);
path.line_to(m_x[2], m_y[2]);
if(m_close.status()) path.close_polygon();
path.move_to((m_x[0] + m_x[1]) / 2, (m_y[0] + m_y[1]) / 2);
path.line_to((m_x[1] + m_x[2]) / 2, (m_y[1] + m_y[2]) / 2);
path.line_to((m_x[2] + m_x[0]) / 2, (m_y[2] + m_y[0]) / 2);
if(m_close.status()) path.close_polygon();
if(m_even_odd.status()) ras.filling_rule(agg::fill_even_odd);
// (1)
ras.add_path(path);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.7, 0.5, 0.1, 0.5));
// (1)
// Start of (2, 3, 4)
agg::conv_smooth_poly1<path_storage_type> smooth(path);
smooth.smooth_value(m_smooth.value());
// (2)
ras.add_path(smooth);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.1, 0.5, 0.7, 0.1));
// (2)
// (3)
agg::conv_stroke<agg::conv_smooth_poly1<path_storage_type> > smooth_outline(smooth);
ras.add_path(smooth_outline);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.0, 0.6, 0.0, 0.8));
// (3)
// (4)
agg::conv_curve<agg::conv_smooth_poly1<path_storage_type> > curve(smooth);
agg::conv_dash<agg::conv_curve<agg::conv_smooth_poly1<path_storage_type> >, agg::vcgen_markers_term> dash(curve);
agg::conv_stroke<agg::conv_dash<agg::conv_curve<agg::conv_smooth_poly1<path_storage_type> >, agg::vcgen_markers_term> > stroke(dash);
stroke.line_cap(cap);
stroke.width(m_width.value());
double k = ::pow(m_width.value(), 0.7);
agg::arrowhead ah;
ah.head(4 * k, 4 * k, 3 * k, 2 * k);
if(!m_close.status()) ah.tail(1 * k, 1.5 * k, 3 * k, 5 * k);
agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead> arrow(dash.markers(), ah);
dash.add_dash(20.0, 5.0);
dash.add_dash(5.0, 5.0);
dash.add_dash(5.0, 5.0);
dash.dash_start(10);
ras.add_path(stroke);
ras.add_path(arrow);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.0, 0.0, 0.0));
// (4)
ras.filling_rule(agg::fill_non_zero);
agg::render_ctrl(ras, sl, renb, m_cap);
agg::render_ctrl(ras, sl, renb, m_width);
agg::render_ctrl(ras, sl, renb, m_smooth);
agg::render_ctrl(ras, sl, renb, m_close);
agg::render_ctrl(ras, sl, renb, m_even_odd);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
unsigned i;
for (i = 0; i < 3; i++)
{
if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 20.0)
{
m_dx = x - m_x[i];
m_dy = y - m_y[i];
m_idx = i;
break;
}
}
if(i == 3)
{
if(agg::point_in_triangle(m_x[0], m_y[0],
m_x[1], m_y[1],
m_x[2], m_y[2],
x, y))
{
m_dx = x - m_x[0];
m_dy = y - m_y[0];
m_idx = 3;
}
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_idx == 3)
{
double dx = x - m_dx;
double dy = y - m_dy;
m_x[1] -= m_x[0] - dx;
m_y[1] -= m_y[0] - dy;
m_x[2] -= m_x[0] - dx;
m_y[2] -= m_y[0] - dy;
m_x[0] = dx;
m_y[0] = dy;
force_redraw();
return;
}
if(m_idx >= 0)
{
m_x[m_idx] = x - m_dx;
m_y[m_idx] = y - m_dy;
force_redraw();
}
}
else
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_idx = -1;
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
double dx = 0;
double dy = 0;
switch(key)
{
case agg::key_left: dx = -0.1; break;
case agg::key_right: dx = 0.1; break;
case agg::key_up: dy = 0.1; break;
case agg::key_down: dy = -0.1; break;
}
m_x[0] += dx;
m_y[0] += dy;
m_x[1] += dx;
m_y[1] += dy;
force_redraw();
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Line Join");
if(app.init(500, 330, 0))
{
return app.run();
}
return 1;
}

276
examples/conv_stroke.cpp Normal file
View File

@ -0,0 +1,276 @@
#include <math.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"
#include "agg_conv_curve.h"
#include "agg_conv_contour.h"
#include "agg_conv_smooth_poly1.h"
#include "agg_conv_marker.h"
#include "agg_arrowhead.h"
#include "agg_vcgen_markers_term.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgb.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
double m_x[3];
double m_y[3];
double m_dx;
double m_dy;
int m_idx;
agg::rbox_ctrl<color_type> m_join;
agg::rbox_ctrl<color_type> m_cap;
agg::slider_ctrl<color_type> m_width;
agg::slider_ctrl<color_type> m_miter_limit;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_idx(-1),
m_join(10.0, 10.0, 133.0, 80.0, !flip_y),
m_cap(10.0, 80.0 + 10.0, 133.0, 80.0 + 80.0, !flip_y),
m_width(130 + 10.0, 10.0 + 4.0, 500.0 - 10.0, 10.0 + 8.0 + 4.0, !flip_y),
m_miter_limit(130 + 10.0, 20.0 + 10.0 + 4.0, 500.0 - 10.0, 20.0 + 10.0 + 8.0 + 4.0, !flip_y)
{
m_x[0] = 57 + 100; m_y[0] = 60;
m_x[1] = 369 + 100; m_y[1] = 170;
m_x[2] = 143 + 100; m_y[2] = 310;
add_ctrl(m_join);
m_join.text_size(7.5);
m_join.text_thickness(1.0);
m_join.add_item("Miter Join");
m_join.add_item("Miter Join Revert");
m_join.add_item("Round Join");
m_join.add_item("Bevel Join");
m_join.cur_item(2);
add_ctrl(m_cap);
m_cap.add_item("Butt Cap");
m_cap.add_item("Square Cap");
m_cap.add_item("Round Cap");
m_cap.cur_item(2);
add_ctrl(m_width);
m_width.range(3.0, 40.0);
m_width.value(20.0);
m_width.label("Width=%1.2f");
add_ctrl(m_miter_limit);
m_miter_limit.range(1.0, 10.0);
m_miter_limit.value(4.0);
m_miter_limit.label("Miter Limit=%1.2f");
m_join.no_transform();
m_cap.no_transform();
m_width.no_transform();
m_miter_limit.no_transform();
}
virtual void on_init()
{
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base renb(pixf);
renb.clear(agg::rgba(1, 1, 1));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
agg::path_storage path;
path.move_to(m_x[0], m_y[0]);
path.line_to((m_x[0] + m_x[1]) / 2, (m_y[0] + m_y[1]) / 2); // This point is added only to check for numerical stability
path.line_to(m_x[1], m_y[1]);
path.line_to(m_x[2], m_y[2]);
path.line_to(m_x[2], m_y[2]); // This point is added only to check for numerical stability
path.move_to((m_x[0] + m_x[1]) / 2, (m_y[0] + m_y[1]) / 2);
path.line_to((m_x[1] + m_x[2]) / 2, (m_y[1] + m_y[2]) / 2);
path.line_to((m_x[2] + m_x[0]) / 2, (m_y[2] + m_y[0]) / 2);
path.close_polygon();
agg::line_cap_e cap = agg::butt_cap;
if(m_cap.cur_item() == 1) cap = agg::square_cap;
if(m_cap.cur_item() == 2) cap = agg::round_cap;
agg::line_join_e join = agg::miter_join;
if(m_join.cur_item() == 1) join = agg::miter_join_revert;
if(m_join.cur_item() == 2) join = agg::round_join;
if(m_join.cur_item() == 3) join = agg::bevel_join;
// (1)
agg::conv_stroke<agg::path_storage> stroke(path);
stroke.line_join(join);
stroke.line_cap(cap);
stroke.miter_limit(m_miter_limit.value());
stroke.width(m_width.value());
ras.add_path(stroke);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.8, 0.7, 0.6));
// (1)
// (2)
agg::conv_stroke<agg::path_storage> poly1(path);
poly1.width(1.5);
ras.add_path(poly1);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0,0,0));
// (2)
// (3)
agg::conv_dash<agg::conv_stroke<agg::path_storage> > poly2_dash(stroke);
agg::conv_stroke<agg::conv_dash<agg::conv_stroke<agg::path_storage> > > poly2(poly2_dash);
poly2.miter_limit(4.0);
poly2.width(m_width.value() / 5.0);
poly2.line_cap(cap);
poly2.line_join(join);
poly2_dash.add_dash(20.0, m_width.value() / 2.5);
ras.add_path(poly2);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0,0,0.3));
// (3)
// (4)
ras.add_path(path);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba(0.0, 0.0, 0.0, 0.2));
// (4)
agg::render_ctrl(ras, sl, renb, m_join);
agg::render_ctrl(ras, sl, renb, m_cap);
agg::render_ctrl(ras, sl, renb, m_width);
agg::render_ctrl(ras, sl, renb, m_miter_limit);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
unsigned i;
for (i = 0; i < 3; i++)
{
if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 20.0)
{
m_dx = x - m_x[i];
m_dy = y - m_y[i];
m_idx = i;
break;
}
}
if(i == 3)
{
if(agg::point_in_triangle(m_x[0], m_y[0],
m_x[1], m_y[1],
m_x[2], m_y[2],
x, y))
{
m_dx = x - m_x[0];
m_dy = y - m_y[0];
m_idx = 3;
}
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_idx == 3)
{
double dx = x - m_dx;
double dy = y - m_dy;
m_x[1] -= m_x[0] - dx;
m_y[1] -= m_y[0] - dy;
m_x[2] -= m_x[0] - dx;
m_y[2] -= m_y[0] - dy;
m_x[0] = dx;
m_y[0] = dy;
force_redraw();
return;
}
if(m_idx >= 0)
{
m_x[m_idx] = x - m_dx;
m_y[m_idx] = y - m_dy;
force_redraw();
}
}
else
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_idx = -1;
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
double dx = 0;
double dy = 0;
switch(key)
{
case agg::key_left: dx = -0.1; break;
case agg::key_right: dx = 0.1; break;
case agg::key_up: dy = 0.1; break;
case agg::key_down: dy = -0.1; break;
}
m_x[0] += dx;
m_y[0] += dy;
m_x[1] += dx;
m_y[1] += dy;
force_redraw();
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Line Join");
if(app.init(500, 330, 0))
{
return app.run();
}
return 1;
}

709
examples/distortions.cpp Normal file
View File

@ -0,0 +1,709 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_ellipse.h"
#include "agg_trans_affine.h"
#include "agg_conv_transform.h"
#include "agg_pixfmt_rgb.h"
#include "agg_span_allocator.h"
#include "agg_span_image_filter_rgb.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_span_interpolator_linear.h"
#include "agg_span_interpolator_adaptor.h"
#include "agg_span_gradient.h"
#include "agg_image_accessors.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
static agg::int8u g_gradient_colors[] =
{
255, 255, 255, 255,
255, 255, 254, 255,
255, 255, 254, 255,
255, 255, 254, 255,
255, 255, 253, 255,
255, 255, 253, 255,
255, 255, 252, 255,
255, 255, 251, 255,
255, 255, 250, 255,
255, 255, 248, 255,
255, 255, 246, 255,
255, 255, 244, 255,
255, 255, 241, 255,
255, 255, 238, 255,
255, 255, 235, 255,
255, 255, 231, 255,
255, 255, 227, 255,
255, 255, 222, 255,
255, 255, 217, 255,
255, 255, 211, 255,
255, 255, 206, 255,
255, 255, 200, 255,
255, 254, 194, 255,
255, 253, 188, 255,
255, 252, 182, 255,
255, 250, 176, 255,
255, 249, 170, 255,
255, 247, 164, 255,
255, 246, 158, 255,
255, 244, 152, 255,
254, 242, 146, 255,
254, 240, 141, 255,
254, 238, 136, 255,
254, 236, 131, 255,
253, 234, 126, 255,
253, 232, 121, 255,
253, 229, 116, 255,
252, 227, 112, 255,
252, 224, 108, 255,
251, 222, 104, 255,
251, 219, 100, 255,
251, 216, 96, 255,
250, 214, 93, 255,
250, 211, 89, 255,
249, 208, 86, 255,
249, 205, 83, 255,
248, 202, 80, 255,
247, 199, 77, 255,
247, 196, 74, 255,
246, 193, 72, 255,
246, 190, 69, 255,
245, 187, 67, 255,
244, 183, 64, 255,
244, 180, 62, 255,
243, 177, 60, 255,
242, 174, 58, 255,
242, 170, 56, 255,
241, 167, 54, 255,
240, 164, 52, 255,
239, 161, 51, 255,
239, 157, 49, 255,
238, 154, 47, 255,
237, 151, 46, 255,
236, 147, 44, 255,
235, 144, 43, 255,
235, 141, 41, 255,
234, 138, 40, 255,
233, 134, 39, 255,
232, 131, 37, 255,
231, 128, 36, 255,
230, 125, 35, 255,
229, 122, 34, 255,
228, 119, 33, 255,
227, 116, 31, 255,
226, 113, 30, 255,
225, 110, 29, 255,
224, 107, 28, 255,
223, 104, 27, 255,
222, 101, 26, 255,
221, 99, 25, 255,
220, 96, 24, 255,
219, 93, 23, 255,
218, 91, 22, 255,
217, 88, 21, 255,
216, 86, 20, 255,
215, 83, 19, 255,
214, 81, 18, 255,
213, 79, 17, 255,
212, 77, 17, 255,
211, 74, 16, 255,
210, 72, 15, 255,
209, 70, 14, 255,
207, 68, 13, 255,
206, 66, 13, 255,
205, 64, 12, 255,
204, 62, 11, 255,
203, 60, 10, 255,
202, 58, 10, 255,
201, 56, 9, 255,
199, 55, 9, 255,
198, 53, 8, 255,
197, 51, 7, 255,
196, 50, 7, 255,
195, 48, 6, 255,
193, 46, 6, 255,
192, 45, 5, 255,
191, 43, 5, 255,
190, 42, 4, 255,
188, 41, 4, 255,
187, 39, 3, 255,
186, 38, 3, 255,
185, 37, 2, 255,
183, 35, 2, 255,
182, 34, 1, 255,
181, 33, 1, 255,
179, 32, 1, 255,
178, 30, 0, 255,
177, 29, 0, 255,
175, 28, 0, 255,
174, 27, 0, 255,
173, 26, 0, 255,
171, 25, 0, 255,
170, 24, 0, 255,
168, 23, 0, 255,
167, 22, 0, 255,
165, 21, 0, 255,
164, 21, 0, 255,
163, 20, 0, 255,
161, 19, 0, 255,
160, 18, 0, 255,
158, 17, 0, 255,
156, 17, 0, 255,
155, 16, 0, 255,
153, 15, 0, 255,
152, 14, 0, 255,
150, 14, 0, 255,
149, 13, 0, 255,
147, 12, 0, 255,
145, 12, 0, 255,
144, 11, 0, 255,
142, 11, 0, 255,
140, 10, 0, 255,
139, 10, 0, 255,
137, 9, 0, 255,
135, 9, 0, 255,
134, 8, 0, 255,
132, 8, 0, 255,
130, 7, 0, 255,
128, 7, 0, 255,
126, 6, 0, 255,
125, 6, 0, 255,
123, 5, 0, 255,
121, 5, 0, 255,
119, 4, 0, 255,
117, 4, 0, 255,
115, 4, 0, 255,
113, 3, 0, 255,
111, 3, 0, 255,
109, 2, 0, 255,
107, 2, 0, 255,
105, 2, 0, 255,
103, 1, 0, 255,
101, 1, 0, 255,
99, 1, 0, 255,
97, 0, 0, 255,
95, 0, 0, 255,
93, 0, 0, 255,
91, 0, 0, 255,
90, 0, 0, 255,
88, 0, 0, 255,
86, 0, 0, 255,
84, 0, 0, 255,
82, 0, 0, 255,
80, 0, 0, 255,
78, 0, 0, 255,
77, 0, 0, 255,
75, 0, 0, 255,
73, 0, 0, 255,
72, 0, 0, 255,
70, 0, 0, 255,
68, 0, 0, 255,
67, 0, 0, 255,
65, 0, 0, 255,
64, 0, 0, 255,
63, 0, 0, 255,
61, 0, 0, 255,
60, 0, 0, 255,
59, 0, 0, 255,
58, 0, 0, 255,
57, 0, 0, 255,
56, 0, 0, 255,
55, 0, 0, 255,
54, 0, 0, 255,
53, 0, 0, 255,
53, 0, 0, 255,
52, 0, 0, 255,
52, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
50, 0, 0, 255,
50, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
51, 0, 0, 255,
52, 0, 0, 255,
52, 0, 0, 255,
53, 0, 0, 255,
54, 1, 0, 255,
55, 2, 0, 255,
56, 3, 0, 255,
57, 4, 0, 255,
58, 5, 0, 255,
59, 6, 0, 255,
60, 7, 0, 255,
62, 8, 0, 255,
63, 9, 0, 255,
64, 11, 0, 255,
66, 12, 0, 255,
68, 13, 0, 255,
69, 14, 0, 255,
71, 16, 0, 255,
73, 17, 0, 255,
75, 18, 0, 255,
77, 20, 0, 255,
79, 21, 0, 255,
81, 23, 0, 255,
83, 24, 0, 255,
85, 26, 0, 255,
87, 28, 0, 255,
90, 29, 0, 255,
92, 31, 0, 255,
94, 33, 0, 255,
97, 34, 0, 255,
99, 36, 0, 255,
102, 38, 0, 255,
104, 40, 0, 255,
107, 41, 0, 255,
109, 43, 0, 255,
112, 45, 0, 255,
115, 47, 0, 255,
117, 49, 0, 255,
120, 51, 0, 255,
123, 52, 0, 255,
126, 54, 0, 255,
128, 56, 0, 255,
131, 58, 0, 255,
134, 60, 0, 255,
137, 62, 0, 255,
140, 64, 0, 255,
143, 66, 0, 255,
145, 68, 0, 255,
148, 70, 0, 255,
151, 72, 0, 255,
154, 74, 0, 255
};
class periodic_distortion
{
public:
periodic_distortion() :
m_cx(0.0),
m_cy(0.0),
m_period(0.5),
m_amplitude(0.5),
m_phase(0.0)
{}
void center(double x, double y) { m_cx = x; m_cy = y; }
void period(double v) { m_period = v; }
void amplitude(double v) { m_amplitude = 1.0 / v; }
void phase(double v) { m_phase = v; }
virtual void calculate(int* x, int* y) const = 0;
protected:
double m_cx;
double m_cy;
double m_period;
double m_amplitude;
double m_phase;
};
inline void calculate_wave(int* x, int* y,
double cx, double cy,
double period, double amplitude, double phase)
{
double xd = double(*x) / agg::image_subpixel_scale - cx;
double yd = double(*y) / agg::image_subpixel_scale - cy;
double d = sqrt(xd*xd + yd*yd);
if(d > 1)
{
double a = cos(d / (16.0 * period) - phase) * (1.0 / (amplitude * d)) + 1.0;
*x = int((xd * a + cx) * agg::image_subpixel_scale);
*y = int((yd * a + cy) * agg::image_subpixel_scale);
}
}
inline void calculate_swirl(int* x, int* y,
double cx, double cy,
double amplitude, double phase)
{
double xd = double(*x) / agg::image_subpixel_scale - cx;
double yd = double(*y) / agg::image_subpixel_scale - cy;
double a = double(100.0 - sqrt(xd * xd + yd * yd)) / 100.0 * (0.1 / -amplitude);
double sa = sin(a - phase/25.0);
double ca = cos(a - phase/25.0);
*x = int((xd * ca - yd * sa + cx) * agg::image_subpixel_scale);
*y = int((xd * sa + yd * ca + cy) * agg::image_subpixel_scale);
}
class distortion_wave : public periodic_distortion
{
virtual void calculate(int* x, int* y) const
{
calculate_wave(x, y, m_cx, m_cy, m_period, m_amplitude, m_phase);
}
};
class distortion_swirl : public periodic_distortion
{
virtual void calculate(int* x, int* y) const
{
calculate_swirl(x, y, m_cx, m_cy, m_amplitude, m_phase);
}
};
class distortion_swirl_wave : public periodic_distortion
{
virtual void calculate(int* x, int* y) const
{
calculate_swirl(x, y, m_cx, m_cy, m_amplitude, m_phase);
calculate_wave(x, y, m_cx, m_cy, m_period, m_amplitude, m_phase);
}
};
class distortion_wave_swirl : public periodic_distortion
{
virtual void calculate(int* x, int* y) const
{
calculate_wave(x, y, m_cx, m_cy, m_period, m_amplitude, m_phase);
calculate_swirl(x, y, m_cx, m_cy, m_amplitude, m_phase);
}
};
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_angle;
agg::slider_ctrl<color_type> m_scale;
agg::slider_ctrl<color_type> m_amplitude;
agg::slider_ctrl<color_type> m_period;
agg::rbox_ctrl<color_type> m_distortion;
double m_center_x;
double m_center_y;
double m_phase;
typedef agg::pod_auto_array<color_type, 256> color_array_type;
color_array_type m_gradient_colors;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_angle (5, 5, 150, 12, !flip_y),
m_scale (5, 5+15, 150, 12+15, !flip_y),
m_period (5+170, 5, 150+170, 12, !flip_y),
m_amplitude (5+170, 5+15, 150+170, 12+15, !flip_y),
m_distortion(480, 5, 600, 90, !flip_y),
m_center_x(0.0),
m_center_y(0.0),
m_phase(0.0)
{
add_ctrl(m_angle);
add_ctrl(m_scale);
add_ctrl(m_amplitude);
add_ctrl(m_period);
add_ctrl(m_distortion);
m_angle.label("Angle=%3.2f");
m_scale.label("Scale=%3.2f");
m_angle.range(-180.0, 180.0);
m_angle.value(20.0);
m_scale.range(0.1, 5.0);
m_scale.value(1.0);
m_amplitude.label("Amplitude=%3.2f");
m_period.label("Period=%3.2f");
m_amplitude.range(0.1, 40.0);
m_period.range(0.1, 2.0);
m_amplitude.value(10.0);
m_period.value(1.0);
m_distortion.add_item("Wave");
m_distortion.add_item("Swirl");
m_distortion.add_item("Wave-Swirl");
m_distortion.add_item("Swirl-Wave");
m_distortion.cur_item(0);
unsigned i;
const agg::int8u* p = g_gradient_colors;
for(i = 0; i < 256; i++)
{
m_gradient_colors[i] = agg::srgba8(p[0], p[1], p[2], p[3]);
p += 4;
}
}
virtual ~the_application()
{
}
virtual void on_init()
{
m_center_x = rbuf_img(0).width() / 2.0 + 10;
m_center_y = rbuf_img(0).height() / 2.0 + 10 + 40;
}
virtual void on_draw()
{
double img_width = rbuf_img(0).width();
double img_height = rbuf_img(0).height();
typedef pixfmt pixfmt;
typedef agg::renderer_base<pixfmt> renderer_base;
pixfmt pixf(rbuf_window());
pixfmt img_pixf(rbuf_img(0));
renderer_base rb(pixf);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
agg::trans_affine src_mtx;
src_mtx *= agg::trans_affine_translation(-img_width/2, -img_height/2);
src_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0);
src_mtx *= agg::trans_affine_translation(img_width/2 + 10, img_height/2 + 10 + 40);
src_mtx *= trans_affine_resizing();
agg::trans_affine img_mtx;
img_mtx *= agg::trans_affine_translation(-img_width/2, -img_height/2);
img_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0);
img_mtx *= agg::trans_affine_scaling(m_scale.value());
img_mtx *= agg::trans_affine_translation(img_width/2 + 10, img_height/2 + 10 + 40);
img_mtx *= trans_affine_resizing();
img_mtx.invert();
typedef agg::span_allocator<color_type> span_alloc_type;
span_alloc_type sa;
typedef agg::span_interpolator_adaptor<agg::span_interpolator_linear<>,
periodic_distortion> interpolator_type;
periodic_distortion* dist = 0;
distortion_wave dist_wave;
distortion_swirl dist_swirl;
distortion_wave_swirl dist_wave_swirl;
distortion_swirl_wave dist_swirl_wave;
switch(m_distortion.cur_item())
{
case 0: dist = &dist_wave; break;
case 1: dist = &dist_swirl; break;
case 2: dist = &dist_wave_swirl; break;
case 3: dist = &dist_swirl_wave; break;
}
dist->period(m_period.value());
dist->amplitude(m_amplitude.value());
dist->phase(m_phase);
double cx = m_center_x;
double cy = m_center_y;
img_mtx.transform(&cx, &cy);
dist->center(cx, cy);
interpolator_type interpolator(img_mtx, *dist);
typedef agg::image_accessor_clip<pixfmt> img_source_type;
img_source_type img_src(img_pixf, agg::rgba(1,1,1));
/*
// Version without filtering (nearest neighbor)
//------------------------------------------
typedef agg::span_image_filter_rgb_nn<img_source_type,
interpolator_type> span_gen_type;
span_gen_type sg(img_src, interpolator);
//------------------------------------------
*/
// Version with "hardcoded" bilinear filter and without
// image_accessor (direct filter, the old variant)
//------------------------------------------
typedef agg::span_image_filter_rgb_bilinear_clip<pixfmt,
interpolator_type> span_gen_type;
span_gen_type sg(img_pixf, agg::rgba(1,1,1), interpolator);
//------------------------------------------
/*
// Version with arbitrary 2x2 filter
//------------------------------------------
typedef agg::span_image_filter_rgb_2x2<img_source_type,
interpolator_type> span_gen_type;
agg::image_filter<agg::image_filter_kaiser> filter;
span_gen_type sg(img_src, interpolator, filter);
//------------------------------------------
*/
/*
// Version with arbitrary filter
//------------------------------------------
typedef agg::span_image_filter_rgb<img_source_type,
interpolator_type> span_gen_type;
agg::image_filter<agg::image_filter_spline36> filter;
span_gen_type sg(img_src, interpolator, filter);
//------------------------------------------
*/
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
double r = img_width;
if(img_height < r) r = img_height;
agg::ellipse ell(img_width / 2.0,
img_height / 2.0,
r / 2.0 - 20.0,
r / 2.0 - 20.0, 200);
agg::conv_transform<agg::ellipse> tr(ell, src_mtx);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb, sa, sg);
src_mtx *= ~trans_affine_resizing();
src_mtx *= agg::trans_affine_translation(img_width - img_width/10, 0.0);
src_mtx *= trans_affine_resizing();
ras.add_path(tr);
agg::render_scanlines_aa_solid(ras, sl, rb, agg::srgba8(0,0,0));
typedef agg::span_gradient<color_type,
interpolator_type,
agg::gradient_circle,
color_array_type> gradient_span_gen;
agg::gradient_circle gradient_function;
color_array_type gradient_colors(m_gradient_colors);
gradient_span_gen span_gradient(interpolator,
gradient_function,
gradient_colors,
0, 180);
agg::trans_affine gr1_mtx;
gr1_mtx *= agg::trans_affine_translation(-img_width/2, -img_height/2);
gr1_mtx *= agg::trans_affine_scaling(0.8);
gr1_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0);
gr1_mtx *= agg::trans_affine_translation(img_width - img_width/10 + img_width/2 + 10,
img_height/2 + 10 + 40);
gr1_mtx *= trans_affine_resizing();
agg::trans_affine gr2_mtx;
gr2_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0);
gr2_mtx *= agg::trans_affine_scaling(m_scale.value());
gr2_mtx *= agg::trans_affine_translation(img_width - img_width/10 + img_width/2 + 10 + 50,
img_height/2 + 10 + 40 + 50);
gr2_mtx *= trans_affine_resizing();
gr2_mtx.invert();
cx = m_center_x + img_width - img_width/10;
cy = m_center_y;
gr2_mtx.transform(&cx, &cy);
dist->center(cx, cy);
interpolator.transformer(gr2_mtx);
agg::conv_transform<agg::ellipse> tr2(ell, gr1_mtx);
ras.add_path(tr2);
agg::render_scanlines_aa(ras, sl, rb, sa, span_gradient);
agg::render_ctrl(ras, sl, rb, m_angle);
agg::render_ctrl(ras, sl, rb, m_scale);
agg::render_ctrl(ras, sl, rb, m_amplitude);
agg::render_ctrl(ras, sl, rb, m_period);
agg::render_ctrl(ras, sl, rb, m_distortion);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags)
{
m_center_x = x;
m_center_y = y;
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & 1)
{
m_center_x = x;
m_center_y = y;
force_redraw();
}
}
virtual void on_idle()
{
m_phase += 15.0 * agg::pi / 180.0;
if(m_phase > agg::pi * 200.0) m_phase -= agg::pi * 200.0;
force_redraw();
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Image and Gradient Distortions");
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
char buf[256];
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
if(app.init(app.rbuf_img(0).width() + 300, app.rbuf_img(0).height() + 40 + 20, agg::window_resize))
{
app.wait_mode(false);
return app.run();
}
return 0;
}

View File

@ -0,0 +1,561 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "agg_rendering_buffer.h"
#include "agg_trans_viewport.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_conv_curve.h"
#include "agg_conv_stroke.h"
#include "agg_gsv_text.h"
#include "agg_scanline_u.h"
#include "agg_scanline_bin.h"
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_rasterizer_compound_aa.h"
#include "agg_span_allocator.h"
#include "agg_pixfmt_rgba.h"
#include "agg_bounding_rect.h"
#include "agg_color_gray.h"
#include "platform/agg_platform_support.h"
#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum { flip_y = false };
namespace agg
{
struct path_style
{
unsigned path_id;
int left_fill;
int right_fill;
int line;
};
class compound_shape
{
public:
~compound_shape()
{
if(m_fd)
{
fclose(m_fd);
}
}
compound_shape() :
m_path(),
m_affine(),
m_curve(m_path),
m_trans(m_curve, m_affine),
m_styles()
{}
bool open(const char* fname)
{
m_fd = fopen(fname, "r");
return m_fd != 0;
}
bool read_next()
{
m_path.remove_all();
m_styles.remove_all();
const char space[] = " \t\n\r";
double ax, ay, cx, cy;
if(m_fd)
{
char buf[1024];
char* ts;
for(;;)
{
if(fgets(buf, 1022, m_fd) == 0) return false;
if(buf[0] == '=') break;
}
while(fgets(buf, 1022, m_fd))
{
if(buf[0] == '!') break;
if(buf[0] == 'P')
{
// BeginPath
path_style style;
style.path_id = m_path.start_new_path();
ts = strtok(buf, space); // Path;
ts = strtok(0, space); // left_style
style.left_fill = atoi(ts);
ts = strtok(0, space); // right_style
style.right_fill = atoi(ts);
ts = strtok(0, space); // line_style
style.line = atoi(ts);
ts = strtok(0, space); // ax
ax = atof(ts);
ts = strtok(0, space); // ay
ay = atof(ts);
m_path.move_to(ax, ay);
m_styles.add(style);
}
if(buf[0] == 'C')
{
ts = strtok(buf, space); // Curve;
ts = strtok(0, space); // cx
cx = atof(ts);
ts = strtok(0, space); // cy
cy = atof(ts);
ts = strtok(0, space); // ax
ax = atof(ts);
ts = strtok(0, space); // ay
ay = atof(ts);
m_path.curve3(cx, cy, ax, ay);
}
if(buf[0] == 'L')
{
ts = strtok(buf, space); // Line;
ts = strtok(0, space); // ax
ax = atof(ts);
ts = strtok(0, space); // ay
ay = atof(ts);
m_path.line_to(ax, ay);
}
if(buf[0] == '<')
{
// EndPath
}
}
return true;
}
return false;
}
unsigned operator [] (unsigned i) const
{
return m_styles[i].path_id;
}
unsigned paths() const { return m_styles.size(); }
const path_style& style(unsigned i) const
{
return m_styles[i];
}
void rewind(unsigned path_id)
{
m_trans.rewind(path_id);
}
unsigned vertex(double* x, double* y)
{
return m_trans.vertex(x, y);
}
double scale() const
{
return m_affine.scale();
}
void scale(double w, double h)
{
m_affine.reset();
double x1, y1, x2, y2;
bounding_rect(m_path, *this, 0, m_styles.size(),
&x1, &y1, &x2, &y2);
if(x1 < x2 && y1 < y2)
{
trans_viewport vp;
vp.preserve_aspect_ratio(0.5, 0.5, aspect_ratio_meet);
vp.world_viewport(x1, y1, x2, y2);
vp.device_viewport(0, 0, w, h);
m_affine = vp.to_affine();
}
m_curve.approximation_scale(m_affine.scale());
}
void approximation_scale(double s)
{
m_curve.approximation_scale(m_affine.scale() * s);
}
int hit_test(double x, double y, double r)
{
m_affine.inverse_transform(&x, &y);
r /= m_affine.scale();
unsigned i;
for(i = 0; i < m_path.total_vertices(); i++)
{
double vx, vy;
unsigned cmd = m_path.vertex(i, &vx, &vy);
if(is_vertex(cmd))
{
if(calc_distance(x, y, vx, vy) <= r)
{
return i;
}
}
}
return -1;
}
void modify_vertex(unsigned i, double x, double y)
{
m_affine.inverse_transform(&x, &y);
m_path.modify_vertex(i, x, y);
}
private:
path_storage m_path;
trans_affine m_affine;
conv_curve<path_storage> m_curve;
conv_transform<conv_curve<path_storage> > m_trans;
pod_bvector<path_style> m_styles;
double m_x1, m_y1, m_x2, m_y2;
FILE* m_fd;
};
// Testing class, color provider and span generator
//-------------------------------------------------
class test_styles
{
public:
test_styles(const color_type* solid_colors,
const color_type* gradient) :
m_solid_colors(solid_colors),
m_gradient(gradient)
{}
// Suppose that style=1 is a gradient
//---------------------------------------------
bool is_solid(unsigned style) const
{
return true;//style != 1;
}
// Just returns a color
//---------------------------------------------
const color_type& color(unsigned style) const
{
return m_solid_colors[style];
}
// Generate span. In our test case only one style (style=1)
// can be a span generator, so that, parameter "style"
// isn't used here.
//---------------------------------------------
void generate_span(color_type* span, int x, int y, unsigned len, unsigned style)
{
memcpy(span, m_gradient + x, sizeof(color_type) * len);
}
private:
const color_type* m_solid_colors;
const color_type* m_gradient;
};
}
class the_application : public agg::platform_support
{
public:
agg::compound_shape m_shape;
color_type m_colors[100];
agg::trans_affine m_scale;
agg::pod_array<color_type> m_gradient;
int m_point_idx;
int m_hit_x;
int m_hit_y;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_point_idx(-1),
m_hit_x(-1),
m_hit_y(-1)
{
for(unsigned i = 0; i < 100; i++)
{
m_colors[i] = agg::srgba8(
(rand() & 0xFF),
(rand() & 0xFF),
(rand() & 0xFF),
230);
m_colors[i].premultiply();
}
}
bool open(const char* fname)
{
return m_shape.open(full_file_name(fname));
}
void read_next()
{
m_shape.read_next();
m_shape.scale(width(), height());
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt_pre> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
typedef agg::scanline_u8 scanline;
pixfmt_pre pixf(rbuf_window());
renderer_base ren_base(pixf);
ren_base.clear(agg::rgba(1.0, 1.0, 0.95));
renderer_scanline ren(ren_base);
unsigned i;
unsigned w = unsigned(width());
m_gradient.resize(w);
agg::srgba8 c1(255, 0, 0, 180);
agg::srgba8 c2(0, 0, 255, 180);
for(i = 0; i < w; i++)
{
m_gradient[i] = c1.gradient(c2, i / width());
m_gradient[i].premultiply();
}
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> ras;
agg::rasterizer_compound_aa<agg::rasterizer_sl_clip_dbl> rasc;
agg::scanline_u8 sl;
agg::scanline_bin sl_bin;
agg::conv_transform<agg::compound_shape> shape(m_shape, m_scale);
agg::conv_stroke<agg::conv_transform<agg::compound_shape> > stroke(shape);
agg::test_styles style_handler(m_colors, m_gradient.data());
agg::span_allocator<color_type> alloc;
m_shape.approximation_scale(m_scale.scale());
// Fill shape
//----------------------
rasc.clip_box(0, 0, width(), height());
rasc.reset();
//rasc.filling_rule(agg::fill_even_odd);
start_timer();
for(i = 0; i < m_shape.paths(); i++)
{
if(m_shape.style(i).left_fill >= 0 ||
m_shape.style(i).right_fill >= 0)
{
rasc.styles(m_shape.style(i).left_fill,
m_shape.style(i).right_fill);
rasc.add_path(shape, m_shape.style(i).path_id);
}
}
agg::render_scanlines_compound(rasc, sl, sl_bin, ren_base, alloc, style_handler);
double tfill = elapsed_time();
// Hit-test test
bool draw_strokes = true;
if(m_hit_x >= 0 && m_hit_y >= 0)
{
if(rasc.hit_test(m_hit_x, m_hit_y))
{
draw_strokes = false;
}
}
// Draw strokes
//----------------------
start_timer();
if(draw_strokes)
{
ras.clip_box(0, 0, width(), height());
stroke.width(sqrt(m_scale.scale()));
stroke.line_join(agg::round_join);
stroke.line_cap(agg::round_cap);
for(i = 0; i < m_shape.paths(); i++)
{
ras.reset();
if(m_shape.style(i).line >= 0)
{
ras.add_path(stroke, m_shape.style(i).path_id);
ren.color(agg::srgba8(0,0,0, 128));
agg::render_scanlines(ras, sl, ren);
}
}
}
double tstroke = elapsed_time();
char buf[256];
agg::gsv_text t;
t.size(8.0);
t.flip(true);
agg::conv_stroke<agg::gsv_text> ts(t);
ts.width(1.6);
ts.line_cap(agg::round_cap);
sprintf(buf, "Fill=%.2fms (%dFPS) Stroke=%.2fms (%dFPS) Total=%.2fms (%dFPS)\n\n"
"Space: Next Shape\n\n"
"+/- : ZoomIn/ZoomOut (with respect to the mouse pointer)",
tfill, int(1000.0 / tfill),
tstroke, int(1000.0 / tstroke),
tfill+tstroke, int(1000.0 / (tfill+tstroke)));
t.start_point(10.0, 20.0);
t.text(buf);
ras.add_path(ts);
ren.color(agg::rgba(0,0,0));
agg::render_scanlines(ras, sl, ren);
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
m_shape.read_next();
m_shape.scale(width(), height());
force_redraw();
}
if(key == '+' || key == agg::key_kp_plus)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_scaling(1.1);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
if(key == '-' || key == agg::key_kp_minus)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_scaling(1/1.1);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
if(key == agg::key_left)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_rotation(-agg::pi / 20.0);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
if(key == agg::key_right)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_rotation(agg::pi / 20.0);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
}
void on_mouse_move(int x, int y, unsigned flags)
{
if((flags & 3) == 0)
{
on_mouse_button_up(x, y, flags);
}
else
{
if(m_point_idx >= 0)
{
double xd = x;
double yd = y;
m_scale.inverse_transform(&xd, &yd);
m_shape.modify_vertex(m_point_idx, xd, yd);
force_redraw();
}
}
}
void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & 1)
{
double xd = x;
double yd = y;
double r = 4.0 / m_scale.scale();
m_scale.inverse_transform(&xd, &yd);
m_point_idx = m_shape.hit_test(xd, yd, r);
force_redraw();
}
if(flags & 2)
{
m_hit_x = x;
m_hit_y = y;
force_redraw();
}
}
void on_mouse_button_up(int x, int y, unsigned flags)
{
m_point_idx = -1;
m_hit_x = -1;
m_hit_y = -1;
force_redraw();
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example - Flash Rasterizer");
const char* fname = "shapes.txt";
if(argc > 1) fname = argv[1];
if(!app.open(fname))
{
char buf[256];
if(strcmp(fname, "shapes.txt") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
fname, fname);
}
else
{
sprintf(buf, "File not found: %s", fname);
}
app.message(buf);
return 1;
}
if(app.init(655, 520, agg::window_resize))
{
app.read_next();
return app.run();
}
return 1;
}

View File

@ -0,0 +1,535 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <limits>
#include "agg_rendering_buffer.h"
#include "agg_trans_viewport.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_conv_curve.h"
#include "agg_conv_stroke.h"
#include "agg_gsv_text.h"
#include "agg_scanline_u.h"
#include "agg_scanline_bin.h"
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_span_allocator.h"
#include "agg_pixfmt_rgba.h"
#include "agg_bounding_rect.h"
#include "platform/agg_platform_support.h"
#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum { flip_y = false };
namespace agg
{
struct path_style
{
unsigned path_id;
int left_fill;
int right_fill;
int line;
};
class compound_shape
{
public:
~compound_shape()
{
if(m_fd)
{
fclose(m_fd);
}
}
compound_shape() :
m_path(),
m_affine(),
m_curve(m_path),
m_trans(m_curve, m_affine),
m_styles(),
m_min_style(std::numeric_limits<int>::max()),
m_max_style(std::numeric_limits<int>::min())
{}
bool open(const char* fname)
{
m_fd = fopen(fname, "r");
return m_fd != 0;
}
bool read_next()
{
m_path.remove_all();
m_styles.remove_all();
m_min_style = std::numeric_limits<int>::max();
m_max_style = std::numeric_limits<int>::min();
const char space[] = " \t\n\r";
double ax, ay, cx, cy;
if(m_fd)
{
char buf[1024];
char* ts;
for(;;)
{
if(fgets(buf, 1022, m_fd) == 0) return false;
if(buf[0] == '=') break;
}
while(fgets(buf, 1022, m_fd))
{
if(buf[0] == '!') break;
if(buf[0] == 'P')
{
// BeginPath
path_style style;
style.path_id = m_path.start_new_path();
ts = strtok(buf, space); // Path;
ts = strtok(0, space); // left_style
style.left_fill = atoi(ts);
ts = strtok(0, space); // right_style
style.right_fill = atoi(ts);
ts = strtok(0, space); // line_style
style.line = atoi(ts);
ts = strtok(0, space); // ax
ax = atof(ts);
ts = strtok(0, space); // ay
ay = atof(ts);
m_path.move_to(ax, ay);
m_styles.add(style);
if(style.left_fill >= 0)
{
if(style.left_fill < m_min_style) m_min_style = style.left_fill;
if(style.left_fill > m_max_style) m_max_style = style.left_fill;
}
if(style.right_fill >= 0)
{
if(style.right_fill < m_min_style) m_min_style = style.right_fill;
if(style.right_fill > m_max_style) m_max_style = style.right_fill;
}
}
if(buf[0] == 'C')
{
ts = strtok(buf, space); // Curve;
ts = strtok(0, space); // cx
cx = atof(ts);
ts = strtok(0, space); // cy
cy = atof(ts);
ts = strtok(0, space); // ax
ax = atof(ts);
ts = strtok(0, space); // ay
ay = atof(ts);
m_path.curve3(cx, cy, ax, ay);
}
if(buf[0] == 'L')
{
ts = strtok(buf, space); // Line;
ts = strtok(0, space); // ax
ax = atof(ts);
ts = strtok(0, space); // ay
ay = atof(ts);
m_path.line_to(ax, ay);
}
if(buf[0] == '<')
{
// EndPath
}
}
return true;
}
return false;
}
unsigned operator [] (unsigned i) const
{
return m_styles[i].path_id;
}
unsigned paths() const { return m_styles.size(); }
const path_style& style(unsigned i) const
{
return m_styles[i];
}
int min_style() const { return m_min_style; }
int max_style() const { return m_max_style; }
void rewind(unsigned path_id)
{
m_trans.rewind(path_id);
}
unsigned vertex(double* x, double* y)
{
return m_trans.vertex(x, y);
}
double scale() const
{
return m_affine.scale();
}
void scale(double w, double h)
{
m_affine.reset();
double x1, y1, x2, y2;
bounding_rect(m_path, *this, 0, m_styles.size(),
&x1, &y1, &x2, &y2);
if(x1 < x2 && y1 < y2)
{
trans_viewport vp;
vp.preserve_aspect_ratio(0.5, 0.5, aspect_ratio_meet);
vp.world_viewport(x1, y1, x2, y2);
vp.device_viewport(0, 0, w, h);
m_affine = vp.to_affine();
}
m_curve.approximation_scale(m_affine.scale());
}
void approximation_scale(double s)
{
m_curve.approximation_scale(m_affine.scale() * s);
}
int hit_test(double x, double y, double r)
{
m_affine.inverse_transform(&x, &y);
r /= m_affine.scale();
unsigned i;
for(i = 0; i < m_path.total_vertices(); i++)
{
double vx, vy;
unsigned cmd = m_path.vertex(i, &vx, &vy);
if(is_vertex(cmd))
{
if(calc_distance(x, y, vx, vy) <= r)
{
return i;
}
}
}
return -1;
}
void modify_vertex(unsigned i, double x, double y)
{
m_affine.inverse_transform(&x, &y);
m_path.modify_vertex(i, x, y);
}
private:
path_storage m_path;
trans_affine m_affine;
conv_curve<path_storage> m_curve;
conv_transform<conv_curve<path_storage> > m_trans;
pod_bvector<path_style> m_styles;
double m_x1, m_y1, m_x2, m_y2;
int m_min_style;
int m_max_style;
FILE* m_fd;
};
}
class the_application : public agg::platform_support
{
public:
agg::compound_shape m_shape;
color_type m_colors[100];
agg::trans_affine m_scale;
int m_point_idx;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_point_idx(-1)
{
for(unsigned i = 0; i < 100; i++)
{
m_colors[i] = agg::srgba8(
(rand() & 0xFF),
(rand() & 0xFF),
(rand() & 0xFF),
230);
m_colors[i].premultiply();
}
}
bool open(const char* fname)
{
return m_shape.open(full_file_name(fname));
}
void read_next()
{
m_shape.read_next();
m_shape.scale(width(), height());
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt_pre> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
typedef agg::scanline_u8 scanline;
pixfmt_pre pixf(rbuf_window());
renderer_base ren_base(pixf);
ren_base.clear(agg::rgba(1.0, 1.0, 0.95));
renderer_scanline ren(ren_base);
agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> ras;
agg::scanline_u8 sl;
agg::conv_transform<agg::compound_shape> shape(m_shape, m_scale);
agg::conv_stroke<agg::conv_transform<agg::compound_shape> > stroke(shape);
m_shape.approximation_scale(m_scale.scale());
unsigned i;
agg::path_storage tmp_path;
ras.clip_box(0, 0, width(), height());
// This is an alternative method of Flash rasterization.
// We decompose the compound shape into separate paths
// and select the ones that fit the given style (left or right).
// So that, we form a sub-shape and draw it as a whole.
//
// Here the regular scanline rasterizer is used, but it doesn't
// automatically close the polygons. So that, the rasterizer
// actually works with a set of polylines instead of polygons.
// Of course, the data integrity must be preserved, that is,
// the polylines must eventually form a closed contour
// (or a set of closed contours). So that, first we set
// auto_close(false);
//
// The second important thing is that one path can be rasterized
// twice, if it has both, left and right fill. Sometimes the
// path has equal left and right fill, so that, the same path
// will be added twice even for a single sub-shape. If the
// rasterizer can tolerate these degenerates you can add them,
// but it's also fine just to omit them.
//
// The third thing is that for one side (left or right)
// you should invert the direction of the paths.
//
// The main disadvantage of this method is imperfect stitching
// of the adjacent polygons. The problem can be solved if we use
// compositing operation "plus" instead of alpha-blend. But
// in this case we are forced to use an RGBA buffer, clean it with
// zero, rasterize using "plus" operation, and then alpha-blend
// the result over the final scene. It can be too expensive.
//------------------------------------------------------------
ras.auto_close(false);
//ras.filling_rule(agg::fill_even_odd);
start_timer();
for(int s = m_shape.min_style(); s <= m_shape.max_style(); s++)
{
ras.reset();
for(i = 0; i < m_shape.paths(); i++)
{
const agg::path_style& style = m_shape.style(i);
if(style.left_fill != style.right_fill)
{
if(style.left_fill == s)
{
ras.add_path(shape, style.path_id);
}
if(style.right_fill == s)
{
tmp_path.remove_all();
tmp_path.concat_path(shape, style.path_id);
tmp_path.invert_polygon(0);
ras.add_path(tmp_path);
}
}
}
agg::render_scanlines_aa_solid(ras, sl, ren_base, m_colors[s]);
}
double tfill = elapsed_time();
ras.auto_close(true);
// Draw strokes
//----------------------
start_timer();
stroke.width(sqrt(m_scale.scale()));
stroke.line_join(agg::round_join);
stroke.line_cap(agg::round_cap);
for(i = 0; i < m_shape.paths(); i++)
{
ras.reset();
if(m_shape.style(i).line >= 0)
{
ras.add_path(stroke, m_shape.style(i).path_id);
ren.color(agg::srgba8(0,0,0, 128));
agg::render_scanlines(ras, sl, ren);
}
}
double tstroke = elapsed_time();
char buf[256];
agg::gsv_text t;
t.size(8.0);
t.flip(true);
agg::conv_stroke<agg::gsv_text> ts(t);
ts.width(1.6);
ts.line_cap(agg::round_cap);
sprintf(buf, "Fill=%.2fms (%dFPS) Stroke=%.2fms (%dFPS) Total=%.2fms (%dFPS)\n\n"
"Space: Next Shape\n\n"
"+/- : ZoomIn/ZoomOut (with respect to the mouse pointer)",
tfill, int(1000.0 / tfill),
tstroke, int(1000.0 / tstroke),
tfill+tstroke, int(1000.0 / (tfill+tstroke)));
t.start_point(10.0, 20.0);
t.text(buf);
ras.add_path(ts);
ren.color(agg::rgba(0,0,0));
agg::render_scanlines(ras, sl, ren);
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
m_shape.read_next();
m_shape.scale(width(), height());
force_redraw();
}
if(key == '+' || key == agg::key_kp_plus)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_scaling(1.1);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
if(key == '-' || key == agg::key_kp_minus)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_scaling(1/1.1);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
if(key == agg::key_left)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_rotation(-agg::pi / 20.0);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
if(key == agg::key_right)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_rotation(agg::pi / 20.0);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
}
void on_mouse_move(int x, int y, unsigned flags)
{
if((flags & 1) == 0)
{
on_mouse_button_up(x, y, flags);
}
else
{
if(m_point_idx >= 0)
{
double xd = x;
double yd = y;
m_scale.inverse_transform(&xd, &yd);
m_shape.modify_vertex(m_point_idx, xd, yd);
force_redraw();
}
}
}
void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & 1)
{
double xd = x;
double yd = y;
double r = 4.0 / m_scale.scale();
m_scale.inverse_transform(&xd, &yd);
m_point_idx = m_shape.hit_test(xd, yd, r);
force_redraw();
}
}
void on_mouse_button_up(int x, int y, unsigned flags)
{
m_point_idx = -1;
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example - Flash Rasterizer");
const char* fname = "shapes.txt";
if(argc > 1) fname = argv[1];
if(!app.open(fname))
{
char buf[256];
if(strcmp(fname, "shapes.txt") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
fname, fname);
}
else
{
sprintf(buf, "File not found: %s", fname);
}
app.message(buf);
return 1;
}
if(app.init(655, 520, agg::window_resize))
{
app.read_next();
return app.run();
}
return 1;
}

484
examples/freetype_test.cpp Normal file
View File

@ -0,0 +1,484 @@
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_scanline_u.h"
#include "agg_scanline_bin.h"
#include "agg_renderer_scanline.h"
#include "agg_renderer_primitives.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_conv_curve.h"
#include "agg_conv_contour.h"
#include "agg_pixfmt_rgb.h"
#include "agg_font_freetype.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
bool font_flip_y = !flip_y;
static char text[] =
"Anti-Grain Geometry is designed as a set of loosely coupled "
"algorithms and class templates united with a common idea, "
"so that all the components can be easily combined. Also, "
"the template based design allows you to replace any part of "
"the library without the necessity to modify a single byte in "
"the existing code. "
"AGG is designed keeping in mind extensibility and flexibility. "
"Basically I just wanted to create a toolkit that would allow me "
"(and anyone else) to add new fancy algorithms very easily. "
"AGG does not dictate you any style of its use, you are free to "
"use any part of it. However, AGG is often associated with a tool "
"for rendering images in memory. That is not quite true, but it can "
"be a good starting point in studying. The tutorials describe the "
"use of AGG starting from the low level functionality that deals with "
"frame buffers and pixels. Then you will gradually understand how to "
"abstract different parts of the library and how to use them separately. "
"Remember, the raster picture is often not the only thing you want to "
"obtain, you will probably want to print your graphics with highest "
"possible quality and in this case you can easily combine the \"vectorial\" "
"part of the library with some API like Windows GDI, having a common "
"external interface. If that API can render multi-polygons with non-zero "
"and even-odd filling rules it's all you need to incorporate AGG into "
"your application. For example, Windows API PolyPolygon perfectly fits "
"these needs, except certain advanced things like gradient filling, "
"Gouraud shading, image transformations, and so on. Or, as an alternative, "
"you can use all AGG algorithms producing high resolution pixel images and "
"then to send the result to the printer as a pixel map."
"Below is a typical brief scheme of the AGG rendering pipeline. "
"Please note that any component between the Vertex Source "
"and Screen Output is not mandatory. It all depends on your "
"particular needs. For example, you can use your own rasterizer, "
"based on Windows API. In this case you won't need the AGG rasterizer "
"and renderers. Or, if you need to draw only lines, you can use the "
"AGG outline rasterizer that has certain restrictions but works faster. "
"The number of possibilities is endless. "
"Vertex Source is some object that produces polygons or polylines as "
"a set of consecutive 2D vertices with commands like MoveTo, LineTo. "
"It can be a container or some other object that generates vertices "
"on demand. "
"Coordinate conversion pipeline consists of a number of coordinate "
"converters. It always works with vectorial data (X,Y) represented "
"as floating point numbers (double). For example, it can contain an "
"affine transformer, outline (stroke) generator, some marker "
"generator (like arrowheads/arrowtails), dashed lines generator, "
"and so on. The pipeline can have branches and you also can have "
"any number of different pipelines. You also can write your own "
"converter and include it into the pipeline. "
"Scanline Rasterizer converts vectorial data into a number of "
"horizontal scanlines. The scanlines usually (but not obligatory) "
"carry information about Anti-Aliasing as coverage values. "
"Renderers render scanlines, sorry for the tautology. The simplest "
"example is solid filling. The renderer just adds a color to the "
"scanline and writes the result into the rendering buffer. "
"More complex renderers can produce multi-color result, "
"like gradients, Gouraud shading, image transformations, "
"patterns, and so on. Rendering Buffer is a buffer in memory "
"that will be displayed afterwards. Usually but not obligatory "
"it contains pixels in format that fits your video system. "
"For example, 24 bits B-G-R, 32 bits B-G-R-A, or 15 "
"bits R-G-B-555 for Windows. But in general, there're no "
"restrictions on pixel formats or color space if you write "
"your own low level class that supports that format. "
"Colors in AGG appear only in renderers, that is, when you "
"actually put some data to the rendering buffer. In general, "
"there's no general purpose structure or class like color, "
"instead, AGG always operates with concrete color space. "
"There are plenty of color spaces in the world, like RGB, "
"HSV, CMYK, etc., and all of them have certain restrictions. "
"For example, the RGB color space is just a poor subset of "
"colors that a human eye can recognize. If you look at the full "
"CIE Chromaticity Diagram, you will see that the RGB triangle "
"is just a little part of it. "
"In other words there are plenty of colors in the real world "
"that cannot be reproduced with RGB, CMYK, HSV, etc. Any color "
"space except the one existing in Nature is restrictive. Thus, "
"it was decided not to introduce such an object like color in "
"order not to restrict the possibilities in advance. Instead, "
"there are objects that operate with concrete color spaces. "
"Currently there are agg::rgba and agg::srgba8 that operate "
"with the most popular RGB color space (strictly speaking there's "
"RGB plus Alpha). The RGB color space is used with different "
"pixel formats, like 24-bit RGB or 32-bit RGBA with different "
"order of color components. But the common property of all of "
"them is that they are essentially RGB. Although, AGG doesn't "
"explicitly support any other color spaces, there is at least "
"a potential possibility of adding them. It means that all "
"class and function templates that depend on the color type "
"are parameterized with the ColorT argument. "
"Basically, AGG operates with coordinates of the output device. "
"On your screen there are pixels. But unlike many other libraries "
"and APIs AGG initially supports Subpixel Accuracy. It means "
"that the coordinates are represented as doubles, where fractional "
"values actually take effect. AGG doesn't have an embedded "
"conversion mechanism from world to screen coordinates in order "
"not to restrict your freedom. It's very important where and when "
"you do that conversion, so, different applications can require "
"different approaches. AGG just provides you a transformer of "
"that kind, namely, that can convert your own view port to the "
"device one. And it's your responsibility to include it into "
"the proper place of the pipeline. You can also write your "
"own very simple class that will allow you to operate with "
"millimeters, inches, or any other physical units. "
"Internally, the rasterizers use integer coordinates of the "
"format 24.8 bits, that is, 24 bits for the integer part and 8 "
"bits for the fractional one. In other words, all the internal "
"coordinates are multiplied by 256. If you intend to use AGG in "
"some embedded system that has inefficient floating point "
"processing, you still can use the rasterizers with their "
"integer interfaces. Although, you won't be able to use the "
"floating point coordinate pipelines in this case. ";
template<class VS> void dump_path(VS& path)
{
FILE* fd = fopen("dump_path", "a");
fprintf(fd, "-------\n");
path.rewind(0);
unsigned cmd;
double x, y;
while(!agg::is_stop(cmd = path.vertex(&x, &y)))
{
fprintf(fd, "%02X %8.2f %8.2f\n", cmd, x, y);
}
fclose(fd);
}
class the_application : public agg::platform_support
{
typedef agg::renderer_base<pixfmt> base_ren_type;
typedef agg::renderer_scanline_aa_solid<base_ren_type> renderer_solid;
typedef agg::renderer_scanline_bin_solid<base_ren_type> renderer_bin;
typedef agg::font_engine_freetype_int32 font_engine_type;
typedef agg::font_cache_manager<font_engine_type> font_manager_type;
agg::rbox_ctrl<color_type> m_ren_type;
agg::slider_ctrl<color_type> m_height;
agg::slider_ctrl<color_type> m_width;
agg::slider_ctrl<color_type> m_weight;
agg::slider_ctrl<color_type> m_gamma;
agg::cbox_ctrl<color_type> m_hinting;
agg::cbox_ctrl<color_type> m_kerning;
agg::cbox_ctrl<color_type> m_performance;
font_engine_type m_feng;
font_manager_type m_fman;
double m_old_height;
// Pipeline to process the vectors glyph paths (curves + contour)
agg::conv_curve<font_manager_type::path_adaptor_type> m_curves;
agg::conv_contour<agg::conv_curve<font_manager_type::path_adaptor_type> > m_contour;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_ren_type (5.0, 5.0, 5.0+150.0, 110.0, !flip_y),
m_height (160, 10.0, 640-5.0, 18.0, !flip_y),
m_width (160, 30.0, 640-5.0, 38.0, !flip_y),
m_weight (160, 50.0, 640-5.0, 58.0, !flip_y),
m_gamma (260, 70.0, 640-5.0, 78.0, !flip_y),
m_hinting (160, 65.0, "Hinting", !flip_y),
m_kerning (160, 80.0, "Kerning", !flip_y),
m_performance (160, 95.0, "Test Performance", !flip_y),
m_feng(),
m_fman(m_feng),
m_old_height(0.0),
m_curves(m_fman.path_adaptor()),
m_contour(m_curves)
{
m_ren_type.add_item("Native Mono");
m_ren_type.add_item("Native Gray 8");
m_ren_type.add_item("Outline");
m_ren_type.add_item("AGG Mono");
m_ren_type.add_item("AGG Gray 8");
m_ren_type.cur_item(1);
add_ctrl(m_ren_type);
m_ren_type.no_transform();
m_height.label("Font Height=%.2f");
m_height.range(8, 32);
m_height.num_steps(32-8);
m_height.value(18);
m_height.text_thickness(1.5);
add_ctrl(m_height);
m_height.no_transform();
m_width.label("Font Width=%.2f");
m_width.range(8, 32);
m_width.num_steps(32-8);
m_width.text_thickness(1.5);
m_width.value(18);
add_ctrl(m_width);
m_width.no_transform();
m_weight.label("Font Weight=%.2f");
m_weight.range(-1, 1);
m_weight.text_thickness(1.5);
add_ctrl(m_weight);
m_weight.no_transform();
m_gamma.label("Gamma=%.2f");
m_gamma.range(0.1, 2.0);
m_gamma.value(1.0);
m_gamma.text_thickness(1.5);
add_ctrl(m_gamma);
m_gamma.no_transform();
add_ctrl(m_hinting);
m_hinting.status(true);
m_hinting.no_transform();
add_ctrl(m_kerning);
m_kerning.status(true);
m_kerning.no_transform();
add_ctrl(m_performance);
m_performance.no_transform();
m_curves.approximation_scale(2.0);
m_contour.auto_detect_orientation(false);
}
template<class Rasterizer, class Scanline, class RenSolid, class RenBin>
unsigned draw_text(Rasterizer& ras, Scanline& sl,
RenSolid& ren_solid, RenBin& ren_bin)
{
agg::glyph_rendering gren = agg::glyph_ren_native_mono;
switch(m_ren_type.cur_item())
{
case 0: gren = agg::glyph_ren_native_mono; break;
case 1: gren = agg::glyph_ren_native_gray8; break;
case 2: gren = agg::glyph_ren_outline; break;
case 3: gren = agg::glyph_ren_agg_mono; break;
case 4: gren = agg::glyph_ren_agg_gray8; break;
}
unsigned num_glyphs = 0;
m_contour.width(-m_weight.value() * m_height.value() * 0.05);
if(m_feng.load_font(full_file_name("timesi.ttf"), 0, gren))
{
m_feng.hinting(m_hinting.status());
m_feng.height(m_height.value());
m_feng.width(m_width.value());
m_feng.flip_y(font_flip_y);
agg::trans_affine mtx;
mtx *= agg::trans_affine_rotation(agg::deg2rad(-4.0));
//mtx *= agg::trans_affine_skewing(-0.4, 0);
//mtx *= agg::trans_affine_translation(1, 0);
m_feng.transform(mtx);
double x = 10.0;
double y0 = height() - m_height.value() - 10.0;
double y = y0;
const char* p = text;
while(*p)
{
const agg::glyph_cache* glyph = m_fman.glyph(*p);
if(glyph)
{
if(m_kerning.status())
{
m_fman.add_kerning(&x, &y);
}
if(x >= width() - m_height.value())
{
x = 10.0;
y0 -= m_height.value();
if(y0 <= 120) break;
y = y0;
}
m_fman.init_embedded_adaptors(glyph, x, y);
switch(glyph->data_type)
{
default: break;
case agg::glyph_data_mono:
ren_bin.color(agg::srgba8(0, 0, 0));
agg::render_scanlines(m_fman.mono_adaptor(),
m_fman.mono_scanline(),
ren_bin);
break;
case agg::glyph_data_gray8:
ren_solid.color(agg::srgba8(0, 0, 0));
agg::render_scanlines(m_fman.gray8_adaptor(),
m_fman.gray8_scanline(),
ren_solid);
break;
case agg::glyph_data_outline:
ras.reset();
if(fabs(m_weight.value()) <= 0.01)
{
// For the sake of efficiency skip the
// contour converter if the weight is about zero.
//-----------------------
ras.add_path(m_curves);
}
else
{
ras.add_path(m_contour);
}
ren_solid.color(agg::srgba8(0, 0, 0));
agg::render_scanlines(ras, sl, ren_solid);
//dump_path(m_fman.path_adaptor());
break;
}
// increment pen position
x += glyph->advance_x;
y += glyph->advance_y;
++num_glyphs;
}
++p;
}
}
else
{
message("Please copy file timesi.ttf to the current directory\n"
"or unzip it from ../art/timesi.zip");
}
return num_glyphs;
}
virtual void on_draw()
{
pixfmt pf(rbuf_window());
base_ren_type ren_base(pf);
renderer_solid ren_solid(ren_base);
renderer_bin ren_bin(ren_base);
ren_base.clear(agg::rgba(1,1,1));
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
if(m_height.value() != m_old_height)
{
m_width.value(m_old_height = m_height.value());
}
if(m_ren_type.cur_item() == 3)
{
// When rendering in mono format,
// Set threshold gamma = 0.5
//-------------------
m_feng.gamma(agg::gamma_threshold(m_gamma.value() / 2.0));
}
else
{
m_feng.gamma(agg::gamma_power(m_gamma.value()));
}
if(m_ren_type.cur_item() == 2)
{
// For outline cache set gamma for the rasterizer
//-------------------
ras.gamma(agg::gamma_power(m_gamma.value()));
}
//ren_base.copy_hline(0, int(height() - m_height.value()) - 10, 100, agg::rgba(0,0,0));
draw_text(ras, sl, ren_solid, ren_bin);
ras.gamma(agg::gamma_power(1.0));
agg::render_ctrl(ras, sl, ren_base, m_ren_type);
agg::render_ctrl(ras, sl, ren_base, m_height);
agg::render_ctrl(ras, sl, ren_base, m_width);
agg::render_ctrl(ras, sl, ren_base, m_weight);
agg::render_ctrl(ras, sl, ren_base, m_gamma);
agg::render_ctrl(ras, sl, ren_base, m_hinting);
agg::render_ctrl(ras, sl, ren_base, m_kerning);
agg::render_ctrl(ras, sl, ren_base, m_performance);
}
virtual void on_ctrl_change()
{
if(m_performance.status())
{
pixfmt pf(rbuf_window());
base_ren_type ren_base(pf);
renderer_solid ren_solid(ren_base);
renderer_bin ren_bin(ren_base);
ren_base.clear(agg::rgba(1,1,1));
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
unsigned num_glyphs = 0;
start_timer();
for(int i = 0; i < 50; i++)
{
num_glyphs += draw_text(ras, sl, ren_solid, ren_bin);
}
double t = elapsed_time();
char buf[100];
sprintf(buf,
"Glyphs=%u, Time=%.3fms, %.3f glyps/sec, %.3f microsecond/glyph",
num_glyphs,
t,
(num_glyphs / t) * 1000.0,
(t / num_glyphs) * 1000.0);
message(buf);
m_performance.status(false);
force_redraw();
}
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
font_flip_y = !font_flip_y;
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Rendering Fonts with FreeType");
if(app.init(640, 520, agg::window_resize))
{
return app.run();
}
return 1;
}

View File

@ -0,0 +1,178 @@
#include <stdio.h>
#include "agg_trans_affine.h"
#include "agg_conv_stroke.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_rendering_buffer.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_gamma_lut.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
// Only 8-bit formats support gamma, so here's a way to turn it off.
#define ENABLE_GAMMA_CTRL 1
// Corrected sRGB, should look right with gamma at 1.0.
#define AGG_BGR24
// Uncorrected sRGB, should look right with gamma at ~2.2.
//#define AGG_SBGR24
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_thickness;
agg::slider_ctrl<color_type> m_contrast;
agg::slider_ctrl<color_type> m_gamma;
double m_rx;
double m_ry;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_thickness(5, 5, 400-5, 11, !flip_y),
m_contrast (5, 5+15, 400-5, 11+15, !flip_y),
m_gamma (5, 5+30, 400-5, 11+30, !flip_y)
{
add_ctrl(m_thickness);
m_thickness.label("Thickness=%3.2f");
m_thickness.range(0.0, 3.0);
m_thickness.value(1.0);
add_ctrl(m_contrast);
m_contrast.label("Contrast");
m_contrast.range(0.0, 1.0);
m_contrast.value(1.0);
#if ENABLE_GAMMA_CTRL
add_ctrl(m_gamma);
m_gamma.label("Gamma=%3.2f");
m_gamma.range(0.5, 3.0);
m_gamma.value(1.0);
#endif
}
virtual void on_init()
{
m_rx = width() / 3.0;
m_ry = height() / 3.0;
}
virtual void on_draw()
{
#if ENABLE_GAMMA_CTRL
typedef agg::gamma_lut<agg::int8u, agg::int8u, 8, 8> gamma_type;
typedef pixfmt_gamma<gamma_type> pixfmt_type;
typedef agg::renderer_base<pixfmt_type> ren_base;
double g = m_gamma.value();
gamma_type gamma(g);
pixfmt_type pixf(rbuf_window(), gamma);
#else
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
#endif
ren_base renb(pixf);
renb.clear(agg::rgba(1, 1, 1));
double dark = 1.0 - m_contrast.value();
double light = m_contrast.value();
renb.copy_bar(0,0,int(width())/2, int(height()), agg::rgba(dark,dark,dark));
renb.copy_bar(int(width())/2+1,0, int(width()), int(height()), agg::rgba(light,light,light));
renb.copy_bar(0,int(height())/2+1, int(width()), int(height()), agg::rgba(1.0,dark,dark));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::path_storage path;
#if ENABLE_GAMMA_CTRL
unsigned i;
double x = (width() - 256.0) / 2.0;
double y = 50.0;
path.remove_all();
agg::gamma_power gp(g);
for(i = 0; i < 256; i++)
{
double v = double(i) / 255.0;
double gval = gp(v);
double dy = gval * 255.0;
if(i == 0) path.move_to(x + i, y + dy);
else path.line_to(x + i, y + dy);
}
agg::conv_stroke<agg::path_storage> gpoly(path);
gpoly.width(2.0);
ras.reset();
ras.add_path(gpoly);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(80,127,80));
#endif
agg::ellipse ell(width() / 2, height() / 2, m_rx, m_ry, 150);
agg::conv_stroke<agg::ellipse> poly(ell);
poly.width(m_thickness.value());
ras.reset();
ras.add_path(poly);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(255,0,0));
ell.init(width() / 2, height() / 2, m_rx-5.0, m_ry-5.0, 150);
ras.reset();
ras.add_path(poly);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(0,255,0));
ell.init(width() / 2, height() / 2, m_rx-10.0, m_ry-10.0, 150);
ras.reset();
ras.add_path(poly);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(0,0,255));
ell.init(width() / 2, height() / 2, m_rx-15.0, m_ry-15.0, 150);
ras.reset();
ras.add_path(poly);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(0,0,0));
ell.init(width() / 2, height() / 2, m_rx-20.0, m_ry-20.0, 150);
ras.reset();
ras.add_path(poly);
agg::render_scanlines_aa_solid(ras, sl, renb, agg::srgba8(255,255,255));
agg::render_ctrl(ras, sl, renb, m_thickness);
agg::render_ctrl(ras, sl, renb, m_contrast);
#if ENABLE_GAMMA_CTRL
agg::render_ctrl(ras, sl, renb, m_gamma);
#endif
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_rx = fabs(width()/2 - x);
m_ry = fabs(height()/2 - y);
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
on_mouse_button_down(x, y, flags);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Thin red ellipse");
if(app.init(400, 320, 0))
{
return app.run();
}
return 1;
}

251
examples/gamma_ctrl.cpp Normal file
View File

@ -0,0 +1,251 @@
#include <stdio.h>
#include <stdlib.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_gsv_text.h"
#include "agg_conv_stroke.h"
#include "agg_path_storage.h"
#include "ctrl/agg_gamma_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGR96
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
agg::gamma_ctrl<color_type> g_ctrl(10.0, 10.0, 300.0, 200.0, !flip_y);
void read_gamma(const char* fname)
{
FILE* fd = fopen(fname, "rb");
if(fd)
{
char buf[32];
double kx1, ky1, kx2, ky2;
fgets(buf, 30, fd); kx1 = atof(buf);
fgets(buf, 30, fd); ky1 = atof(buf);
fgets(buf, 30, fd); kx2 = atof(buf);
fgets(buf, 30, fd); ky2 = atof(buf);
g_ctrl.values(kx1, ky1, kx2, ky2);
fclose(fd);
}
}
void write_gamma_bin(const char* fname)
{
const unsigned char* gamma = g_ctrl.gamma();
FILE* fd = fopen(fname, "wb");
if(fd)
{
fwrite(gamma, 256, 1, fd);
fclose(fd);
}
}
void write_gamma_txt(const char* fname)
{
const unsigned char* gamma = g_ctrl.gamma();
FILE* fd = fopen(fname, "w");
if(fd)
{
double kx1, ky1, kx2, ky2;
g_ctrl.values(&kx1, &ky1, &kx2, &ky2);
fprintf(fd, "%5.3f\n", kx1);
fprintf(fd, "%5.3f\n", ky1);
fprintf(fd, "%5.3f\n", kx2);
fprintf(fd, "%5.3f\n", ky2);
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 16; j++)
{
fprintf(fd, "%3d,", gamma[i*16 + j]);
}
fprintf(fd, "\n");
}
fclose(fd);
}
}
class the_application : public agg::platform_support
{
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y)
{
add_ctrl(g_ctrl);
}
virtual void on_init()
{
read_gamma(full_file_name("gamma.txt"));
}
virtual ~the_application()
{
write_gamma_txt(full_file_name("gamma.txt"));
write_gamma_bin(full_file_name("gamma.bin"));
}
virtual void on_draw()
{
double ewidth = initial_width() / 2 - 10;
double ecenter = initial_width() / 2;
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base rb(pixf);
agg::srgba8 color;
rb.clear(agg::rgba(1, 1, 1));
g_ctrl.text_size(10.0, 12.0);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
agg::render_ctrl(ras, sl, rb, g_ctrl);
ras.gamma(g_ctrl);
agg::ellipse ellipse;
agg::conv_stroke<agg::ellipse> poly(ellipse);
agg::conv_transform<agg::conv_stroke<agg::ellipse> > tpoly(poly, trans_affine_resizing());
color = agg::srgba8(0, 0, 0);
ellipse.init(ecenter, 220, ewidth, 15, 100);
poly.width(2.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 220, 11, 11, 100);
poly.width(2.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
color = agg::srgba8(127, 127, 127);
ellipse.init(ecenter, 260, ewidth, 15, 100);
poly.width(2.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 260, 11, 11, 100);
poly.width(2.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
color = agg::srgba8(192, 192, 192);
ellipse.init(ecenter, 300, ewidth, 15, 100);
poly.width(2.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 300, 11, 11, 100);
poly.width(2.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
color = agg::rgba(0.0, 0.0, 0.4);
ellipse.init(ecenter, 340, ewidth, 15.5, 100);
poly.width(1.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 340, 10.5, 10.5, 100);
poly.width(1.0);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 380, ewidth, 15.5, 100);
poly.width(0.4);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 380, 10.5, 10.5, 100);
poly.width(0.4);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 420, ewidth, 15.5, 100);
poly.width(0.1);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
ellipse.init(ecenter, 420, 10.5, 10.5, 100);
poly.width(0.1);
ras.add_path(tpoly, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
agg::trans_affine mtx;
mtx *= agg::trans_affine_skewing(0.15, 0.0);
mtx *= trans_affine_resizing();
agg::gsv_text text;
agg::gsv_text_outline<agg::trans_affine> text1(text, mtx);
text.text("Text 2345");
text.size(50, 20);
text1.width(2.0);
text.start_point(320, 10);
color = agg::rgba(0.0, 0.5, 0.0);
ras.add_path(text1, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
color = agg::rgba(0.5, 0.0, 0.0);
agg::path_storage path;
path.move_to(30, -1.0);
path.line_to(60, 0.0);
path.line_to(30, 1.0);
path.move_to(27, -1.0);
path.line_to(10, 0.0);
path.line_to(27, 1.0);
agg::conv_transform<agg::path_storage> trans(path, mtx);
for(int i = 0; i < 35; i++)
{
mtx.reset();
mtx *= agg::trans_affine_rotation(double(i) / 35.0 * agg::pi * 2.0);
mtx *= agg::trans_affine_translation(400, 130);
mtx *= trans_affine_resizing();
ras.add_path(trans, 0);
agg::render_scanlines_aa_solid(ras, sl, rb, color);
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Anti-Aliasing Gamma Correction");
if(app.init(500, 400, agg::window_resize))
{
return app.run();
}
return 1;
}

236
examples/gamma_tuner.cpp Normal file
View File

@ -0,0 +1,236 @@
#include <stdio.h>
#include "agg_trans_affine.h"
#include "agg_conv_stroke.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_rendering_buffer.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_gamma_lut.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "platform/agg_platform_support.h"
#include "agg_pixfmt_rgb.h"
// This example only makes any sense in uncorrected sRGB.
#define AGG_SBGR24
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_gamma;
agg::slider_ctrl<color_type> m_r;
agg::slider_ctrl<color_type> m_g;
agg::slider_ctrl<color_type> m_b;
agg::rbox_ctrl <agg::srgba8> m_pattern;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_r (5, 5, 350-5, 11, !flip_y),
m_g (5, 5+15, 350-5, 11+15, !flip_y),
m_b (5, 5+30, 350-5, 11+30, !flip_y),
m_gamma (5, 5+45, 350-5, 11+45, !flip_y),
m_pattern (355, 1, 495, 60, !flip_y)
{
add_ctrl(m_r);
m_r.value(1.0);
m_r.label("R=%.2f");
add_ctrl(m_g);
m_g.value(1.0);
m_g.label("G=%.2f");
add_ctrl(m_b);
m_b.value(1.0);
m_b.label("B=%.2f");
add_ctrl(m_gamma);
m_gamma.range(0.5, 4.0);
m_gamma.value(2.2);
m_gamma.label("Gamma=%.2f");
m_pattern.text_size(8);
m_pattern.add_item("Horizontal");
m_pattern.add_item("Vertical");
m_pattern.add_item("Checkered");
m_pattern.cur_item(2);
add_ctrl(m_pattern);
}
virtual void on_init()
{
}
virtual void on_draw()
{
typedef agg::gamma_lut<color_type::value_type, color_type::value_type,
color_type::base_shift, color_type::base_shift> gamma_type;
typedef pixfmt_gamma<gamma_type> pixfmt_type;
typedef agg::renderer_base<pixfmt_type> ren_base;
double g = m_gamma.value();
gamma_type gamma(g);
pixfmt_type pixf(rbuf_window(), gamma);
ren_base renb(pixf);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
enum
{
square_size = 400,
ver_strips = 5
};
color_type span1[square_size];
color_type span2[square_size];
color_type color(agg::rgba(m_r.value(), m_g.value(), m_b.value()));
unsigned i, j;
// Draw vertical gradient
//-----------------------
unsigned w = (unsigned)width();
unsigned h = (unsigned)height();
for(i = 0; i < h; i++)
{
double k = (i - 80) / double(square_size - 1);
if(i < 80) k = 0.0;
if(i >= 80+square_size) k = 1.0;
k = 1 - pow(k/2, 1/m_gamma.value());
color_type c = color.gradient(color_type(0,0,0), k);
renb.copy_hline(0, i, w-1, c);
}
// Calculate spans
//-----------------------
switch(m_pattern.cur_item())
{
case 0:
for(i = 0; i < square_size; i++)
{
span1[i] = span2[i] = color;
span1[i].a = i * color_type::full_value() / square_size;
span2[i].a = color_type::full_value() - span1[i].a;
}
break;
case 1:
for(i = 0; i < square_size; i++)
{
span1[i] = span2[i] = color;
if(i & 1)
{
span1[i].a = i * color_type::full_value() / square_size;
span2[i].a = span1[i].a;
}
else
{
span1[i].a = color_type::full_value() -
i * color_type::full_value() / square_size;
span2[i].a = span1[i].a;
}
}
break;
case 2:
for(i = 0; i < square_size; i++)
{
span1[i] = span2[i] = color;
if(i & 1)
{
span1[i].a = i * color_type::full_value() / square_size;
span2[i].a = color_type::full_value() - span1[i].a;
}
else
{
span2[i].a = i * color_type::full_value() / square_size;
span1[i].a = color_type::full_value() - span2[i].a;
}
}
break;
}
// Clear the area
//---------------------
renb.copy_bar(50, 80, 50+square_size-1, 80+square_size-1, agg::rgba(0,0,0));
// Draw the patern
//---------------------
for(i = 0; i < square_size; i += 2)
{
double k = i / double(square_size - 1);
k = 1 - pow(k, 1/m_gamma.value());
color_type c = color.gradient(agg::rgba(0,0,0), k);
for(j = 0; j < square_size; j++)
{
span1[j].r = span2[j].r = c.r;
span1[j].g = span2[j].g = c.g;
span1[j].b = span2[j].b = c.b;
}
renb.blend_color_hspan(50, i + 80 + 0, square_size, span1, 0, 255);
renb.blend_color_hspan(50, i + 80 + 1, square_size, span2, 0, 255);
}
// Draw vertical strips
//---------------------
for(i = 0; i < square_size; i++)
{
double k = i / double(square_size - 1);
k = 1 - pow(k/2, 1/m_gamma.value());
color_type c = color.gradient(color_type(0,0,0), k);
for(j = 0; j < ver_strips; j++)
{
int xc = square_size * (j + 1) / (ver_strips + 1);
renb.copy_hline(50+xc-10, i+80, 50+xc+10, c);
}
}
agg::render_ctrl(ras, sl, renb, m_gamma);
agg::render_ctrl(ras, sl, renb, m_r);
agg::render_ctrl(ras, sl, renb, m_g);
agg::render_ctrl(ras, sl, renb, m_b);
agg::render_ctrl(ras, sl, renb, m_pattern);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Gamma Tuner");
if(app.init(500, 500, 0))
{
return app.run();
}
return 1;
}

314
examples/gouraud.cpp Normal file
View File

@ -0,0 +1,314 @@
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_span_allocator.h"
#include "agg_span_gouraud_rgba.h"
#include "agg_span_gouraud_gray.h"
#include "agg_span_solid.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
//#define AGG_GRAY8
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
#include "agg_math.h"
#include "agg_dda_line.h"
class the_application : public agg::platform_support
{
double m_x[3];
double m_y[3];
double m_dx;
double m_dy;
int m_idx;
agg::slider_ctrl<agg::rgba> m_dilation;
agg::slider_ctrl<agg::rgba> m_gamma;
agg::slider_ctrl<agg::rgba> m_alpha;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_idx(-1),
m_dilation(5, 5, 400-5, 11, !flip_y),
m_gamma (5, 5+15, 400-5, 11+15, !flip_y),
m_alpha (5, 5+30, 400-5, 11+30, !flip_y)
{
m_x[0] = 57; m_y[0] = 60;
m_x[1] = 369; m_y[1] = 170;
m_x[2] = 143; m_y[2] = 310;
add_ctrl(m_dilation);
add_ctrl(m_gamma);
add_ctrl(m_alpha);
m_dilation.label("Dilation=%3.2f");
m_gamma.label("Linear gamma=%3.2f");
m_alpha.label("Opacity=%3.2f");
m_dilation.value(0.175);
m_gamma.value(0.809);
m_alpha.value(1.0);
}
template<class Scanline, class Ras>
void render_gouraud(Scanline& sl, Ras& ras)
{
double alpha = m_alpha.value();
double brc = 1;
typedef agg::renderer_base<pixfmt> base_ren_type;
#ifdef AGG_GRAY8
typedef agg::span_gouraud_gray<color_type> span_gen_type;
#else
typedef agg::span_gouraud_rgba<color_type> span_gen_type;
#endif
typedef agg::span_allocator<color_type> span_alloc_type;
pixfmt pf(rbuf_window());
base_ren_type ren_base(pf);
span_alloc_type span_alloc;
span_gen_type span_gen;
ras.gamma(agg::gamma_linear(0.0, m_gamma.value()));
double d = m_dilation.value();
// Single triangle
//span_gen.colors(agg::rgba(1, 0, 0, alpha),
// agg::rgba(0, 1, 0, alpha),
// agg::rgba(0, 0, 1, alpha));
//span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], m_x[2], m_y[2], d);
//ras.add_path(span_gen);
//agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
// Six triangles
double xc = (m_x[0] + m_x[1] + m_x[2]) / 3.0;
double yc = (m_y[0] + m_y[1] + m_y[2]) / 3.0;
double x1 = (m_x[1] + m_x[0]) / 2 - (xc - (m_x[1] + m_x[0]) / 2);
double y1 = (m_y[1] + m_y[0]) / 2 - (yc - (m_y[1] + m_y[0]) / 2);
double x2 = (m_x[2] + m_x[1]) / 2 - (xc - (m_x[2] + m_x[1]) / 2);
double y2 = (m_y[2] + m_y[1]) / 2 - (yc - (m_y[2] + m_y[1]) / 2);
double x3 = (m_x[0] + m_x[2]) / 2 - (xc - (m_x[0] + m_x[2]) / 2);
double y3 = (m_y[0] + m_y[2]) / 2 - (yc - (m_y[0] + m_y[2]) / 2);
span_gen.colors(agg::rgba(1, 0, 0, alpha),
agg::rgba(0, 1, 0, alpha),
agg::rgba(brc, brc, brc, alpha));
span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], xc, yc, d);
ras.add_path(span_gen);
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
span_gen.colors(agg::rgba(0, 1, 0, alpha),
agg::rgba(0, 0, 1, alpha),
agg::rgba(brc, brc, brc, alpha));
span_gen.triangle(m_x[1], m_y[1], m_x[2], m_y[2], xc, yc, d);
ras.add_path(span_gen);
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
span_gen.colors(agg::rgba(0, 0, 1, alpha),
agg::rgba(1, 0, 0, alpha),
agg::rgba(brc, brc, brc, alpha));
span_gen.triangle(m_x[2], m_y[2], m_x[0], m_y[0], xc, yc, d);
ras.add_path(span_gen);
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
brc = 1-brc;
span_gen.colors(agg::rgba(1, 0, 0, alpha),
agg::rgba(0, 1, 0, alpha),
agg::rgba(brc, brc, brc, alpha));
span_gen.triangle(m_x[0], m_y[0], m_x[1], m_y[1], x1, y1, d);
ras.add_path(span_gen);
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
span_gen.colors(agg::rgba(0, 1, 0, alpha),
agg::rgba(0, 0, 1, alpha),
agg::rgba(brc, brc, brc, alpha));
span_gen.triangle(m_x[1], m_y[1], m_x[2], m_y[2], x2, y2, d);
ras.add_path(span_gen);
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
span_gen.colors(agg::rgba(0, 0, 1, alpha),
agg::rgba(1, 0, 0, alpha),
agg::rgba(brc, brc, brc, alpha));
span_gen.triangle(m_x[2], m_y[2], m_x[0], m_y[0], x3, y3, d);
ras.add_path(span_gen);
agg::render_scanlines_aa(ras, sl, ren_base, span_alloc, span_gen);
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> base_ren_type;
pixfmt pf(rbuf_window());
base_ren_type ren_base(pf);
ren_base.clear(agg::rgba(1,1,1));
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
render_gouraud(sl, ras);
ras.gamma(agg::gamma_none());
agg::render_ctrl(ras, sl, ren_base, m_dilation);
agg::render_ctrl(ras, sl, ren_base, m_gamma);
agg::render_ctrl(ras, sl, ren_base, m_alpha);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
unsigned i;
if(flags & agg::mouse_right)
{
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
start_timer();
for(i = 0; i < 100; i++)
{
render_gouraud(sl, ras);
}
char buf[100];
sprintf(buf, "Time=%2.2f ms", elapsed_time());
message(buf);
}
if(flags & agg::mouse_left)
{
for (i = 0; i < 3; i++)
{
if(sqrt( (x-m_x[i]) * (x-m_x[i]) + (y-m_y[i]) * (y-m_y[i]) ) < 10.0)
{
m_dx = x - m_x[i];
m_dy = y - m_y[i];
m_idx = i;
break;
}
}
if(i == 3)
{
if(agg::point_in_triangle(m_x[0], m_y[0],
m_x[1], m_y[1],
m_x[2], m_y[2],
x, y))
{
m_dx = x - m_x[0];
m_dy = y - m_y[0];
m_idx = 3;
}
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_idx == 3)
{
double dx = x - m_dx;
double dy = y - m_dy;
m_x[1] -= m_x[0] - dx;
m_y[1] -= m_y[0] - dy;
m_x[2] -= m_x[0] - dx;
m_y[2] -= m_y[0] - dy;
m_x[0] = dx;
m_y[0] = dy;
force_redraw();
return;
}
if(m_idx >= 0)
{
m_x[m_idx] = x - m_dx;
m_y[m_idx] = y - m_dy;
force_redraw();
}
}
else
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_idx = -1;
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
double dx = 0;
double dy = 0;
switch(key)
{
case agg::key_left: dx = -0.1; break;
case agg::key_right: dx = 0.1; break;
case agg::key_up: dy = 0.1; break;
case agg::key_down: dy = -0.1; break;
}
m_x[0] += dx;
m_y[0] += dy;
m_x[1] += dx;
m_y[1] += dy;
force_redraw();
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Gouraud Shading");
if(app.init(400, 320, agg::window_resize))
{
return app.run();
}
return 1;
}

485
examples/gouraud_mesh.cpp Normal file
View File

@ -0,0 +1,485 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "agg_rendering_buffer.h"
#include "agg_conv_transform.h"
#include "agg_conv_stroke.h"
#include "agg_conv_clip_polyline.h"
#include "agg_scanline_u.h"
#include "agg_scanline_bin.h"
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_span_allocator.h"
#include "agg_span_gouraud_rgba.h"
#include "agg_arc.h"
#include "agg_bezier_arc.h"
#include "agg_pixfmt_rgb.h"
#include "agg_pixfmt_rgba.h"
#include "agg_bounding_rect.h"
#include "agg_vpgen_clip_polygon.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_bezier_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#include "agg_rasterizer_compound_aa.h"
#define AGG_BGRA32
#include "pixel_formats.h"
enum { flip_y = true };
namespace agg
{
struct mesh_point
{
double x,y;
double dx,dy;
srgba8 color;
srgba8 dc;
mesh_point() {}
mesh_point(double x_, double y_,
double dx_, double dy_,
srgba8 c, srgba8 dc_) :
x(x_), y(y_),
dx(dx_), dy(dy_),
color(c), dc(dc_)
{}
};
struct mesh_triangle
{
unsigned p1, p2, p3;
mesh_triangle() {}
mesh_triangle(unsigned i, unsigned j, unsigned k) :
p1(i), p2(j), p3(k)
{}
};
struct mesh_edge
{
unsigned p1, p2;
int tl, tr;
mesh_edge() {}
mesh_edge(unsigned p1_, unsigned p2_, int tl_, int tr_) :
p1(p1_), p2(p2_), tl(tl_), tr(tr_)
{}
};
static double random(double v1, double v2)
{
return (v2 - v1) * (rand() % 1000) / 999.0 + v1;
}
class mesh_ctrl
{
public:
mesh_ctrl();
void generate(unsigned cols, unsigned rows,
double cell_w, double cell_h,
double start_x, double start_y);
void randomize_points(double delta);
void rotate_colors();
bool on_mouse_button_down(double x, double y, unsigned flags);
bool on_mouse_move(double x, double y, unsigned flags);
bool on_mouse_button_up(double x, double y, unsigned flags);
unsigned num_vertices() const { return m_vertices.size(); }
const mesh_point& vertex(unsigned i) const { return m_vertices[i]; }
mesh_point& vertex(unsigned i) { return m_vertices[i]; }
const mesh_point& vertex(unsigned x, unsigned y) const { return m_vertices[y * m_rows + x]; }
mesh_point& vertex(unsigned x, unsigned y) { return m_vertices[y * m_rows + x]; }
unsigned num_triangles() const { return m_triangles.size(); }
const mesh_triangle& triangle(unsigned i) const { return m_triangles[i]; }
mesh_triangle& triangle(unsigned i) { return m_triangles[i]; }
unsigned num_edges() const { return m_edges.size(); }
const mesh_edge& edge(unsigned i) const { return m_edges[i]; }
mesh_edge& edge(unsigned i) { return m_edges[i]; }
private:
unsigned m_cols;
unsigned m_rows;
int m_drag_idx;
double m_drag_dx;
double m_drag_dy;
double m_cell_w;
double m_cell_h;
double m_start_x;
double m_start_y;
pod_bvector<mesh_point> m_vertices;
pod_bvector<mesh_triangle> m_triangles;
pod_bvector<mesh_edge> m_edges;
};
mesh_ctrl::mesh_ctrl() :
m_cols(0),
m_rows(0),
m_drag_idx(-1),
m_drag_dx(0),
m_drag_dy(0)
{}
void mesh_ctrl::generate(unsigned cols, unsigned rows,
double cell_w, double cell_h,
double start_x, double start_y)
{
m_cols = cols;
m_rows = rows;
m_cell_w = cell_w;
m_cell_h = cell_h;
m_start_x = start_x;
m_start_y = start_y;
m_vertices.remove_all();
unsigned i, j;
for(i = 0; i < m_rows; i++)
{
double x = start_x;
for(j = 0; j < m_cols; j++)
{
double dx = random(-0.5, 0.5);
double dy = random(-0.5, 0.5);
srgba8 c(rand() & 0xFF, rand() & 0xFF, rand() & 0xFF);
srgba8 dc(rand() & 1, rand() & 1, rand() & 1);
m_vertices.add(mesh_point(x, start_y, dx, dy, c, dc));
x += cell_w;
}
start_y += cell_h;
}
// 4---3
// |t2/|
// | / |
// |/t1|
// 1---2
m_triangles.remove_all();
m_edges.remove_all();
for(i = 0; i < m_rows - 1; i++)
{
for(j = 0; j < m_cols - 1; j++)
{
int p1 = i * m_cols + j;
int p2 = p1 + 1;
int p3 = p2 + m_cols;
int p4 = p1 + m_cols;
m_triangles.add(mesh_triangle(p1, p2, p3));
m_triangles.add(mesh_triangle(p3, p4, p1));
int curr_cell = i * (m_cols - 1) + j;
int left_cell = j ? int(curr_cell - 1) : -1;
int bott_cell = i ? int(curr_cell - (m_cols - 1)) : -1;
int curr_t1 = curr_cell * 2;
int curr_t2 = curr_t1 + 1;
int left_t1 = (left_cell >= 0) ? left_cell * 2 : -1;
int left_t2 = (left_cell >= 0) ? left_t1 + 1 : -1;
int bott_t1 = (bott_cell >= 0) ? bott_cell * 2 : -1;
int bott_t2 = (bott_cell >= 0) ? bott_t1 + 1 : -1;
m_edges.add(mesh_edge(p1, p2, curr_t1, bott_t2));
m_edges.add(mesh_edge(p1, p3, curr_t2, curr_t1));
m_edges.add(mesh_edge(p1, p4, left_t1, curr_t2));
if(j == m_cols - 2) // Last column
{
m_edges.add(mesh_edge(p2, p3, curr_t1, -1));
}
if(i == m_rows - 2) // Last row
{
m_edges.add(mesh_edge(p3, p4, curr_t2, -1));
}
}
}
}
void mesh_ctrl::randomize_points(double delta)
{
unsigned i, j;
for(i = 0; i < m_rows; i++)
{
for(j = 0; j < m_cols; j++)
{
double xc = j * m_cell_w + m_start_x;
double yc = i * m_cell_h + m_start_y;
double x1 = xc - m_cell_w / 4;
double y1 = yc - m_cell_h / 4;
double x2 = xc + m_cell_w / 4;
double y2 = yc + m_cell_h / 4;
mesh_point& p = vertex(j, i);
p.x += p.dx;
p.y += p.dy;
if(p.x < x1) { p.x = x1; p.dx = -p.dx; }
if(p.y < y1) { p.y = y1; p.dy = -p.dy; }
if(p.x > x2) { p.x = x2; p.dx = -p.dx; }
if(p.y > y2) { p.y = y2; p.dy = -p.dy; }
}
}
}
void mesh_ctrl::rotate_colors()
{
unsigned i;
for(i = 1; i < m_vertices.size(); i++)
{
srgba8& c = m_vertices[i].color;
srgba8& dc = m_vertices[i].dc;
int r = c.r + (dc.r ? 5 : -5);
int g = c.g + (dc.g ? 5 : -5);
int b = c.b + (dc.b ? 5 : -5);
if(r < 0) { r = 0; dc.r ^= 1; } if(r > 255) { r = 255; dc.r ^= 1; }
if(g < 0) { g = 0; dc.g ^= 1; } if(g > 255) { g = 255; dc.g ^= 1; }
if(b < 0) { b = 0; dc.b ^= 1; } if(b > 255) { b = 255; dc.b ^= 1; }
c.r = r;
c.g = g;
c.b = b;
}
}
bool mesh_ctrl::on_mouse_button_down(double x, double y, unsigned flags)
{
if(flags & 1)
{
unsigned i;
for(i = 0; i < m_vertices.size(); i++)
{
if(calc_distance(x, y, m_vertices[i].x, m_vertices[i].y) < 5)
{
m_drag_idx = i;
m_drag_dx = x - m_vertices[i].x;
m_drag_dy = y - m_vertices[i].y;
return true;
}
}
}
return false;
}
bool mesh_ctrl::on_mouse_move(double x, double y, unsigned flags)
{
if(flags & 1)
{
if(m_drag_idx >= 0)
{
m_vertices[m_drag_idx].x = x - m_drag_dx;
m_vertices[m_drag_idx].y = y - m_drag_dy;
return true;
}
}
else
{
return on_mouse_button_up(x, y, flags);
}
return false;
}
bool mesh_ctrl::on_mouse_button_up(double x, double y, unsigned flags)
{
bool ret = m_drag_idx >= 0;
m_drag_idx = -1;
return ret;
}
class styles_gouraud
{
public:
typedef span_gouraud_rgba<color_type> gouraud_type;
styles_gouraud(const mesh_ctrl& mesh)
{
unsigned i;
for(i = 0; i < mesh.num_triangles(); i++)
{
const agg::mesh_triangle& t = mesh.triangle(i);
const agg::mesh_point& p1 = mesh.vertex(t.p1);
const agg::mesh_point& p2 = mesh.vertex(t.p2);
const agg::mesh_point& p3 = mesh.vertex(t.p3);
agg::srgba8 c1 = p1.color;
agg::srgba8 c2 = p2.color;
agg::srgba8 c3 = p3.color;
gouraud_type gouraud(c1, c2, c3,
p1.x, p1.y,
p2.x, p2.y,
p3.x, p3.y);
gouraud.prepare();
m_triangles.add(gouraud);
}
}
bool is_solid(unsigned style) const { return false; }
color_type color(unsigned style) const { return color_type::no_color(); }
void generate_span(color_type* span, int x, int y, unsigned len, unsigned style)
{
m_triangles[style].generate(span, x, y, len);
}
private:
pod_bvector<gouraud_type> m_triangles;
};
}
class the_application : public agg::platform_support
{
public:
typedef agg::renderer_base<pixfmt_pre> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
typedef agg::rasterizer_scanline_aa<> rasterizer_scanline;
typedef agg::scanline_u8 scanline;
agg::mesh_ctrl m_mesh;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y)
{
}
virtual void on_init()
{
m_mesh.generate(20, 20, 17, 17, 40, 40);
}
virtual void on_draw()
{
pixfmt_pre pf(rbuf_window());
renderer_base ren_base(pf);
ren_base.clear(agg::rgba(0, 0, 0));
renderer_scanline ren(ren_base);
rasterizer_scanline ras;
agg::scanline_u8 sl;
agg::scanline_bin sl_bin;
agg::rasterizer_compound_aa<> rasc;
agg::span_allocator<color_type> alloc;
unsigned i;
agg::styles_gouraud styles(m_mesh);
start_timer();
rasc.reset();
//rasc.clip_box(40, 40, width() - 40, height() - 40);
for(i = 0; i < m_mesh.num_edges(); i++)
{
const agg::mesh_edge& e = m_mesh.edge(i);
const agg::mesh_point& p1 = m_mesh.vertex(e.p1);
const agg::mesh_point& p2 = m_mesh.vertex(e.p2);
rasc.styles(e.tl, e.tr);
rasc.move_to_d(p1.x, p1.y);
rasc.line_to_d(p2.x, p2.y);
}
agg::render_scanlines_compound(rasc, sl, sl_bin, ren_base, alloc, styles);
double tm = elapsed_time();
char buf[256];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
pt.line_cap(agg::round_cap);
pt.line_join(agg::round_join);
sprintf(buf, "%3.2f ms, %d triangles, %.0f tri/sec",
tm,
m_mesh.num_triangles(),
m_mesh.num_triangles() / tm * 1000.0);
t.start_point(10.0, 10.0);
t.text(buf);
ras.add_path(pt);
agg::render_scanlines_aa_solid(ras, sl, ren_base, agg::rgba(1,1,1));
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(m_mesh.on_mouse_move(x, y, flags))
{
force_redraw();
}
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(m_mesh.on_mouse_button_down(x, y, flags))
{
force_redraw();
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
if(m_mesh.on_mouse_button_up(x, y, flags))
{
force_redraw();
}
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
}
void on_idle()
{
m_mesh.randomize_points(1.0);
m_mesh.rotate_colors();
force_redraw();
}
virtual void on_ctrl_change()
{
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example");
if(app.init(400, 400, 0))//agg::window_resize))
{
app.wait_mode(false);
return app.run();
}
return 1;
}

685
examples/gpc_test.cpp Normal file
View File

@ -0,0 +1,685 @@
#include <stdio.h>
#include "agg_conv_gpc.h"
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_renderer_primitives.h"
#include "agg_conv_curve.h"
#include "agg_conv_stroke.h"
#include "agg_conv_clip_polygon.h"
#include "agg_gsv_text.h"
#include "agg_pixfmt_rgb.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class spiral
{
public:
spiral(double x, double y, double r1, double r2, double step, double start_angle=0) :
m_x(x),
m_y(y),
m_r1(r1),
m_r2(r2),
m_step(step),
m_start_angle(start_angle),
m_angle(start_angle),
m_da(agg::deg2rad(4.0)),
m_dr(m_step / 90.0)
{
}
void rewind(unsigned)
{
m_angle = m_start_angle;
m_curr_r = m_r1;
m_start = true;
}
unsigned vertex(double* x, double* y)
{
if(m_curr_r > m_r2) return agg::path_cmd_stop;
*x = m_x + cos(m_angle) * m_curr_r;
*y = m_y + sin(m_angle) * m_curr_r;
m_curr_r += m_dr;
m_angle += m_da;
if(m_start)
{
m_start = false;
return agg::path_cmd_move_to;
}
return agg::path_cmd_line_to;
}
private:
double m_x;
double m_y;
double m_r1;
double m_r2;
double m_step;
double m_start_angle;
double m_angle;
double m_curr_r;
double m_da;
double m_dr;
bool m_start;
};
namespace agg
{
// A simple counter of points and contours
template<class Src> struct conv_poly_counter
{
unsigned m_contours;
unsigned m_points;
conv_poly_counter(Src& src) : m_src(&src), m_contours(0), m_points(0) {}
void rewind(unsigned path_id)
{
m_contours = 0;
m_points = 0;
m_src->rewind(path_id);
}
unsigned vertex(double* x, double* y)
{
unsigned cmd = m_src->vertex(x, y);
if(is_vertex(cmd)) ++m_points;
if(is_move_to(cmd)) ++m_contours;
return cmd;
}
private:
Src* m_src;
};
}
void make_gb_poly(agg::path_storage& ps);
void make_arrows(agg::path_storage& ps);
class the_application : public agg::platform_support
{
agg::rbox_ctrl<color_type> m_polygons;
agg::rbox_ctrl<color_type> m_operation;
double m_x;
double m_y;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_polygons (5.0, 5.0, 5.0+205.0, 110.0, !flip_y),
m_operation(555.0, 5.0, 555.0+80.0, 130.0, !flip_y)
{
m_operation.add_item("None");
m_operation.add_item("OR");
m_operation.add_item("AND");
m_operation.add_item("XOR");
m_operation.add_item("A-B");
m_operation.add_item("B-A");
m_operation.cur_item(2);
add_ctrl(m_operation);
m_polygons.add_item("Two Simple Paths");
m_polygons.add_item("Closed Stroke");
m_polygons.add_item("Great Britain and Arrows");
m_polygons.add_item("Great Britain and Spiral");
m_polygons.add_item("Spiral and Glyph");
m_polygons.cur_item(3);
add_ctrl(m_polygons);
}
template<class Scanline, class Ras, class Ren, class Gpc>
void perform_rendering(Scanline& sl, Ras& ras, Ren& ren, Gpc& gpc)
{
if(m_operation.cur_item() > 0)
{
ras.reset();
switch(m_operation.cur_item())
{
case 1: gpc.operation(agg::gpc_or); break;
case 2: gpc.operation(agg::gpc_and); break;
case 3: gpc.operation(agg::gpc_xor); break;
case 4: gpc.operation(agg::gpc_a_minus_b); break;
case 5: gpc.operation(agg::gpc_b_minus_a); break;
}
agg::conv_poly_counter<Gpc> counter(gpc);
start_timer();
counter.rewind(0);
double t1 = elapsed_time();
ras.reset();
double x;
double y;
unsigned cmd;
start_timer();
while(!agg::is_stop(cmd = counter.vertex(&x, &y)))
{
ras.add_vertex(x, y, cmd);
}
ren.color(agg::rgba(0.5, 0.0, 0, 0.5));
agg::render_scanlines(ras, sl, ren);
double t2 = elapsed_time();
char buf[100];
sprintf(buf, "Contours: %d Points: %d", counter.m_contours, counter.m_points);
agg::gsv_text txt;
agg::conv_stroke<agg::gsv_text> txt_stroke(txt);
txt_stroke.width(1.5);
txt_stroke.line_cap(agg::round_cap);
txt.size(10.0);
txt.start_point(250, 5);
txt.text(buf);
ras.add_path(txt_stroke);
ren.color(agg::rgba(0.0, 0.0, 0.0));
agg::render_scanlines(ras, sl, ren);
sprintf(buf, "GPC=%.3fms Render=%.3fms", t1, t2);
txt.start_point(250, 20);
txt.text(buf);
ras.add_path(txt_stroke);
ren.color(agg::rgba(0.0, 0.0, 0.0));
agg::render_scanlines(ras, sl, ren);
}
}
template<class Scanline, class Ras>
unsigned render_gpc(Scanline& sl, Ras& ras)
{
pixfmt pf(rbuf_window());
agg::renderer_base<pixfmt> rb(pf);
agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt> > ren(rb);
switch(m_polygons.cur_item())
{
case 0:
{
//------------------------------------
// Two simple paths
//
agg::path_storage ps1;
agg::path_storage ps2;
agg::conv_gpc<agg::path_storage, agg::path_storage> gpc(ps1, ps2);
double x = m_x - initial_width()/2 + 100;
double y = m_y - initial_height()/2 + 100;
ps1.move_to(x+140, y+145);
ps1.line_to(x+225, y+44);
ps1.line_to(x+296, y+219);
ps1.close_polygon();
ps1.line_to(x+226, y+289);
ps1.line_to(x+82, y+292);
ps1.move_to(x+220, y+222);
ps1.line_to(x+363, y+249);
ps1.line_to(x+265, y+331);
ps1.move_to(x+242, y+243);
ps1.line_to(x+268, y+309);
ps1.line_to(x+325, y+261);
ps1.move_to(x+259, y+259);
ps1.line_to(x+273, y+288);
ps1.line_to(x+298, y+266);
ps2.move_to(100+32, 100+77);
ps2.line_to(100+473, 100+263);
ps2.line_to(100+351, 100+290);
ps2.line_to(100+354, 100+374);
ras.reset();
ras.add_path(ps1);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
ras.reset();
ras.add_path(ps2);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, gpc);
}
break;
case 1:
{
//------------------------------------
// Closed stroke
//
agg::path_storage ps1;
agg::path_storage ps2;
agg::conv_stroke<agg::path_storage> stroke(ps2);
stroke.width(10.0);
agg::conv_gpc<agg::path_storage,
agg::conv_stroke<agg::path_storage> > gpc(ps1, stroke);
double x = m_x - initial_width()/2 + 100;
double y = m_y - initial_height()/2 + 100;
ps1.move_to(x+140, y+145);
ps1.line_to(x+225, y+44);
ps1.line_to(x+296, y+219);
ps1.close_polygon();
ps1.line_to(x+226, y+289);
ps1.line_to(x+82, y+292);
ps1.move_to(x+220-50, y+222);
ps1.line_to(x+265-50, y+331);
ps1.line_to(x+363-50, y+249);
ps1.close_polygon(agg::path_flags_ccw);
ps2.move_to(100+32, 100+77);
ps2.line_to(100+473, 100+263);
ps2.line_to(100+351, 100+290);
ps2.line_to(100+354, 100+374);
ps2.close_polygon();
ras.reset();
ras.add_path(ps1);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
ras.reset();
ras.add_path(stroke);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, gpc);
}
break;
case 2:
{
//------------------------------------
// Great Britain and Arrows
//
agg::path_storage gb_poly;
agg::path_storage arrows;
make_gb_poly(gb_poly);
make_arrows(arrows);
agg::trans_affine mtx1;
agg::trans_affine mtx2;
mtx1 *= agg::trans_affine_translation(-1150, -1150);
mtx1 *= agg::trans_affine_scaling(2.0);
mtx2 = mtx1;
mtx2 *= agg::trans_affine_translation(m_x - initial_width()/2,
m_y - initial_height()/2);
agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx1);
agg::conv_transform<agg::path_storage> trans_arrows(arrows, mtx2);
agg::conv_gpc<agg::conv_transform<agg::path_storage>,
agg::conv_transform<agg::path_storage> > gpc(trans_gb_poly, trans_arrows);
ras.add_path(trans_gb_poly);
ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
stroke_gb_poly.width(0.1);
ras.add_path(stroke_gb_poly);
ren.color(agg::rgba(0, 0, 0));
agg::render_scanlines(ras, sl, ren);
ras.add_path(trans_arrows);
ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, gpc);
}
break;
case 3:
{
//------------------------------------
// Great Britain and a Spiral
//
spiral sp(m_x, m_y, 10, 150, 30, 0.0);
agg::conv_stroke<spiral> stroke(sp);
stroke.width(15.0);
agg::path_storage gb_poly;
make_gb_poly(gb_poly);
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-1150, -1150);
mtx *= agg::trans_affine_scaling(2.0);
agg::conv_transform<agg::path_storage> trans_gb_poly(gb_poly, mtx);
agg::conv_gpc<agg::conv_transform<agg::path_storage>,
agg::conv_stroke<spiral> > gpc(trans_gb_poly, stroke);
/*
FILE* fd = fopen("contours.txt", "w");
if(fd)
{
unsigned cmd;
double x, y;
trans_gb_poly.rewind(0);
while(!agg::is_stop(cmd = trans_gb_poly.vertex(&x, &y)))
{
if(agg::is_move_to(cmd))
{
fprintf(fd, "\npoly[] = {\n");
}
fprintf(fd, " %.3f, %.3f,\n", x, y);
}
stroke.rewind(0);
while(!agg::is_stop(cmd = stroke.vertex(&x, &y)))
{
if(agg::is_move_to(cmd))
{
fprintf(fd, "\nspiral[] = {\n");
}
fprintf(fd, " %.3f, %.3f,\n", x, y);
}
fclose(fd);
}
*/
ras.add_path(trans_gb_poly);
ren.color(agg::rgba(0.5, 0.5, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
agg::conv_stroke<agg::conv_transform<agg::path_storage> > stroke_gb_poly(trans_gb_poly);
stroke_gb_poly.width(0.1);
ras.add_path(stroke_gb_poly);
ren.color(agg::rgba(0, 0, 0));
agg::render_scanlines(ras, sl, ren);
ras.add_path(stroke);
ren.color(agg::rgba(0.0, 0.5, 0.5, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, gpc);
}
break;
case 4:
{
//------------------------------------
// Spiral and glyph
//
spiral sp(m_x, m_y, 10, 150, 30, 0.0);
agg::conv_stroke<spiral> stroke(sp);
stroke.width(15.0);
agg::path_storage glyph;
glyph.move_to(28.47, 6.45);
glyph.curve3(21.58, 1.12, 19.82, 0.29);
glyph.curve3(17.19, -0.93, 14.21, -0.93);
glyph.curve3(9.57, -0.93, 6.57, 2.25);
glyph.curve3(3.56, 5.42, 3.56, 10.60);
glyph.curve3(3.56, 13.87, 5.03, 16.26);
glyph.curve3(7.03, 19.58, 11.99, 22.51);
glyph.curve3(16.94, 25.44, 28.47, 29.64);
glyph.line_to(28.47, 31.40);
glyph.curve3(28.47, 38.09, 26.34, 40.58);
glyph.curve3(24.22, 43.07, 20.17, 43.07);
glyph.curve3(17.09, 43.07, 15.28, 41.41);
glyph.curve3(13.43, 39.75, 13.43, 37.60);
glyph.line_to(13.53, 34.77);
glyph.curve3(13.53, 32.52, 12.38, 31.30);
glyph.curve3(11.23, 30.08, 9.38, 30.08);
glyph.curve3(7.57, 30.08, 6.42, 31.35);
glyph.curve3(5.27, 32.62, 5.27, 34.81);
glyph.curve3(5.27, 39.01, 9.57, 42.53);
glyph.curve3(13.87, 46.04, 21.63, 46.04);
glyph.curve3(27.59, 46.04, 31.40, 44.04);
glyph.curve3(34.28, 42.53, 35.64, 39.31);
glyph.curve3(36.52, 37.21, 36.52, 30.71);
glyph.line_to(36.52, 15.53);
glyph.curve3(36.52, 9.13, 36.77, 7.69);
glyph.curve3(37.01, 6.25, 37.57, 5.76);
glyph.curve3(38.13, 5.27, 38.87, 5.27);
glyph.curve3(39.65, 5.27, 40.23, 5.62);
glyph.curve3(41.26, 6.25, 44.19, 9.18);
glyph.line_to(44.19, 6.45);
glyph.curve3(38.72, -0.88, 33.74, -0.88);
glyph.curve3(31.35, -0.88, 29.93, 0.78);
glyph.curve3(28.52, 2.44, 28.47, 6.45);
glyph.close_polygon();
glyph.move_to(28.47, 9.62);
glyph.line_to(28.47, 26.66);
glyph.curve3(21.09, 23.73, 18.95, 22.51);
glyph.curve3(15.09, 20.36, 13.43, 18.02);
glyph.curve3(11.77, 15.67, 11.77, 12.89);
glyph.curve3(11.77, 9.38, 13.87, 7.06);
glyph.curve3(15.97, 4.74, 18.70, 4.74);
glyph.curve3(22.41, 4.74, 28.47, 9.62);
glyph.close_polygon();
agg::trans_affine mtx;
mtx *= agg::trans_affine_scaling(4.0);
mtx *= agg::trans_affine_translation(220, 200);
agg::conv_transform<agg::path_storage> trans(glyph, mtx);
agg::conv_curve<agg::conv_transform<agg::path_storage> > curve(trans);
agg::conv_gpc<agg::conv_stroke<spiral>,
agg::conv_curve<
agg::conv_transform<
agg::path_storage> > > gpc(stroke, curve);
ras.reset();
ras.add_path(stroke);
ren.color(agg::rgba(0, 0, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
ras.reset();
ras.add_path(curve);
ren.color(agg::rgba(0, 0.6, 0, 0.1));
agg::render_scanlines(ras, sl, ren);
perform_rendering(sl, ras, ren, gpc);
}
break;
}
return 0;
}
virtual void on_init()
{
m_x = width() / 2.0;
m_y = height() / 2.0;
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> base_ren_type;
pixfmt pf(rbuf_window());
base_ren_type ren_base(pf);
ren_base.clear(agg::rgba(1,1,1));
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
render_gpc(sl, ras);
agg::render_ctrl(ras, sl, ren_base, m_polygons);
agg::render_ctrl(ras, sl, ren_base, m_operation);
}
/*
// Stress-test.
// Works quite well on random polygons, no crashes, no memory leaks!
// Sometimes takes long to produce the result
double random(double min, double max)
{
int r = (rand() << 15) | rand();
return ((r & 0xFFFFFFF) / double(0xFFFFFFF + 1)) * (max - min) + min;
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
typedef agg::renderer_base<pixfmt> base_ren_type;
typedef agg::renderer_scanline_aa_solid<base_ren_type> renderer_solid;
pixfmt pf(rbuf_window());
base_ren_type ren_base(pf);
renderer_solid ren_solid(ren_base);
agg::path_storage ps1;
agg::path_storage ps2;
agg::conv_gpc<agg::path_storage, agg::path_storage> gpc(ps1, ps2);
unsigned i;
for(i = 0; i < 1000; i++)
{
ren_base.clear(agg::rgba(1,1,1));
unsigned num_poly1 = rand() % 10 + 1;
unsigned num_poly2 = rand() % 10 + 1;
unsigned j;
ps1.remove_all();
ps2.remove_all();
for(j = 0; j < num_poly1; j++)
{
ps1.move_to(random(0, width()), random(0, height()));
unsigned k;
unsigned np = rand() % 20 + 2;
for(k = 0; k < np; k++)
{
ps1.line_to(random(0, width()), random(0, height()));
}
}
for(j = 0; j < num_poly2; j++)
{
ps2.move_to(random(0, width()), random(0, height()));
unsigned k;
unsigned np = rand() % 20 + 2;
for(k = 0; k < np; k++)
{
ps2.line_to(random(0, width()), random(0, height()));
}
}
unsigned op = rand() % 5;
switch(op)
{
case 0: gpc.operation(agg::gpc_or); break;
case 1: gpc.operation(agg::gpc_and); break;
case 2: gpc.operation(agg::gpc_xor); break;
case 3: gpc.operation(agg::gpc_a_minus_b); break;
case 4: gpc.operation(agg::gpc_b_minus_a); break;
}
ras.add_path(gpc);
ren_solid.color(agg::rgba(0.5, 0.0, 0, 0.5));
agg::render_scanlines(ras, sl, ren_solid);
update_window();
}
message("Done");
}
*/
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_x = x;
m_y = y;
force_redraw();
}
if(flags & agg::mouse_right)
{
char buf[100];
sprintf(buf, "%d %d", x, y);
message(buf);
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_x = x;
m_y = y;
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. General Polygon Clipping (GPC)");
if(app.init(640, 520, agg::window_resize))
{
return app.run();
}
return 1;
}

252
examples/gradient_focal.cpp Normal file
View File

@ -0,0 +1,252 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_span_allocator.h"
#include "agg_span_gradient.h"
#include "agg_gradient_lut.h"
#include "agg_gamma_lut.h"
#include "agg_span_interpolator_linear.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
#include "pixel_formats.h"
enum { flip_y = true };
class the_application : public agg::platform_support
{
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
typedef agg::gamma_lut<agg::int8u, agg::int8u> gamma_lut_type;
typedef agg::gradient_radial_focus gradient_func_type;
typedef agg::gradient_reflect_adaptor<gradient_func_type> gradient_adaptor_type;
typedef agg::gradient_lut<agg::color_interpolator<agg::srgba8>, 1024> color_func_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_allocator<color_type> span_allocator_type;
typedef agg::span_gradient<color_type,
interpolator_type,
gradient_adaptor_type,
color_func_type> span_gradient_type;
agg::slider_ctrl<color_type> m_gamma;
agg::scanline_u8 m_scanline;
agg::rasterizer_scanline_aa<> m_rasterizer;
span_allocator_type m_alloc;
color_func_type m_gradient_lut;
gamma_lut_type m_gamma_lut;
double m_mouse_x, m_mouse_y;
double m_old_gamma;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_gamma(5.0, 5.0, 340.0, 12.0, !flip_y),
m_mouse_x(200), m_mouse_y(200)
{
m_gamma.range(0.5, 2.5);
m_gamma.value(1.0);
m_gamma.label("Gamma = %.3f");
add_ctrl(m_gamma);
m_gamma.no_transform();
m_gamma_lut.gamma(m_gamma.value());
m_old_gamma = m_gamma.value();
build_gradient_lut();
}
virtual void on_init()
{
m_mouse_y = initial_height() / 2;
m_mouse_x = initial_width() / 2;
}
void build_gradient_lut()
{
m_gradient_lut.remove_all();
m_gradient_lut.add_color(0.0, agg::rgba8_gamma_dir(agg::srgba8(0, 255, 0), m_gamma_lut));
m_gradient_lut.add_color(0.2, agg::rgba8_gamma_dir(agg::srgba8(120, 0, 0), m_gamma_lut));
m_gradient_lut.add_color(0.7, agg::rgba8_gamma_dir(agg::srgba8(120, 120, 0), m_gamma_lut));
m_gradient_lut.add_color(1.0, agg::rgba8_gamma_dir(agg::srgba8(0, 0, 255), m_gamma_lut));
//m_gradient_lut.add_color(0.0, agg::srgba8::from_wavelength(380, m_gamma.value()));
//m_gradient_lut.add_color(0.1, agg::srgba8::from_wavelength(420, m_gamma.value()));
//m_gradient_lut.add_color(0.2, agg::srgba8::from_wavelength(460, m_gamma.value()));
//m_gradient_lut.add_color(0.3, agg::srgba8::from_wavelength(500, m_gamma.value()));
//m_gradient_lut.add_color(0.4, agg::srgba8::from_wavelength(540, m_gamma.value()));
//m_gradient_lut.add_color(0.5, agg::srgba8::from_wavelength(580, m_gamma.value()));
//m_gradient_lut.add_color(0.6, agg::srgba8::from_wavelength(620, m_gamma.value()));
//m_gradient_lut.add_color(0.7, agg::srgba8::from_wavelength(660, m_gamma.value()));
//m_gradient_lut.add_color(0.8, agg::srgba8::from_wavelength(700, m_gamma.value()));
//m_gradient_lut.add_color(0.9, agg::srgba8::from_wavelength(740, m_gamma.value()));
//m_gradient_lut.add_color(1.0, agg::srgba8::from_wavelength(780, m_gamma.value()));
m_gradient_lut.build_lut();
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
renderer_solid rs(rb);
rb.clear(agg::rgba(1, 1, 1));
// When Gamma changes rebuild the gamma and gradient LUTs
//------------------
if(m_old_gamma != m_gamma.value())
{
m_gamma_lut.gamma(m_gamma.value());
build_gradient_lut();
m_old_gamma = m_gamma.value();
}
// Gradient center. All gradient functions assume the
// center being in the origin (0,0) and you can't
// change it. But you can apply arbitrary transformations
// to the gradient (see below).
//------------------
double cx = initial_width() / 2;
double cy = initial_height() / 2;
double r = 100;
// Focal center. Defined in the gradient coordinates,
// that is, with respect to the origin (0,0)
//------------------
double fx = m_mouse_x - cx;
double fy = m_mouse_y - cy;
gradient_func_type gradient_func(r, fx, fy);
gradient_adaptor_type gradient_adaptor(gradient_func);
agg::trans_affine gradient_mtx;
// Making the affine matrix. Move to (cx,cy),
// apply the resizing transformations and invert
// the matrix. Gradients and images always assume the
// inverse transformations.
//------------------
gradient_mtx.translate(cx, cy);
gradient_mtx *= trans_affine_resizing();
gradient_mtx.invert();
interpolator_type span_interpolator(gradient_mtx);
span_gradient_type span_gradient(span_interpolator,
gradient_adaptor,
m_gradient_lut,
0, r);
// Form the simple rectangle
//------------------
m_rasterizer.reset();
m_rasterizer.move_to_d(0,0);
m_rasterizer.line_to_d(width(), 0);
m_rasterizer.line_to_d(width(), height());
m_rasterizer.line_to_d(0, height());
// Render the gradient to the whole screen and measure the time
//------------------
start_timer();
agg::render_scanlines_aa(m_rasterizer, m_scanline, rb, m_alloc, span_gradient);
double tm = elapsed_time();
// Draw the transformed circle that shows the gradient boundary
//------------------
agg::ellipse e(cx, cy, r, r);
agg::conv_stroke<agg::ellipse> estr(e);
agg::conv_transform<
agg::conv_stroke<
agg::ellipse> > etrans(estr, trans_affine_resizing());
m_rasterizer.add_path(etrans);
agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(1,1,1));
// Show the gradient time
//------------------
char buf[64];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
sprintf(buf, "%3.2f ms", tm);
t.start_point(10.0, 35.0);
t.text(buf);
m_rasterizer.add_path(pt);
agg::render_scanlines_aa_solid(m_rasterizer, m_scanline, rb, agg::rgba(0,0,0));
// Show the controls
//------------------
agg::render_ctrl(m_rasterizer, m_scanline, rb, m_gamma);
// Apply the inverse gamma to the whole buffer
// (transform the colors to the perceptually uniform space)
//------------------
pixf.apply_gamma_inv(m_gamma_lut);
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_mouse_x = x;
m_mouse_y = y;
trans_affine_resizing().inverse_transform(&m_mouse_x, &m_mouse_y);
force_redraw();
}
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
m_mouse_x = x;
m_mouse_y = y;
trans_affine_resizing().inverse_transform(&m_mouse_x, &m_mouse_y);
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. PDF linear and radial gradients");
if(app.init(600, 400, agg::window_resize))
{
return app.run();
}
return 1;
}

531
examples/gradients.cpp Normal file
View File

@ -0,0 +1,531 @@
#include <stdio.h>
#include <stdlib.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_conv_transform.h"
#include "agg_color_rgba.h"
#include "agg_color_gray.h"
#include "agg_span_allocator.h"
#include "agg_span_gradient.h"
#include "agg_span_interpolator_linear.h"
#include "agg_renderer_scanline.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_spline_ctrl.h"
#include "ctrl/agg_gamma_ctrl.h"
#include "platform/agg_platform_support.h"
//#define AGG_GRAY8
//#define AGG_GRAY16
//#define AGG_GRAY32
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_RGB_AAA
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGR96
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
const double center_x = 350;
const double center_y = 280;
class gradient_polymorphic_wrapper_base
{
public:
virtual int calculate(int x, int y, int) const = 0;
};
template<class GradientF>
class gradient_polymorphic_wrapper : public gradient_polymorphic_wrapper_base
{
public:
gradient_polymorphic_wrapper() : m_adaptor(m_gradient) {}
virtual int calculate(int x, int y, int d) const
{
return m_adaptor.calculate(x, y, d);
}
GradientF m_gradient;
agg::gradient_reflect_adaptor<GradientF> m_adaptor;
};
struct color_function_profile
{
color_function_profile() {}
color_function_profile(const color_type* colors, const agg::int8u* profile) :
m_colors(colors), m_profile(profile) {}
static unsigned size() { return 256; }
const color_type& operator [] (unsigned v) const
{
return m_colors[m_profile[v]];
}
const color_type* m_colors;
const agg::int8u* m_profile;
};
class the_application : public agg::platform_support
{
agg::gamma_ctrl<color_type> m_profile;
agg::spline_ctrl<color_type> m_spline_r;
agg::spline_ctrl<color_type> m_spline_g;
agg::spline_ctrl<color_type> m_spline_b;
agg::spline_ctrl<color_type> m_spline_a;
agg::rbox_ctrl<color_type> m_rbox;
double m_pdx;
double m_pdy;
double m_center_x;
double m_center_y;
double m_scale;
double m_prev_scale;
double m_angle;
double m_prev_angle;
double m_scale_x;
double m_prev_scale_x;
double m_scale_y;
double m_prev_scale_y;
bool m_mouse_move;
public:
virtual ~the_application()
{
FILE* fd = fopen(full_file_name("settings.dat"), "w");
fprintf(fd, "%f\n", m_center_x);
fprintf(fd, "%f\n", m_center_y);
fprintf(fd, "%f\n", m_scale);
fprintf(fd, "%f\n", m_angle);
fprintf(fd, "%f\n", m_spline_r.x(0));
fprintf(fd, "%f\n", m_spline_r.y(0));
fprintf(fd, "%f\n", m_spline_r.x(1));
fprintf(fd, "%f\n", m_spline_r.y(1));
fprintf(fd, "%f\n", m_spline_r.x(2));
fprintf(fd, "%f\n", m_spline_r.y(2));
fprintf(fd, "%f\n", m_spline_r.x(3));
fprintf(fd, "%f\n", m_spline_r.y(3));
fprintf(fd, "%f\n", m_spline_r.x(4));
fprintf(fd, "%f\n", m_spline_r.y(4));
fprintf(fd, "%f\n", m_spline_r.x(5));
fprintf(fd, "%f\n", m_spline_r.y(5));
fprintf(fd, "%f\n", m_spline_g.x(0));
fprintf(fd, "%f\n", m_spline_g.y(0));
fprintf(fd, "%f\n", m_spline_g.x(1));
fprintf(fd, "%f\n", m_spline_g.y(1));
fprintf(fd, "%f\n", m_spline_g.x(2));
fprintf(fd, "%f\n", m_spline_g.y(2));
fprintf(fd, "%f\n", m_spline_g.x(3));
fprintf(fd, "%f\n", m_spline_g.y(3));
fprintf(fd, "%f\n", m_spline_g.x(4));
fprintf(fd, "%f\n", m_spline_g.y(4));
fprintf(fd, "%f\n", m_spline_g.x(5));
fprintf(fd, "%f\n", m_spline_g.y(5));
fprintf(fd, "%f\n", m_spline_b.x(0));
fprintf(fd, "%f\n", m_spline_b.y(0));
fprintf(fd, "%f\n", m_spline_b.x(1));
fprintf(fd, "%f\n", m_spline_b.y(1));
fprintf(fd, "%f\n", m_spline_b.x(2));
fprintf(fd, "%f\n", m_spline_b.y(2));
fprintf(fd, "%f\n", m_spline_b.x(3));
fprintf(fd, "%f\n", m_spline_b.y(3));
fprintf(fd, "%f\n", m_spline_b.x(4));
fprintf(fd, "%f\n", m_spline_b.y(4));
fprintf(fd, "%f\n", m_spline_b.x(5));
fprintf(fd, "%f\n", m_spline_b.y(5));
fprintf(fd, "%f\n", m_spline_a.x(0));
fprintf(fd, "%f\n", m_spline_a.y(0));
fprintf(fd, "%f\n", m_spline_a.x(1));
fprintf(fd, "%f\n", m_spline_a.y(1));
fprintf(fd, "%f\n", m_spline_a.x(2));
fprintf(fd, "%f\n", m_spline_a.y(2));
fprintf(fd, "%f\n", m_spline_a.x(3));
fprintf(fd, "%f\n", m_spline_a.y(3));
fprintf(fd, "%f\n", m_spline_a.x(4));
fprintf(fd, "%f\n", m_spline_a.y(4));
fprintf(fd, "%f\n", m_spline_a.x(5));
fprintf(fd, "%f\n", m_spline_a.y(5));
double x1,y1,x2,y2;
m_profile.values(&x1, &y1, &x2, &y2);
fprintf(fd, "%f\n", x1);
fprintf(fd, "%f\n", y1);
fprintf(fd, "%f\n", x2);
fprintf(fd, "%f\n", y2);
fclose(fd);
}
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_profile(10.0, 10.0, 200.0, 170.0-5.0, !flip_y),
m_spline_r(210, 10, 210+250, 5+40, 6, !flip_y),
m_spline_g(210, 10+40, 210+250, 5+80, 6, !flip_y),
m_spline_b(210, 10+80, 210+250, 5+120, 6, !flip_y),
m_spline_a(210, 10+120, 210+250, 5+160, 6, !flip_y),
m_rbox(10.0, 180.0, 200.0, 300.0, !flip_y),
m_pdx(0.0),
m_pdy(0.0),
m_center_x(center_x),
m_center_y(center_y),
m_scale(1.0),
m_prev_scale(1.0),
m_angle(0.0),
m_prev_angle(0.0),
m_scale_x(1.0),
m_prev_scale_x(1.0),
m_scale_y(1.0),
m_prev_scale_y(1.0),
m_mouse_move(false)
{
add_ctrl(m_profile);
add_ctrl(m_spline_r);
add_ctrl(m_spline_g);
add_ctrl(m_spline_b);
add_ctrl(m_spline_a);
add_ctrl(m_rbox);
m_profile.border_width(2.0, 2.0);
m_spline_r.background_color(agg::rgba(1.0, 0.8, 0.8));
m_spline_g.background_color(agg::rgba(0.8, 1.0, 0.8));
m_spline_b.background_color(agg::rgba(0.8, 0.8, 1.0));
m_spline_a.background_color(agg::rgba(1.0, 1.0, 1.0));
m_spline_r.border_width(1.0, 2.0);
m_spline_g.border_width(1.0, 2.0);
m_spline_b.border_width(1.0, 2.0);
m_spline_a.border_width(1.0, 2.0);
m_rbox.border_width(2.0, 2.0);
m_spline_r.point(0, 0.0, 1.0);
m_spline_r.point(1, 1.0/5.0, 1.0 - 1.0/5.0);
m_spline_r.point(2, 2.0/5.0, 1.0 - 2.0/5.0);
m_spline_r.point(3, 3.0/5.0, 1.0 - 3.0/5.0);
m_spline_r.point(4, 4.0/5.0, 1.0 - 4.0/5.0);
m_spline_r.point(5, 1.0, 0.0);
m_spline_r.update_spline();
m_spline_g.point(0, 0.0, 1.0);
m_spline_g.point(1, 1.0/5.0, 1.0 - 1.0/5.0);
m_spline_g.point(2, 2.0/5.0, 1.0 - 2.0/5.0);
m_spline_g.point(3, 3.0/5.0, 1.0 - 3.0/5.0);
m_spline_g.point(4, 4.0/5.0, 1.0 - 4.0/5.0);
m_spline_g.point(5, 1.0, 0.0);
m_spline_g.update_spline();
m_spline_b.point(0, 0.0, 1.0);
m_spline_b.point(1, 1.0/5.0, 1.0 - 1.0/5.0);
m_spline_b.point(2, 2.0/5.0, 1.0 - 2.0/5.0);
m_spline_b.point(3, 3.0/5.0, 1.0 - 3.0/5.0);
m_spline_b.point(4, 4.0/5.0, 1.0 - 4.0/5.0);
m_spline_b.point(5, 1.0, 0.0);
m_spline_b.update_spline();
m_spline_a.point(0, 0.0, 1.0);
m_spline_a.point(1, 1.0/5.0, 1.0);
m_spline_a.point(2, 2.0/5.0, 1.0);
m_spline_a.point(3, 3.0/5.0, 1.0);
m_spline_a.point(4, 4.0/5.0, 1.0);
m_spline_a.point(5, 1.0, 1.0);
m_spline_a.update_spline();
m_rbox.add_item("Circular");
m_rbox.add_item("Diamond");
m_rbox.add_item("Linear");
m_rbox.add_item("XY");
m_rbox.add_item("sqrt(XY)");
m_rbox.add_item("Conic");
m_rbox.cur_item(0);
FILE* fd = fopen(full_file_name("settings.dat"), "r");
if(fd)
{
float x;
float y;
float x2;
float y2;
float t;
fscanf(fd, "%f\n", &t); m_center_x = t;
fscanf(fd, "%f\n", &t); m_center_y = t;
fscanf(fd, "%f\n", &t); m_scale = t;
fscanf(fd, "%f\n", &t); m_angle = t;
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_r.point(0, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_r.point(1, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_r.point(2, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_r.point(3, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_r.point(4, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_r.point(5, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_g.point(0, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_g.point(1, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_g.point(2, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_g.point(3, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_g.point(4, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_g.point(5, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_b.point(0, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_b.point(1, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_b.point(2, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_b.point(3, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_b.point(4, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_b.point(5, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_a.point(0, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_a.point(1, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_a.point(2, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_a.point(3, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_a.point(4, x, y);
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y); m_spline_a.point(5, x, y);
m_spline_r.update_spline();
m_spline_g.update_spline();
m_spline_b.update_spline();
m_spline_a.update_spline();
fscanf(fd, "%f\n", &x);
fscanf(fd, "%f\n", &y);
fscanf(fd, "%f\n", &x2);
fscanf(fd, "%f\n", &y2);
m_profile.values(x, y, x2, y2);
fclose(fd);
}
}
virtual void on_draw()
{
agg::rasterizer_scanline_aa<> ras;
typedef agg::renderer_base<pixfmt> renderer_base;
agg::scanline_u8 sl;
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
rb.clear(agg::rgba(0, 0, 0));
m_profile.text_size(8.0);
agg::render_ctrl(ras, sl, rb, m_profile);
agg::render_ctrl(ras, sl, rb, m_spline_r);
agg::render_ctrl(ras, sl, rb, m_spline_g);
agg::render_ctrl(ras, sl, rb, m_spline_b);
agg::render_ctrl(ras, sl, rb, m_spline_a);
agg::render_ctrl(ras, sl, rb, m_rbox);
double ini_scale = 1.0;
agg::trans_affine mtx1;
mtx1 *= agg::trans_affine_scaling(ini_scale, ini_scale);
mtx1 *= agg::trans_affine_rotation(agg::deg2rad(0.0));
mtx1 *= agg::trans_affine_translation(center_x, center_y);
mtx1 *= trans_affine_resizing();
agg::ellipse e1;
e1.init(0.0, 0.0, 110.0, 110.0, 64);
agg::trans_affine mtx_g1;
mtx_g1 *= agg::trans_affine_scaling(ini_scale, ini_scale);
mtx_g1 *= agg::trans_affine_scaling(m_scale, m_scale);
mtx_g1 *= agg::trans_affine_scaling(m_scale_x, m_scale_y);
mtx_g1 *= agg::trans_affine_rotation(m_angle);
mtx_g1 *= agg::trans_affine_translation(m_center_x, m_center_y);
mtx_g1 *= trans_affine_resizing();
mtx_g1.invert();
color_type color_profile[256]; // color_type is defined in pixel_formats.h
int i;
for(i = 0; i < 256; i++)
{
color_profile[i] = color_type(agg::rgba(m_spline_r.spline()[i],
m_spline_g.spline()[i],
m_spline_b.spline()[i],
m_spline_a.spline()[i]));
}
agg::conv_transform<agg::ellipse, agg::trans_affine> t1(e1, mtx1);
gradient_polymorphic_wrapper<agg::gradient_radial> gr_circle;
gradient_polymorphic_wrapper<agg::gradient_diamond> gr_diamond;
gradient_polymorphic_wrapper<agg::gradient_x> gr_x;
gradient_polymorphic_wrapper<agg::gradient_xy> gr_xy;
gradient_polymorphic_wrapper<agg::gradient_sqrt_xy> gr_sqrt_xy;
gradient_polymorphic_wrapper<agg::gradient_conic> gr_conic;
gradient_polymorphic_wrapper_base* gr_ptr = &gr_circle;
// gr_circle.m_gradient.init(150, 80, 80);
switch(m_rbox.cur_item())
{
case 1: gr_ptr = &gr_diamond; break;
case 2: gr_ptr = &gr_x; break;
case 3: gr_ptr = &gr_xy; break;
case 4: gr_ptr = &gr_sqrt_xy; break;
case 5: gr_ptr = &gr_conic; break;
}
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_gradient<color_type,
interpolator_type,
gradient_polymorphic_wrapper_base,
color_function_profile> gradient_span_gen;
typedef agg::span_allocator<gradient_span_gen::color_type> gradient_span_alloc;
gradient_span_alloc span_alloc;
color_function_profile colors(color_profile, m_profile.gamma());
interpolator_type inter(mtx_g1);
gradient_span_gen span_gen(inter, *gr_ptr, colors, 0, 150);
ras.add_path(t1);
agg::render_scanlines_aa(ras, sl, rb, span_alloc, span_gen);
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(m_mouse_move)
{
double x2 = x;
double y2 = y;
trans_affine_resizing().inverse_transform(&x2, &y2);
if(flags & agg::kbd_ctrl)
{
double dx = x2 - m_center_x;
double dy = y2 - m_center_y;
m_scale_x = m_prev_scale_x * dx / m_pdx;
m_scale_y = m_prev_scale_y * dy / m_pdy;
force_redraw();
}
else
{
if(flags & agg::mouse_left)
{
m_center_x = x2 + m_pdx;
m_center_y = y2 + m_pdy;
force_redraw();
}
if(flags & agg::mouse_right)
{
double dx = x2 - m_center_x;
double dy = y2 - m_center_y;
m_scale = m_prev_scale *
sqrt(dx * dx + dy * dy) /
sqrt(m_pdx * m_pdx + m_pdy * m_pdy);
m_angle = m_prev_angle + atan2(dy, dx) - atan2(m_pdy, m_pdx);
force_redraw();
}
}
}
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
m_mouse_move = true;
double x2 = x;
double y2 = y;
trans_affine_resizing().inverse_transform(&x2, &y2);
m_pdx = m_center_x - x2;
m_pdy = m_center_y - y2;
m_prev_scale = m_scale;
m_prev_angle = m_angle + agg::pi;
m_prev_scale_x = m_scale_x;
m_prev_scale_y = m_scale_y;
force_redraw();
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_mouse_move = false;
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == agg::key_f1)
{
FILE* fd = fopen(full_file_name("colors.dat"), "w");
int i;
for(i = 0; i < 256; i++)
{
agg::srgba8 c = agg::rgba(m_spline_r.spline()[i],
m_spline_g.spline()[i],
m_spline_b.spline()[i],
m_spline_a.spline()[i]);
fprintf(fd, " %3d, %3d, %3d, %3d,\n", c.r, c.g, c.b, c.a);
}
fclose(fd);
fd = fopen(full_file_name("profile.dat"), "w");
for(i = 0; i < 256; i++)
{
fprintf(fd, "%3d, ", unsigned(m_profile.gamma()[i]));
if((i & 0xF) == 0xF) fprintf(fd, "\n");
}
fclose(fd);
}
}
};
int agg_main(int argc, char* argv[])
{
//#ifdef _WIN32
// FILE* fd = fopen("stdout.txt", "w"); fclose(fd);
//#endif
//AGG_WATCHDOGGY(wd1, false);
the_application app(pix_format, flip_y);
app.caption("AGG gradients with Mach bands compensation");
if(app.init(512, 400, agg::window_resize | agg::window_hw_buffer))
{
return app.run();
}
return 1;
}

File diff suppressed because it is too large Load Diff

925
examples/graph_test.cpp Normal file
View File

@ -0,0 +1,925 @@
#include <math.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_rasterizer_outline.h"
#include "agg_conv_stroke.h"
#include "agg_conv_dash.h"
#include "agg_conv_curve.h"
#include "agg_conv_contour.h"
#include "agg_conv_marker.h"
#include "agg_conv_shorten_path.h"
#include "agg_conv_marker_adaptor.h"
#include "agg_conv_concat.h"
#include "agg_arrowhead.h"
#include "agg_vcgen_markers_term.h"
#include "agg_scanline_p.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_renderer_primitives.h"
#include "agg_span_allocator.h"
#include "agg_span_gradient.h"
#include "agg_span_interpolator_linear.h"
#include "agg_pixfmt_rgb.h"
#include "agg_pixfmt_rgba.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
typedef agg::renderer_base<pixfmt> base_renderer;
typedef agg::renderer_primitives<base_renderer> primitives_renderer;
typedef agg::renderer_scanline_aa_solid<base_renderer> solid_renderer;
typedef agg::renderer_scanline_bin_solid<base_renderer> draft_renderer;
typedef agg::gradient_radial_d gradient_function;
typedef agg::span_interpolator_linear<> interpolator;
typedef agg::pod_auto_array<color_type, 256> color_array_type;
typedef agg::span_gradient<color_type,
interpolator,
gradient_function,
color_array_type> gradient_span_gen;
typedef agg::span_allocator<color_type> gradient_span_alloc;
typedef agg::renderer_scanline_aa<base_renderer,
gradient_span_alloc,
gradient_span_gen> gradient_renderer;
typedef agg::rasterizer_scanline_aa<> scanline_rasterizer;
typedef agg::rasterizer_outline<primitives_renderer> outline_rasterizer;
//============================================================================
class graph
{
public:
struct node
{
double x, y;
node() {}
node(double x_, double y_) : x(x_), y(y_) {}
};
struct edge
{
int node1;
int node2;
edge() {}
edge(int n1, int n2) : node1(n1), node2(n2) {}
};
~graph()
{
delete [] m_edges;
delete [] m_nodes;
}
graph(int num_nodes, int num_edges) :
m_num_nodes(num_nodes),
m_num_edges(num_edges),
m_nodes(new node[num_nodes]),
m_edges(new edge[num_edges])
{
int i;
srand(100);
for(i = 0; i < m_num_nodes; i++)
{
m_nodes[i].x = (double(rand()) / RAND_MAX) * 0.75 + 0.2;
m_nodes[i].y = (double(rand()) / RAND_MAX) * 0.85 + 0.1;
}
for(i = 0; i < m_num_edges; i++)
{
m_edges[i].node1 = rand() % m_num_nodes;
m_edges[i].node2 = rand() % m_num_nodes;
if(m_edges[i].node1 == m_edges[i].node2) i--;
}
}
int get_num_nodes() const { return m_num_nodes; }
int get_num_edges() const { return m_num_edges; }
node get_node(int idx, double w, double h) const
{
node p(0.0, 0.0);
if(idx < m_num_nodes)
{
p = m_nodes[idx];
p.x = p.x * w;
p.y = p.y * h;
}
return p;
}
edge get_edge(int idx) const
{
edge b(0,0);
if(idx < m_num_edges)
{
b = m_edges[idx];
}
return b;
}
private:
graph(const graph&);
const graph& operator = (const graph&);
int m_num_nodes;
int m_num_edges;
node* m_nodes;
edge* m_edges;
};
//============================================================================
struct line
{
double x1, y1, x2, y2;
int f;
line(double x1_, double y1_, double x2_, double y2_) :
x1(x1_), y1(y1_), x2(x2_), y2(y2_), f(0) {}
void rewind(unsigned) { f = 0; }
unsigned vertex(double* x, double* y)
{
if(f == 0) { ++f; *x = x1; *y = y1; return agg::path_cmd_move_to; }
if(f == 1) { ++f; *x = x2; *y = y2; return agg::path_cmd_line_to; }
return agg::path_cmd_stop;
}
};
//============================================================================
struct curve
{
agg::curve4 c;
curve(double x1, double y1, double x2, double y2, double k=0.5)
{
c.init(x1, y1,
x1 - (y2 - y1) * k,
y1 + (x2 - x1) * k,
x2 + (y2 - y1) * k,
y2 - (x2 - x1) * k,
x2, y2);
}
void rewind(unsigned path_id) { c.rewind(path_id); }
unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
};
//============================================================================
template<class Source> struct stroke_draft_simple
{
Source& s;
stroke_draft_simple(Source& src, double w) :
s(src)
{
}
void rewind(unsigned path_id) { s.rewind(path_id); }
unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
};
//============================================================================
template<class Source> struct stroke_draft_arrow
{
typedef agg::conv_marker_adaptor<Source, agg::vcgen_markers_term> stroke_type;
typedef agg::conv_marker<typename stroke_type::marker_type, agg::arrowhead> marker_type;
typedef agg::conv_concat<stroke_type, marker_type> concat_type;
stroke_type s;
agg::arrowhead ah;
marker_type m;
concat_type c;
stroke_draft_arrow(Source& src, double w) :
s(src),
ah(),
m(s.markers(), ah),
c(s, m)
{
ah.head(0, 10, 5, 0);
s.shorten(10.0);
}
void rewind(unsigned path_id) { c.rewind(path_id); }
unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
};
//============================================================================
template<class Source> struct stroke_fine_simple
{
typedef agg::conv_stroke<Source> stroke_type;
stroke_type s;
stroke_fine_simple(Source& src, double w) :
s(src)
{
s.width(w);
}
void rewind(unsigned path_id) { s.rewind(path_id); }
unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
};
//============================================================================
template<class Source> struct stroke_fine_arrow
{
typedef agg::conv_stroke<Source, agg::vcgen_markers_term> stroke_type;
typedef agg::conv_marker<typename stroke_type::marker_type, agg::arrowhead> marker_type;
typedef agg::conv_concat<stroke_type, marker_type> concat_type;
stroke_type s;
agg::arrowhead ah;
marker_type m;
concat_type c;
stroke_fine_arrow(Source& src, double w) :
s(src),
ah(),
m(s.markers(), ah),
c(s, m)
{
s.width(w);
ah.head(0, 10, 5, 0);
s.shorten(w * 2.0);
}
void rewind(unsigned path_id) { c.rewind(path_id); }
unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
};
//============================================================================
template<class Source> struct dash_stroke_draft_simple
{
typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
dash_type d;
dash_stroke_draft_simple(Source& src,
double dash_len,
double gap_len,
double w) :
d(src)
{
d.add_dash(dash_len, gap_len);
}
void rewind(unsigned path_id) { d.rewind(path_id); }
unsigned vertex(double* x, double* y) { return d.vertex(x, y); }
};
//============================================================================
template<class Source> struct dash_stroke_draft_arrow
{
typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
typedef agg::conv_marker<typename dash_type::marker_type, agg::arrowhead> marker_type;
typedef agg::conv_concat<dash_type, marker_type> concat_type;
dash_type d;
agg::arrowhead ah;
marker_type m;
concat_type c;
dash_stroke_draft_arrow(Source& src,
double dash_len, double gap_len, double w) :
d(src),
ah(),
m(d.markers(), ah),
c(d, m)
{
d.add_dash(dash_len, gap_len);
ah.head(0, 10, 5, 0);
d.shorten(10.0);
}
void rewind(unsigned path_id) { c.rewind(path_id); }
unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
};
//============================================================================
template<class Source> struct dash_stroke_fine_simple
{
typedef agg::conv_dash<Source> dash_type;
typedef agg::conv_stroke<dash_type> stroke_type;
dash_type d;
stroke_type s;
dash_stroke_fine_simple(Source& src,
double dash_len, double gap_len, double w) :
d(src),
s(d)
{
d.add_dash(dash_len, gap_len);
s.width(w);
}
void rewind(unsigned path_id) { s.rewind(path_id); }
unsigned vertex(double* x, double* y) { return s.vertex(x, y); }
};
//============================================================================
template<class Source> struct dash_stroke_fine_arrow
{
typedef agg::conv_dash<Source, agg::vcgen_markers_term> dash_type;
typedef agg::conv_stroke<dash_type> stroke_type;
typedef agg::conv_marker<typename dash_type::marker_type, agg::arrowhead> marker_type;
typedef agg::conv_concat<stroke_type, marker_type> concat_type;
dash_type d;
stroke_type s;
agg::arrowhead ah;
marker_type m;
concat_type c;
dash_stroke_fine_arrow(Source& src,
double dash_len, double gap_len, double w) :
d(src),
s(d),
ah(),
m(d.markers(), ah),
c(s, m)
{
d.add_dash(dash_len, gap_len);
s.width(w);
ah.head(0, 10, 5, 0);
d.shorten(w * 2.0);
}
void rewind(unsigned path_id) { c.rewind(path_id); }
unsigned vertex(double* x, double* y) { return c.vertex(x, y); }
};
//#define stroke_draft stroke_draft_simple
//#define dash_stroke_draft dash_stroke_draft_simple
//#define stroke_fine stroke_fine_simple
//#define dash_stroke_fine dash_stroke_fine_simple
#define stroke_draft stroke_draft_arrow
#define dash_stroke_draft dash_stroke_draft_arrow
#define stroke_fine stroke_fine_arrow
#define dash_stroke_fine dash_stroke_fine_arrow
class the_application : public agg::platform_support
{
agg::rbox_ctrl<agg::rgba> m_type;
agg::slider_ctrl<agg::rgba> m_width;
agg::cbox_ctrl<agg::rgba> m_benchmark;
agg::cbox_ctrl<agg::rgba> m_draw_nodes;
agg::cbox_ctrl<agg::rgba> m_draw_edges;
agg::cbox_ctrl<agg::rgba> m_draft;
agg::cbox_ctrl<agg::rgba> m_translucent;
graph m_graph;
color_array_type m_gradient_colors;
int m_draw;
agg::scanline_u8 m_sl;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_type(-1, -1, -1, -1, !flip_y),
m_width(110+80, 8.0, 110+200.0+80, 8.0 + 7.0, !flip_y),
m_benchmark(110+200+80+8, 8.0-2.0, "Benchmark", !flip_y),
m_draw_nodes(110+200+80+8, 8.0-2.0+15.0, "Draw Nodes", !flip_y),
m_draw_edges(200+200+80+8, 8.0-2.0+15.0, "Draw Edges", !flip_y),
m_draft(200+200+80+8, 8.0-2.0, "Draft Mode", !flip_y),
m_translucent(110+80, 8.0-2.0+15.0, "Translucent Mode", !flip_y),
m_graph(200, 100),
m_gradient_colors(),
m_draw(3)
{
add_ctrl(m_type);
m_type.text_size(8.0);
m_type.add_item("Solid lines");
m_type.add_item("Bezier curves");
m_type.add_item("Dashed curves");
m_type.add_item("Poygons AA");
m_type.add_item("Poygons Bin");
m_type.cur_item(0);
add_ctrl(m_width);
m_width.num_steps(20);
m_width.range(0.0, 5.0);
m_width.value(2.0);
m_width.label("Width=%1.2f");
m_benchmark.text_size(8.0);
m_draw_nodes.text_size(8.0);
m_draft.text_size(8.0);
m_draw_nodes.status(true);
m_draw_edges.status(true);
add_ctrl(m_benchmark);
add_ctrl(m_draw_nodes);
add_ctrl(m_draw_edges);
add_ctrl(m_draft);
add_ctrl(m_translucent);
agg::rgba c1(1, 1, 0, 0.25);
agg::rgba c2(0, 0, 1);
int i;
for(i = 0; i < 256; i++)
{
m_gradient_colors[i] = c1.gradient(c2, double(i) / 255.0);
}
}
//------------------------------------------------------------------------
void draw_nodes_draft()
{
pixfmt pixf(rbuf_window());
base_renderer rb(pixf);
primitives_renderer prim(rb);
int i;
for(i = 0; i < m_graph.get_num_nodes(); i++)
{
graph::node n = m_graph.get_node(i, width(), height());
prim.fill_color(m_gradient_colors[147]);
prim.line_color(m_gradient_colors[255]);
prim.outlined_ellipse(int(n.x), int(n.y), 10, 10);
prim.fill_color(m_gradient_colors[50]);
prim.solid_ellipse(int(n.x), int(n.y), 4, 4);
}
}
//------------------------------------------------------------------------
void draw_nodes_fine(scanline_rasterizer& ras)
{
gradient_span_alloc sa;
pixfmt pixf(rbuf_window());
base_renderer rb(pixf);
int i;
for(i = 0; i < m_graph.get_num_nodes(); i++)
{
graph::node n = m_graph.get_node(i, width(), height());
agg::ellipse ell(n.x, n.y, 5.0 * m_width.value(), 5.0 * m_width.value());
double x, y;
switch(m_draw)
{
case 0:
ell.rewind(0);
while(!agg::is_stop(ell.vertex(&x, &y)));
break;
case 1:
ras.reset();
ras.add_path(ell);
break;
case 2:
ras.reset();
ras.add_path(ell);
ras.sort();
break;
case 3:
{
gradient_function gf;
agg::trans_affine mtx;
mtx *= agg::trans_affine_scaling(m_width.value() / 2.0);
mtx *= agg::trans_affine_translation(n.x, n.y);
mtx.invert();
interpolator inter(mtx);
gradient_span_gen sg(inter, gf, m_gradient_colors, 0.0, 10.0);
gradient_renderer ren(rb, sa, sg);
ras.add_path(ell);
agg::render_scanlines(ras, m_sl, ren);
}
break;
}
}
}
//------------------------------------------------------------------------
template<class Source>
void render_edge_fine(scanline_rasterizer& ras,
solid_renderer& ren_fine,
draft_renderer& ren_draft,
Source& src)
{
double x, y;
switch(m_draw)
{
case 0:
src.rewind(0);
while(!agg::is_stop(src.vertex(&x, &y)));
break;
case 1:
ras.reset();
ras.add_path(src);
break;
case 2:
ras.reset();
ras.add_path(src);
ras.sort();
break;
case 3:
{
int r = rand() & 0x7F;
int g = rand() & 0x7F;
int b = rand() & 0x7F;
int a = 255;
if(m_translucent.status()) a = 80;
ras.add_path(src);
if(m_type.cur_item() < 4)
{
ren_fine.color(agg::srgba8(r, g, b, a));
agg::render_scanlines(ras, m_sl, ren_fine);
}
else
{
ren_draft.color(agg::srgba8(r, g, b, a));
agg::render_scanlines(ras, m_sl, ren_draft);
}
}
break;
}
}
//------------------------------------------------------------------------
void draw_lines_draft()
{
pixfmt pixf(rbuf_window());
base_renderer rb(pixf);
primitives_renderer prim(rb);
outline_rasterizer ras(prim);
int i;
for(i = 0; i < m_graph.get_num_edges(); i++)
{
graph::edge e = m_graph.get_edge(i);
graph::node n1 = m_graph.get_node(e.node1, width(), height());
graph::node n2 = m_graph.get_node(e.node2, width(), height());
line l(n1.x, n1.y, n2.x, n2.y);
stroke_draft<line> s(l, m_width.value());
int r = rand() & 0x7F;
int g = rand() & 0x7F;
int b = rand() & 0x7F;
int a = 255;
if(m_translucent.status()) a = 80;
prim.line_color(agg::srgba8(r, g, b, a));
ras.add_path(s);
}
}
//------------------------------------------------------------------------
void draw_curves_draft()
{
pixfmt pixf(rbuf_window());
base_renderer rb(pixf);
primitives_renderer prim(rb);
outline_rasterizer ras(prim);
int i;
for(i = 0; i < m_graph.get_num_edges(); i++)
{
graph::edge e = m_graph.get_edge(i);
graph::node n1 = m_graph.get_node(e.node1, width(), height());
graph::node n2 = m_graph.get_node(e.node2, width(), height());
curve c(n1.x, n1.y, n2.x, n2.y);
stroke_draft<curve> s(c, m_width.value());
int r = rand() & 0x7F;
int g = rand() & 0x7F;
int b = rand() & 0x7F;
int a = 255;
if(m_translucent.status()) a = 80;
prim.line_color(agg::srgba8(r, g, b, a));
ras.add_path(s);
}
}
//------------------------------------------------------------------------
void draw_dashes_draft()
{
pixfmt pixf(rbuf_window());
base_renderer rb(pixf);
primitives_renderer prim(rb);
outline_rasterizer ras(prim);
int i;
for(i = 0; i < m_graph.get_num_edges(); i++)
{
graph::edge e = m_graph.get_edge(i);
graph::node n1 = m_graph.get_node(e.node1, width(), height());
graph::node n2 = m_graph.get_node(e.node2, width(), height());
curve c(n1.x, n1.y, n2.x, n2.y);
dash_stroke_draft<curve> s(c, 6.0, 3.0, m_width.value());
int r = rand() & 0x7F;
int g = rand() & 0x7F;
int b = rand() & 0x7F;
int a = 255;
if(m_translucent.status()) a = 80;
prim.line_color(agg::srgba8(r, g, b, a));
ras.add_path(s);
}
}
//------------------------------------------------------------------------
void draw_lines_fine(scanline_rasterizer& ras,
solid_renderer& solid,
draft_renderer& draft)
{
int i;
for(i = 0; i < m_graph.get_num_edges(); i++)
{
graph::edge b = m_graph.get_edge(i);
graph::node n1 = m_graph.get_node(b.node1, width(), height());
graph::node n2 = m_graph.get_node(b.node2, width(), height());
line l(n1.x, n1.y, n2.x, n2.y);
stroke_fine<line> s(l, m_width.value());
render_edge_fine(ras, solid, draft, s);
}
}
//------------------------------------------------------------------------
void draw_curves_fine(scanline_rasterizer& ras,
solid_renderer& solid,
draft_renderer& draft)
{
int i;
for(i = 0; i < m_graph.get_num_edges(); i++)
{
graph::edge b = m_graph.get_edge(i);
graph::node n1 = m_graph.get_node(b.node1, width(), height());
graph::node n2 = m_graph.get_node(b.node2, width(), height());
curve c(n1.x, n1.y, n2.x, n2.y);
stroke_fine<curve> s(c, m_width.value());
render_edge_fine(ras, solid, draft, s);
}
}
//------------------------------------------------------------------------
void draw_dashes_fine(scanline_rasterizer& ras,
solid_renderer& solid,
draft_renderer& draft)
{
int i;
for(i = 0; i < m_graph.get_num_edges(); i++)
{
graph::edge b = m_graph.get_edge(i);
graph::node n1 = m_graph.get_node(b.node1, width(), height());
graph::node n2 = m_graph.get_node(b.node2, width(), height());
curve c(n1.x, n1.y, n2.x, n2.y);
dash_stroke_fine<curve> s(c, 6.0, 3.0, m_width.value());
render_edge_fine(ras, solid, draft, s);
}
}
//------------------------------------------------------------------------
void draw_polygons(scanline_rasterizer& ras,
solid_renderer& solid,
draft_renderer& draft)
{
int i;
if(m_type.cur_item() == 4)
{
ras.gamma(agg::gamma_threshold(0.5));
}
for(i = 0; i < m_graph.get_num_edges(); i++)
{
graph::edge b = m_graph.get_edge(i);
graph::node n1 = m_graph.get_node(b.node1, width(), height());
graph::node n2 = m_graph.get_node(b.node2, width(), height());
curve c(n1.x, n1.y, n2.x, n2.y);
render_edge_fine(ras, solid, draft, c);
}
ras.gamma(agg::gamma_none());
}
//------------------------------------------------------------------------
void draw_scene(scanline_rasterizer& ras,
solid_renderer& solid,
draft_renderer& draft)
{
ras.gamma(agg::gamma_none());
srand(100);
if(m_draw_nodes.status())
{
if(m_draft.status())
{
draw_nodes_draft();
}
else
{
draw_nodes_fine(ras);
}
}
if(m_draw_edges.status())
{
if(m_draft.status())
{
switch(m_type.cur_item())
{
case 0: draw_lines_draft(); break;
case 1: draw_curves_draft(); break;
case 2: draw_dashes_draft(); break;
}
}
else
{
switch(m_type.cur_item())
{
case 0: draw_lines_fine(ras, solid, draft); break;
case 1: draw_curves_fine(ras, solid, draft); break;
case 2: draw_dashes_fine(ras, solid, draft); break;
case 3:
case 4: draw_polygons(ras, solid, draft); break;
}
}
}
}
//------------------------------------------------------------------------
virtual void on_draw()
{
scanline_rasterizer ras;
pixfmt pixf(rbuf_window());
base_renderer rb(pixf);
solid_renderer solid(rb);
draft_renderer draft(rb);
rb.clear(agg::rgba(1, 1, 1));
draw_scene(ras, solid, draft);
ras.filling_rule(agg::fill_non_zero);
agg::render_ctrl(ras, m_sl, rb, m_type);
agg::render_ctrl(ras, m_sl, rb, m_width);
agg::render_ctrl(ras, m_sl, rb, m_benchmark);
agg::render_ctrl(ras, m_sl, rb, m_draw_nodes);
agg::render_ctrl(ras, m_sl, rb, m_draw_edges);
agg::render_ctrl(ras, m_sl, rb, m_draft);
agg::render_ctrl(ras, m_sl, rb, m_translucent);
}
virtual void on_ctrl_change()
{
if(m_benchmark.status())
{
int i;
on_draw();
update_window();
scanline_rasterizer ras;
pixfmt pixf(rbuf_window());
base_renderer rb(pixf);
solid_renderer solid(rb);
draft_renderer draft(rb);
char buf[256];
if(m_draft.status())
{
start_timer();
for(i = 0; i < 10; i++)
{
draw_scene(ras, solid, draft);
}
sprintf(buf, "%3.3f milliseconds", elapsed_time());
}
else
{
double times[5];
for(m_draw = 0; m_draw < 4; m_draw++)
{
start_timer();
for(i = 0; i < 10; i++)
{
draw_scene(ras, solid, draft);
}
times[m_draw] = elapsed_time();
}
m_draw = 3;
times[4] = times[3];
times[3] -= times[2];
times[2] -= times[1];
times[1] -= times[0];
FILE* fd = fopen(full_file_name("benchmark"), "a");
fprintf(fd, "%10.3f %10.3f %10.3f %10.3f %10.3f\n",
times[0], times[1], times[2], times[3], times[4]);
fclose(fd);
sprintf(buf, " pipeline add_path sort render total\n"
"%10.3f %10.3f %10.3f %10.3f %10.3f",
times[0], times[1], times[2], times[3], times[4]);
}
message(buf);
m_benchmark.status(false);
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Line Join");
if(app.init(600+100, 500+30, agg::window_resize))
{
return app.run();
}
return 1;
}

364
examples/idea.cpp Normal file
View File

@ -0,0 +1,364 @@
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_trans_affine.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGR96
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = false };
struct path_attributes
{
unsigned index;
agg::srgba8 fill_color;
agg::srgba8 stroke_color;
double stroke_width;
path_attributes() {}
path_attributes(unsigned idx,
const agg::srgba8& fill,
const agg::srgba8& stroke,
double width) :
index(idx),
fill_color(fill),
stroke_color(stroke),
stroke_width(width)
{
}
};
static double g_poly_bulb[] =
{
-6,-67, -6,-71, -7,-74, -8,-76, -10,-79,
-10,-82, -9,-84, -6,-86, -4,-87, -2,-86,
-1,-86, 1,-84, 2,-82, 2,-79, 0,-77,
-2,-73, -2,-71, -2,-69, -3,-67, -4,-65
};
static double g_poly_beam1[] =
{
-14,-84,-22,-85,-23,-87,-22,-88,-21,-88
};
static double g_poly_beam2[] =
{
-10,-92, -14,-96, -14,-98, -12,-99, -11,-97
};
static double g_poly_beam3[] =
{
-1,-92, -2,-98, 0,-100, 2,-100, 1,-98
};
static double g_poly_beam4[] =
{
5,-89, 11,-94, 13,-93, 13,-92, 12,-91
};
static double g_poly_fig1[] =
{
1,-48,-3,-54,-7,-58,-12,-58,-17,-55,-20,-52,-21,-47,
-20,-40,-17,-33,-11,-28,-6,-26,-2,-25,2,-26,4,-28,5,
-33,5,-39,3,-44,12,-48,12,-50,12,-51,3,-46
};
static double g_poly_fig2[] =
{
11,-27,6,-23,4,-22,3,-19,5,
-16,6,-15,11,-17,19,-23,25,-30,32,-38,32,-41,32,-50,30,-64,32,-72,
32,-75,31,-77,28,-78,26,-80,28,-87,27,-89,25,-88,24,-79,24,-76,23,
-75,20,-76,17,-76,17,-74,19,-73,22,-73,24,-71,26,-69,27,-64,28,-55,
28,-47,28,-40,26,-38,20,-33,14,-30
};
static double g_poly_fig3[] =
{
-6,-20,-9,-21,-15,-21,-20,-17,
-28,-8,-32,-1,-32,1,-30,6,-26,8,-20,10,-16,12,-14,14,-15,16,-18,20,
-22,20,-25,19,-27,20,-26,22,-23,23,-18,23,-14,22,-11,20,-10,17,-9,14,
-11,11,-16,9,-22,8,-26,5,-28,2,-27,-2,-23,-8,-19,-11,-12,-14,-6,-15,
-6,-18
};
static double g_poly_fig4[] =
{
11,-6,8,-16,5,-21,-1,-23,-7,
-22,-10,-17,-9,-10,-8,0,-8,10,-10,18,-11,22,-10,26,-7,28,-3,30,0,31,
5,31,10,27,14,18,14,11,11,2
};
static double g_poly_fig5[] =
{
0,22,-5,21,-8,22,-9,26,-8,49,
-8,54,-10,64,-10,75,-9,81,-10,84,-16,89,-18,95,-18,97,-13,100,-12,99,
-12,95,-10,90,-8,87,-6,86,-4,83,-3,82,-5,80,-6,79,-7,74,-6,63,-3,52,
0,42,1,31
};
static double g_poly_fig6[] =
{
12,31,12,24,8,21,3,21,2,24,3,
30,5,40,8,47,10,56,11,64,11,71,10,76,8,77,8,79,10,81,13,82,17,82,26,
84,28,87,32,86,33,81,32,80,25,79,17,79,14,79,13,76,14,72,14,64,13,55,
12,44,12,34
};
static path_attributes g_attr[3];
static agg::path_storage g_path;
static unsigned g_npaths = 0;
static agg::filling_rule_e g_pflag = agg::fill_non_zero;
static agg::rasterizer_scanline_aa<> g_rasterizer;
static agg::scanline_p8 g_scanline;
static double g_angle = 0.0;
#define AGG_POLY_SIZE(p) (sizeof(p) / (sizeof(*p) * 2))
struct trans_roundoff
{
static void transform(double* x, double* y)
{
*x = floor(*x + 0.5);
*y = floor(*y + 0.5);
}
};
class the_application : public agg::platform_support
{
double m_dx;
double m_dy;
agg::cbox_ctrl<color_type> m_rotate;
agg::cbox_ctrl<color_type> m_even_odd;
agg::cbox_ctrl<color_type> m_draft;
agg::cbox_ctrl<color_type> m_roundoff;
agg::slider_ctrl<color_type> m_angle_delta;
bool m_redraw_flag;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_rotate(10, 3, "Rotate", !flip_y),
m_even_odd(60, 3, "Even-Odd", !flip_y),
m_draft(130, 3, "Draft", !flip_y),
m_roundoff(175, 3, "Roundoff", !flip_y),
m_angle_delta(10, 21, 250-10, 27, !flip_y),
m_redraw_flag(true)
{
m_angle_delta.label("Step=%4.3f degree");
g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
agg::srgba8(255, 255, 0),
agg::srgba8(0, 0, 0),
1.0);
g_path.concat_poly(g_poly_bulb, AGG_POLY_SIZE(g_poly_bulb), true);
g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
agg::srgba8(255, 255, 200),
agg::srgba8(90, 0, 0),
0.7);
g_path.concat_poly(g_poly_beam1, AGG_POLY_SIZE(g_poly_beam1), true);
g_path.concat_poly(g_poly_beam2, AGG_POLY_SIZE(g_poly_beam2), true);
g_path.concat_poly(g_poly_beam3, AGG_POLY_SIZE(g_poly_beam3), true);
g_path.concat_poly(g_poly_beam4, AGG_POLY_SIZE(g_poly_beam4), true);
g_attr[g_npaths++] = path_attributes(g_path.start_new_path(),
agg::srgba8(0, 0, 0),
agg::srgba8(0, 0, 0),
0.0);
g_path.concat_poly(g_poly_fig1, AGG_POLY_SIZE(g_poly_fig1), true);
g_path.concat_poly(g_poly_fig2, AGG_POLY_SIZE(g_poly_fig2), true);
g_path.concat_poly(g_poly_fig3, AGG_POLY_SIZE(g_poly_fig3), true);
g_path.concat_poly(g_poly_fig4, AGG_POLY_SIZE(g_poly_fig4), true);
g_path.concat_poly(g_poly_fig5, AGG_POLY_SIZE(g_poly_fig5), true);
g_path.concat_poly(g_poly_fig6, AGG_POLY_SIZE(g_poly_fig6), true);
m_rotate.text_size(7);
m_even_odd.text_size(7);
m_draft.text_size(7);
m_roundoff.text_size(7);
add_ctrl(m_rotate);
add_ctrl(m_even_odd);
add_ctrl(m_draft);
add_ctrl(m_roundoff);
add_ctrl(m_angle_delta);
m_angle_delta.value(0.01);
}
virtual void on_init()
{
m_dx = rbuf_window().width();
m_dy = rbuf_window().height();
}
virtual void on_resize(int, int)
{
m_redraw_flag = true;
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> ren_base;
pixfmt pixf(rbuf_window());
ren_base rbase(pixf);
trans_roundoff roundoff;
if(m_redraw_flag)
{
g_rasterizer.gamma(agg::gamma_none());
rbase.clear(agg::srgba8(255,255,255));
g_rasterizer.filling_rule(agg::fill_non_zero);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_rotate);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_even_odd);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_draft);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_roundoff);
agg::render_ctrl(g_rasterizer, g_scanline, rbase, m_angle_delta);
m_redraw_flag = false;
}
else
{
rbase.copy_bar(0,
int(32.0 * rbuf_window().height() / m_dy),
rbuf_window().width(),
rbuf_window().height(),
agg::srgba8(255,255,255));
}
if(m_draft.status())
{
g_rasterizer.gamma(agg::gamma_threshold(0.4));
}
agg::trans_affine mtx;
mtx.reset();
mtx *= agg::trans_affine_rotation(g_angle * agg::pi / 180.0);
mtx *= agg::trans_affine_translation(m_dx / 2, m_dy / 2 + 10);
mtx *= agg::trans_affine_scaling(rbuf_window().width() / m_dx,
rbuf_window().height() / m_dy);
agg::conv_transform<agg::path_storage> fill(g_path, mtx);
agg::conv_transform
<
agg::conv_transform<agg::path_storage>,
trans_roundoff
>
fill_roundoff(fill, roundoff);
agg::conv_stroke
<
agg::conv_transform<agg::path_storage>
>
stroke(fill);
agg::conv_stroke
<
agg::conv_transform
<
agg::conv_transform<agg::path_storage>,
trans_roundoff
>
>
stroke_roundoff(fill_roundoff);
g_pflag = m_even_odd.status() ? agg::fill_even_odd : agg::fill_non_zero;
unsigned i;
for(i = 0; i < g_npaths; i++)
{
g_rasterizer.filling_rule(g_pflag);
if(m_roundoff.status()) g_rasterizer.add_path(fill_roundoff, g_attr[i].index);
else g_rasterizer.add_path(fill, g_attr[i].index);
if(m_draft.status())
{
agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color);
}
else
{
agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].fill_color);
}
if(g_attr[i].stroke_width > 0.001)
{
stroke.width(g_attr[i].stroke_width * mtx.scale());
stroke_roundoff.width(g_attr[i].stroke_width * mtx.scale());
if(m_roundoff.status()) g_rasterizer.add_path(stroke_roundoff, g_attr[i].index);
else g_rasterizer.add_path(stroke, g_attr[i].index);
if(m_draft.status())
{
agg::render_scanlines_bin_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color);
}
else
{
agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase, g_attr[i].stroke_color);
}
}
}
}
virtual void on_idle()
{
g_angle += m_angle_delta.value();
if(g_angle > 360.0) g_angle -= 360.0;
force_redraw();
}
virtual void on_ctrl_change()
{
wait_mode(!m_rotate.status());
m_redraw_flag = true;
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Idea");
if(app.init(250, 280, agg::window_resize))
{
return app.run();
}
return 1;
}

214
examples/image1.cpp Normal file
View File

@ -0,0 +1,214 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_ellipse.h"
#include "agg_trans_affine.h"
#include "agg_conv_transform.h"
#include "agg_span_image_filter_rgb.h"
#include "agg_span_image_filter_rgba.h"
#include "agg_span_image_filter_gray.h"
#include "agg_pixfmt_rgba.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_span_allocator.h"
#include "agg_span_interpolator_linear.h"
#include "agg_image_accessors.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
enum flip_y_e { flip_y = true };
#define AGG_BGR24
//#define AGG_RGB565
#include "pixel_formats.h"
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_angle;
agg::slider_ctrl<color_type> m_scale;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_angle(5, 5, 300, 12, !flip_y),
m_scale(5, 5+15, 300, 12+15, !flip_y)
{
add_ctrl(m_angle);
add_ctrl(m_scale);
m_angle.label("Angle=%3.2f");
m_scale.label("Scale=%3.2f");
m_angle.range(-180.0, 180.0);
m_angle.value(0.0);
m_scale.range(0.1, 5.0);
m_scale.value(1.0);
}
virtual ~the_application()
{
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
pixfmt pixf(rbuf_window());
pixfmt_pre pixf_pre(rbuf_window());
renderer_base rb(pixf);
renderer_base_pre rb_pre(pixf_pre);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
agg::trans_affine src_mtx;
src_mtx *= agg::trans_affine_translation(-initial_width()/2 - 10, -initial_height()/2 - 20 - 10);
src_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0);
src_mtx *= agg::trans_affine_scaling(m_scale.value());
src_mtx *= agg::trans_affine_translation(initial_width()/2, initial_height()/2 + 20);
src_mtx *= trans_affine_resizing();
agg::trans_affine img_mtx;
img_mtx *= agg::trans_affine_translation(-initial_width()/2 + 10, -initial_height()/2 + 20 + 10);
img_mtx *= agg::trans_affine_rotation(m_angle.value() * agg::pi / 180.0);
img_mtx *= agg::trans_affine_scaling(m_scale.value());
img_mtx *= agg::trans_affine_translation(initial_width()/2, initial_height()/2 + 20);
img_mtx *= trans_affine_resizing();
img_mtx.invert();
agg::span_allocator<color_type> sa;
typedef agg::span_interpolator_linear<> interpolator_type;
interpolator_type interpolator(img_mtx);
typedef agg::image_accessor_clip<pixfmt> img_source_type;
pixfmt img_pixf(rbuf_img(0));
img_source_type img_src(img_pixf, agg::rgba_pre(0, 0.4, 0, 0.5));
/*
// Version without filtering (nearest neighbor)
//------------------------------------------
typedef agg::span_image_filter_rgb_nn<img_source_type,
interpolator_type> span_gen_type;
span_gen_type sg(img_src, interpolator);
//------------------------------------------
*/
// Version with "hardcoded" bilinear filter and without
// image_accessor (direct filter, the old variant)
//------------------------------------------
typedef agg::span_image_filter_rgb_bilinear_clip<pixfmt,
interpolator_type> span_gen_type;
span_gen_type sg(img_pixf, agg::rgba_pre(0, 0.4, 0, 0.5), interpolator);
//------------------------------------------
/*
// Version with arbitrary 2x2 filter
//------------------------------------------
typedef agg::span_image_filter_rgb_2x2<img_source_type,
interpolator_type> span_gen_type;
agg::image_filter<agg::image_filter_kaiser> filter;
span_gen_type sg(img_src, interpolator, filter);
//------------------------------------------
*/
/*
// Version with arbitrary filter
//------------------------------------------
typedef agg::span_image_filter_rgb<img_source_type,
interpolator_type> span_gen_type;
agg::image_filter<agg::image_filter_spline36> filter;
span_gen_type sg(img_src, interpolator, filter);
//------------------------------------------
*/
agg::rasterizer_scanline_aa<> ras;
ras.clip_box(0, 0, width(), height());
agg::scanline_u8 sl;
double r = initial_width();
if(initial_height() - 60 < r) r = initial_height() - 60;
agg::ellipse ell(initial_width() / 2.0 + 10,
initial_height() / 2.0 + 20 + 10,
r / 2.0 + 16.0,
r / 2.0 + 16.0, 200);
agg::conv_transform<agg::ellipse> tr(ell, src_mtx);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb_pre, sa, sg);
agg::render_ctrl(ras, sl, rb, m_angle);
agg::render_ctrl(ras, sl, rb, m_scale);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Image Affine Transformations with filtering");
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
char buf[256];
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
if(app.init(app.rbuf_img(0).width() + 20, app.rbuf_img(0).height() + 40 + 20, agg::window_resize))
{
// Test the plain/premultiplied issue
//-------------------
//typedef agg::pixfmt_bgra32 pixfmt;
//typedef agg::renderer_base<pixfmt> renderer_base;
//pixfmt pixf(app.rbuf_img(0));
//renderer_base rb(pixf);
//for(unsigned i = 0; i < app.rbuf_img(0).height(); i += 2)
//{
// // Fully transparent
// rb.copy_hline(0, i, app.rbuf_img(0).width(), agg::rgba(0, 0, 0, 0));
// if(i + 1 < app.rbuf_img(0).height())
// {
// // Fully opaque white
// rb.copy_hline(0, i + 1, app.rbuf_img(0).width(), agg::rgba(1, 1, 1, 1));
// }
//}
return app.run();
}
return 0;
}
/*
E:\agg23\examples\image1.cpp(111) : error C2664:
'__thiscall agg::span_image_filter_gray_bilinear<struct agg::sgray8,
struct agg::order_bgra,
class agg::span_interpolator_linear<class agg::trans_affine,8> >::agg::span_image_filter_gray_bilinear<struct agg::sgray8,struct agg::order_bgra,class agg::span_interpolator_linear<class agg::trans_affine,8> >(class agg::span_interpolator_linear<class agg::trans_affine,8> &,const class agg::row_ptr_cache<unsigned char> &,const struct agg::sgray8 &,struct agg::order_bgra &)' :
cannot convert parameter 1 from
'class agg::span_allocator<struct agg::sgray8>' to
'class agg::span_interpolator_linear<class agg::trans_affine,8> &'
*/

251
examples/image_alpha.cpp Normal file
View File

@ -0,0 +1,251 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "agg_ellipse.h"
#include "agg_trans_affine.h"
#include "agg_conv_transform.h"
#include "agg_rendering_buffer.h"
#include "agg_span_allocator.h"
#include "agg_span_image_filter_rgb.h"
#include "agg_image_accessors.h"
#include "agg_span_interpolator_linear.h"
#include "agg_span_converter.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_scanline_aa.h"
#include "ctrl/agg_spline_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
namespace agg
{
//--------------------------------------------------------------------
class span_conv_brightness_alpha
{
public:
typedef int8u alpha_type;
enum array_size_e
{
array_size = 256 * 3
};
span_conv_brightness_alpha(const alpha_type* alpha_array) :
m_alpha_array(alpha_array)
{
}
void prepare() {}
void generate(color_type* span, int x, int y, unsigned len) const
{
do
{
// It's a bit of a hack, but we can treat the 8-bit alpha value as a cover.
color_type::calc_type x = span->r + span->g + span->b;
cover_type cover = m_alpha_array[int(x * array_size / (3 * color_type::full_value()))];
span->a = color_type::mult_cover(color_type::full_value(), cover);
++span;
}
while(--len);
}
private:
const alpha_type* m_alpha_array;
};
}
class the_application : public agg::platform_support
{
agg::spline_ctrl<color_type> m_alpha;
double m_x[50];
double m_y[50];
double m_rx[50];
double m_ry[50];
color_type m_colors[50];
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_alpha(2, 2, 200, 30, 6, !flip_y)
{
m_alpha.value(0, 1.0);
m_alpha.value(1, 1.0);
m_alpha.value(2, 1.0);
m_alpha.value(3, 0.5);
m_alpha.value(4, 0.5);
m_alpha.value(5, 1.0);
m_alpha.update_spline();
add_ctrl(m_alpha);
}
virtual ~the_application()
{
}
virtual void on_init()
{
unsigned i;
for(i = 0; i < 50; i++)
{
m_x[i] = rand() % int(width());
m_y[i] = rand() % int(height());
m_rx[i] = rand() % 60 + 10;
m_ry[i] = rand() % 60 + 10;
m_colors[i] = agg::srgba8(rand() & 0xFF,
rand() & 0xFF,
rand() & 0xFF,
rand() & 0xFF);
}
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> renderer_base;
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
agg::trans_affine src_mtx;
src_mtx *= agg::trans_affine_translation(-initial_width()/2, -initial_height()/2);
src_mtx *= agg::trans_affine_rotation(10.0 * agg::pi / 180.0);
src_mtx *= agg::trans_affine_translation(initial_width()/2, initial_height()/2);
src_mtx *= trans_affine_resizing();
agg::trans_affine img_mtx = src_mtx;
img_mtx.invert();
typedef agg::span_allocator<color_type> span_alloc;
unsigned i;
unsigned char brightness_alpha_array[agg::span_conv_brightness_alpha::array_size];
for(i = 0; i < agg::span_conv_brightness_alpha::array_size; i++)
{
brightness_alpha_array[i] =
agg::int8u(m_alpha.value(double(i) /
double(agg::span_conv_brightness_alpha::array_size)) * 255.0);
}
agg::span_conv_brightness_alpha color_alpha(brightness_alpha_array);
typedef agg::image_accessor_clip<pixfmt> img_source_type;
typedef agg::span_interpolator_linear<> interpolator_type;
typedef agg::span_image_filter_rgb_bilinear<img_source_type,
interpolator_type> span_gen;
typedef agg::span_converter<span_gen,
agg::span_conv_brightness_alpha> span_conv;
span_alloc sa;
interpolator_type interpolator(img_mtx);
pixfmt img_pixf(rbuf_img(0));
img_source_type img_src(img_pixf, agg::rgba(0,0,0,0));
span_gen sg(img_src, interpolator);
span_conv sc(sg, color_alpha);
agg::ellipse ell;
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
for(i = 0; i < 50; i++)
{
ell.init(m_x[i], m_y[i], m_rx[i], m_ry[i], 50);
ras.add_path(ell);
agg::render_scanlines_aa_solid(ras, sl, rb, m_colors[i]);
}
ell.init(initial_width() / 2.0,
initial_height() / 2.0,
initial_width() / 1.9,
initial_height() / 1.9, 200);
agg::conv_transform<agg::ellipse> tr(ell, src_mtx);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb, sa, sc);
agg::render_ctrl(ras, sl, rb, m_alpha);
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
FILE* fd = fopen(full_file_name("alpha"), "w");
int i;
for(i = 0; i < agg::span_conv_brightness_alpha::array_size; i++)
{
int alpha =
agg::int8u(m_alpha.value(double(i) /
double(agg::span_conv_brightness_alpha::array_size)) * 255.0);
if(i % 32 == 0) fprintf(fd, "\n");
fprintf(fd, "%3d, ", alpha);
}
fclose(fd);
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Image Affine Transformations with Alpha-function");
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
char buf[256];
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
if(app.init(app.rbuf_img(0).width(), app.rbuf_img(0).height(), agg::window_resize))
{
return app.run();
}
return 0;
}

428
examples/image_filters.cpp Normal file
View File

@ -0,0 +1,428 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_ellipse.h"
#include "agg_trans_affine.h"
#include "agg_conv_transform.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_image_accessors.h"
#include "agg_renderer_scanline.h"
#include "agg_span_allocator.h"
#include "agg_span_interpolator_linear.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
#include "agg_span_image_filter_rgb.h"
#define span_image_filter span_image_filter_rgb
#define span_image_filter_nn span_image_filter_rgb_nn
#define span_image_filter_bilinear span_image_filter_rgb_bilinear_clip
#define span_image_filter_2x2 span_image_filter_rgb_2x2
enum flip_y_e { flip_y = true };
// Uncomment this for more accurate timings.
// Well, it currently works well only on Windows, where there's
// high accuracy QueryPerformanceCounter is available. On Unix
// it uses regular clock() anyway, so, it won't work for short
// time periods and will give you totally wrong result (probably #INF).
#define AGG_ACCURATE_TIME
class the_application : public agg::platform_support
{
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
agg::slider_ctrl<agg::rgba> m_radius;
agg::slider_ctrl<agg::rgba> m_step;
agg::rbox_ctrl<agg::rgba> m_filters;
agg::cbox_ctrl<agg::rgba> m_normalize;
agg::cbox_ctrl<agg::rgba> m_run;
agg::cbox_ctrl<agg::rgba> m_single_step;
agg::cbox_ctrl<agg::rgba> m_refresh;
double m_cur_angle;
int m_cur_filter;
int m_num_steps;
double m_num_pix;
double m_time1;
double m_time2;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_step (115, 5, 400, 11, !flip_y),
m_radius(115, 5+15, 400, 11+15, !flip_y),
m_filters(0.0, 0.0, 110.0, 210.0, !flip_y),
m_normalize (8.0, 215.0, "Normalize Filter", !flip_y),
m_run (8.0, 245.0, "RUN Test!", !flip_y),
m_single_step(8.0, 230.0, "Single Step", !flip_y),
m_refresh (8.0, 265.0, "Refresh", !flip_y),
m_cur_angle(0.0),
m_cur_filter(1),
m_num_steps(0),
m_num_pix(0.0),
m_time1(0),
m_time2(0)
{
add_ctrl(m_radius);
add_ctrl(m_step);
add_ctrl(m_filters);
add_ctrl(m_run);
add_ctrl(m_single_step);
add_ctrl(m_normalize);
add_ctrl(m_refresh);
m_run.text_size(7.5);
m_single_step.text_size(7.5);
m_normalize.text_size(7.5);
m_refresh.text_size(7.5);
m_normalize.status(true);
m_radius.label("Filter Radius=%.3f");
m_step.label("Step=%3.2f");
m_radius.range(2.0, 8.0);
m_radius.value(4.0);
m_step.range(1.0, 10.0);
m_step.value(5.0);
m_filters.add_item("simple (NN)");
m_filters.add_item("bilinear");
m_filters.add_item("bicubic");
m_filters.add_item("spline16");
m_filters.add_item("spline36");
m_filters.add_item("hanning");
m_filters.add_item("hamming");
m_filters.add_item("hermite");
m_filters.add_item("kaiser");
m_filters.add_item("quadric");
m_filters.add_item("catrom");
m_filters.add_item("gaussian");
m_filters.add_item("bessel");
m_filters.add_item("mitchell");
m_filters.add_item("sinc");
m_filters.add_item("lanczos");
m_filters.add_item("blackman");
m_filters.cur_item(1);
m_filters.border_width(0, 0);
m_filters.background_color(agg::rgba(0.0, 0.0, 0.0, 0.1));
m_filters.text_size(6.0);
m_filters.text_thickness(0.85);
}
virtual ~the_application()
{
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
rb.copy_from(rbuf_img(0), 0, 110, 35);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
char buf[64];
sprintf(buf, "NSteps=%d", m_num_steps);
agg::gsv_text t;
t.start_point(10.0, 295.0);
t.size(10.0);
t.text(buf);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
ras.add_path(pt);
agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba(0,0,0));
if(m_time1 != m_time2 && m_num_pix > 0.0)
{
#ifdef AGG_ACCURATE_TIME
sprintf(buf, "%3.2f Kpix/sec", m_num_pix / (m_time2 - m_time1));
#else
sprintf(buf, "%3.2f Kpix/sec", m_num_pix /
1000.0 /
(double(m_time2 - m_time1) / CLOCKS_PER_SEC));
#endif
t.start_point(10.0, 310.0);
t.text(buf);
ras.add_path(pt);
agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba(0,0,0));
}
if(m_filters.cur_item() >= 14)
{
agg::render_ctrl(ras, sl, rb, m_radius);
}
agg::render_ctrl(ras, sl, rb, m_step);
agg::render_ctrl(ras, sl, rb, m_filters);
agg::render_ctrl(ras, sl, rb, m_run);
agg::render_ctrl(ras, sl, rb, m_normalize);
agg::render_ctrl(ras, sl, rb, m_single_step);
agg::render_ctrl(ras, sl, rb, m_refresh);
}
void transform_image(double angle)
{
double width = rbuf_img(0).width();
double height = rbuf_img(0).height();
pixfmt pixf(rbuf_img(0));
pixfmt_pre pixf_pre(rbuf_img(0));
renderer_base rb(pixf);
renderer_base_pre rb_pre(pixf_pre);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::span_allocator<color_type> sa;
agg::trans_affine src_mtx;
src_mtx *= agg::trans_affine_translation(-width/2.0, -height/2.0);
src_mtx *= agg::trans_affine_rotation(angle * agg::pi / 180.0);
src_mtx *= agg::trans_affine_translation(width/2.0, height/2.0);
agg::trans_affine img_mtx = src_mtx;
img_mtx.invert();
double r = width;
if(height < r) r = height;
r *= 0.5;
r -= 4.0;
agg::ellipse ell(width / 2.0,
height / 2.0,
r, r, 200);
agg::conv_transform<agg::ellipse> tr(ell, src_mtx);
m_num_pix += r * r * agg::pi;
typedef agg::span_interpolator_linear<> interpolator_type;
interpolator_type interpolator(img_mtx);
agg::image_filter_lut filter;
bool norm = m_normalize.status();
typedef agg::image_accessor_clip<pixfmt> source_type;
pixfmt pixf_img(rbuf_img(1));
source_type source(pixf_img, agg::rgba_pre(0,0,0,0));
switch(m_filters.cur_item())
{
case 0:
{
typedef agg::span_image_filter_nn<source_type, interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb_pre, sa, sg);
}
break;
case 1:
{
typedef agg::span_image_filter_bilinear<pixfmt, interpolator_type> span_gen_type;
span_gen_type sg(pixf_img, agg::rgba_pre(0,0,0,0), interpolator);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb_pre, sa, sg);
}
break;
case 5:
case 6:
case 7:
{
switch(m_filters.cur_item())
{
case 5: filter.calculate(agg::image_filter_hanning(), norm); break;
case 6: filter.calculate(agg::image_filter_hamming(), norm); break;
case 7: filter.calculate(agg::image_filter_hermite(), norm); break;
}
typedef agg::span_image_filter_2x2<source_type, interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator, filter);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb_pre, sa, sg);
}
break;
case 2:
case 3:
case 4:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
{
switch(m_filters.cur_item())
{
case 2: filter.calculate(agg::image_filter_bicubic(), norm); break;
case 3: filter.calculate(agg::image_filter_spline16(), norm); break;
case 4: filter.calculate(agg::image_filter_spline36(), norm); break;
case 8: filter.calculate(agg::image_filter_kaiser(), norm); break;
case 9: filter.calculate(agg::image_filter_quadric(), norm); break;
case 10: filter.calculate(agg::image_filter_catrom(), norm); break;
case 11: filter.calculate(agg::image_filter_gaussian(), norm); break;
case 12: filter.calculate(agg::image_filter_bessel(), norm); break;
case 13: filter.calculate(agg::image_filter_mitchell(), norm); break;
case 14: filter.calculate(agg::image_filter_sinc(m_radius.value()), norm); break;
case 15: filter.calculate(agg::image_filter_lanczos(m_radius.value()), norm); break;
case 16: filter.calculate(agg::image_filter_blackman(m_radius.value()), norm); break;
}
typedef agg::span_image_filter<source_type, interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator, filter);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb_pre, sa, sg);
}
break;
}
}
void on_ctrl_change()
{
if(m_single_step.status())
{
m_cur_angle += m_step.value();
copy_img_to_img(1, 0);
transform_image(m_step.value());
m_num_steps++;
force_redraw();
m_single_step.status(false);
}
if(m_run.status())
{
#ifdef AGG_ACCURATE_TIME
start_timer();
m_time1 = m_time2 = elapsed_time();
#else
m_time1 = m_time2 = clock();
#endif
m_num_pix = 0.0;
wait_mode(false);
}
if(m_refresh.status() || m_filters.cur_item() != m_cur_filter)
{
#ifdef AGG_ACCURATE_TIME
start_timer();
m_time1 = m_time2 = 0;
#else
m_time1 = m_time2 = clock();
#endif
m_num_pix = 0.0;
m_cur_angle = 0.0;
copy_img_to_img(1, 2);
transform_image(0.0);
m_refresh.status(false);
m_cur_filter = m_filters.cur_item();
m_num_steps = 0;
force_redraw();
}
}
void on_idle()
{
if(m_run.status())
{
if(m_cur_angle < 360.0)
{
m_cur_angle += m_step.value();
copy_img_to_img(1, 0);
#ifdef AGG_ACCURATE_TIME
start_timer();
#endif
transform_image(m_step.value());
#ifdef AGG_ACCURATE_TIME
m_time2 += elapsed_time();
#endif
m_num_steps++;
}
else
{
m_cur_angle = 0.0;
#ifndef AGG_ACCURATE_TIME
m_time2 = clock();
#endif
wait_mode(true);
m_run.status(false);
}
force_redraw();
}
else
{
wait_mode(true);
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Image transformation filters comparison");
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
char buf[256];
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
app.copy_img_to_img(1, 0);
app.copy_img_to_img(2, 0);
app.transform_image(0.0);
unsigned w = app.rbuf_img(0).width() + 110;
unsigned h = app.rbuf_img(0).height() + 40;
if(w < 305) w = 305;
if(h < 325) h = 325;
if(app.init(w, h, 0))
{
return app.run();
}
return 0;
}

273
examples/image_filters2.cpp Normal file
View File

@ -0,0 +1,273 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_ellipse.h"
#include "agg_trans_affine.h"
#include "agg_conv_transform.h"
#include "agg_scanline_u.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_pixfmt_rgba.h"
#include "agg_span_allocator.h"
#include "agg_span_image_filter_rgba.h"
#include "agg_span_interpolator_linear.h"
#include "agg_image_accessors.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGRA32
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
using agg::rgba;
static rgba g_image[] =
{
rgba(0,1,0,1), rgba(1,0,0,1), rgba(1,1,1,1), rgba(0,0,1,1),
rgba(0,0,1,1), rgba(0,0,0,1), rgba(1,1,1,1), rgba(1,1,1,1),
rgba(1,1,1,1), rgba(1,1,1,1), rgba(1,0,0,1), rgba(0,0,1,1),
rgba(1,0,0,1), rgba(1,1,1,1), rgba(0,0,0,1), rgba(0,1,0,1)
};
class the_application : public agg::platform_support
{
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
agg::slider_ctrl<agg::rgba> m_radius;
agg::rbox_ctrl<agg::rgba> m_filters;
agg::cbox_ctrl<agg::rgba> m_normalize;
double m_cur_angle;
int m_cur_filter;
int m_num_steps;
double m_num_pix;
clock_t m_time1;
clock_t m_time2;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_radius(115, 5, 500-5, 11, !flip_y),
m_filters(0.0, 0.0, 110.0, 210.0, !flip_y),
m_normalize (8.0, 215.0, "Normalize Filter", !flip_y),
m_cur_angle(0.0),
m_cur_filter(1),
m_num_steps(0),
m_num_pix(0.0),
m_time1(0),
m_time2(0)
{
add_ctrl(m_radius);
add_ctrl(m_filters);
add_ctrl(m_normalize);
m_normalize.text_size(7.5);
m_normalize.status(true);
m_radius.label("Filter Radius=%.3f");
m_radius.range(2.0, 8.0);
m_radius.value(4.0);
m_filters.add_item("simple (NN)");
m_filters.add_item("bilinear");
m_filters.add_item("bicubic");
m_filters.add_item("spline16");
m_filters.add_item("spline36");
m_filters.add_item("hanning");
m_filters.add_item("hamming");
m_filters.add_item("hermite");
m_filters.add_item("kaiser");
m_filters.add_item("quadric");
m_filters.add_item("catrom");
m_filters.add_item("gaussian");
m_filters.add_item("bessel");
m_filters.add_item("mitchell");
m_filters.add_item("sinc");
m_filters.add_item("lanczos");
m_filters.add_item("blackman");
m_filters.cur_item(1);
m_filters.border_width(0, 0);
m_filters.background_color(agg::rgba(0.0, 0.0, 0.0, 0.1));
m_filters.text_size(6.0);
m_filters.text_thickness(0.85);
}
virtual ~the_application()
{
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
rb.copy_from(rbuf_img(0), 0, 110, 35);
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::pod_array<agg::int8u> image(4 * 4 * pixfmt::pix_width);
agg::rendering_buffer img_rbuf(image.data(), 4, 4, 4 * pixfmt::pix_width);
pixfmt img_pixf(img_rbuf);
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 4; ++x)
img_pixf.copy_pixel(x, y, g_image[4 * y + x]);
double para[] = { 200, 40, 200+300, 40, 200+300, 40+300, 200, 40+300 };
agg::trans_affine img_mtx(para, 0,0,4,4);
typedef agg::span_interpolator_linear<> interpolator_type;
interpolator_type interpolator(img_mtx);
agg::span_allocator<color_type> sa;
typedef agg::image_accessor_clone<pixfmt> img_source_type;
img_source_type source(img_pixf);
ras.reset();
ras.move_to_d(para[0], para[1]);
ras.line_to_d(para[2], para[3]);
ras.line_to_d(para[4], para[5]);
ras.line_to_d(para[6], para[7]);
switch(m_filters.cur_item())
{
case 0:
{
typedef agg::span_image_filter_rgba_nn<img_source_type,
interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator);
agg::render_scanlines_aa(ras, sl, rb, sa, sg);
}
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
{
agg::image_filter_lut filter;
bool norm = m_normalize.status();
switch(m_filters.cur_item())
{
case 1: filter.calculate(agg::image_filter_bilinear(), norm); break;
case 2: filter.calculate(agg::image_filter_bicubic(), norm); break;
case 3: filter.calculate(agg::image_filter_spline16(), norm); break;
case 4: filter.calculate(agg::image_filter_spline36(), norm); break;
case 5: filter.calculate(agg::image_filter_hanning(), norm); break;
case 6: filter.calculate(agg::image_filter_hamming(), norm); break;
case 7: filter.calculate(agg::image_filter_hermite(), norm); break;
case 8: filter.calculate(agg::image_filter_kaiser(), norm); break;
case 9: filter.calculate(agg::image_filter_quadric(), norm); break;
case 10: filter.calculate(agg::image_filter_catrom(), norm); break;
case 11: filter.calculate(agg::image_filter_gaussian(), norm); break;
case 12: filter.calculate(agg::image_filter_bessel(), norm); break;
case 13: filter.calculate(agg::image_filter_mitchell(), norm); break;
case 14: filter.calculate(agg::image_filter_sinc(m_radius.value()), norm); break;
case 15: filter.calculate(agg::image_filter_lanczos(m_radius.value()), norm); break;
case 16: filter.calculate(agg::image_filter_blackman(m_radius.value()), norm); break;
}
typedef agg::span_image_filter_rgba<img_source_type,
interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator, filter);
agg::render_scanlines_aa(ras, sl, rb, sa, sg);
double x_start = 5.0;
double x_end = 195.0;
double y_start = 235.0;
double y_end = initial_height() - 5.0;
double x_center = (x_start + x_end) / 2;
agg::path_storage p;
agg::conv_stroke<agg::path_storage> stroke(p);
stroke.width(0.8);
unsigned i;
for(i = 0; i <= 16; i++)
{
double x = x_start + (x_end - x_start) * i / 16.0;
p.remove_all();
p.move_to(x+0.5, y_start);
p.line_to(x+0.5, y_end);
ras.add_path(stroke);
agg::render_scanlines_aa_solid(ras, sl, rb,
agg::srgba8(0, 0, 0, i == 8 ? 255 : 100));
}
double ys = y_start + (y_end - y_start) / 6.0;
p.remove_all();
p.move_to(x_start, ys);
p.line_to(x_end, ys);
ras.add_path(stroke);
agg::render_scanlines_aa_solid(ras, sl, rb, agg::srgba8(0, 0, 0));
double radius = filter.radius();
unsigned n = unsigned(radius * 256 * 2);
double dx = (x_end - x_start) * radius / 8.0;
double dy = y_end - ys;
const agg::int16* weights = filter.weight_array();
double xs = (x_end + x_start)/2.0 - (filter.diameter() * (x_end - x_start) / 32.0);
unsigned nn = filter.diameter() * 256;
p.remove_all();
p.move_to(xs+0.5, ys + dy * weights[0] / agg::image_filter_scale);
for(i = 1; i < nn; i++)
{
p.line_to(xs + dx * i / n + 0.5,
ys + dy * weights[i] / agg::image_filter_scale);
}
ras.add_path(stroke);
agg::render_scanlines_aa_solid(ras, sl, rb, agg::srgba8(100, 0, 0));
}
break;
}
if(m_filters.cur_item() >= 14)
{
agg::render_ctrl(ras, sl, rb, m_radius);
}
agg::render_ctrl(ras, sl, rb, m_filters);
agg::render_ctrl(ras, sl, rb, m_normalize);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Image transformation filters comparison");
if(app.init(500, 340, 0))
{
return app.run();
}
return 0;
}

View File

@ -0,0 +1,315 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_ellipse.h"
#include "agg_trans_affine.h"
#include "agg_conv_transform.h"
#include "agg_conv_stroke.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_image_filters.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
struct filter_base
{
virtual double radius() const = 0;
virtual void set_radius(double r) = 0;
virtual double calc_weight(double x) const = 0;
};
template<class Filter> struct image_filter_const_radius_adaptor : filter_base
{
virtual double radius() const { return m_filter.radius(); }
virtual void set_radius(double r) {}
virtual double calc_weight(double x) const { return m_filter.calc_weight(fabs(x)); }
Filter m_filter;
};
template<class Filter> struct image_filter_variable_radius_adaptor : filter_base
{
virtual double radius() const { return m_filter.radius(); }
virtual double calc_weight(double x) const { return m_filter.calc_weight(fabs(x)); }
virtual void set_radius(double r) { m_filter = Filter(r); }
image_filter_variable_radius_adaptor() : m_filter(2.0) {}
Filter m_filter;
};
class the_application : public agg::platform_support
{
agg::slider_ctrl<agg::rgba> m_radius;
agg::cbox_ctrl<agg::rgba> m_bilinear;
agg::cbox_ctrl<agg::rgba> m_bicubic;
agg::cbox_ctrl<agg::rgba> m_spline16;
agg::cbox_ctrl<agg::rgba> m_spline36;
agg::cbox_ctrl<agg::rgba> m_hanning;
agg::cbox_ctrl<agg::rgba> m_hamming;
agg::cbox_ctrl<agg::rgba> m_hermite;
agg::cbox_ctrl<agg::rgba> m_kaiser;
agg::cbox_ctrl<agg::rgba> m_quadric;
agg::cbox_ctrl<agg::rgba> m_catrom;
agg::cbox_ctrl<agg::rgba> m_gaussian;
agg::cbox_ctrl<agg::rgba> m_bessel;
agg::cbox_ctrl<agg::rgba> m_mitchell;
agg::cbox_ctrl<agg::rgba> m_sinc;
agg::cbox_ctrl<agg::rgba> m_lanczos;
agg::cbox_ctrl<agg::rgba> m_blackman;
agg::cbox_ctrl<agg::rgba>* m_filters[32];
image_filter_const_radius_adaptor<agg::image_filter_bilinear> m_filter_bilinear;
image_filter_const_radius_adaptor<agg::image_filter_bicubic> m_filter_bicubic;
image_filter_const_radius_adaptor<agg::image_filter_spline16> m_filter_spline16;
image_filter_const_radius_adaptor<agg::image_filter_spline36> m_filter_spline36;
image_filter_const_radius_adaptor<agg::image_filter_hanning> m_filter_hanning;
image_filter_const_radius_adaptor<agg::image_filter_hamming> m_filter_hamming;
image_filter_const_radius_adaptor<agg::image_filter_hermite> m_filter_hermite;
image_filter_const_radius_adaptor<agg::image_filter_kaiser> m_filter_kaiser;
image_filter_const_radius_adaptor<agg::image_filter_quadric> m_filter_quadric;
image_filter_const_radius_adaptor<agg::image_filter_catrom> m_filter_catrom;
image_filter_const_radius_adaptor<agg::image_filter_gaussian> m_filter_gaussian;
image_filter_const_radius_adaptor<agg::image_filter_bessel> m_filter_bessel;
image_filter_const_radius_adaptor<agg::image_filter_mitchell> m_filter_mitchell;
image_filter_variable_radius_adaptor<agg::image_filter_sinc> m_filter_sinc;
image_filter_variable_radius_adaptor<agg::image_filter_lanczos> m_filter_lanczos;
image_filter_variable_radius_adaptor<agg::image_filter_blackman> m_filter_blackman;
filter_base* m_filter_func[32];
unsigned m_num_filters;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_radius (5.0, 5.0, 780-5, 10.0, !flip_y),
m_bilinear (8.0, 30.0+15*0, "bilinear", !flip_y),
m_bicubic (8.0, 30.0+15*1, "bicubic ", !flip_y),
m_spline16 (8.0, 30.0+15*2, "spline16", !flip_y),
m_spline36 (8.0, 30.0+15*3, "spline36", !flip_y),
m_hanning (8.0, 30.0+15*4, "hanning ", !flip_y),
m_hamming (8.0, 30.0+15*5, "hamming ", !flip_y),
m_hermite (8.0, 30.0+15*6, "hermite ", !flip_y),
m_kaiser (8.0, 30.0+15*7, "kaiser ", !flip_y),
m_quadric (8.0, 30.0+15*8, "quadric ", !flip_y),
m_catrom (8.0, 30.0+15*9, "catrom ", !flip_y),
m_gaussian (8.0, 30.0+15*10, "gaussian", !flip_y),
m_bessel (8.0, 30.0+15*11, "bessel ", !flip_y),
m_mitchell (8.0, 30.0+15*12, "mitchell", !flip_y),
m_sinc (8.0, 30.0+15*13, "sinc ", !flip_y),
m_lanczos (8.0, 30.0+15*14, "lanczos ", !flip_y),
m_blackman (8.0, 30.0+15*15, "blackman", !flip_y),
m_num_filters(0)
{
m_filters[m_num_filters++] = &m_bilinear;
m_filters[m_num_filters++] = &m_bicubic;
m_filters[m_num_filters++] = &m_spline16;
m_filters[m_num_filters++] = &m_spline36;
m_filters[m_num_filters++] = &m_hanning;
m_filters[m_num_filters++] = &m_hamming;
m_filters[m_num_filters++] = &m_hermite;
m_filters[m_num_filters++] = &m_kaiser;
m_filters[m_num_filters++] = &m_quadric;
m_filters[m_num_filters++] = &m_catrom;
m_filters[m_num_filters++] = &m_gaussian;
m_filters[m_num_filters++] = &m_bessel;
m_filters[m_num_filters++] = &m_mitchell;
m_filters[m_num_filters++] = &m_sinc;
m_filters[m_num_filters++] = &m_lanczos;
m_filters[m_num_filters++] = &m_blackman;
unsigned i = 0;
m_filter_func[i++] = &m_filter_bilinear;
m_filter_func[i++] = &m_filter_bicubic;
m_filter_func[i++] = &m_filter_spline16;
m_filter_func[i++] = &m_filter_spline36;
m_filter_func[i++] = &m_filter_hanning;
m_filter_func[i++] = &m_filter_hamming;
m_filter_func[i++] = &m_filter_hermite;
m_filter_func[i++] = &m_filter_kaiser;
m_filter_func[i++] = &m_filter_quadric;
m_filter_func[i++] = &m_filter_catrom;
m_filter_func[i++] = &m_filter_gaussian;
m_filter_func[i++] = &m_filter_bessel;
m_filter_func[i++] = &m_filter_mitchell;
m_filter_func[i++] = &m_filter_sinc;
m_filter_func[i++] = &m_filter_lanczos;
m_filter_func[i++] = &m_filter_blackman;
for(i = 0; i < m_num_filters; i++)
{
add_ctrl(*m_filters[i]);
}
m_radius.range(2.0, 8.0);
m_radius.value(4.0);
m_radius.label("Radius=%.3f");
add_ctrl(m_radius);
}
virtual ~the_application()
{
}
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
renderer_solid rs(rb);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
double x_start = 125.0;
double x_end = initial_width() - 15.0;
double y_start = 10.0;
double y_end = initial_height() - 10.0;
double x_center = (x_start + x_end) / 2;
unsigned i;
agg::path_storage p;
agg::conv_stroke<agg::path_storage> pl(p);
agg::conv_transform<agg::conv_stroke<agg::path_storage> > tr(pl, trans_affine_resizing());
for(i = 0; i <= 16; i++)
{
double x = x_start + (x_end - x_start) * i / 16.0;
p.remove_all();
p.move_to(x+0.5, y_start);
p.line_to(x+0.5, y_end);
ras.add_path(tr);
rs.color(agg::srgba8(0, 0, 0, i == 8 ? 255 : 100));
agg::render_scanlines(ras, sl, rs);
}
double ys = y_start + (y_end - y_start) / 6.0;
p.remove_all();
p.move_to(x_start, ys);
p.line_to(x_end, ys);
ras.add_path(tr);
rs.color(agg::srgba8(0, 0, 0));
agg::render_scanlines(ras, sl, rs);
pl.width(1.5);
for(i = 0; i < m_num_filters; i++)
{
if(m_filters[i]->status())
{
m_filter_func[i]->set_radius(m_radius.value());
unsigned j;
double radius = m_filter_func[i]->radius();
unsigned n = unsigned(radius * 256 * 2);
double dy = y_end - ys;
double xs = (x_end + x_start)/2.0 - (radius * (x_end - x_start) / 16.0);
double dx = (x_end - x_start) * radius / 8.0;
p.remove_all();
p.move_to(xs+0.5, ys + dy * m_filter_func[i]->calc_weight(-radius));
for(j = 1; j < n; j++)
{
p.line_to(xs + dx * j / n + 0.5,
ys + dy * m_filter_func[i]->calc_weight(j / 256.0 - radius));
}
ras.add_path(tr);
rs.color(agg::rgba(0.5, 0, 0));
agg::render_scanlines(ras, sl, rs);
p.remove_all();
unsigned xint;
int ir = int(ceil(radius) + 0.1);
for(xint = 0; xint < 256; xint++)
{
int xfract;
double sum = 0;
for(xfract = -ir; xfract < ir; xfract++)
{
double xf = xint/256.0 + xfract;
if(xf >= -radius || xf <= radius)
{
sum += m_filter_func[i]->calc_weight(xf);
}
}
double x = x_center + ((-128.0 + xint) / 128.0) * radius * (x_end - x_start) / 16.0;
double y = ys + sum * 256 - 256;
if(xint == 0) p.move_to(x, y);
else p.line_to(x, y);
}
ras.add_path(tr);
rs.color(agg::rgba(0, 0.5, 0));
agg::render_scanlines(ras, sl, rs);
agg::image_filter_lut normalized(*m_filter_func[i]);
const agg::int16* weights = normalized.weight_array();
xs = (x_end + x_start)/2.0 - (normalized.diameter() * (x_end - x_start) / 32.0);
unsigned nn = normalized.diameter() * 256;
p.remove_all();
p.move_to(xs+0.5, ys + dy * weights[0] / agg::image_filter_scale);
for(j = 1; j < nn; j++)
{
p.line_to(xs + dx * j / n + 0.5,
ys + dy * weights[j] / agg::image_filter_scale);
}
ras.add_path(tr);
rs.color(agg::rgba(0, 0, 0.5));
agg::render_scanlines(ras, sl, rs);
}
}
for(i = 0; i < m_num_filters; i++)
{
agg::render_ctrl(ras, sl, rb, *m_filters[i]);
}
if(m_sinc.status() || m_lanczos.status() || m_blackman.status())
{
agg::render_ctrl(ras, sl, rb, m_radius);
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Image filters' shape comparison");
if(app.init(780, 300, agg::window_resize))
{
return app.run();
}
return 0;
}

View File

@ -0,0 +1,329 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_trans_affine.h"
#include "agg_trans_bilinear.h"
#include "agg_trans_perspective.h"
#include "agg_span_allocator.h"
#include "agg_span_interpolator_linear.h"
#include "agg_span_interpolator_trans.h"
#include "agg_span_subdiv_adaptor.h"
#include "agg_pixfmt_rgba.h"
#include "agg_image_accessors.h"
#include "agg_span_image_filter_rgba.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "platform/agg_platform_support.h"
#include "interactive_polygon.h"
#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
agg::rasterizer_scanline_aa<> g_rasterizer;
agg::scanline_u8 g_scanline;
double g_x1 = 0;
double g_y1 = 0;
double g_x2 = 0;
double g_y2 = 0;
class the_application : public agg::platform_support
{
public:
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
agg::interactive_polygon m_quad;
agg::rbox_ctrl<color_type> m_trans_type;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_quad(4, 5.0),
m_trans_type(420, 5.0, 420+170.0, 70.0, !flip_y)
{
m_trans_type.add_item("Affine Parallelogram");
m_trans_type.add_item("Bilinear");
m_trans_type.add_item("Perspective");
m_trans_type.cur_item(2);
add_ctrl(m_trans_type);
}
virtual void on_init()
{
double d = 0.0;
g_x1 = d;
g_y1 = d;
g_x2 = rbuf_img(0).width() - d;
g_y2 = rbuf_img(0).height() - d;
m_quad.xn(0) = 100;
m_quad.yn(0) = 100;
m_quad.xn(1) = width() - 100;
m_quad.yn(1) = 100;
m_quad.xn(2) = width() - 100;
m_quad.yn(2) = height() - 100;
m_quad.xn(3) = 100;
m_quad.yn(3) = height() - 100;
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
pixfmt_pre pixf_pre(rbuf_window());
renderer_base rb(pixf);
renderer_base_pre rb_pre(pixf_pre);
renderer_solid r(rb);
rb.clear(agg::rgba(1, 1, 1));
if(m_trans_type.cur_item() == 0)
{
// For the affine parallelogram transformations we
// calculate the 4-th (implicit) point of the parallelogram
m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1));
m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1));
}
//--------------------------
// Render the "quad" tool and controls
g_rasterizer.add_path(m_quad);
agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rb,
agg::rgba(0, 0.3, 0.5, 0.6));
// Prepare the polygon to rasterize. Here we need to fill
// the destination (transformed) polygon.
g_rasterizer.clip_box(0, 0, width(), height());
g_rasterizer.reset();
g_rasterizer.move_to_d(m_quad.xn(0), m_quad.yn(0));
g_rasterizer.line_to_d(m_quad.xn(1), m_quad.yn(1));
g_rasterizer.line_to_d(m_quad.xn(2), m_quad.yn(2));
g_rasterizer.line_to_d(m_quad.xn(3), m_quad.yn(3));
agg::span_allocator<color_type> sa;
agg::image_filter_bilinear filter_kernel;
agg::image_filter_lut filter(filter_kernel, false);
pixfmt pixf_img(rbuf_img(0));
//typedef agg::image_accessor_wrap<pixfmt,
// agg::wrap_mode_reflect,
// agg::wrap_mode_reflect> img_accessor_type;
//img_accessor_type ia(pixf_img);
//typedef agg::image_accessor_clip<pixfmt> img_accessor_type;
//img_accessor_type ia(pixf_img, agg::rgba(1,1,1));
typedef agg::image_accessor_clone<pixfmt> img_accessor_type;
img_accessor_type ia(pixf_img);
start_timer();
switch(m_trans_type.cur_item())
{
case 0:
{
// Note that we consruct an affine matrix that transforms
// a parallelogram to a rectangle, i.e., it's inverted.
// It's actually the same as:
// tr(g_x1, g_y1, g_x2, g_y2, m_triangle.polygon());
// tr.invert();
agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
// Also note that we can use the linear interpolator instead of
// arbitrary span_interpolator_trans. It works much faster,
// but the transformations must be linear and parellel.
typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
interpolator_type interpolator(tr);
typedef agg::span_image_filter_rgba_nn<img_accessor_type,
interpolator_type> span_gen_type;
span_gen_type sg(ia, interpolator);
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
break;
}
case 1:
{
agg::trans_bilinear tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
if(tr.is_valid())
{
typedef agg::span_interpolator_linear<agg::trans_bilinear> interpolator_type;
interpolator_type interpolator(tr);
typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
interpolator_type> span_gen_type;
span_gen_type sg(ia, interpolator, filter);
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
}
break;
}
case 2:
{
agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
if(tr.is_valid())
{
// Subdivision and linear interpolation (faster, but less accurate)
//-----------------------
//typedef agg::span_interpolator_linear<agg::trans_perspective> interpolator_type;
//typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;
//interpolator_type interpolator(tr);
//subdiv_adaptor_type subdiv_adaptor(interpolator);
//
//typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
// subdiv_adaptor_type> span_gen_type;
//span_gen_type sg(ia, subdiv_adaptor, filter);
//-----------------------
// Direct calculations of the coordinates
//-----------------------
typedef agg::span_interpolator_trans<agg::trans_perspective> interpolator_type;
interpolator_type interpolator(tr);
typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
interpolator_type> span_gen_type;
span_gen_type sg(ia, interpolator, filter);
//-----------------------
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
}
break;
}
}
double tm = elapsed_time();
char buf[128];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
sprintf(buf, "%3.2f ms", tm);
t.start_point(10.0, 10.0);
t.text(buf);
g_rasterizer.add_path(pt);
agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rb,
agg::rgba(0,0,0));
//--------------------------
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_quad.on_mouse_button_down(x, y))
{
force_redraw();
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_quad.on_mouse_move(x, y))
{
force_redraw();
}
}
if((flags & agg::mouse_left) == 0)
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
if(m_quad.on_mouse_button_up(x, y))
{
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Image Perspective Transformations");
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
char buf[256];
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
/*
// Testing the "black border" issue with alpha channel
//----------------------------------------
the_application::pixfmt pixf(app.rbuf_img(0));
the_application::renderer_base rbase(pixf);
rbase.clear(agg::srgba8(0,0,0,0));
unsigned i;
for(i = 0; i < 50; i++)
{
agg::ellipse ell(rand() % rbase.width(),
rand() % rbase.height(),
rand() % 20 + 5,
rand() % 20 + 5,
100);
g_rasterizer.add_path(ell);
agg::render_scanlines_aa_solid(g_rasterizer, g_scanline, rbase,
agg::srgba8((rand() & 0x7F) + 127,
(rand() & 0x7F) + 127,
(rand() & 0x7F) + 127,
255));
}
*/
if(app.init(600, 600, agg::window_resize))
{
return app.run();
}
return 1;
}

371
examples/image_resample.cpp Normal file
View File

@ -0,0 +1,371 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_trans_affine.h"
#include "agg_span_allocator.h"
#include "agg_span_interpolator_linear.h"
#include "agg_span_interpolator_trans.h"
#include "agg_span_interpolator_persp.h"
#include "agg_span_subdiv_adaptor.h"
#include "agg_image_accessors.h"
#include "agg_gamma_lut.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
#include "interactive_polygon.h"
#define AGG_BGRA32
//#define AGG_BGRA64
//#define AGG_BGRA128
#include "pixel_formats.h"
int global_offset = 0;
enum flip_y_e { flip_y = true };
agg::rasterizer_scanline_aa<> g_rasterizer;
agg::scanline_u8 g_scanline;
double g_x1 = 0;
double g_y1 = 0;
double g_x2 = 0;
double g_y2 = 0;
#include "agg_span_image_filter_rgba.h"
#define image_filter_2x2_type agg::span_image_filter_rgba_2x2
#define image_resample_affine_type agg::span_image_resample_rgba_affine
#define image_resample_type agg::span_image_resample_rgba
typedef color_type::value_type value_type;
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_base<pixfmt_pre> renderer_base_pre;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
class the_application : public agg::platform_support
{
public:
agg::interactive_polygon m_quad;
agg::rbox_ctrl<agg::rgba> m_trans_type;
agg::slider_ctrl<agg::rgba> m_blur;
agg::slider_ctrl<agg::rgba> m_gamma;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_quad(4, 5.0),
m_trans_type(400, 5.0, 430+170.0, 100.0, !flip_y),
m_blur (5.0, 5.0+15*0, 400-5, 10.0+15*0, !flip_y),
m_gamma(5.0, 5.0+15*1, 400-5, 10.0+15*1, !flip_y)
{
m_trans_type.text_size(7);
m_trans_type.add_item("Affine No Resample");
m_trans_type.add_item("Affine Resample");
m_trans_type.add_item("Perspective No Resample LERP");
m_trans_type.add_item("Perspective No Resample Exact");
m_trans_type.add_item("Perspective Resample LERP");
m_trans_type.add_item("Perspective Resample Exact");
m_trans_type.cur_item(4);
add_ctrl(m_trans_type);
m_blur.range(0.5, 5.0);
m_blur.value(1.0);
m_blur.label("Blur=%.3f");
add_ctrl(m_blur);
}
virtual void on_init()
{
g_x1 = 0.0;
g_y1 = 0.0;
g_x2 = rbuf_img(0).width();
g_y2 = rbuf_img(0).height();
double x1 = g_x1;// * 100.0;
double y1 = g_y1;// * 100.0;
double x2 = g_x2;// * 100.0;
double y2 = g_y2;// * 100.0;
double dx = width() / 2.0 - (x2 - x1) / 2.0;
double dy = height() / 2.0 - (y2 - y1) / 2.0;
m_quad.xn(0) = floor(x1 + dx);
m_quad.yn(0) = floor(y1 + dy);// - 150;
m_quad.xn(1) = floor(x2 + dx);
m_quad.yn(1) = floor(y1 + dy);// - 110;
m_quad.xn(2) = floor(x2 + dx);
m_quad.yn(2) = floor(y2 + dy);// - 300;
m_quad.xn(3) = floor(x1 + dx);
m_quad.yn(3) = floor(y2 + dy);// - 200;
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
pixfmt_pre pixf_pre(rbuf_window());
renderer_base rb(pixf);
renderer_base_pre rb_pre(pixf_pre);
renderer_solid r(rb);
rb.clear(agg::rgba(1, 1, 1));
if(m_trans_type.cur_item() < 2)
{
// For the affine parallelogram transformations we
// calculate the 4-th (implicit) point of the parallelogram
m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1));
m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1));
}
//--------------------------
// Render the "quad" tool and controls
g_rasterizer.add_path(m_quad);
r.color(agg::rgba(0, 0.3, 0.5, 0.5));
agg::render_scanlines(g_rasterizer, g_scanline, r);
// Prepare the polygon to rasterize. Here we need to fill
// the destination (transformed) polygon.
g_rasterizer.clip_box(0, 0, width(), height());
g_rasterizer.reset();
int b = 0;
g_rasterizer.move_to_d(m_quad.xn(0)-b, m_quad.yn(0)-b);
g_rasterizer.line_to_d(m_quad.xn(1)+b, m_quad.yn(1)-b);
g_rasterizer.line_to_d(m_quad.xn(2)+b, m_quad.yn(2)+b);
g_rasterizer.line_to_d(m_quad.xn(3)-b, m_quad.yn(3)+b);
typedef agg::span_allocator<color_type> span_alloc_type;
span_alloc_type sa;
agg::image_filter_bilinear filter_kernel;
agg::image_filter_lut filter(filter_kernel, true);
pixfmt pixf_img(rbuf_img(0));
typedef agg::image_accessor_clone<pixfmt> source_type;
source_type source(pixf_img);
start_timer();
switch(m_trans_type.cur_item())
{
case 0:
{
agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
interpolator_type interpolator(tr);
typedef image_filter_2x2_type<source_type,
interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator, filter);
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
break;
}
case 1:
{
agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
typedef image_resample_affine_type<source_type> span_gen_type;
interpolator_type interpolator(tr);
span_gen_type sg(source, interpolator, filter);
sg.blur(m_blur.value());
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
break;
}
case 2:
{
agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
if(tr.is_valid())
{
typedef agg::span_interpolator_linear_subdiv<agg::trans_perspective> interpolator_type;
interpolator_type interpolator(tr);
typedef image_filter_2x2_type<source_type,
interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator, filter);
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
}
break;
}
case 3:
{
agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
if(tr.is_valid())
{
typedef agg::span_interpolator_trans<agg::trans_perspective> interpolator_type;
interpolator_type interpolator(tr);
typedef image_filter_2x2_type<source_type,
interpolator_type> span_gen_type;
span_gen_type sg(source, interpolator, filter);
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
}
break;
}
case 4:
{
typedef agg::span_interpolator_persp_lerp<> interpolator_type;
typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;
interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
subdiv_adaptor_type subdiv_adaptor(interpolator);
if(interpolator.is_valid())
{
typedef image_resample_type<source_type,
subdiv_adaptor_type> span_gen_type;
span_gen_type sg(source, subdiv_adaptor, filter);
sg.blur(m_blur.value());
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
}
break;
}
case 5:
{
typedef agg::span_interpolator_persp_exact<> interpolator_type;
typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;
interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
subdiv_adaptor_type subdiv_adaptor(interpolator);
if(interpolator.is_valid())
{
typedef image_resample_type<source_type,
subdiv_adaptor_type> span_gen_type;
span_gen_type sg(source, subdiv_adaptor, filter);
sg.blur(m_blur.value());
agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
}
break;
}
}
double tm = elapsed_time();
char buf[64];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
sprintf(buf, "%3.2f ms", tm);
t.start_point(10.0, 70.0);
t.text(buf);
g_rasterizer.add_path(pt);
r.color(agg::rgba(0,0,0));
agg::render_scanlines(g_rasterizer, g_scanline, r);
//--------------------------
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type);
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_blur);
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_quad.on_mouse_button_down(x, y))
{
force_redraw();
}
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_quad.on_mouse_move(x, y))
{
force_redraw();
}
}
if((flags & agg::mouse_left) == 0)
{
on_mouse_button_up(x, y, flags);
}
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
if(m_quad.on_mouse_button_up(x, y))
{
force_redraw();
}
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
double cx = (m_quad.xn(0) + m_quad.xn(1) + m_quad.xn(2) + m_quad.xn(3)) / 4;
double cy = (m_quad.yn(0) + m_quad.yn(1) + m_quad.yn(2) + m_quad.yn(3)) / 4;
agg::trans_affine tr = agg::trans_affine_translation(-cx, -cy);
tr *= agg::trans_affine_rotation(agg::pi / 2.0);
tr *= agg::trans_affine_translation(cx, cy);
tr.transform(&m_quad.xn(0), &m_quad.yn(0));
tr.transform(&m_quad.xn(1), &m_quad.yn(1));
tr.transform(&m_quad.xn(2), &m_quad.yn(2));
tr.transform(&m_quad.xn(3), &m_quad.yn(3));
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Image Transformations with Resampling");
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
char buf[256];
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
if(app.init(600, 600, agg::window_resize))
{
return app.run();
}
return 1;
}

View File

@ -0,0 +1,454 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_path_storage.h"
#include "agg_trans_affine.h"
#include "agg_conv_transform.h"
#include "agg_pixfmt_rgba.h"
#include "agg_span_image_filter_rgba.h"
#include "agg_span_interpolator_linear.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_span_allocator.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_rbox_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::slider_ctrl<agg::rgba> m_polygon_angle;
agg::slider_ctrl<agg::rgba> m_polygon_scale;
agg::slider_ctrl<agg::rgba> m_image_angle;
agg::slider_ctrl<agg::rgba> m_image_scale;
agg::cbox_ctrl<agg::rgba> m_rotate_polygon;
agg::cbox_ctrl<agg::rgba> m_rotate_image;
agg::rbox_ctrl<agg::rgba> m_example;
double m_image_center_x;
double m_image_center_y;
double m_polygon_cx;
double m_polygon_cy;
double m_image_cx;
double m_image_cy;
double m_dx;
double m_dy;
int m_flag;
public:
//------------------------------------------------------------------------
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_polygon_angle(5, 5, 145, 11, !flip_y),
m_polygon_scale(5, 5+14, 145, 12+14, !flip_y),
m_image_angle (155, 5, 300, 12, !flip_y),
m_image_scale (155, 5+14, 300, 12+14, !flip_y),
m_rotate_polygon(5, 5+14+14, "Rotate Polygon", !flip_y),
m_rotate_image (5, 5+14+14+14, "Rotate Image", !flip_y),
m_example(-3.0, 14+14+14+14, -3.0, 14+14+14+14, !flip_y),
m_flag(0)
{
add_ctrl(m_polygon_angle);
add_ctrl(m_polygon_scale);
add_ctrl(m_image_angle);
add_ctrl(m_image_scale);
add_ctrl(m_rotate_polygon);
add_ctrl(m_rotate_image);
add_ctrl(m_example);
m_polygon_angle.label("Polygon Angle=%3.2f");
m_polygon_scale.label("Polygon Scale=%3.2f");
m_polygon_angle.range(-180.0, 180.0);
m_polygon_scale.range(0.1, 5.0);
m_polygon_scale.value(1.0);
m_image_angle.label("Image Angle=%3.2f");
m_image_scale.label("Image Scale=%3.2f");
m_image_angle.range(-180.0, 180.0);
m_image_scale.range(0.1, 5.0);
m_image_scale.value(1.0);
m_example.add_item("0");
m_example.add_item("1");
m_example.add_item("2");
m_example.add_item("3");
m_example.add_item("4");
m_example.add_item("5");
m_example.add_item("6");
m_example.cur_item(0);
}
//------------------------------------------------------------------------
virtual ~the_application()
{
}
//------------------------------------------------------------------------
virtual void on_init()
{
m_image_center_x = initial_width() / 2.0;
m_image_center_y = initial_height() / 2.0;
m_polygon_cx = m_image_cx = initial_width() / 2.0;
m_polygon_cy = m_image_cy = initial_height() / 2.0;
}
//------------------------------------------------------------------------
void create_star(agg::path_storage& ps)
{
double r = initial_width();
if(initial_height() < r) r = initial_height();
double r1 = r / 3 - 8.0;
double r2 = r1 / 1.45;
unsigned nr = 14;
unsigned i;
for(i = 0; i < nr; i++)
{
double a = agg::pi * 2.0 * i / nr - agg::pi / 2.0;
double dx = cos(a);
double dy = sin(a);
if(i & 1)
{
ps.line_to(m_polygon_cx + dx * r1, m_polygon_cy + dy * r1);
}
else
{
if(i) ps.line_to(m_polygon_cx + dx * r2, m_polygon_cy + dy * r2);
else ps.move_to(m_polygon_cx + dx * r2, m_polygon_cy + dy * r2);
}
}
}
//------------------------------------------------------------------------
virtual void on_draw()
{
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
pixfmt pixf(rbuf_window());
pixfmt pixf_img(rbuf_img(0));
renderer_base rb(pixf);
renderer_solid rs(rb);
rb.clear(agg::rgba(1.0, 1.0, 1.0));
agg::trans_affine image_mtx;
agg::trans_affine polygon_mtx;
polygon_mtx *= agg::trans_affine_translation(-m_polygon_cx, -m_polygon_cy);
polygon_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0);
polygon_mtx *= agg::trans_affine_scaling(m_polygon_scale.value());
polygon_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy);
switch(m_example.cur_item())
{
default:
case 0:
// --------------(Example 0, Identity matrix)
break;
case 1:
// --------------(Example 1)
image_mtx *= agg::trans_affine_translation(-m_image_center_x, -m_image_center_y);
image_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0);
image_mtx *= agg::trans_affine_scaling(m_polygon_scale.value());
image_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy);
image_mtx.invert();
break;
case 2:
// --------------(Example 2)
image_mtx *= agg::trans_affine_translation(-m_image_center_x, -m_image_center_y);
image_mtx *= agg::trans_affine_rotation(m_image_angle.value() * agg::pi / 180.0);
image_mtx *= agg::trans_affine_scaling(m_image_scale.value());
image_mtx *= agg::trans_affine_translation(m_image_cx, m_image_cy);
image_mtx.invert();
break;
case 3:
// --------------(Example 3)
image_mtx *= agg::trans_affine_translation(-m_image_center_x, -m_image_center_y);
image_mtx *= agg::trans_affine_rotation(m_image_angle.value() * agg::pi / 180.0);
image_mtx *= agg::trans_affine_scaling(m_image_scale.value());
image_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy);
image_mtx.invert();
break;
case 4:
// --------------(Example 4)
image_mtx *= agg::trans_affine_translation(-m_image_cx, -m_image_cy);
image_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0);
image_mtx *= agg::trans_affine_scaling(m_polygon_scale.value());
image_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy);
image_mtx.invert();
break;
case 5:
// --------------(Example 5)
image_mtx *= agg::trans_affine_translation(-m_image_center_x, -m_image_center_y);
image_mtx *= agg::trans_affine_rotation(m_image_angle.value() * agg::pi / 180.0);
image_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0);
image_mtx *= agg::trans_affine_scaling(m_image_scale.value());
image_mtx *= agg::trans_affine_scaling(m_polygon_scale.value());
image_mtx *= agg::trans_affine_translation(m_image_cx, m_image_cy);
image_mtx.invert();
break;
case 6:
// --------------(Example 6)
image_mtx *= agg::trans_affine_translation(-m_image_cx, -m_image_cy);
image_mtx *= agg::trans_affine_rotation(m_image_angle.value() * agg::pi / 180.0);
image_mtx *= agg::trans_affine_scaling(m_image_scale.value());
image_mtx *= agg::trans_affine_translation(m_image_cx, m_image_cy);
image_mtx.invert();
break;
}
typedef agg::span_interpolator_linear<> interpolator_type;
interpolator_type interpolator(image_mtx);
agg::span_allocator<color_type> sa;
// "hardcoded" bilinear filter
//------------------------------------------
typedef agg::span_image_filter_rgba_bilinear_clip<pixfmt,
interpolator_type> span_gen_type;
span_gen_type sg(pixf_img, agg::rgba(1,1,1), interpolator);
//------------------------------------------
agg::rasterizer_scanline_aa<> ras;
agg::scanline_u8 sl;
agg::path_storage ps;
create_star(ps);
agg::conv_transform<agg::path_storage> tr(ps, polygon_mtx);
ras.add_path(tr);
agg::render_scanlines_aa(ras, sl, rb, sa, sg);
agg::ellipse e1(m_image_cx, m_image_cy, 5, 5, 20);
agg::ellipse e2(m_image_cx, m_image_cy, 2, 2, 20);
agg::conv_stroke<agg::ellipse> c1(e1);
rs.color(agg::rgba(0.7,0.8,0));
ras.add_path(e1);
agg::render_scanlines(ras, sl, rs);
rs.color(agg::rgba(0,0,0));
ras.add_path(c1);
agg::render_scanlines(ras, sl, rs);
ras.add_path(e2);
agg::render_scanlines(ras, sl, rs);
agg::render_ctrl(ras, sl, rb, m_polygon_angle);
agg::render_ctrl(ras, sl, rb, m_polygon_scale);
agg::render_ctrl(ras, sl, rb, m_image_angle);
agg::render_ctrl(ras, sl, rb, m_image_scale);
agg::render_ctrl(ras, sl, rb, m_rotate_polygon);
agg::render_ctrl(ras, sl, rb, m_rotate_image);
agg::render_ctrl(ras, sl, rb, m_example);
}
//------------------------------------------------------------------------
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(sqrt((x - m_image_cx) * (x - m_image_cx) +
(y - m_image_cy) * (y - m_image_cy) ) < 5.0)
{
m_dx = x - m_image_cx;
m_dy = y - m_image_cy;
m_flag = 1;
}
else
{
agg::rasterizer_scanline_aa<> ras;
agg::trans_affine polygon_mtx;
polygon_mtx *= agg::trans_affine_translation(-m_polygon_cx, -m_polygon_cy);
polygon_mtx *= agg::trans_affine_rotation(m_polygon_angle.value() * agg::pi / 180.0);
polygon_mtx *= agg::trans_affine_scaling(m_polygon_scale.value(), m_polygon_scale.value());
polygon_mtx *= agg::trans_affine_translation(m_polygon_cx, m_polygon_cy);
agg::path_storage ps;
create_star(ps);
agg::conv_transform<agg::path_storage> tr(ps, polygon_mtx);
ras.add_path(tr);
if(ras.hit_test(x, y))
{
m_dx = x - m_polygon_cx;
m_dy = y - m_polygon_cy;
m_flag = 2;
}
}
}
}
//------------------------------------------------------------------------
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
if(m_flag == 1)
{
m_image_cx = x - m_dx;
m_image_cy = y - m_dy;
force_redraw();
}
if(m_flag == 2)
{
m_polygon_cx = x - m_dx;
m_polygon_cy = y - m_dy;
force_redraw();
}
}
else
{
on_mouse_button_up(x, y, flags);
}
}
//------------------------------------------------------------------------
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
m_flag = 0;
}
//------------------------------------------------------------------------
virtual void on_ctrl_change()
{
if(m_rotate_polygon.status() || m_rotate_image.status())
{
wait_mode(false);
}
else
{
wait_mode(true);
}
force_redraw();
}
//------------------------------------------------------------------------
virtual void on_idle()
{
bool redraw = false;
if(m_rotate_polygon.status())
{
m_polygon_angle.value(m_polygon_angle.value() + 0.5);
if(m_polygon_angle.value() >= 180.0)
{
m_polygon_angle.value(m_polygon_angle.value() - 360.0);
}
redraw = true;
}
if(m_rotate_image.status())
{
m_image_angle.value(m_image_angle.value() + 0.5);
if(m_image_angle.value() >= 180.0)
{
m_image_angle.value(m_image_angle.value() - 360.0);
}
redraw = true;
}
if(redraw) force_redraw();
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Image Affine Transformations with filtering");
const char* img_name = "spheres";
if(argc >= 2) img_name = argv[1];
if(!app.load_img(0, img_name))
{
char buf[256];
if(strcmp(img_name, "spheres") == 0)
{
sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
"or copy it from the ../art directory.",
img_name, app.img_ext(), img_name, app.img_ext());
}
else
{
sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
}
app.message(buf);
return 1;
}
if(app.init(app.rbuf_img(0).width(),
app.rbuf_img(0).height(),
0))
{
return app.run();
}
return 0;
}

View File

@ -0,0 +1,284 @@
#include "agg_basics.h"
#include "interactive_polygon.h"
namespace agg
{
interactive_polygon::interactive_polygon(unsigned np, double point_radius) :
m_polygon(np * 2),
m_num_points(np),
m_node(-1),
m_edge(-1),
m_vs(&m_polygon[0], m_num_points, false),
m_stroke(m_vs),
m_point_radius(point_radius),
m_status(0),
m_dx(0.0),
m_dy(0.0)
{
m_stroke.width(1.0);
}
void interactive_polygon::rewind(unsigned)
{
m_status = 0;
m_stroke.rewind(0);
}
unsigned interactive_polygon::vertex(double* x, double* y)
{
unsigned cmd = path_cmd_stop;
double r = m_point_radius;
if(m_status == 0)
{
cmd = m_stroke.vertex(x, y);
if(!is_stop(cmd)) return cmd;
if(m_node >= 0 && m_node == int(m_status)) r *= 1.2;
m_ellipse.init(xn(m_status), yn(m_status), r, r, 32);
++m_status;
}
cmd = m_ellipse.vertex(x, y);
if(!is_stop(cmd)) return cmd;
if(m_status >= m_num_points) return path_cmd_stop;
if(m_node >= 0 && m_node == int(m_status)) r *= 1.2;
m_ellipse.init(xn(m_status), yn(m_status), r, r, 32);
++m_status;
return m_ellipse.vertex(x, y);
}
bool interactive_polygon::check_edge(unsigned i, double x, double y) const
{
bool ret = false;
unsigned n1 = i;
unsigned n2 = (i + m_num_points - 1) % m_num_points;
double x1 = xn(n1);
double y1 = yn(n1);
double x2 = xn(n2);
double y2 = yn(n2);
double dx = x2 - x1;
double dy = y2 - y1;
if(sqrt(dx*dx + dy*dy) > 0.0000001)
{
double x3 = x;
double y3 = y;
double x4 = x3 - dy;
double y4 = y3 + dx;
double den = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1);
double u1 = ((x4-x3) * (y1-y3) - (y4-y3) * (x1-x3)) / den;
double xi = x1 + u1 * (x2 - x1);
double yi = y1 + u1 * (y2 - y1);
dx = xi - x;
dy = yi - y;
if (u1 > 0.0 && u1 < 1.0 && sqrt(dx*dx + dy*dy) <= m_point_radius)
{
ret = true;
}
}
return ret;
}
bool interactive_polygon::on_mouse_button_down(double x, double y)
{
unsigned i;
bool ret = false;
m_node = -1;
m_edge = -1;
for (i = 0; i < m_num_points; i++)
{
if(sqrt( (x-xn(i)) * (x-xn(i)) + (y-yn(i)) * (y-yn(i)) ) < m_point_radius)
{
m_dx = x - xn(i);
m_dy = y - yn(i);
m_node = int(i);
ret = true;
break;
}
}
if(!ret)
{
for (i = 0; i < m_num_points; i++)
{
if(check_edge(i, x, y))
{
m_dx = x;
m_dy = y;
m_edge = int(i);
ret = true;
break;
}
}
}
if(!ret)
{
if(point_in_polygon(x, y))
{
m_dx = x;
m_dy = y;
m_node = int(m_num_points);
ret = true;
}
}
return ret;
}
bool interactive_polygon::on_mouse_move(double x, double y)
{
bool ret = false;
double dx;
double dy;
if(m_node == int(m_num_points))
{
dx = x - m_dx;
dy = y - m_dy;
unsigned i;
for(i = 0; i < m_num_points; i++)
{
xn(i) += dx;
yn(i) += dy;
}
m_dx = x;
m_dy = y;
ret = true;
}
else
{
if(m_edge >= 0)
{
unsigned n1 = m_edge;
unsigned n2 = (n1 + m_num_points - 1) % m_num_points;
dx = x - m_dx;
dy = y - m_dy;
xn(n1) += dx;
yn(n1) += dy;
xn(n2) += dx;
yn(n2) += dy;
m_dx = x;
m_dy = y;
ret = true;
}
else
{
if(m_node >= 0)
{
xn(m_node) = x - m_dx;
yn(m_node) = y - m_dy;
ret = true;
}
}
}
return ret;
}
bool interactive_polygon::on_mouse_button_up(double x, double y)
{
bool ret = (m_node >= 0) || (m_edge >= 0);
m_node = -1;
m_edge = -1;
return ret;
}
//======= Crossings Multiply algorithm of InsideTest ========================
//
// By Eric Haines, 3D/Eye Inc, erich@eye.com
//
// This version is usually somewhat faster than the original published in
// Graphics Gems IV; by turning the division for testing the X axis crossing
// into a tricky multiplication test this part of the test became faster,
// which had the additional effect of making the test for "both to left or
// both to right" a bit slower for triangles than simply computing the
// intersection each time. The main increase is in triangle testing speed,
// which was about 15% faster; all other polygon complexities were pretty much
// the same as before. On machines where division is very expensive (not the
// case on the HP 9000 series on which I tested) this test should be much
// faster overall than the old code. Your mileage may (in fact, will) vary,
// depending on the machine and the test data, but in general I believe this
// code is both shorter and faster. This test was inspired by unpublished
// Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson.
// Related work by Samosky is in:
//
// Samosky, Joseph, "SectionView: A system for interactively specifying and
// visualizing sections through three-dimensional medical image data",
// M.S. Thesis, Department of Electrical Engineering and Computer Science,
// Massachusetts Institute of Technology, 1993.
//
// Shoot a test ray along +X axis. The strategy is to compare vertex Y values
// to the testing point's Y and quickly discard edges which are entirely to one
// side of the test ray. Note that CONVEX and WINDING code can be added as
// for the CrossingsTest() code; it is left out here for clarity.
//
// Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
// _point_, returns 1 if inside, 0 if outside.
bool interactive_polygon::point_in_polygon(double tx, double ty) const
{
if(m_num_points < 3) return false;
unsigned j;
int yflag0, yflag1, inside_flag;
double vtx0, vty0, vtx1, vty1;
vtx0 = xn(m_num_points - 1);
vty0 = yn(m_num_points - 1);
// get test bit for above/below X axis
yflag0 = (vty0 >= ty);
vtx1 = xn(0);
vty1 = yn(0);
inside_flag = 0;
for (j = 1; j <= m_num_points; ++j)
{
yflag1 = (vty1 >= ty);
// Check if endpoints straddle (are on opposite sides) of X axis
// (i.e. the Y's differ); if so, +X ray could intersect this edge.
// The old test also checked whether the endpoints are both to the
// right or to the left of the test point. However, given the faster
// intersection point computation used below, this test was found to
// be a break-even proposition for most polygons and a loser for
// triangles (where 50% or more of the edges which survive this test
// will cross quadrants and so have to have the X intersection computed
// anyway). I credit Joseph Samosky with inspiring me to try dropping
// the "both left or both right" part of my code.
if (yflag0 != yflag1)
{
// Check intersection of pgon segment with +X ray.
// Note if >= point's X; if so, the ray hits it.
// The division operation is avoided for the ">=" test by checking
// the sign of the first vertex wrto the test point; idea inspired
// by Joseph Samosky's and Mark Haigh-Hutchinson's different
// polygon inclusion tests.
if ( ((vty1-ty) * (vtx0-vtx1) >=
(vtx1-tx) * (vty0-vty1)) == yflag1 )
{
inside_flag ^= 1;
}
}
// Move to the next pair of vertices, retaining info as possible.
yflag0 = yflag1;
vtx0 = vtx1;
vty0 = vty1;
unsigned k = (j >= m_num_points) ? j - m_num_points : j;
vtx1 = xn(k);
vty1 = yn(k);
}
return inside_flag != 0;
}
}

View File

@ -0,0 +1,111 @@
#ifndef INTERACTIVE_POLYGON_INCLUDED
#define INTERACTIVE_POLYGON_INCLUDED
#include "agg_array.h"
#include "agg_conv_stroke.h"
#include "agg_ellipse.h"
namespace agg
{
class simple_polygon_vertex_source
{
public:
simple_polygon_vertex_source(const double* polygon, unsigned np,
bool roundoff = false,
bool close = true) :
m_polygon(polygon),
m_num_points(np),
m_vertex(0),
m_roundoff(roundoff),
m_close(close)
{
}
void close(bool f) { m_close = f; }
bool close() const { return m_close; }
void rewind(unsigned)
{
m_vertex = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_vertex > m_num_points) return path_cmd_stop;
if(m_vertex == m_num_points)
{
++m_vertex;
return path_cmd_end_poly | (m_close ? path_flags_close : 0);
}
*x = m_polygon[m_vertex * 2];
*y = m_polygon[m_vertex * 2 + 1];
if(m_roundoff)
{
*x = floor(*x) + 0.5;
*y = floor(*y) + 0.5;
}
++m_vertex;
return (m_vertex == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
const double* m_polygon;
unsigned m_num_points;
unsigned m_vertex;
bool m_roundoff;
bool m_close;
};
class interactive_polygon
{
public:
interactive_polygon(unsigned np, double point_radius);
unsigned num_points() const { return m_num_points; }
double xn(unsigned n) const { return m_polygon[n * 2]; }
double yn(unsigned n) const { return m_polygon[n * 2 + 1]; }
double& xn(unsigned n) { return m_polygon[n * 2]; }
double& yn(unsigned n) { return m_polygon[n * 2 + 1]; }
const double* polygon() const { return &m_polygon[0]; }
int node() const { return m_node; }
void node(int n) { m_node = n; }
void close(bool f) { m_vs.close(f); }
bool close() const { return m_vs.close(); }
void rewind(unsigned);
unsigned vertex(double* x, double* y);
bool on_mouse_button_down(double x, double y);
bool on_mouse_move(double x, double y);
bool on_mouse_button_up(double x, double y);
private:
bool check_edge(unsigned i, double x, double y) const;
bool point_in_polygon(double x, double y) const;
pod_array<double> m_polygon;
unsigned m_num_points;
int m_node;
int m_edge;
simple_polygon_vertex_source m_vs;
conv_stroke<simple_polygon_vertex_source> m_stroke;
ellipse m_ellipse;
double m_point_radius;
unsigned m_status;
double m_dx;
double m_dy;
};
}
#endif

334
examples/line_patterns.cpp Normal file
View File

@ -0,0 +1,334 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_conv_transform.h"
#include "agg_conv_stroke.h"
#include "agg_conv_clip_polyline.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_pattern_filters_rgba.h"
#include "agg_renderer_outline_aa.h"
#include "agg_renderer_outline_image.h"
#include "agg_pixfmt_rgb.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_bezier_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
static agg::int8u brightness_to_alpha[256 * 3] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253,
253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252,
252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251,
251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 249, 249, 249, 249,
249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 246,
246, 246, 246, 246, 246, 245, 245, 245, 245, 245, 244, 244, 244, 244, 243, 243,
243, 243, 243, 242, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240, 239, 239,
239, 239, 238, 238, 238, 238, 237, 237, 237, 236, 236, 236, 235, 235, 235, 234,
234, 234, 233, 233, 233, 232, 232, 232, 231, 231, 230, 230, 230, 229, 229, 229,
228, 228, 227, 227, 227, 226, 226, 225, 225, 224, 224, 224, 223, 223, 222, 222,
221, 221, 220, 220, 219, 219, 219, 218, 218, 217, 217, 216, 216, 215, 214, 214,
213, 213, 212, 212, 211, 211, 210, 210, 209, 209, 208, 207, 207, 206, 206, 205,
204, 204, 203, 203, 202, 201, 201, 200, 200, 199, 198, 198, 197, 196, 196, 195,
194, 194, 193, 192, 192, 191, 190, 190, 189, 188, 188, 187, 186, 186, 185, 184,
183, 183, 182, 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172,
171, 171, 170, 169, 168, 167, 166, 166, 165, 164, 163, 162, 162, 161, 160, 159,
158, 157, 156, 156, 155, 154, 153, 152, 151, 150, 149, 148, 148, 147, 146, 145,
144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129,
128, 128, 127, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113,
112, 111, 110, 109, 108, 107, 106, 105, 104, 102, 101, 100, 99, 98, 97, 96,
95, 94, 93, 91, 90, 89, 88, 87, 86, 85, 84, 82, 81, 80, 79, 78,
77, 75, 74, 73, 72, 71, 70, 69, 67, 66, 65, 64, 63, 61, 60, 59,
58, 57, 56, 54, 53, 52, 51, 50, 48, 47, 46, 45, 44, 42, 41, 40,
39, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 25, 24, 23, 22, 20,
19, 18, 17, 15, 14, 13, 12, 11, 9, 8, 7, 6, 4, 3, 2, 1
};
class pattern_src_brightness_to_alpha
{
public:
pattern_src_brightness_to_alpha(agg::rendering_buffer& rb) :
m_rb(&rb), m_pf(*m_rb) {}
unsigned width() const { return m_pf.width(); }
unsigned height() const { return m_pf.height(); }
color_type pixel(int x, int y) const
{
color_type c = m_pf.pixel(x, y);
// It's a bit of a hack, but we can treat the 8-bit alpha value as a cover.
color_type::calc_type sum = c.r + c.g + c.b;
int i = int(sum * sizeof(brightness_to_alpha) / (3 * color_type::full_value()));
agg::cover_type cover = brightness_to_alpha[i];
c.a = color_type::mult_cover(color_type::full_value(), cover);
return c;
}
private:
agg::rendering_buffer* m_rb;
pixfmt m_pf;
};
class the_application : public agg::platform_support
{
agg::srgba8 m_ctrl_color;
agg::bezier_ctrl<color_type> m_curve1;
agg::bezier_ctrl<color_type> m_curve2;
agg::bezier_ctrl<color_type> m_curve3;
agg::bezier_ctrl<color_type> m_curve4;
agg::bezier_ctrl<color_type> m_curve5;
agg::bezier_ctrl<color_type> m_curve6;
agg::bezier_ctrl<color_type> m_curve7;
agg::bezier_ctrl<color_type> m_curve8;
agg::bezier_ctrl<color_type> m_curve9;
agg::slider_ctrl<color_type> m_scale_x;
agg::slider_ctrl<color_type> m_start_x;
public:
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
typedef agg::rasterizer_scanline_aa<> rasterizer_scanline;
typedef agg::scanline_p8 scanline;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_ctrl_color(agg::rgba(0, 0.3, 0.5, 0.3)),
m_scale_x(5.0, 5.0, 240.0, 12.0, !flip_y),
m_start_x(250.0, 5.0, 495.0, 12.0, !flip_y)
{
m_curve1.line_color(m_ctrl_color);
m_curve2.line_color(m_ctrl_color);
m_curve3.line_color(m_ctrl_color);
m_curve4.line_color(m_ctrl_color);
m_curve5.line_color(m_ctrl_color);
m_curve6.line_color(m_ctrl_color);
m_curve7.line_color(m_ctrl_color);
m_curve8.line_color(m_ctrl_color);
m_curve9.line_color(m_ctrl_color);
m_curve1.curve(64, 19, 14, 126, 118, 266, 19, 265);
m_curve2.curve(112, 113, 178, 32, 200, 132, 125, 438);
m_curve3.curve(401, 24, 326, 149, 285, 11, 177, 77);
m_curve4.curve(188, 427, 129, 295, 19, 283, 25, 410);
m_curve5.curve(451, 346, 302, 218, 265, 441, 459, 400);
m_curve6.curve(454, 198, 14, 13, 220, 291, 483, 283);
m_curve7.curve(301, 398, 355, 231, 209, 211, 170, 353);
m_curve8.curve(484, 101, 222, 33, 486, 435, 487, 138);
m_curve9.curve(143, 147, 11, 45, 83, 427, 132, 197);
add_ctrl(m_curve1);
add_ctrl(m_curve2);
add_ctrl(m_curve3);
add_ctrl(m_curve4);
add_ctrl(m_curve5);
add_ctrl(m_curve6);
add_ctrl(m_curve7);
add_ctrl(m_curve8);
add_ctrl(m_curve9);
m_curve1.no_transform();
m_curve2.no_transform();
m_curve3.no_transform();
m_curve4.no_transform();
m_curve5.no_transform();
m_curve6.no_transform();
m_curve7.no_transform();
m_curve8.no_transform();
m_curve9.no_transform();
m_scale_x.label("Scale X=%.2f");
m_scale_x.range(0.2, 3.0);
m_scale_x.value(1.0);
m_scale_x.no_transform();
add_ctrl(m_scale_x);
m_start_x.label("Start X=%.2f");
m_start_x.range(0.0, 10.0);
m_start_x.value(0.0);
m_start_x.no_transform();
add_ctrl(m_start_x);
}
template<class Pattern,
class Rasterizer,
class Renderer,
class PatternSource,
class VertexSource>
void draw_curve(Pattern& patt,
Rasterizer& ras,
Renderer& ren,
PatternSource& src,
VertexSource& vs)
{
patt.create(src);
ren.scale_x(m_scale_x.value());
ren.start_x(m_start_x.value());
ras.add_path(vs);
}
virtual void on_draw()
{
pixfmt pf(rbuf_window());
renderer_base ren_base(pf);
ren_base.clear(agg::rgba(1.0, 1.0, 0.95));
renderer_scanline ren(ren_base);
rasterizer_scanline ras;
scanline sl;
// Pattern source. Must have an interface:
// width() const
// height() const
// pixel(int x, int y) const
// Any agg::renderer_base<> or derived
// is good for the use as a source.
//-----------------------------------
pattern_src_brightness_to_alpha p1(rbuf_img(0));
pattern_src_brightness_to_alpha p2(rbuf_img(1));
pattern_src_brightness_to_alpha p3(rbuf_img(2));
pattern_src_brightness_to_alpha p4(rbuf_img(3));
pattern_src_brightness_to_alpha p5(rbuf_img(4));
pattern_src_brightness_to_alpha p6(rbuf_img(5));
pattern_src_brightness_to_alpha p7(rbuf_img(6));
pattern_src_brightness_to_alpha p8(rbuf_img(7));
pattern_src_brightness_to_alpha p9(rbuf_img(8));
agg::pattern_filter_bilinear_rgba<color_type> fltr; // Filtering functor
// agg::line_image_pattern is the main container for the patterns. It creates
// a copy of the patterns extended according to the needs of the filter.
// agg::line_image_pattern can operate with arbitrary image width, but if the
// width of the pattern is power of 2, it's better to use the modified
// version agg::line_image_pattern_pow2 because it works about 15-25 percent
// faster than agg::line_image_pattern (because of using simple masking instead
// of expensive '%' operation).
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba<color_type> > pattern_type;
typedef agg::renderer_base<pixfmt> base_ren_type;
typedef agg::renderer_outline_image<base_ren_type, pattern_type> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
//-- Create with specifying the source
//pattern_type patt(fltr, src);
//-- Create uninitialized and set the source
pattern_type patt(fltr);
renderer_type ren_img(ren_base, patt);
rasterizer_type ras_img(ren_img);
draw_curve(patt, ras_img, ren_img, p1, m_curve1.curve());
draw_curve(patt, ras_img, ren_img, p2, m_curve2.curve());
draw_curve(patt, ras_img, ren_img, p3, m_curve3.curve());
draw_curve(patt, ras_img, ren_img, p4, m_curve4.curve());
draw_curve(patt, ras_img, ren_img, p5, m_curve5.curve());
draw_curve(patt, ras_img, ren_img, p6, m_curve6.curve());
draw_curve(patt, ras_img, ren_img, p7, m_curve7.curve());
draw_curve(patt, ras_img, ren_img, p8, m_curve8.curve());
draw_curve(patt, ras_img, ren_img, p9, m_curve9.curve());
agg::render_ctrl(ras, sl, ren_base, m_curve1);
agg::render_ctrl(ras, sl, ren_base, m_curve2);
agg::render_ctrl(ras, sl, ren_base, m_curve3);
agg::render_ctrl(ras, sl, ren_base, m_curve4);
agg::render_ctrl(ras, sl, ren_base, m_curve5);
agg::render_ctrl(ras, sl, ren_base, m_curve6);
agg::render_ctrl(ras, sl, ren_base, m_curve7);
agg::render_ctrl(ras, sl, ren_base, m_curve8);
agg::render_ctrl(ras, sl, ren_base, m_curve9);
agg::render_ctrl(ras, sl, ren_base, m_scale_x);
agg::render_ctrl(ras, sl, ren_base, m_start_x);
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == ' ')
{
FILE* fd = fopen(full_file_name("coord"), "w");
fprintf(fd, "%.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f, %.0f",
m_curve1.x1(), m_curve1.y1(),
m_curve1.x2(), m_curve1.y2(),
m_curve1.x3(), m_curve1.y3(),
m_curve1.x4(), m_curve1.y4());
fclose(fd);
}
}
virtual void on_ctrl_change()
{
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Drawing Lines with Image Patterns");
if(!app.load_img(0, "1") ||
!app.load_img(1, "2") ||
!app.load_img(2, "3") ||
!app.load_img(3, "4") ||
!app.load_img(4, "5") ||
!app.load_img(5, "6") ||
!app.load_img(6, "7") ||
!app.load_img(7, "8") ||
!app.load_img(8, "9"))
{
char buf[256];
sprintf(buf, "There must be files 1%s...9%s\n"
"Copy and unzip:\n"
"../art/line_patterns.bmp.zip\n"
"or\n"
"../art/line_patterns.ppm.tar.gz\n",
app.img_ext(), app.img_ext());
app.message(buf);
return 1;
}
if(app.init(500, 450, agg::window_resize))
{
return app.run();
}
return 1;
}

View File

@ -0,0 +1,353 @@
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "agg_math.h"
#include "agg_rendering_buffer.h"
#include "agg_conv_transform.h"
#include "agg_conv_stroke.h"
#include "agg_conv_clip_polyline.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_pattern_filters_rgba.h"
#include "agg_renderer_outline_aa.h"
#include "agg_renderer_outline_image.h"
#include "agg_path_storage.h"
#include "agg_pixfmt_rgb.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_bezier_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGRA32
//#define AGG_BGRA128
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
static agg::int8u brightness_to_alpha[256 * 3] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254, 254, 254,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253,
253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 252,
252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251,
251, 251, 251, 251, 250, 250, 250, 250, 250, 250, 250, 250, 249, 249, 249, 249,
249, 249, 249, 248, 248, 248, 248, 248, 248, 248, 247, 247, 247, 247, 247, 246,
246, 246, 246, 246, 246, 245, 245, 245, 245, 245, 244, 244, 244, 244, 243, 243,
243, 243, 243, 242, 242, 242, 242, 241, 241, 241, 241, 240, 240, 240, 239, 239,
239, 239, 238, 238, 238, 238, 237, 237, 237, 236, 236, 236, 235, 235, 235, 234,
234, 234, 233, 233, 233, 232, 232, 232, 231, 231, 230, 230, 230, 229, 229, 229,
228, 228, 227, 227, 227, 226, 226, 225, 225, 224, 224, 224, 223, 223, 222, 222,
221, 221, 220, 220, 219, 219, 219, 218, 218, 217, 217, 216, 216, 215, 214, 214,
213, 213, 212, 212, 211, 211, 210, 210, 209, 209, 208, 207, 207, 206, 206, 205,
204, 204, 203, 203, 202, 201, 201, 200, 200, 199, 198, 198, 197, 196, 196, 195,
194, 194, 193, 192, 192, 191, 190, 190, 189, 188, 188, 187, 186, 186, 185, 184,
183, 183, 182, 181, 180, 180, 179, 178, 177, 177, 176, 175, 174, 174, 173, 172,
171, 171, 170, 169, 168, 167, 166, 166, 165, 164, 163, 162, 162, 161, 160, 159,
158, 157, 156, 156, 155, 154, 153, 152, 151, 150, 149, 148, 148, 147, 146, 145,
144, 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129,
128, 128, 127, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113,
112, 111, 110, 109, 108, 107, 106, 105, 104, 102, 101, 100, 99, 98, 97, 96,
95, 94, 93, 91, 90, 89, 88, 87, 86, 85, 84, 82, 81, 80, 79, 78,
77, 75, 74, 73, 72, 71, 70, 69, 67, 66, 65, 64, 63, 61, 60, 59,
58, 57, 56, 54, 53, 52, 51, 50, 48, 47, 46, 45, 44, 42, 41, 40,
39, 37, 36, 35, 34, 33, 31, 30, 29, 28, 27, 25, 24, 23, 22, 20,
19, 18, 17, 15, 14, 13, 12, 11, 9, 8, 7, 6, 4, 3, 2, 1
};
class pattern_src_brightness_to_alpha
{
public:
pattern_src_brightness_to_alpha(agg::rendering_buffer& rb) :
m_rb(&rb), m_pf(*m_rb) {}
unsigned width() const { return m_pf.width(); }
unsigned height() const { return m_pf.height(); }
color_type pixel(int x, int y) const
{
color_type c = m_pf.pixel(x, y);
// It's a bit of a hack, but we can treat the 8-bit alpha value as a cover.
color_type::calc_type sum = c.r + c.g + c.b;
int i = int(sum * sizeof(brightness_to_alpha) / (3 * color_type::full_value()));
agg::cover_type cover = brightness_to_alpha[i];
c.a = color_type::mult_cover(color_type::full_value(), cover);
return c;
}
private:
agg::rendering_buffer* m_rb;
pixfmt m_pf;
};
class the_application : public agg::platform_support
{
agg::srgba8 m_ctrl_color;
agg::polygon_ctrl<color_type> m_line1;
agg::slider_ctrl<color_type> m_scale_x;
agg::slider_ctrl<color_type> m_start_x;
agg::trans_affine m_scale;
public:
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_int_sat> rasterizer_scanline;
typedef agg::scanline_p8 scanline;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_ctrl_color(agg::rgba(0, 0.3, 0.5, 0.3)),
m_line1(5),
m_scale_x(5.0, 5.0, 240.0, 12.0, !flip_y),
m_start_x(250.0, 5.0, 495.0, 12.0, !flip_y)
{
m_line1.line_color(m_ctrl_color);
m_line1.xn(0) = 20;
m_line1.yn(0) = 20;
m_line1.xn(1) = 500-20;
m_line1.yn(1) = 500-20;
m_line1.xn(2) = 500-60;
m_line1.yn(2) = 20;
m_line1.xn(3) = 40;
m_line1.yn(3) = 500-40;
m_line1.xn(4) = 100;
m_line1.yn(4) = 300;
m_line1.close(false);
add_ctrl(m_line1);
m_line1.transform(m_scale);
m_scale_x.label("Scale X=%.2f");
m_scale_x.range(0.2, 3.0);
m_scale_x.value(1.0);
add_ctrl(m_scale_x);
m_scale_x.no_transform();
m_start_x.label("Start X=%.2f");
m_start_x.range(0.0, 10.0);
m_start_x.value(0.0);
add_ctrl(m_start_x);
m_start_x.no_transform();
}
template<class Rasterizer, class Renderer>
void draw_polyline(Rasterizer& ras,
Renderer& ren,
const double* polyline,
int num_points)
{
agg::poly_plain_adaptor<double> vs(polyline, num_points, m_line1.close());
agg::conv_transform<agg::poly_plain_adaptor<double> > trans(vs, m_scale);
ras.add_path(trans);
}
virtual void on_draw()
{
pixfmt pf(rbuf_window());
renderer_base ren_base(pf);
ren_base.clear(agg::rgba(0.5, 0.75, 0.85));
renderer_scanline ren(ren_base);
rasterizer_scanline ras;
scanline sl;
ras.clip_box(0, 0, width(), height());
// Pattern source. Must have an interface:
// width() const
// height() const
// pixel(int x, int y) const
// Any agg::renderer_base<> or derived
// is good for the use as a source.
//-----------------------------------
pattern_src_brightness_to_alpha p1(rbuf_img(0));
agg::pattern_filter_bilinear_rgba<color_type> fltr; // Filtering functor
// agg::line_image_pattern is the main container for the patterns. It creates
// a copy of the patterns extended according to the needs of the filter.
// agg::line_image_pattern can operate with arbitrary image width, but if the
// width of the pattern is power of 2, it's better to use the modified
// version agg::line_image_pattern_pow2 because it works about 15-25 percent
// faster than agg::line_image_pattern (because of using simple masking instead
// of expensive '%' operation).
typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba<color_type> > pattern_type;
typedef agg::renderer_base<pixfmt> base_ren_type;
typedef agg::renderer_outline_image<base_ren_type, pattern_type> renderer_img_type;
typedef agg::rasterizer_outline_aa<renderer_img_type, agg::line_coord_sat> rasterizer_img_type;
typedef agg::renderer_outline_aa<base_ren_type> renderer_line_type;
typedef agg::rasterizer_outline_aa<renderer_line_type, agg::line_coord_sat> rasterizer_line_type;
//-- Create with specifying the source
//pattern_type patt(fltr, src);
//-- Create uninitialized and set the source
pattern_type patt(fltr);
patt.create(p1);
renderer_img_type ren_img(ren_base, patt);
rasterizer_img_type ras_img(ren_img);
//-- create uninitialized and set parameters
agg::line_profile_aa profile;
profile.smoother_width(10.0); //optional
profile.width(8.0); //mandatory!
renderer_line_type ren_line(ren_base, profile);
ren_line.color(agg::srgba8(0,0,127)); //mandatory!
rasterizer_line_type ras_line(ren_line);
ras_line.round_cap(true); //optional
//ras_line.line_join(agg::outline_no_join); //optional
// Calculate the dilation value so that, the line caps were
// drawn correctly.
//---------------
double w2 = 9.0;//p1.height() / 2 + 2;
// Set the clip box a bit bigger than you expect. You need it
// to draw the clipped line caps correctly. The correct result
// is achieved with raster clipping.
//------------------------
ren_img.scale_x(m_scale_x.value());
ren_img.start_x(m_start_x.value());
ren_img.clip_box (50-w2, 50-w2, width()-50+w2, height()-50+w2);
ren_line.clip_box(50-w2, 50-w2, width()-50+w2, height()-50+w2);
// First, draw polyline without raster clipping just to show the idea
//------------------------
draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points());
draw_polyline(ras_img, ren_img, m_line1.polygon(), m_line1.num_points());
// Clear the area, almost opaque, but not completely
//------------------------
ren_base.blend_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1), 200);
// Set the raster clip box and then, draw again.
// In reality there shouldn't be two calls above.
// It's done only for demonstration
//------------------------
ren_base.clip_box((int)50, (int)50, (int)width()-50, (int)height()-50);
// This "copy_bar" is also for demonstration only
//------------------------
ren_base.copy_bar(0, 0, (int)width(), (int)height(), agg::rgba(1,1,1));
// Finally draw polyline correctly clipped: We use double clipping,
// first is vector clipping, with extended clip box, second is raster
// clipping with normal clip box.
//------------------------
ren_img.scale_x(m_scale_x.value());
ren_img.start_x(m_start_x.value());
draw_polyline(ras_line, ren_line, m_line1.polygon(), m_line1.num_points());
draw_polyline(ras_img, ren_img, m_line1.polygon(), m_line1.num_points());
// Reset clipping and draw the controls and stuff
ren_base.reset_clipping(true);
m_line1.line_width(1/m_scale.scale());
m_line1.point_radius(5/m_scale.scale());
agg::render_ctrl(ras, sl, ren_base, m_line1);
agg::render_ctrl(ras, sl, ren_base, m_scale_x);
agg::render_ctrl(ras, sl, ren_base, m_start_x);
char buf[256];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
pt.line_cap(agg::round_cap);
const double* p = m_line1.polygon();
sprintf(buf, "Len=%.2f", agg::calc_distance(p[0], p[1], p[2], p[3]) * m_scale.scale());
t.start_point(10.0, 30.0);
t.text(buf);
ras.add_path(pt);
ren.color(agg::rgba(0,0,0));
agg::render_scanlines(ras, sl, ren);
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == '+' || key == agg::key_kp_plus)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_scaling(1.1);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
if(key == '-' || key == agg::key_kp_minus)
{
m_scale *= agg::trans_affine_translation(-x, -y);
m_scale *= agg::trans_affine_scaling(1/1.1);
m_scale *= agg::trans_affine_translation(x, y);
force_redraw();
}
}
virtual void on_ctrl_change()
{
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Clipping Lines with Image Patterns");
if(!app.load_img(0, "1"))
{
char buf[256];
sprintf(buf, "There must be file 1%s\n", app.img_ext());
app.message(buf);
return 1;
}
if(app.init(500, 500, agg::window_resize))
{
return app.run();
}
return 1;
}

145
examples/line_thickness.cpp Normal file
View File

@ -0,0 +1,145 @@
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
#include "agg_renderer_scanline.h"
#include "agg_blur.h"
#include "util/agg_color_conv.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
//#define AGG_GRAY8
//#define AGG_GRAY32
//#define AGG_BGR24
#define AGG_BGR96
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_slider1;
agg::slider_ctrl<color_type> m_slider2;
agg::cbox_ctrl<color_type> m_cbox1;
agg::cbox_ctrl<color_type> m_cbox2;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_slider1(10, 10, 640-10, 19, !flip_y),
m_slider2(10, 10+20, 640-10, 19+20, !flip_y),
m_cbox1(10, 10+40, "Monochrome", !flip_y),
m_cbox2(10, 10+60, "Invert", !flip_y)
{
add_ctrl(m_slider1);
add_ctrl(m_slider2);
add_ctrl(m_cbox1);
add_ctrl(m_cbox2);
m_slider1.label("Line thickness=%1.2f");
m_slider1.range(0.0, 5.0);
m_slider1.value(1.0);
m_slider2.label("Blur radius=%1.2f");
m_slider2.range(0.0, 2.0);
m_slider2.value(1.5);
m_cbox1.status(true);
m_cbox2.status(false);
m_slider1.no_transform();
m_slider2.no_transform();
m_cbox1.no_transform();
m_cbox2.no_transform();
}
template<class T>
void SetCtrlClr(T & ctrl, agg::rgba const & clr)
{
ctrl.text_color(clr);
ctrl.inactive_color(clr);
ctrl.active_color(clr);
}
virtual void on_draw()
{
pixfmt pf(rbuf_window());
agg::renderer_base<pixfmt> ren(pf);
agg::scanline_u8 sl;
agg::rasterizer_scanline_aa<> ras;
agg::path_storage ps;
agg::conv_stroke<agg::path_storage> pg(ps);
agg::rgba clr1 = m_cbox1.status() ? agg::rgba(1, 1, 1) : agg::rgba(1, 0, 1);
agg::rgba clr2 = m_cbox1.status() ? agg::rgba(0, 0, 0) : agg::rgba(0, 1, 0);
agg::rgba foreground = m_cbox2.status() ? clr1 : clr2;
agg::rgba background = m_cbox2.status() ? clr2 : clr1;
SetCtrlClr(m_cbox1, foreground);
SetCtrlClr(m_cbox2, foreground);
ren.clear(background);
// Draw row of straight lines.
for (int i = 0; i < 20; ++i)
{
pg.width(m_slider1.value() * 0.3 * (i + 1));
ps.remove_all();
ps.move_to(20 + 30 * i, 310);
ps.line_to(40 + 30 * i, 460);
ras.add_path(pg);
agg::render_scanlines_aa_solid(ras, sl, ren, foreground);
}
// Draw wheel of lines.
for (int i = 0; i < 40; ++i)
{
pg.width(m_slider1.value());
ps.remove_all();
ps.move_to(320 + 20 * sin(i * agg::pi / 20), 180 + 20 * cos(i * agg::pi / 20));
ps.line_to(320 + 100 * sin(i * agg::pi / 20), 180 + 100 * cos(i * agg::pi / 20));
ras.add_path(pg);
agg::render_scanlines_aa_solid(ras, sl, ren, foreground);
}
// Apply blur.
start_timer();
agg::apply_slight_blur(ren, m_slider2.value());
double tm = elapsed_time();
// Display the blur time.
char buf[64];
agg::gsv_text t;
t.size(10.0);
agg::conv_stroke<agg::gsv_text> st(t);
st.width(1.5);
sprintf(buf, "Blur: %3.2f ms", tm);
t.start_point(10.0, 90.0);
t.text(buf);
ras.add_path(st);
agg::render_scanlines_aa_solid(ras, sl, ren, foreground);
// Render the controls
render_ctrl(ras, sl, ren, m_slider1);
render_ctrl(ras, sl, ren, m_slider2);
render_ctrl(ras, sl, ren, m_cbox1);
render_ctrl(ras, sl, ren, m_cbox2);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("Anti-aliased lines with blurring");
if(app.init(640, 480, agg::window_resize))
{
return app.run();
}
return 1;
}

175
examples/lion.cpp Normal file
View File

@ -0,0 +1,175 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_bounding_rect.h"
#include "ctrl/agg_slider_ctrl.h"
#include "platform/agg_platform_support.h"
//#define AGG_GRAY16
//#define AGG_GRAY32
#define AGG_BGR24
//#define AGG_BGR48
//#define AGG_RGB_AAA
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGR96
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
agg::rasterizer_scanline_aa<> g_rasterizer;
agg::scanline_p8 g_scanline;
agg::path_storage g_path;
agg::srgba8 g_colors[100];
unsigned g_path_idx[100];
unsigned g_npaths = 0;
double g_x1 = 0;
double g_y1 = 0;
double g_x2 = 0;
double g_y2 = 0;
double g_base_dx = 0;
double g_base_dy = 0;
double g_angle = 0;
double g_scale = 1.0;
double g_skew_x = 0;
double g_skew_y = 0;
int g_nclick = 0;
unsigned parse_lion(agg::path_storage& ps, agg::srgba8* colors, unsigned* path_idx);
void parse_lion()
{
g_npaths = parse_lion(g_path, g_colors, g_path_idx);
agg::pod_array_adaptor<unsigned> path_idx(g_path_idx, 100);
agg::bounding_rect(g_path, path_idx, 0, g_npaths, &g_x1, &g_y1, &g_x2, &g_y2);
g_base_dx = (g_x2 - g_x1) / 2.0;
g_base_dy = (g_y2 - g_y1) / 2.0;
}
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_alpha_slider;
public:
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_alpha_slider(5, 5, 512-5, 12, !flip_y)
{
parse_lion();
add_ctrl(m_alpha_slider);
m_alpha_slider.no_transform();
m_alpha_slider.label("Alpha%3.3f");
m_alpha_slider.value(0.1);
}
virtual void on_resize(int cx, int cy)
{
pixfmt pf(rbuf_window());
renderer_base r(pf);
r.clear(agg::rgba(1, 1, 1));
}
virtual void on_draw()
{
int width = rbuf_window().width();
int height = rbuf_window().height();
unsigned i;
for(i = 0; i < g_npaths; i++)
{
g_colors[i].a = agg::int8u(m_alpha_slider.value() * 255);
}
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
renderer_solid r(rb);
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
mtx *= agg::trans_affine_scaling(g_scale, g_scale);
mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0);
mtx *= agg::trans_affine_translation(width/2, height/2);
// This code renders the lion:
agg::conv_transform<agg::path_storage, agg::trans_affine> trans(g_path, mtx);
agg::render_all_paths(g_rasterizer, g_scanline, r, trans, g_colors, g_path_idx, g_npaths);
// Render the control
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_alpha_slider);
}
void transform(double width, double height, double x, double y)
{
x -= width / 2;
y -= height / 2;
g_angle = atan2(y, x);
g_scale = sqrt(y * y + x * x) / 100.0;
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
int width = rbuf_window().width();
int height = rbuf_window().height();
transform(width, height, x, y);
force_redraw();
}
if(flags & agg::mouse_right)
{
g_skew_x = x;
g_skew_y = y;
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
on_mouse_button_down(x, y, flags);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Lion");
if(app.init(512, 400, agg::window_resize))
{
return app.run();
}
return 1;
}

204
examples/lion_lens.cpp Normal file
View File

@ -0,0 +1,204 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_trans_warp_magnifier.h"
#include "agg_conv_segmentator.h"
#include "agg_bounding_rect.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGR96
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
//#define AGG_RGB_AAA
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
agg::rasterizer_scanline_aa<> g_rasterizer;
agg::scanline_p8 g_scanline;
agg::path_storage g_path;
agg::srgba8 g_colors[100];
unsigned g_path_idx[100];
unsigned g_npaths = 0;
double g_x1 = 0;
double g_y1 = 0;
double g_x2 = 0;
double g_y2 = 0;
double g_base_dx = 0;
double g_base_dy = 0;
double g_angle = 0;
double g_scale = 1.0;
double g_skew_x = 0;
double g_skew_y = 0;
int g_nclick = 0;
unsigned parse_lion(agg::path_storage& ps, agg::srgba8* colors, unsigned* path_idx);
void parse_lion()
{
g_npaths = parse_lion(g_path, g_colors, g_path_idx);
agg::pod_array_adaptor<unsigned> path_idx(g_path_idx, 100);
agg::bounding_rect(g_path, path_idx, 0, g_npaths, &g_x1, &g_y1, &g_x2, &g_y2);
g_base_dx = (g_x2 - g_x1) / 2.0;
g_base_dy = (g_y2 - g_y1) / 2.0;
}
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_magn_slider;
agg::slider_ctrl<color_type> m_radius_slider;
public:
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_magn_slider (5, 5, 495, 12, !flip_y),
m_radius_slider(5, 20, 495, 27, !flip_y)
{
parse_lion();
add_ctrl(m_magn_slider);
m_magn_slider.no_transform();
m_magn_slider.range(0.01, 4.0);
m_magn_slider.value(3.0);
m_magn_slider.label("Scale=%3.2f");
add_ctrl(m_radius_slider);
m_radius_slider.no_transform();
m_radius_slider.range(0.0, 100.0);
m_radius_slider.value(70.0);
m_radius_slider.label("Radius=%3.2f");
}
virtual void on_init()
{
g_x1 = 200;
g_y1 = 150;
}
virtual void on_resize(int cx, int cy)
{
}
virtual void on_draw()
{
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
renderer_solid r(rb);
rb.clear(agg::rgba(1, 1, 1));
agg::trans_warp_magnifier lens;
lens.center(g_x1, g_y1);
lens.magnification(m_magn_slider.value());
lens.radius(m_radius_slider.value() / m_magn_slider.value());
agg::conv_segmentator<agg::path_storage> segm(g_path);
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
mtx *= agg::trans_affine_translation(width()/2, height()/2);
agg::conv_transform<
agg::conv_segmentator<
agg::path_storage> > trans_mtx(segm, mtx);
agg::conv_transform<
agg::conv_transform<
agg::conv_segmentator<
agg::path_storage> >, agg::trans_warp_magnifier> trans_lens(trans_mtx, lens);
agg::render_all_paths(g_rasterizer, g_scanline, r, trans_lens, g_colors, g_path_idx, g_npaths);
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_magn_slider);
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_radius_slider);
// Testing inverse_transform()
//--------------------
//double x, y;
//for(y = 0; y < height(); y += 10)
//{
// for(x = 0; x < height(); x += 10)
// {
// double x2 = x+0.5;
// double y2 = y+0.5;
// lens.transform(&x2, &y2);
// lens.inverse_transform(&x2, &y2);
// agg::ellipse e(x2, y2, 1, 1);
// g_rasterizer.add_path(e);
// r.color(agg::srgba8(0,0,0));
// agg::render_scanlines(g_rasterizer, g_scanline, r);
// }
//}
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
g_x1 = x;
g_y1 = y;
force_redraw();
}
if(flags & agg::mouse_right)
{
g_x2 = x;
g_y2 = y;
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
on_mouse_button_down(x, y, flags);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Lion");
if(app.init(500, 600, agg::window_resize))
{
return app.run();
}
return 1;
}

192
examples/lion_outline.cpp Normal file
View File

@ -0,0 +1,192 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_renderer_outline_aa.h"
#include "agg_rasterizer_outline_aa.h"
#include "agg_scanline_p.h"
#include "agg_renderer_scanline.h"
#include "agg_path_storage.h"
#include "agg_conv_transform.h"
#include "agg_bounding_rect.h"
#include "ctrl/agg_slider_ctrl.h"
#include "ctrl/agg_cbox_ctrl.h"
#include "platform/agg_platform_support.h"
#define AGG_BGR24
//#define AGG_RGB24
//#define AGG_BGRA32
//#define AGG_RGBA32
//#define AGG_ARGB32
//#define AGG_ABGR32
//#define AGG_BGR96
//#define AGG_BGRA128
//#define AGG_RGB565
//#define AGG_RGB555
#include "pixel_formats.h"
enum flip_y_e { flip_y = true };
agg::rasterizer_scanline_aa<> g_rasterizer;
agg::scanline_p8 g_scanline;
agg::path_storage g_path;
agg::srgba8 g_colors[100];
unsigned g_path_idx[100];
unsigned g_npaths = 0;
double g_x1 = 0;
double g_y1 = 0;
double g_x2 = 0;
double g_y2 = 0;
double g_base_dx = 0;
double g_base_dy = 0;
double g_angle = 0;
double g_scale = 1.0;
double g_skew_x = 0;
double g_skew_y = 0;
int g_nclick = 0;
unsigned parse_lion(agg::path_storage& ps, agg::srgba8* colors, unsigned* path_idx);
void parse_lion()
{
g_npaths = parse_lion(g_path, g_colors, g_path_idx);
agg::pod_array_adaptor<unsigned> path_idx(g_path_idx, 100);
agg::bounding_rect(g_path, path_idx, 0, g_npaths, &g_x1, &g_y1, &g_x2, &g_y2);
g_base_dx = (g_x2 - g_x1) / 2.0;
g_base_dy = (g_y2 - g_y1) / 2.0;
}
class the_application : public agg::platform_support
{
agg::slider_ctrl<color_type> m_width_slider;
agg::cbox_ctrl<color_type> m_scanline;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
m_width_slider(5, 5, 150, 12, !flip_y),
m_scanline(160, 5, "Use Scanline Rasterizer", !flip_y)
{
parse_lion();
add_ctrl(m_width_slider);
m_width_slider.no_transform();
m_width_slider.range(0.0, 4.0);
m_width_slider.value(1.0);
m_width_slider.label("Width %3.2f");
add_ctrl(m_scanline);
m_scanline.no_transform();
}
virtual void on_draw()
{
int width = rbuf_window().width();
int height = rbuf_window().height();
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
renderer_solid r(rb);
rb.clear(agg::rgba(1,1,1));
agg::trans_affine mtx;
mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
mtx *= agg::trans_affine_scaling(g_scale, g_scale);
mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0);
mtx *= agg::trans_affine_translation(width/2, height/2);
if(m_scanline.status())
{
agg::conv_stroke<agg::path_storage> stroke(g_path);
stroke.width(m_width_slider.value());
stroke.line_join(agg::round_join);
agg::conv_transform<agg::conv_stroke<agg::path_storage> > trans(stroke, mtx);
agg::render_all_paths(g_rasterizer, g_scanline, r, trans, g_colors, g_path_idx, g_npaths);
}
else
{
typedef agg::renderer_outline_aa<renderer_base> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
double w = m_width_slider.value() * mtx.scale();
agg::line_profile_aa profile(w, agg::gamma_none());
renderer_type ren(rb, profile);
rasterizer_type ras(ren);
agg::conv_transform<agg::path_storage> trans(g_path, mtx);
ras.render_all_paths(trans, g_colors, g_path_idx, g_npaths);
}
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_width_slider);
agg::render_ctrl(g_rasterizer, g_scanline, rb, m_scanline);
}
void transform(double width, double height, double x, double y)
{
x -= width / 2;
y -= height / 2;
g_angle = atan2(y, x);
g_scale = sqrt(y * y + x * x) / 100.0;
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if(flags & agg::mouse_left)
{
int width = rbuf_window().width();
int height = rbuf_window().height();
transform(width, height, x, y);
force_redraw();
}
if(flags & agg::mouse_right)
{
g_skew_x = x;
g_skew_y = y;
force_redraw();
}
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
on_mouse_button_down(x, y, flags);
}
};
int agg_main(int argc, char* argv[])
{
the_application app(pix_format, flip_y);
app.caption("AGG Example. Lion");
if(app.init(512, 512, agg::window_resize))
{
return app.run();
}
return 1;
}

Some files were not shown because too many files have changed in this diff Show More